Exposing a Robot
This is the model behind everything else in these docs: a robot’s ROS graph is private by default, and a developer decides what part of it becomes an API.
The five kinds of exposed service
| Kind | Direction | What it is |
|---|---|---|
| Datapoint | Robot → clients | One field of a topic, or a whole topic — never several topics at once (if you need that, publish a custom message on its own topic instead). Per field: unit, range, scaling. Optional retention. Send rate is either “max N Hz” or “only on change.” |
| Publisher | Clients → robot | Client apps publish messages onto a topic. Configured with a timeout + failsafe message the bridge publishes itself if clients go quiet, plus a user quiet-timeout (see Disconnect Behaviour). |
| Service | Request/response | A ROS service call with validated parameters. |
| Action | A job with a lifecycle | A ROS action with feedback, progress, result, and cancel. |
| Camera | Robot → clients | ROS image topic, RTSP, MJPEG or V4L2 — see Cameras. |
Every exposed service gets a slug: stable, chosen by the developer, decoupled from the ROS name. Rename the underlying topic in the robot’s launch file and no client app notices.
Three built-in datapoints, on every robot
bridge_state— online/offline plus latency. Build your app’s offline UI on this rather than inferring connectivity from timeouts.robot_details— developer-maintained static key/value metadata (strings, numbers, arrays or JSON objects) — a model name, a serial number, whatever doesn’t come from ROS.bridge_pressure— the bridge’s own bandwidth-shaping state: what the link measures, what each priority tier sent and dropped, and where the video budget stands. See Link Pressure.
None of the three is configured, and each is granted to a role like any other slug.
Configuration is offline-first
You can configure a robot that has never connected. If the bridge is connected, introspection — a browsable view of the robot’s live ROS graph, with type field trees — becomes a shortcut and a template (“adopt this topic”), not a requirement.
Every configuration change goes through draft → publish, with version history. The bridge only ever applies the published version. A configuration is copyable to another robot — copying carries the configuration and its custom type definitions together; a name collision with a differently-defined type on the target is a shown conflict, never a silent choice.
Parameter validation happens on the cloud
For every action, service or publisher parameter, the developer defines checks: min/max, enum, pattern, required. Validation happens at the cloud layer — an invalid value never reaches the bridge. The bridge does its own structural validation too (it has to construct the ROS message anyway), but the semantic rules — the ones a developer wrote — live in the cloud. Rejections are machine-readable and name the field and the rule that failed.
Custom types are per-robot
The console knows every standard ROS type globally. Custom message,
service and action types are scoped to one robot — two robots may define
custom_msgs/Speed differently. They’re either hand-defined in the console
or auto-detected from a connected bridge’s sourced workspace and offered for
adoption.
Assets: URDF and meshes
A robot’s URDF and its meshes live in a separate mechanism — the asset store, covered in its own chapter: URDF & Meshes. Assets are not a service kind; they’re immutable, UUID-addressed files, authenticated the same way as every other API call.