📡 Publishers
A publisher is a topic clients may send to. This is where the format’s whole safety story lives.
publishers:
drive:
topic: /cmd_vel
type: geometry_msgs/msg/Twist
description: Velocity command. If sending stops, the robot stops.
message:
linear: { x: "${linear_speed}", y: 0.0, z: 0.0 }
angular: { x: 0.0, y: 0.0, z: "${angular_speed}" }
parameters:
linear_speed: { type: float64, min_value: -0.5, max_value: 0.5 }
angular_speed: { type: float64, min_value: -0.25, max_value: 0.25 }
failsafe:
timeout_ms: 500
message: ${stop_twist}
quiet_timeout_ms: 2000
| field | type | bounds | absent means |
|---|---|---|---|
topic |
ROS graph name | absolute, at most 255 characters | required |
type |
ROS type name | the middle segment is msg, at most 255 characters |
required |
message |
message template | null refused at any depth |
required |
failsafe.timeout_ms |
integer | 1 to 60000 milliseconds |
required |
failsafe.message |
message template | no placeholder, at any depth | required |
quiet_timeout_ms |
integer | 0 to 600000 milliseconds |
required |
parameters |
map of names | at most 50 per entry | the message has no holes |
description |
text | 1 to 2000 characters | offered as description: null |
Everything but parameters and description is required, and three of those
required fields are about stopping rather than sending. message is required
here because a publisher with nothing to send is not a publisher.
No client ever names a topic. A caller addresses the entry by its slug, so the topics an app can write to are exactly the ones written in this file.
failsafe is required
The deadline and the message sit in one group because the deadline exists only to trigger the message.
timeout_ms— how long the bridge waits for the client’s next send before stepping in.message— what the bridge itself sends when that time runs out. For a drive command, a zero twist.
That is the core of it. A client that crashes, loses its connection, or whose operator closes the window does not leave a robot driving. The failsafe message has to be safe in every state, because it is sent precisely when nobody is watching any more.
The deadline runs on the robot, not in the cloud. So it still fires when the link to the cloud is what failed, which is the case it exists for.
The failsafe message may hold no placeholder, inline or through a
shared message. There
is no caller left to fill one, and the refusal is
failsafe_has_parameters.
quiet_timeout_ms answers a different question
It is how long this publisher must stay silent before another user may send to it. Whoever sends holds the publisher implicitly exclusive, with no session and no lock, so this one number is the whole handover policy.
Too short and two operators fight over one robot. Too long and a crashed
client blocks it for everyone for minutes. 0 hands the publisher over the
moment a send finishes.
A caller who arrives too early is refused with publisher_busy, and the
refusal carries the configured quiet_timeout_ms and the milliseconds left to
wait.
One type per publisher
type fixes the shape that message and failsafe.message both have to
fill. A second message type therefore needs a second publisher, which is also
what lets a role grant one and withhold the other.
The parameter constraints are enforced in the cloud before anything reaches the robot, and are described under Messages & Parameters.