Appendix A: Topic reference

Every topic pattern in one table: key, transport, direction, payload and rate.

Every wire name in the system has the shape vrobots/<sys_id>/<transport>/<subject...>, where the segment after the id names the transport, z for zenoh and i for iceoryx2. The words manager and scene sit where a sys_id would, so a scope key can never collide with a robot key. Both ends of a wire must match byte for byte and a mismatch is silent: a subscriber on a slightly wrong key never fires, and a GET to an unopened key returns NoResponder. vrobots topic list prints what is really there, tagged [z] or [i].

Every topic

Key patternWireDirectionContentsRate
vrobots/{sys_id}/z/state[z]the simulator publishesswarmbotix.states.State, the full snapshot: kinematics, wrench, actuator, sensors, environment, estimate25 Hz
vrobots/{sys_id}/z/cmd[z]the simulator subscribesswarmbotix.commands.Command, one command id plus its CmdArgs. Many-to-many, so clients can read it tooset by the sender; the in-game IMU panel publishes SET_ANGVEL at 50 Hz
vrobots/{sys_id}/z/frames[z]the simulator publishesswarmbotix.coordinates.CoordFrameDef, the resulting frame definitions, one message per distinct frame the robot and its devices use. Distinct from the srv/frames service, which sets them. Read with frame_defon change, plus a slow keepalive
vrobots/{sys_id}/z/estimate[z]the simulator subscribesswarmbotix.states.EstimateState, an attitude estimate you publish with publish_estimate or publish_estimate_euler. Read by the fixed wing under FW_EST_OBSERVER; nothing else consumes it, and the simulator never echoes it back into State.estimateset by the sender; aged from arrival and stale after 0.5 s, so publish at 20 Hz or better
vrobots/{sys_id}/z/srv/{segment}[z]request and responseper-robot services; see the segment tables belowon demand
vrobots/{sys_id}/i/cam/{name}/{res}_{fmt}[i]the simulator publishesraw camera frames, shared memory, same host onlynot documented; measure with vrobots topic hz
vrobots/manager/z/srv/create[z]request and responseSrvVRobotCreate to SrvVRobotCreated; the reply carries the assigned sys_id. The one non-idempotent service in the systemon demand
vrobots/manager/z/srv/delete[z]request and responseSrvVRobotDelete to SrvAck. Answers ok = false for an unknown sys_idon demand
vrobots/scene/z/srv/frame[z]request and responsepayload-less GET to SrvAck whose message is the scene's active coordinate frame id. Scene scope: one answer however many robots are loadedon demand

Two wildcards the SDK subscribes with rather than publishes on: vrobots/**, which backs topic discovery, and vrobots/*/z/state, which is the whole-swarm state subscribe.

Common service segments

Every live robot serves all seven of these on vrobots/{sys_id}/z/srv/{segment}.

SegmentRequest to replyPurposeSDK entry point
activatepayload-less GET to SrvAckreleases a dormant robot's dynamics hold; an already-active robot acks and no-opsactivate, and connect when activate_after_create is set
resetSrvReset, or a payload-less GET, to SrvAckteleports to the first-physics-step pose, zeroes velocity, rests the actuators, re-latches the initial commandreset
paramsSrvVRobotPhysicalProperty to SrvAckmass and principal moments of inertiaset_physical_params
skinSrvVRobotSkin to SrvAckappearance; the only service that ever answers ok = falseset_skin
sensorsSrvSensorConfig to SrvAcknoise models and GPS quality, gated block by blockconfigure_sensors
framesSrvVRobotFrame to SrvAckwhich coordinate frame the robot and each device report inset_frames
camerasSrvCameraConfig to SrvAckupsert, remove or replace the camera listmount_camera, mount_camera_with, unmount_camera

Gotcha. reset and activate are the two keys where a payload-less GET performs the action instead of probing for a receipt. The simulator enqueues the empty request because the in-game Reset button cannot attach a payload. Probing srv/reset for reachability resets the robot; probing srv/activate releases a dormant robot's hold, which is idempotent and so harmless on one already running.

Type-specific service segments

SegmentRequest to replyRobotSDK entry point
driveSrvUgvDriveConfig to SrvAckTruckconfigure_drive
rotorsSrvMultirotorRotorConfig to SrvAckMultirotorconfigure_rotors
msdSrvMsdConfig to SrvAckMsdconfigure_msd
cartpoleSrvCartPoleConfig to SrvAckCartPoleconfigure_cartpole

HalfDrone and GlobalHawk add nothing to the common seven. Querying a segment the robot's type does not serve is not an error on the wire, only a GET nobody answers, which the SDK reports as NoResponder and which is exactly how a capability probe works.

One key, decomposed

vrobots/1/i/cam/front_left/720p_rgba8

SegmentValueMeaning
1vrobotsthe root every key in the system shares
21the sys_id; manager or scene here means a scope rather than a robot
3iiceoryx2, so shared memory and same host only; z would be zenoh
4camthe subject
5front_leftthe camera name, from CameraSpec::name
6720p_rgba8{res}_{fmt}, from CameraSpec::stream_segment(): 1280 by 720, four bytes per pixel

The format segment is part of the key, so changing a camera's resolution or pixel format renames its stream. A reader opened on the old name goes quiet rather than failing. CameraStream::service_name() returns the key that vrobots topic list prints, character for character, which is the fastest way to check the two agree.

Next: Appendix B: Command reference

See also: The topic namespace, Discovery from code