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:
typetask_id(string or number allowed)task_type(start,complete,fail,reject, etc.)
Recommended fields:
action_namedevice_iddevice_namereasonfail_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)
Recommended state-transition sequence
TASK_STARTEDwhen work beginsTASK_COMPLETEDon normal completionTASK_FAILEDorTASK_ABORTEDon failure or stopTASK_REJECTEDwhen refusing concurrent work
Default config.yaml locations
cobiz/src/cobiz_bridge/config/config.yamlinstall/cobiz_bridge/share/cobiz_bridge/config/config.yaml
videos configuration
Meaning of source and format
type: topicsource: ROS image topic nameformat: input image pixel-format hint (rgb8,bgr8,jpeg, etc.)
type: rtspsource: RTSP URLformat: stream codec hint (H264,H265,JPEG)
type: uvcsource: 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 withtype: 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: MJPEGSize: Discrete 1280x720→width: 1280,height: 720Interval: 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: alsasource: ALSA input device name (hw:CARD=PCH,DEV=0,plughw:CARD=PCH,DEV=0, etc.)
type: pulsesource: Pulse source name
type: rtspsource: RTSP URLformat:mulaworalawsample_rate: RTP clock-rate hint
How to inspect ALSA input devices:
cat /proc/asound/cards
arecord -l
arecord -L
speaker configuration
type: alsasource: ALSA output device name
type: pulsesource: Pulse sink name
- the critical values are
type,source,rate, andchannels
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 addressserver.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.