Robot Configuration
robot.toml is the per-robot configuration the agent reads at startup. It declares
the robot's transport, ingest and command topics, command policy, and the UI
capabilities (services, sensors, settings, and resource producers) the robot
advertises to the fleet manager. This page documents every key the agent parses.
File location and loading
- Path:
{state_dir}/robot.toml, where the state directory defaults to/var/lib/rdyn/robot(override with theRDYN_STATE_DIRenvironment variable). So the default path is/var/lib/rdyn/robot/robot.toml. - Read once at startup. The agent loads the file a single time when it starts. Changes take effect on the next agent restart.
- Format: TOML. All config access goes through the agent's central loader; do not parse config files elsewhere in your own on-host tooling.
- Unknown keys are ignored silently, so a typo in a key name is dropped rather than reported.
- No secrets.
robot.tomlholds no keys, certificates, CA roots, or tokens; those live in separate files referenced by path fromagent.toml.
Every section below is optional. A minimal (even empty) robot.toml is valid: the
agent then uses local Zenoh with the robot/** uplink wildcard, the command
base topic, all commands allowed, and no advertised UI capabilities.
What lives in agent.toml instead
Some settings that relate to the robot are not part of robot.toml. The agent
reads them from agent.toml, and keys for them placed in robot.toml are ignored:
- The robot's identity (
robot_id), written intoagent.tomlduring enrollment. - Server and signaling URLs.
- TLS paths (
ca_root,device_cert,key_private) and Zenoh router endpoints.
See the agent Configuration reference for
those. The local coordinate origin is also not a robot.toml key: it is
delivered as onboard settings from the cloud and persisted by the agent. See
Coordinate Frames.
Naming convention. The top-level flags and the keys under
[zenoh_topics],[zenoh_command_topics],[local_transport], and[allowed_commands]usesnake_case. The capability-array fields under[[services]],[[sensors]],[[settings]], and[[resources]]usecamelCase(for examplecapabilityType,displayHint,geometryType). Enum-valued fields are case-insensitive.
System flags (top-level keys)
These keys sit at the top of the file, outside any section.
| Key | Default | What it controls |
|---|---|---|
use_ros2 |
true |
Detection-only flag. The agent always uses the local Zenoh Cap'n Proto path regardless of this value; ROS 2 systems run an external bridge onto the same topics. The value is logged at startup and reserved for future use. |
mission_catch_up_window_sec |
3600 |
Mission catch-up window, in seconds. At startup the scheduler deletes any persisted mission whose scheduled end time is older than now - window. Default is one hour. |
enforce_spatial_directives |
true |
Enables the agent-side field rule evaluator. See below. |
convert_commands_to_local |
false |
Delivers downlink geometry in your local ENU frame instead of WGS84. See below. |
allow_remote_config_read |
false |
Lets the fleet server fetch this file over the control plane. See below. |
allow_remote_config_write |
false |
Lets the fleet server overwrite this file over the control plane. See below. |
robot_link |
(unset) | Optional URL to the robot's local user interface or OEM UI. Reported to the fleet server at startup and shown in the fleet UI. See below. |
enforce_spatial_directives. When true, the agent compares the robot's WGS84
position against stored polygon field rules and, on zone enter/exit, reports status
to the server and applies the zone's settings and services to your robot software.
Set it to false to disable only the agent-side evaluator: field rules are
still persisted and queryable, and any status your robot software publishes itself
is still forwarded. (The key name mirrors the wire identifier; the customer-facing
concept is "field rules.") See Field Rules.
convert_commands_to_local. When true and a local origin is configured,
the agent converts geometry-bearing commands and query replies from WGS84 into your
robot's local ENU frame before delivering them. The default passes WGS84 through
unchanged. Inbound telemetry is always normalized to WGS84 regardless of this flag.
See Coordinate Frames.
Remote config access. When enabled, the fleet server can remotely read
(allow_remote_config_read) and/or overwrite (allow_remote_config_write) this
file over the control plane. Both default to false, so remote access is strictly
opt-in. A remote overwrite replaces the whole file and takes effect on the next
agent restart. Because robot.toml holds no secrets, exposing it is low-risk, but
it is still the operator's explicit choice.
robot_link. An optional URL pointing at the robot's on-device user interface
or OEM UI — a page an operator can open to reach the robot directly. When set, the
agent reports it to the fleet server at startup (over the control plane); the server
records it against the robot so the fleet UI can link to it. Leave it unset (the
default) to report no link. Unlike the flags above, this is a string, not a boolean,
and blank/whitespace-only values are treated as unset.
# robot.toml system flags (all shown with their defaults)
use_ros2 = true
# mission_catch_up_window_sec = 3600
# enforce_spatial_directives = true
# convert_commands_to_local = false
# allow_remote_config_read = false
# allow_remote_config_write = false
# robot_link = "https://192.168.1.50/ui" # optional; unset by default
[local_transport]
Selects the transport for the robot-software to agent hop on the same host. Absent
(the default) means local Zenoh. kind = "uds" switches to a Unix domain socket
carrying the same Cap'n Proto payloads.
[local_transport]
kind = "uds" # "zenoh" (default) | "uds"
uds_socket_path = "/run/rover-agent/agent.sock" # optional; this is the default
kind = "uds" requires the agent's local-uds build feature (on by default);
otherwise the agent logs a warning and falls back to Zenoh. See
Unix Domain Socket.
[zenoh_topics] (uplink ingest)
Your robot software (or the ROS 2 bridge) publishes Cap'n Proto
RobotUplinkMsg to these local Zenoh keys, and the agent subscribes to them. The
keys carry no robot id; the agent adds identity when it relays to the cloud.
By default the agent subscribes to a single wildcard key, wildcard_topic =
"robot/**", which receives every uplink type. While wildcard_topic is set, the
per-type keys are ignored. The per-type keys let you name individual subscriptions;
their default topic names (all sub-keys of robot/**) are:
| Key | Default local key | Message type |
|---|---|---|
motion_telemetry_topic |
robot/telemetry/motion |
GlobalMotionTelemetry |
status_telemetry_topic |
robot/telemetry/status |
StatusTelemetry |
extras_topic |
robot/telemetry/extras |
SensorTelemetry |
fault_topic |
robot/fault |
Fault |
mission_topic |
robot/mission |
MissionRunStatus |
geometry_topic |
robot/geometry |
Feature (reported) |
path_topic |
robot/path |
Path |
object_topic |
robot/object |
Object |
system_health_topic |
robot/health |
SystemHealth |
usage_telemetry_topic |
robot/usage |
UsageTelemetry |
consumable_status_topic |
robot/consumable |
ConsumableStatus |
wildcard_topic |
robot/** |
all types (takes precedence when set) |
[zenoh_topics]
# Option A: one subscription for everything (the default behavior)
wildcard_topic = "robot/**"
# Option B: name topics per message type (omit wildcard_topic to use these)
# motion_telemetry_topic = "robot/telemetry/motion"
# fault_topic = "robot/fault"
For the full uplink message catalog and publishing conventions, see Uplink Messages and Telemetry Mappings.
[zenoh_command_topics] (downlink)
The agent publishes each downlink command as a Cap'n Proto RobotCommand. A command
goes to the base command_topic unless a per-command subtopic is set, in which case
it goes to {command_topic}/{subtopic}. Every subtopic is optional.
| Key | Default | Command |
|---|---|---|
command_topic |
command |
Base topic; every command with no subtopic set. |
set_mode_topic |
(base) | SetRobotMode |
goto_topic |
(base) | NavigateTo |
velocity_topic |
(base) | VelocityCmd |
stop_topic |
(base) | Pause |
resume_topic |
(base) | Resume |
service_topic |
(base) | InvokeService |
mission_topic |
(base) | ControlMissionRun |
mission_command_topic |
(base) | AssignMission |
spatial_directive_topic |
(base) | SpatialDirective (field rules) |
geometry_topic |
(base) | UpdateFeature |
path_topic |
(base) | Path |
object_topic |
(base) | Object |
setting_topic |
(base) | UpdateSettings |
teleop_joy_topic |
(base) | TeleopJoy |
agent_text_topic |
(base) | AgentTextRequest |
say_text_topic |
(base) | SayText |
message_confirmation_topic |
(base) | MessageConfirmation |
[zenoh_command_topics]
command_topic = "command" # base (default)
velocity_topic = "velocity" # VelocityCmd -> "command/velocity"
stop_topic = "stop" # Pause -> "command/stop"
# keys not listed fall through to the base "command" topic
Subscribe to the base command key (or command/** when you split by subtopic) to
receive all commands. See Command Messages.
[allowed_commands]
Gates which commands the fleet manager may send to this robot. Every command
defaults to allowed, so you list only the ones you want to restrict by
setting them to false. Omitting the section (or restricting nothing) leaves every
command allowed and sends no AllowedCommands message at startup. Pause and
Resume cannot be restricted.
Recognized keys, all defaulting to true:
set_mode, assign_mission, control_mission_run, invoke_service,
update_settings, update_feature, spatial_directive, object, go_to,
velocity_cmd, teleop_joy, agent_text_request, say_text_request,
message_confirmation.
# A robot that forbids manual teleop and raw velocity commands.
[allowed_commands]
teleop_joy = false
velocity_cmd = false
UI capabilities
The [[services]], [[sensors]], [[settings]], and [[resources]] arrays
describe what the fleet manager UI renders for this robot. They are bundled into a
Capabilities message sent to the server at startup. Each is a TOML array of
tables, so repeat the header to add entries. For the concept and how the cloud
matches work to robots, see Capabilities.
[[services]]
Actions and mission types the robot advertises.
| Field | Required | Purpose |
|---|---|---|
name |
yes | Unique identifier passed back in the invoke-service command. |
description |
yes | Human-readable description shown in the UI. |
capabilityType |
yes | trigger (one-shot button), setbool (on/off toggle; alias switch), or missiontype (declares a mission type the robot can perform; no button). |
requiresRole |
no | Minimum role to invoke: viewer, operator, admin, or owner. Default operator. |
confirmationMessage |
no | If set, the UI shows a confirmation dialog with this text before invoking. |
dangerLevel |
no | normal, warning, or critical. Affects UI styling. Default normal. |
stateKey |
no | Links a toggle to a sensor key whose current bool value reflects the service state. |
[[services]]
name = "start_mowing"
description = "Begin autonomous mowing routine"
capabilityType = "trigger"
requiresRole = "operator"
confirmationMessage = "This will start the blades. Proceed?"
dangerLevel = "warning"
[[services]]
name = "lights"
description = "Toggle work lights"
capabilityType = "setbool"
requiresRole = "viewer"
stateKey = "lights_on"
[[services]]
name = "area_coverage"
description = "Area coverage mission"
capabilityType = "missiontype"
[[sensors]]
Read-only values shown in the UI.
| Field | Required | Purpose |
|---|---|---|
key |
yes | Unique identifier; matches the key the robot publishes in telemetry extras. |
label |
yes | Human-readable label shown in the UI. |
valueType |
yes | Simple type string, int, number, or bool; or an enumerated type { enum = { options = ["A", "B"] } }. |
unit |
no | Unit string displayed after the value (for example %, V). |
range |
no | [min, max] used for gauge bounds and validation. |
displayHint |
no | UI rendering hint: none, onOff, gauge, text, online, warningLight, temperature, or progress. Default none. |
[[sensors]]
key = "batteryPct"
label = "Battery"
valueType = "number"
unit = "%"
range = [0.0, 100.0]
displayHint = "gauge"
[[sensors]]
key = "mode"
label = "Mode"
valueType = { enum = { options = ["IDLE", "AUTO", "MANUAL"] } }
displayHint = "text"
[[settings]]
Configurable parameters the operator can edit from the UI. The agent seeds each default into its local settings store the first time it sees the key (insert-if-not-exists), then tracks updates from either the fleet manager or your robot software and persists them across restarts. Settings are queryable locally and remotely (see Zenoh queryables).
| Field | Required | Purpose |
|---|---|---|
key |
yes | Unique identifier used in settings-update messages. |
label |
yes | Human-readable label shown in the UI. |
default |
yes | Default value, tagged with its type (see below). |
range |
no | [min, max] bounds for numeric values. |
step |
no | Step increment for numeric sliders in the UI. |
The default is a tagged value. Use the form that matches the type:
default = { type = "string", data = "value" }
default = { type = "int", data = 42 }
default = { type = "number", data = 1.5 }
default = { type = "bool", data = true }
default = { type = "enum", data = { value = "MED", options = ["LOW", "MED", "HIGH"] } }
[[settings]]
key = "maxSpeedMps"
label = "Max speed"
default = { type = "number", data = 1.2 }
range = [0.0, 3.0]
step = 0.1
[[settings]]
key = "cutHeight"
label = "Cut height"
default = { type = "enum", data = { value = "MED", options = ["LOW", "MED", "HIGH"] } }
[[resources]]
Feature/resource channels this robot can produce: geographic features of a given type that Rover Nexus can then use in operations and missions (for example detected pallet locations, or mowed-area coverage).
| Field | Required | Purpose |
|---|---|---|
id |
yes | Stable resource-producer id. The robot references this id when reporting features for the channel. |
label |
no | Human-readable label shown in the UI. Defaults to id. |
description |
no | Human-readable description shown in the UI. |
geometryType |
yes | Geometry the producer emits: point, lineString, polygon, multiPoint, multiLineString, or multiPolygon. |
layerRole |
yes | Role of the produced features. One of: allowedArea, preferred, keepout, softExclusion, workArea, target, queue, controlZone, triggerZone, coverage, occupied, reserved, consumed, hazard, blocked, plannedPath. |
geometryType and layerRole are case-insensitive and ignore separators, so
workArea, work_area, and WorkArea are equivalent.
[[resources]]
id = "pallet_locations"
label = "pallet locations"
description = "Location of detected pallets"
geometryType = "point"
layerRole = "target"
[[resources]]
id = "coverage"
label = "Mowed area"
geometryType = "multiPolygon"
layerRole = "coverage"