Skip to main content
Version: 3.4.x

Plugin Contract and Config Authoring

/task_state plugin contract

Why publish to /task_state

  • removes duplicated HTTP logic across plugins
  • centralizes token and address management
  • creates a single place for failure analysis and logs
  • lets plugins focus on domain logic

Publish rules

Required fields:

  • type
  • task_id (string or number allowed)
  • task_type (start, complete, fail, reject, etc.)

Recommended fields:

  • action_name
  • device_id
  • device_name
  • reason
  • fail_point

Example:

{
"type": "TASK_STARTED",
"task_id": 12059,
"task_type": "start",
"action_name": "SLAM_NAVIGATION",
"device_id": 4559,
"device_name": "isaac-sim"
}

Python example:

from std_msgs.msg import String
import json

pub = node.create_publisher(String, '/task_state', 10)

body = {
'type': 'TASK_COMPLETED',
'task_id': task_id,
'task_type': 'complete',
'action_name': action_name,
'device_id': device_id,
'device_name': device_name,
}
msg = String()
msg.data = json.dumps(body)
pub.publish(msg)
  1. TASK_STARTED when work begins
  2. TASK_COMPLETED on normal completion
  3. TASK_FAILED or TASK_ABORTED on failure or stop
  4. TASK_REJECTED when refusing concurrent work

Default config.yaml locations

  • cobiz/src/cobiz_bridge/config/config.yaml
  • install/cobiz_bridge/share/cobiz_bridge/config/config.yaml

videos configuration

Meaning of source and format

  • type: topic
    • source: ROS image topic name
    • format: input image pixel-format hint (rgb8, bgr8, jpeg, etc.)
  • type: rtsp
    • source: RTSP URL
    • format: stream codec hint (H264, H265, JPEG)
  • type: uvc
    • source: camera device path (for example /dev/video0)
    • format: capture format supported by the device (MJPEG, YUY2, H264, etc.)

What UVC means

  • UVC (USB Video Class) is the standard for USB cameras.
  • USB cameras that appear as /dev/video0, /dev/video1, and similar paths are typically configured with type: uvc.
  • In day-to-day practice, thinking of it as “a USB camera” is usually accurate enough.

How to verify width, height, and fps

v4l2-ctl --list-devices
ls -l /dev/video*
v4l2-ctl --device=/dev/video0 --list-formats-ext

Examples of mapping command output into config:

  • Pixel Format: 'MJPG'format: MJPEG
  • Size: Discrete 1280x720width: 1280, height: 720
  • Interval: Discrete 0.033s (30.000 fps)fps: 30

UVC example:

videos:
- name: usb_front
type: uvc
source: /dev/video0
format: MJPEG
width: 1280
height: 720
fps: 30

Topic-input inspection example:

ros2 topic list | grep image
ros2 topic info -v /realsense/color/image_raw
ros2 topic hz /realsense/color/image_raw
videos:
- name: front_camera
type: topic
source: /realsense/color/image_raw
format: rgb8
width: 1280
height: 720
fps: 30

audios configuration

  • type: alsa
    • source: ALSA input device name (hw:CARD=PCH,DEV=0, plughw:CARD=PCH,DEV=0, etc.)
  • type: pulse
    • source: Pulse source name
  • type: rtsp
    • source: RTSP URL
    • format: mulaw or alaw
    • sample_rate: RTP clock-rate hint

How to inspect ALSA input devices:

cat /proc/asound/cards
arecord -l
arecord -L

speaker configuration

  • type: alsa
    • source: ALSA output device name
  • type: pulse
    • source: Pulse sink name
  • the critical values are type, source, rate, and channels

How to inspect output devices:

aplay -l
aplay -L
pactl info
pactl list short sinks
fuser -v /dev/snd/*

bridge and server configuration

  • bridge.address: target request API address
  • server.id, server.token: filled after registration

Full example

videos:
- name: front_camera
type: topic
source: /realsense/color/image_raw
format: rgb8
width: 1280
height: 720
fps: 30

- name: rear_usb_camera
type: uvc
source: /dev/video0
format: MJPEG
width: 1280
height: 720
fps: 30

- name: ceiling_rtsp
type: rtsp
source: rtsp://user:pass@192.168.0.10:554/stream1
format: H264
width: 1920
height: 1080
fps: 15

audios:
- name: mic_front
type: alsa
source: plughw:CARD=Device,DEV=0
sample_rate: 16000
channels: 1

topics:
battery: /battery_state
custom:
- /diagnostics
- /robot_state

bridge:
address: dev.cobiz.kr
device_name: robot-01
secret_key: change-me
device_info_period: 5.0

lidar:
- name: main_lidar
topic: /points

control:
default_mode: false
default_topic: /joy
topics:
- name: go2_control
topic: /go2_control
- name: arm_control
topic: /arm/joy

actions:
custom:
- CUSTOM_ACTION1
- CUSTOM_ACTION2
slam_navigation:
enabled: true
map_topic: /map
odom_topic: /odom
3d_navigation:
enabled: true
odom_topic: /odom
path_topic: /trajectory
map_navigation:
enabled: true
gps_navigation:
enabled: false
gps_topic: /fix
tts: true
parking: false

speaker:
- name: speaker
type: pulse
source: alsa_output.usb-robot_speaker.analog-stereo
format: S16LE
rate: 48000
channels: 1

server:
state: NotRegistered
id: ~
token: ~

Minimal example:

videos:
- name: front_camera
type: topic
source: /realsense/color/image_raw
format: rgb8
width: 1280
height: 720
fps: 30

audios: ~
topics:
battery: /battery_state
custom: ~

bridge:
address: dev.cobiz.kr
device_name: robot-01
secret_key: change-me
device_info_period: 5.0

lidar: ~

control:
default_mode: false
default_topic: ~
topics: ~

actions:
custom: ~
slam_navigation:
enabled: false
map_topic: ~
odom_topic: ~
3d_navigation:
enabled: false
odom_topic: ~
path_topic: ~
map_navigation:
enabled: false
gps_navigation:
enabled: false
gps_topic: ~
tts: false
parking: false

speaker: ~

server:
state: NotRegistered
id: ~
token: ~

If actions.3d_navigation.enabled: true, then odom_topic is registered as the ODOMETRY Track and path_topic is registered as the TRAJECTORY Track, while TRAJECTORY is executed from manager_node through sensor_node.