rt-control HTTP API
On this page
- Quick start
- Operations at a glance
- Connecting
- Request envelope
- Idempotent retries
- Responses and errors
- Common reasons
- Observation
- describe
- status
- jog_clock
- jog_status
- jog_ingress
- subscribe_events
- telemetry
- resource
- Authority
- acquire
- renew
- release
- stop
- Machine control
- enable
- arm
- home
- halt
- restore_anchor
- reset_fault
- recovery_status
- io_arm
- io_disarm
- mark_telemetry
- Jog
- begin_jog
- update_jog
- end_jog
- jog
- Trajectories
- prepare_trajectory
- start_trajectory
- discard_trajectory
- Programs
- prepare_program
- start_program
- Reserved operations
- abort
- readiness
- Types
- Authority
- Requests and responses
- Motion
- Jog
- Description
- Status
- Recovery
- Events
- Telemetry
- Cell I/O
- Related pages
rt-control is the only public way to command a RosieOS cell. It serves HTTP/1.1 and JSON over a Unix socket on the cell host, and optionally over mutual TLS for remote clients. Every client uses it: the offline programming server, the motion servers, the pendant, rtctl and your own code. Behind it, rt-control talks to the real-time core over a private IPC channel, which is internal and not part of this API.
This page is generated from the contract file rt-core/protocol/application-v1.schema.json (contract_version 2) and the adapter code. It lists all 33 capabilities, every request and response field, and the reason codes each operation can return. The full catalogue of 153 reason codes is on Error codes and fault states.
Warning
Commands on this page move hardware. enable, arm, home, jog and every Start energise the drives. The hardware E-stop is the only emergency stop: RosieOS has no software E-stop, and stop is not one. Only planned weld programs pass the planner's collision and limit check before they can be loaded. Jog, Home and point-list moves rely on the core's limit and readiness checks only. Read the safety model before you arm a real cell.
Tip
Machine-readable. The same contract as an OpenAPI 3.1 document, the contract file itself, and every reason code as JSON.
Quick start#
Read the description and status, then take and release authority, from a shell on the cell host (or on a machine running the simulated core). The socket path is the installed default.
SOCK=/run/rosie-rt-core/control.sock
rt() { curl -sS --unix-socket "$SOCK" "http://localhost$1" "${@:2}"; }
# 1. Who is this cell? Check the backend, identity and axis order.
rt /v1/describe | jq '.data | {backend, machine_sha256, cycle_ns, axes: [.axes[] | {id, position_unit, min_position, max_position}]}'
# 2. What is it doing now?
rt /v1/status | jq '{armed: .data.core.armed, homed: .data.core.home_valid_mask, faults: .data.core.safety_fault_mask}'
# 3. Take authority, then give it back. Use the pair ID and revision rt-control was started with.
D=$(rt /v1/describe)
GRANT=$(rt /v1/control -H 'Content-Type: application/json' -d "$(jq -n --argjson d "$D" '{
schema: "rosie.rt-control.request.v1", operation: "acquire", controller: "curl-demo",
binding: {pair_id: "cell-a", revision: 1,
configuration_sha256: $d.data.configuration_sha256, machine_sha256: $d.data.machine_sha256}}')")
echo "$GRANT" | jq '.data | {session, generation, lease_ms}'
rt /v1/control -d "$(echo "$GRANT" | jq '{schema: "rosie.rt-control.request.v1", operation: "release",
session: .data.session, generation: .data.generation}')" | jq '.data.session == ""'The default lease is 500 ms, and a shell cannot renew it between steps. For anything beyond this round trip, use a client that renews in the background: the Go SDK or the C++ client. rtctl wraps the same calls for one-off commands; see rtctl.
Operations at a glance#
Each capability has a state. implemented means the interface exists and is tested in software; it is not a hardware qualification. interim is the current reset API, test_only is for fixtures, and unimplemented returns capability_unimplemented. Describe returns this list at run time.
| Operation | State | Transport | Lease | Result |
|---|---|---|---|---|
telemetry | implemented | GET /v1/telemetry?after=<sequence>GET /v1/telemetry/stream?after=<sequence> | none | TelemetryBatch |
mark_telemetry | implemented | POST /v1/control | session and generation | sequence |
acquire | implemented | POST /v1/control | no fence; checks binding | Grant |
renew | implemented | POST /v1/control | session and generation | Grant |
release | implemented | POST /v1/control | session and generation | Grant |
stop | implemented | POST /v1/control | session and generation | Grant |
enable | implemented | POST /v1/control | session and generation | sequence |
arm | implemented | POST /v1/control | session and generation | sequence |
home | implemented | POST /v1/control | session and generation | sequence |
reset_fault | interim | POST /v1/control | session and generation | RecoveryStatus |
recovery_status | implemented | POST /v1/control | session and generation | RecoveryStatus |
jog | test_only | POST /v1/control | session and generation | sequence |
begin_jog | implemented | POST /v1/control | session and generation | handle |
end_jog | implemented | POST /v1/control | session and generation | handle |
prepare_trajectory | implemented | POST /v1/control | session and generation | handle |
start_trajectory | implemented | POST /v1/control | session and generation | sequence |
discard_trajectory | implemented | POST /v1/control | session and generation | sequence |
start_program | implemented | POST /v1/control | session and generation | sequence |
describe | implemented | GET /v1/describe | none | Description |
status | implemented | GET /v1/status | none | ProcessStatus |
jog_clock | implemented | GET /v1/jog/clock | none | LocalJogClock |
jog_status | implemented | GET /v1/jog | none | JogObservation |
jog_ingress | implemented | GET /v1/jog/ingress | none | JogIngressObservation |
prepare_program | implemented | POST /v1/program | session and generation headers | Program |
update_jog | implemented | jog.sock datagram or WSS /v1/jogprotocol/control.json local_jog_update | session and generation | JogObservation |
halt | implemented | POST /v1/control | session and generation | Response.sequence/native_result |
abort | unimplemented | none | none | none |
subscribe_events | implemented | GET /v1/events?after=<sequence>GET /v1/events/stream?after=<sequence> (SSE) | none | EventBatch |
readiness | unimplemented | none | none | none |
restore_anchor | implemented | POST /v1/control | session and generation | RecoveryStatus |
io_arm | implemented | POST /v1/control | session and generation | sequence |
io_disarm | implemented | POST /v1/control | session and generation | sequence |
resource | implemented | GET /v1/resources/<sha256> | none | binary |
Connecting#
| Transport | Address | Who can use it |
|---|---|---|
| HTTP over a Unix socket | /run/rosie-rt-core/control.sock (a link to public/control.sock in the same directory) | Local processes in the socket's group. File permissions are the authentication. |
| Jog datagrams | /run/rosie-rt-core/jog.sock | Local jog producers. Binary frames only; see update_jog. |
| HTTPS with mutual TLS 1.3 | --remote-listen, which cell configs set to 127.0.0.1:8443 | Remote clients with a certificate from the cell's component CA. See Remote access. |
rt-control's own flags set these paths: --socket (default /run/rosie-rt-core/control.sock; jog.sock is created beside it) and --remote-listen. Use localhost as the HTTP host name on the Unix socket. Keep connections alive: the listener's idle timeout is control_idle_timeout_ns from Describe (90 s).
Request envelope#
Every JSON command is a POST /v1/control whose body is one Request object. schema and operation are always required. After acquire, every command also carries the session and generation of the current grant (the fence). Fields an operation does not use can be omitted. The server decodes strictly: unknown fields, duplicate fields and trailing data are refused.
| Name | Type | Required | Description |
|---|---|---|---|
request_id | string | No | Optional, non-null string of 1..64 printable ASCII bytes (0x20..0x7e). |
schema | string | Yes | Exactly rosie.rt-control.request.v1. |
operation | string | Yes | Operation name, for example acquire. Only POST /v1/control operations dispatch here. |
| (embedded) | Fence | Yes | All fields of Fence appear at this level of the object. |
label | string | No | mark_telemetry requires 1..128 UTF-8 bytes; free-text dump label. |
controller | string | No | Acquire requires 1..63 bytes; opaque controller name. |
binding | Binding | No | Acquire requires exact equality with the configured Binding. |
axis_mask | uint32 | No | Uint32 configured axis group mask; interpretation is native operation-specific; reset_fault defaults zero to all axes. |
velocity | float64[] | No | Finite logical velocities in described axis order for legacy jog; native vector and velocity-limit validation applies. |
timeout_ms | uint32 | No | Legacy jog requires an integer 1..250 milliseconds. |
handle | uint64 | No | Nonzero opaque uint64 handle for start/discard, owned by the current daemon incarnation and grant. |
points | Point[] | No | 2..250000 Point records; declared axis order, native limits and continuity apply. Large bodies require the envelope before this array. |
identity | Identity | No | Exact prepared program Identity for start_program. |
jog_generation | uint64 | No | EndJog requires the exact current nonzero independent jog generation. |
source_sequence | uint64 | No | Accepted envelope field retained for compatibility; current /v1/control dispatch does not consume it. Independent updates use the binary lane. |
source_origin_host_ns | uint64 | No | BeginJog origin in the negotiated host monotonic clock, uint64 nanoseconds; native freshness validation applies. |
deadline_host_ns | uint64 | No | BeginJog producer deadline in host monotonic nanoseconds; after origin and never extended by admission or renewal. |
clock_incarnation | string | No | BeginJog requires exact equality with GET /v1/jog/clock incarnation. |
requested_lease_ms | int | No | Acquire requested lease in whole ms, 1..10000; omitted or zero retains the LAN default capped by the cell. Adapter returns min(request, cell ceiling) in Grant.lease_ms. Clients require at least three measured round trips plus renewal cadence. |
session and generation come from the embedded Fence, so they sit at the top level of the object.
- Large uploads. For a large
prepare_trajectory, sendschema,operation,sessionand a non-zerogenerationbeforepoints, within the first 16384 bytes. rt-control admits the fence and reserves the upload slot before it reads the rest. - Size caps. 16384 bytes for ordinary commands, 222516384 bytes for
prepare_trajectoryand 39298580 bytes for a.rdtupload to/v1/program. Larger bodies get HTTP 413body_too_large. - Units. Positions are in each axis's
position_unit(rad or m), velocities per second, times in ns. Host times use the cell'sCLOCK_MONOTONIC.
Idempotent retries#
Add request_id (1..64 printable ASCII bytes) to make a JSON command safe to retry. The current session remembers its last 256 outcomes. Resending the same decoded payload with the same ID joins the in-flight request or replays its final reply. Changing the payload under the same ID returns request_id_conflict. Release and lease expiry drop the cache, and so does an adapter restart.
Keep one ID for one logical attempt. Use a fresh ID for every renewal and after you correct a refused request. /v1/program uploads have no deduplication. After an ambiguous Start, inspect handle state and incarnations before you try new motion. The Go and C++ clients add a random request_id to every command.
Responses and errors#
Ordinary replies are one Response object with schema: rosie.rt-control.response.v1. data holds the operation's result type; sequence and handle are top-level fields. Fields that are zero or empty are omitted.
| Name | Type | Required | Description |
|---|---|---|---|
native_jog_result | JogObservation | No | The core's JogObservation when the jog lane refused. |
native_result | CommandResult | No | The core's CommandResult when the core refused a command. Field names are case-sensitive (Reason, Sequence …). |
schema | string | Yes | rosie.rt-control.response.v1. |
operation | string | Yes | The operation this reply answers. |
sequence | uint64 | No | Native command sequence, for operations that return one. Exact uint64. |
handle | uint64 | No | Trajectory handle, or jog generation for jog calls. Exact uint64. |
data | any | No | The operation's result type (see each operation). On some refusals, structured evidence such as limit_violation. |
error | string | No | Present only on failure: a reason code, or a diagnostic string that starts with one. |
| HTTP status | Meaning |
|---|---|
| 200 | Admitted. For motion this acknowledges admission, not physical completion. |
| 409 | Refused. error holds the reason. This covers every refusal except the two below. |
| 413 | body_too_large. |
| 404 | resource_unknown, from /v1/resources/<sha256> only. |
error is usually one catalogue label. It can also be an open diagnostic: JSON decoder errors, I/O and context errors, native receipts such as RTCore rejected operation 0x124: reason 2, or two causes joined with a newline. Some labels carry detail after a colon, for example native_limit_exceeded: segment=<index> sample=<index> axis=<id>. Match on the leading label. Treat anything you do not recognise, and any transport failure, as an unknown outcome: stop producing motion, issue an authenticated stop if you can, and reconcile Status before you acquire again.
Common reasons#
These sets apply in addition to each operation's own table. The operation sections say which sets apply.
Envelope reasons (every POST /v1/control)#
| Reason | When |
|---|---|
body_too_large | The body is larger than the operation's cap. HTTP 413. |
invalid_request_envelope | The body is not a JSON object, or a key is not a string. |
duplicate_request_field | A field appears twice in the envelope prefix. |
schema_mismatch | schema is not rosie.rt-control.request.v1. |
unknown_operation | operation is not a POST /v1/control operation. |
trailing_request_data | Data follows the JSON object. |
request_envelope_changed | The fully decoded envelope differs from the admitted prefix. |
invalid_request_id | request_id is null, not a string, or not 1..64 printable ASCII bytes. |
request_id_conflict | The request_id was already used in this session with a different payload. |
session_principal_mismatch | The session belongs to another TLS principal or to the local transport. |
Authority reasons (every fenced call)#
| Reason | When |
|---|---|
control_session_stale | Wrong or stale session or generation, lease expired, or a Stop is in flight. |
daemon_restarted | The session belongs to a previous native daemon incarnation. |
fence | A well-formed session this adapter never issued (for example, from before an adapter restart), or authority was revoked during Start. |
Native reasons (calls the core admits)#
| Reason | When |
|---|---|
native_rejected | The core refused the command. Read the numeric native reason in native_result.Reason. |
outside_limits_outward | The command would move an axis further outside its limits (native reason 8). |
Cell I/O reasons (calls that can carry outputs)#
| Reason | When |
|---|---|
no_grant | Native cell I/O refusal: no current grant. |
wrong_generation | Native cell I/O refusal: generation mismatch. |
inhibited | Native cell I/O refusal: outputs are inhibited. |
io_not_configured | No cell I/O is configured. |
io_not_armed | An ON intent needs io_arm first. |
io_fast_input_unsatisfied | A cyclic fast input contact is invalid or not satisfied. |
io_readback_disagreement | Physical feedback disagrees with the commanded output. |
io_torch_unqualified | A torch-class output was requested. Always refused. |
io_marker_late | A process marker missed its one-cycle delivery bound. |
io_exchange_lost | Cell I/O has no current complete exchange. |
Observation#
Reads need no lease. On the remote listener they still need a valid client certificate.
describe#
/v1/describe Read the machine description, identities and capability states. State: implemented. Lease: none.
Returns the native description (backend, protocol version, digests, cycle period, axis order, units and limits), the contract version and digest, every capability with its state, the prepared program if there is one, and the compiled robot description and drive identities.
Call it first. Check backend, machine_sha256, the axis order and capabilities_digest against what your client was built for before you acquire authority. max_grant_lease_ns and max_jog_input_age_ns are the cell's timing ceilings.
Request#
No parameters.
Response#
data is a Description.
| Name | Type | Required | Description |
|---|---|---|---|
| (embedded) | NativeDescription | Yes | All fields of NativeDescription appear at this level of the object. |
contract_version | uint32 | Yes | Exactly 1. |
capabilities_digest | string | Yes | Lowercase SHA-256 of the exact committed UTF-8 LF schema file bytes, including its final newline; no self-referential digest field. |
capabilities | CapabilityInfo[] | Yes | Every target capability with its implementation state and transport. |
control_idle_timeout_ns | uint64 | No | Compiled link idle timeout in ns; clients keep reserved connections alive at one third of this bound, independently of grants. Unverified LAN and internet policy: 90000000000 ns. An omitted legacy field uses 30000000000 ns. |
program | Program | No | Detached prepared program metadata including both identity digests; absent when no program is prepared. |
robot | RobotDescription | No | Null when no robot definition is bound or no compiled artefact is loaded; never guessed from axis count. |
drives | DriveDescription[] | Yes | Per-axis compiled drive configuration and current verified bring-up identity; empty without a compiled artefact. |
Example#
GET /v1/describe HTTP/1.1
Host: localhost{
"schema": "rosie.rt-control.response.v1",
"operation": "describe",
"data": {
"backend": "simulation",
"schema": "…",
"protocol_major": 1,
"protocol_minor": 10,
"configuration_sha256": "c2b097096fef301cad3b9c3e594f32266c625feaccba02be3410ed08df2b63ea",
"machine_sha256": "4f1d9a7c2e6b8d0f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f",
"deployment_sha256": "…",
"max_trajectory_points": 250000,
"resident_plans": 3,
"cycle_ns": 1000000,
"interpolation": "…",
"stop": "…",
"axes": [
{
"index": 0,
"id": "J1",
"position_unit": "rad",
"min_position": -2.96,
"max_position": 2.96,
"max_velocity": 1.5,
"…": "…"
}
],
"bus": {},
"max_grant_lease_ns": 500000000,
"max_jog_input_age_ns": 250000000,
"contract_version": 2,
"capabilities_digest": "d63b2aee7bbcb7e4f11eca7148ce9ffda0e5d8db421f165d20918ccb4f119158",
"capabilities": [
{
"name": "acquire",
"state": "implemented",
"transport": "POST /v1/control"
},
"…"
],
"control_idle_timeout_ns": 90000000000,
"robot": null,
"drives": []
}
}Axis values in the example are illustrative. Read the real limits from your cell.
Reason codes#
No operation-specific reason codes. Unknown diagnostics mean the request failed.
Client libraries. Go: Client.Describe. C++: describe().
status#
/v1/status Read one timestamped snapshot of the core, the grant, jog, execution and every axis. State: implemented. Lease: none.
Every successful snapshot belongs to one daemon incarnation: daemon_incarnation equals core.daemon_incarnation. time_ns is the native publication time, not an adapter estimate. Check validity flags and timestamps before you treat a logical position as valid.
execution.state reports the program lifecycle: prepared, executing, completed, faulted, cancelled, discarded or released (empty before any observation). A faulted program carries native_execution_failed in execution.error.
Request#
No parameters.
Response#
data is a ProcessStatus.
| Name | Type | Required | Description |
|---|---|---|---|
daemon_incarnation | string | Yes | Core process identity for this snapshot. |
adapter_incarnation | string | Yes | rt-control process identity. |
grant | GrantObservation | Yes | Native grant observation. |
jog | JogObservation | Yes | Native jog observation. |
jog_ingress | JogIngressObservation | Yes | Adapter-lifetime ingress outcomes across datagram, WSS and UpdateJog; counters and latest refusal match GET /v1/jog/ingress. |
core | NativeStatus | Yes | Native core status. |
motion | MotionState | Yes | Native motion state. |
execution | Execution | Yes | Program and handle lifecycle. |
time_ns | uint64 | Yes | Native publication time, ns. |
axes | LogicalAxisStatus[] | Yes | Per-axis logical status, in Describe order. |
generations | StatusGenerations | Yes | Current generations and epochs. |
plan_cursor | PlanCursor | Yes | Native plan cursor. |
buffer_health | BufferHealth | Yes | Native buffer health. |
adapter | AdapterStatus | Yes | Adapter runtime observations; not native motion state. |
Example#
GET /v1/status HTTP/1.1
Host: localhost{
"schema": "rosie.rt-control.response.v1",
"operation": "status",
"data": {
"daemon_incarnation": "3b9d…",
"adapter_incarnation": "a41c…",
"grant": {},
"jog": {},
"jog_ingress": {},
"core": {
"armed": 0,
"axis_enable_mask": 0,
"home_valid_mask": 511,
"safety_fault_mask": 0,
"…": "…"
},
"motion": {
"mode": 0,
"state": 0,
"done": false,
"…": "…"
},
"execution": {
"state": "",
"generation": 0,
"handles": [],
"…": "…"
},
"time_ns": 81234567890123,
"axes": [
{
"logical_position": 0,
"logical_valid": true,
"readiness": "not_enabled",
"…": "…"
}
],
"generations": {},
"plan_cursor": {},
"buffer_health": {},
"adapter": {}
}
}Reason codes#
| Reason | When |
|---|---|
daemon_restarted | The native daemon was replaced while the snapshot was read. Re-read Describe and reconcile before any motion. |
Client libraries. Go: Client.Status. C++: status().
jog_clock#
/v1/jog/clock Sample the host monotonic clock and its incarnation for begin_jog. State: implemented. Lease: none.
Returns domain (CLOCK_MONOTONIC), the clock incarnation, mapping_generation and now_host_ns. Pass incarnation to begin_jog as clock_incarnation; every jog time you send uses this clock, in ns.
Request#
No parameters.
Response#
data is a LocalJogClock.
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | CLOCK_MONOTONIC. |
incarnation | string | Yes | Clock incarnation; pass it to begin_jog. |
mapping_generation | uint64 | Yes | Clock mapping generation (1 for the local lane). |
now_host_ns | uint64 | Yes | Current host monotonic time, ns. |
Example#
GET /v1/jog/clock HTTP/1.1
Host: localhost{
"schema": "rosie.rt-control.response.v1",
"operation": "jog_clock",
"data": {
"domain": "CLOCK_MONOTONIC",
"incarnation": "0f3c9a…",
"mapping_generation": 1,
"now_host_ns": 81234567890123
}
}Reason codes#
| Reason | When |
|---|---|
independent_jog_unavailable | The native client offers no independent jog lane. |
Client libraries. Go: Client.JogClock. C++: jog_clock().
jog_status#
/v1/jog Read the native jog-lane observation (local socket only). State: implemented. Lease: none.
On the local socket this returns the native JogObservation. Its fields keep their native, case-sensitive names (Open, JogGeneration, InputDeadlineHostNs, StateReason …). The reasons are the numeric native jog reasons.
On the mutual-TLS listener the same path is the WebSocket upgrade for remote jog. See Remote access.
Request#
No parameters.
Response#
data is a JogObservation.
| Name | Type | Required | Description |
|---|---|---|---|
Ticket | uint64 | Yes | — |
ConnectionId | uint64 | Yes | — |
NativeGeneration | uint64 | Yes | — |
CapabilityId | uint8[16] | Yes | — |
AppGrantGeneration | uint64 | Yes | — |
ConfigurationEpoch | uint64 | Yes | — |
HomeEpoch | uint64 | Yes | — |
ClockMappingGeneration | uint64 | Yes | — |
JogGeneration | uint64 | Yes | Current jog generation. |
SourceSequence | uint64 | Yes | Sequence of the latest applied input. |
InputDeadlineHostNs | uint64 | Yes | Deadline of the latest applied input, host ns. |
NowHostNs | uint64 | Yes | Publication time, host ns. |
ObservedSourceSequence | uint64 | Yes | — |
ObservedOriginHostNs | uint64 | Yes | — |
FirstObservedHostNs | uint64 | Yes | — |
ControlReason | uint32 | Yes | — |
ControlAccepted | uint32 | Yes | — |
UpdateReason | uint32 | Yes | — |
StateReason | uint32 | Yes | Native jog reason for the current state. |
AxisMask | uint32 | Yes | Axes of the jog session. |
Open | uint32 | Yes | 1 while the jog session accepts input. |
HasInput | uint32 | Yes | 1 once an input has been applied. |
VelocityScalePpm | uint32 | Yes | — |
Example#
GET /v1/jog HTTP/1.1
Host: localhost{
"schema": "rosie.rt-control.response.v1",
"operation": "jog_status",
"data": {
"Open": 1,
"JogGeneration": 4,
"AxisMask": 1,
"InputDeadlineHostNs": 81234817890123,
"StateReason": 0,
"…": "…"
}
}Reason codes#
| Reason | When |
|---|---|
independent_jog_unavailable | The native client offers no independent jog lane. |
Client libraries. Go: Client.JogStatus. C++: jog_status().
jog_ingress#
/v1/jog/ingress Read cumulative jog-input refusal counters for this adapter process. State: implemented. Lease: none.
Counts every refused jog input across jog.sock datagrams, WebSocket frames and internal updates. refused_by_reason is indexed by native jog reason 0..14. The counters reset only when rt-control restarts.
Local datagrams get no reply, so this endpoint is how a local jog producer sees its refusals.
Request#
No parameters.
Response#
data is a JogIngressObservation.
| Name | Type | Required | Description |
|---|---|---|---|
source_sequence | uint64 | Yes | — |
reason | uint32 | Yes | — |
now_host_ns | uint64 | Yes | — |
refused | uint64 | Yes | Cumulative refused ingress count for this adapter process; accepted frames do not increment it. |
refused_by_reason | uint64[15] | Yes | Cumulative refusal counts indexed by protocol/control.json jog reason 0..14; index 0 remains zero. Unverified fixed capacity: 15 reason slots. |
latest_refusal | JogIngressRefusal | Yes | Most recent refusal across all ingress transports; zero before any refusal and preserved through acceptance and grant changes. |
Example#
GET /v1/jog/ingress HTTP/1.1
Host: localhost{
"schema": "rosie.rt-control.response.v1",
"operation": "jog_ingress",
"data": {
"source_sequence": 120,
"reason": 0,
"now_host_ns": 81234567890123,
"refused": 2,
"refused_by_reason": [
0,
0,
0,
0,
2,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"latest_refusal": {
"source_sequence": 7,
"reason": 4,
"now_host_ns": 81230000000000
}
}
}Reason codes#
No operation-specific reason codes. Unknown diagnostics mean the request failed.
Client libraries. Go: Client.JogIngress. C++: jog_ingress().
subscribe_events#
/v1/events?after=<sequence> Poll or stream the event log from a cursor. State: implemented. Lease: none.
/v1/events/stream?after=<sequence> Same operation, alternative transport.
/v1/events returns one EventBatch inside the normal response envelope. /v1/events/stream is Server-Sent Events: each message has id (the sequence), event (the type) and data (one Event as JSON, with no envelope). after is the last sequence you handled; omit it to start from 0.
The ring keeps 256 events and a batch holds at most 64. The full model, including loss handling, is in Events and telemetry.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
after (query) | uint64 | No | Last consumed sequence, as unsigned decimal text. Default 0. |
Response#
data is a EventBatch.
| Name | Type | Required | Description |
|---|---|---|---|
events | Event[] | Yes | At most 64 records, including at most one leading events_dropped record; 256 retained events. |
next_sequence | uint64 | Yes | Resume cursor after the last returned event; unchanged when empty. |
latest_sequence | uint64 | Yes | Newest retained sequence at batch capture. |
adapter_incarnation | string | Yes | — |
Example#
GET /v1/events?after=41 HTTP/1.1
Host: localhost{
"schema": "rosie.rt-control.response.v1",
"operation": "subscribe_events",
"data": {
"events": [
{
"sequence": 42,
"time_ns": 81234567890123,
"type": "grant_acquired",
"daemon_incarnation": "3b9d…",
"adapter_incarnation": "a41c…",
"grant": {
"…": "…"
}
}
],
"next_sequence": 42,
"latest_sequence": 42,
"adapter_incarnation": "a41c…"
}
}Reason codes#
| Reason | When |
|---|---|
invalid_event_cursor | after is duplicated, empty or not one unsigned decimal uint64. |
event_cursor_ahead | after is newer than this adapter incarnation's newest event. |
session_principal_mismatch | An X-Control-Session header or session query names a session owned by another principal. |
event_cursor_lost | Raised by the C++ client (EventCursorLost) when a stream reports events_dropped. The server never returns it. |
Client libraries. Go: Client.Events, Client.StreamEvents. C++: events(), events_stream().
telemetry#
/v1/telemetry?after=<sequence> Read full-rate binary cycle records from a cursor. State: implemented. Lease: none.
/v1/telemetry/stream?after=<sequence> Same operation, alternative transport.
Returns application/octet-stream: one 312-byte TelemetryBatchHeaderV1 followed by record_count 5392-byte CycleCaptureRecordV2 records. It is never JSON. /v1/telemetry returns one batch (gzip if you send Accept-Encoding: gzip). /v1/telemetry/stream writes one complete batch per flush, about every 20 ms, including empty batches.
Errors come back as a JSON Response. The binary layout and decoders are in Events and telemetry.
The contract describes it as: “Full-rate binary cycle records; observation needs no session or authority.”
Request#
| Name | Type | Required | Description |
|---|---|---|---|
after (query) | uint64 | No | Last consumed record sequence. 0 (the default) starts at sequence 1 and reports overwritten history in dropped. |
Response#
The body is binary: a TelemetryBatch.
Example#
GET /v1/telemetry?after=0 HTTP/1.1
Host: localhost
Accept-Encoding: gzipHTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Encoding: gzip
Cache-Control: no-store
<312-byte header><record_count × 5392-byte records>Reason codes#
| Reason | When |
|---|---|
invalid_telemetry_cursor | after is duplicated, empty or not one unsigned decimal uint64. |
telemetry_cursor_ahead | after is beyond the ring's current sequence. Reconcile the incarnation first. |
telemetry_busy | The ring header stayed torn after bounded retries. Retry the same cursor; the reply carries Retry-After: 1. |
telemetry_unavailable | No compatible live telemetry ring could be observed. |
session_principal_mismatch | A supplied session header or query belongs to another principal. |
Client libraries. Go: Client.TelemetryBatches, Client.TelemetryStream. C++: telemetry(), telemetry_stream().
resource#
/v1/resources/<sha256> Download one immutable compiled robot resource by digest. State: implemented. Lease: none.
Serves the files of the compiled robot description (robot_description_manifest.json, robot.urdf, meshes, machine_planning_calibration.json …) listed in Describe robot.resources. The path component is the lowercase SHA-256 of the exact bytes.
The reply is the raw bytes with Content-Type, Content-Length and a quoted-digest ETag. rt-control never looks anything up in a repository at request time: only the loaded compiled resource set is served. Remote clients need the mutual-TLS listener, like every remote call.
The contract describes it as: “Read one bounded content-addressed compiled resource without a lease; remote mutual TLS required.”
Request#
| Name | Type | Required | Description |
|---|---|---|---|
sha256 (path) | string | Yes | 64 lowercase hex characters, from ResourceInfo.sha256. |
Response#
The body is the resource itself. ResourceInfo (from Describe) describes it.
Example#
GET /v1/resources/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 HTTP/1.1
Host: localhostHTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: 48213
ETag: "9f86d081…"
X-Content-Type-Options: nosniff
<robot name="…">…Reason codes#
| Reason | When |
|---|---|
resource_unknown | The digest is malformed or not in the loaded resource set. HTTP 404. |
Client libraries. Go: Client.Resource. C++: none.
Authority#
One controller at a time. See Control authority for the model behind these four calls.
acquire#
/v1/control Take control of the cell and receive a session and fence. State: implemented. Lease: no fence; checks binding.
Only one controller holds authority at a time. acquire checks your binding against the pair and digests rt-control was started with. When you supply machine_sha256 it must match exactly and there is no fallback; without it, configuration_sha256 must match. On success you get a fresh 64-hex session, a generation one higher than the last, and the effective lease_ms.
The effective lease is min(requested_lease_ms, cell ceiling). Omit requested_lease_ms (or send 0) for the 500 ms default, still capped by the cell. Renew before it runs out. Local socket permissions or the remote TLS identity authenticate the connection; controller is only a label.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | acquire. |
controller | string | Yes | Opaque controller name, 1..63 bytes. Not a credential. |
binding | Binding | Yes | Pair ID and revision rt-control was started with, plus configuration_sha256 and, preferably, machine_sha256 from Describe. |
requested_lease_ms | int | No | Requested lease in whole ms, 1..10000. Default 0: keep the 500 ms LAN default, capped by the cell ceiling. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, controller, binding.
Response#
data is a Grant.
| Name | Type | Required | Description |
|---|---|---|---|
stopping | bool | Yes | True means renewal keeps the lease alive while Stop is in flight; it grants no movement permission. |
deadline_host_ns | uint64 | Yes | Uint64 absolute lease deadline in host monotonic nanoseconds. |
session | string | Yes | 64-character unpredictable lowercase hexadecimal token while owned; empty after release/expiry. |
generation | uint64 | Yes | Monotonically increasing uint64 application generation, fenced by Stop and acquisition. |
controller | string | Yes | The controller label sent to acquire. |
binding | Binding | Yes | The binding, completed with the adapter's digests. |
lease_ms | int | Yes | Effective negotiated lease in whole milliseconds: min(client requested lease, compiled cell ceiling); zero/omitted request retains 500 ms capped by the cell. Renew preserves this value. Longer leases increase worst-case unattended-stop delay after link loss. Unverified absolute bound: 10000 ms. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "acquire",
"controller": "my-app",
"binding": {
"pair_id": "cell-a",
"revision": 1,
"configuration_sha256": "c2b097096fef301cad3b9c3e594f32266c625feaccba02be3410ed08df2b63ea",
"machine_sha256": "4f1d9a7c2e6b8d0f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f"
},
"requested_lease_ms": 500
}{
"schema": "rosie.rt-control.response.v1",
"operation": "acquire",
"data": {
"stopping": false,
"deadline_host_ns": 81234567890123,
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"controller": "my-app",
"binding": {
"pair_id": "cell-a",
"revision": 1,
"configuration_sha256": "c2b097096fef301cad3b9c3e594f32266c625feaccba02be3410ed08df2b63ea",
"machine_sha256": "4f1d9a7c2e6b8d0f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f"
},
"lease_ms": 500
}
}Reason codes#
| Reason | When |
|---|---|
authority_binding_mismatch | controller is empty or longer than 63 bytes, or binding does not match the configured pair, revision and digest. |
control_already_owned | Another session holds authority, or a Stop is still draining. |
application_generation_exhausted | The uint64 grant generation is exhausted. Restart and reconcile. |
invalid_requested_lease | requested_lease_ms is negative or above 10000. |
control_session_stale | The new grant was lost while it was being mirrored to the core. |
session_principal_mismatch | A retried request_id was first used by another transport principal. |
Also the common envelope reasons.
Client libraries. Go: Client.Acquire, Client.AcquireLease. C++: acquire().
renew#
/v1/control Extend the lease of the current session. State: implemented. Lease: session and generation.
Renew keeps the session alive. The deadline moves to now plus the effective lease_ms, which never changes after Acquire. Renew at most every third of the lease, on its own connection, and use a fresh request_id each time: a reused ID replays the old receipt.
An older non-zero generation of the same live session may renew and learns the current fence from the reply, but it cannot move the robot. While a Stop is in flight, renew returns stopping: true: the lease is kept alive, and no motion permission is granted.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | renew. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
data is a Grant.
| Name | Type | Required | Description |
|---|---|---|---|
stopping | bool | Yes | True means renewal keeps the lease alive while Stop is in flight; it grants no movement permission. |
deadline_host_ns | uint64 | Yes | Uint64 absolute lease deadline in host monotonic nanoseconds. |
session | string | Yes | 64-character unpredictable lowercase hexadecimal token while owned; empty after release/expiry. |
generation | uint64 | Yes | Monotonically increasing uint64 application generation, fenced by Stop and acquisition. |
controller | string | Yes | The controller label sent to acquire. |
binding | Binding | Yes | The binding, completed with the adapter's digests. |
lease_ms | int | Yes | Effective negotiated lease in whole milliseconds: min(client requested lease, compiled cell ceiling); zero/omitted request retains 500 ms capped by the cell. Renew preserves this value. Longer leases increase worst-case unattended-stop delay after link loss. Unverified absolute bound: 10000 ms. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "renew",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"request_id": "5f0c2a9e6b1d4c3a8e7f0b2d4c6a8e1f"
}{
"schema": "rosie.rt-control.response.v1",
"operation": "renew",
"data": {
"stopping": false,
"deadline_host_ns": 81234567890123,
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"controller": "my-app",
"binding": {
"pair_id": "cell-a",
"revision": 1,
"configuration_sha256": "c2b097096fef301cad3b9c3e594f32266c625feaccba02be3410ed08df2b63ea",
"machine_sha256": "4f1d9a7c2e6b8d0f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f"
},
"lease_ms": 500
}
}Reason codes#
| Reason | When |
|---|---|
expired | The lease deadline passed, or the core reported the grant expired. Stop producing, reconcile and acquire again. |
control_session_stale | The session is not the current one, or generation is 0 or newer than the current generation. |
Also the common envelope and authority reasons.
Client libraries. Go: Client.Renew, Client.StartRenewal. C++: renew(), start_renewal().
release#
/v1/control Stop, then give up authority. State: implemented. Lease: session and generation.
Release runs the same inhibiting sequence as Stop and then clears the session: the returned Grant has an empty session. Stop your renewal loop first. The Go and C++ clients do that for you and never replay a Release automatically after a transport failure.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | release. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
data is a Grant.
| Name | Type | Required | Description |
|---|---|---|---|
stopping | bool | Yes | True means renewal keeps the lease alive while Stop is in flight; it grants no movement permission. |
deadline_host_ns | uint64 | Yes | Uint64 absolute lease deadline in host monotonic nanoseconds. |
session | string | Yes | 64-character unpredictable lowercase hexadecimal token while owned; empty after release/expiry. |
generation | uint64 | Yes | Monotonically increasing uint64 application generation, fenced by Stop and acquisition. |
controller | string | Yes | The controller label sent to acquire. |
binding | Binding | Yes | The binding, completed with the adapter's digests. |
lease_ms | int | Yes | Effective negotiated lease in whole milliseconds: min(client requested lease, compiled cell ceiling); zero/omitted request retains 500 ms capped by the cell. Renew preserves this value. Longer leases increase worst-case unattended-stop delay after link loss. Unverified absolute bound: 10000 ms. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "release",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "release",
"data": {
"stopping": false,
"deadline_host_ns": 81234567890123,
"session": "",
"generation": 4,
"controller": "my-app",
"binding": {
"pair_id": "cell-a",
"revision": 1,
"configuration_sha256": "c2b097096fef301cad3b9c3e594f32266c625feaccba02be3410ed08df2b63ea",
"machine_sha256": "4f1d9a7c2e6b8d0f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f"
},
"lease_ms": 500
}
}Reason codes#
| Reason | When |
|---|---|
control_session_stale | The session was never issued by this adapter, or generation is 0 or newer than current. |
expired | The lease expired while the release was being processed. |
Also the common envelope and authority reasons.
Client libraries. Go: Client.Release. C++: release().
stop#
/v1/control Inhibit outputs immediately and fence all motion. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Stop cancels execution, uploads, handles and jog at once, inhibits the drive outputs and increments the generation. It does not wait for a ramp. If the session is still valid you get it back with the new generation, and you need a fresh Enable and Arm before moving again.
A session that has expired or been revoked can still send Stop to inhibit, but it cannot regain motion permission. Concurrent Stop and Release calls join one cancellation. A Stop receipt does not prove the robot is at standstill.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | stop. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
data is a Grant.
| Name | Type | Required | Description |
|---|---|---|---|
stopping | bool | Yes | True means renewal keeps the lease alive while Stop is in flight; it grants no movement permission. |
deadline_host_ns | uint64 | Yes | Uint64 absolute lease deadline in host monotonic nanoseconds. |
session | string | Yes | 64-character unpredictable lowercase hexadecimal token while owned; empty after release/expiry. |
generation | uint64 | Yes | Monotonically increasing uint64 application generation, fenced by Stop and acquisition. |
controller | string | Yes | The controller label sent to acquire. |
binding | Binding | Yes | The binding, completed with the adapter's digests. |
lease_ms | int | Yes | Effective negotiated lease in whole milliseconds: min(client requested lease, compiled cell ceiling); zero/omitted request retains 500 ms capped by the cell. Renew preserves this value. Longer leases increase worst-case unattended-stop delay after link loss. Unverified absolute bound: 10000 ms. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "stop",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "stop",
"data": {
"stopping": false,
"deadline_host_ns": 81234567890123,
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 4,
"controller": "my-app",
"binding": {
"pair_id": "cell-a",
"revision": 1,
"configuration_sha256": "c2b097096fef301cad3b9c3e594f32266c625feaccba02be3410ed08df2b63ea",
"machine_sha256": "4f1d9a7c2e6b8d0f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f"
},
"lease_ms": 500
}
}Reason codes#
| Reason | When |
|---|---|
control_session_stale | The session was never issued by this adapter, or generation is 0 or newer than current. |
expired | The lease expired while the stop was reacquiring native authority. |
Also the common envelope and authority reasons.
Client libraries. Go: Client.Stop. C++: stop().
Machine control#
Every call here needs the current session and generation.
enable#
/v1/control Request CiA402 enable for the selected axes. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Sends a native enable for axis_mask and waits for the native result. The receipt only confirms admission. Poll Status until each axis reports the expected enable bit and readiness. Enable and Arm on their own do not establish Home or permit a Start.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | enable. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | Yes | Axes to enable, by Describe index (bit 0 = first axis). A nine-axis cell uses 511. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, axis_mask.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "enable",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 511
}{
"schema": "rosie.rt-control.response.v1",
"operation": "enable",
"sequence": 17
}Reason codes#
Only the common envelope, authority and native reasons.
Client libraries. Go: Client.Enable. C++: enable().
arm#
/v1/control Arm the core so that motion commands can be admitted. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Sends a native arm and waits for its result. Observe core.armed == 1 in Status. A successful Arm does not mean every axis is ready: the motion start gate is still checked at every Start and jog.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | arm. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "arm",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "arm",
"sequence": 18
}Reason codes#
Only the common envelope, authority and native reasons.
Client libraries. Go: Client.Arm. C++: arm().
home#
/v1/control Run the drives' native Home on the selected axes. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Runs native Home (commissioning) on axis_mask and waits up to 60 s for the result. Home leaves the selected axes disabled: observe the new home_epoch, an idle commissioning_phase and every selected bit in home_valid_mask, then Enable and Arm again. If Home fails, rt-control issues a Stop.
When ROSIE_RT_ANCHOR_DIR is set in rt-control's environment, a successful Home also saves one anchor file per selected axis, for later use by restore_anchor. Losing the HTTP reply does not cancel Home; Stop, lease expiry or transport loss do.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | home. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | Yes | Non-zero mask of configured axes whose Describe entry has native_home: true. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, axis_mask.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "home",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 511
}{
"schema": "rosie.rt-control.response.v1",
"operation": "home",
"sequence": 19
}Reason codes#
| Reason | When |
|---|---|
anchor_source_invalid | Anchor capture after Home found the machine armed or enabled, or a selected axis had no valid source. |
anchor_identity_mismatch | The captured anchor does not match the adapter's pair ID and revision. |
anchor_store_io | The anchor directory could not be written. Details go to the local log only. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.Home. C++: home().
halt#
/v1/control Decelerate to an enabled hold, keeping authority and Arm. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Halt requests a controlled deceleration using the active trajectory's acceleration, or the jog acceleration when no trajectory bound is declared. It retires the active trajectory handle and jog generation, but keeps the grant, Enable and Arm. A new Start must begin at the held target; jogging needs a new begin_jog.
Halt does not replace Stop. Stop, faults and lease expiry always inhibit immediately. The receipt confirms admission, not a completed hold. A native refusal also carries native_result.
The contract describes it as: “Controlled deceleration to enabled hold using the active trajectory acceleration, or jog acceleration when no trajectory bound is declared. Retires active motion; preserves authority and Arm. Stop and faults always inhibit immediately.”
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | halt. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "halt",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "halt",
"sequence": 20
}Reason codes#
| Reason | When |
|---|---|
no_grant | There is no current valid grant for this session, or its lease has expired. |
wrong_generation | generation differs from the current application or native generation. |
inhibited | A Stop is in flight, or the core is not armed, enabled and ready (native Home and service also refuse Halt). |
capability_unimplemented | The native client has no Halt support. |
Also the common envelope and authority reasons.
Client libraries. Go: Client.Command with Operation "halt". C++: command() with operation halt.
restore_anchor#
/v1/control Re-establish Home from saved absolute-encoder anchors, without moving. State: implemented. Lease: session and generation.
An alternative to Home after a restart. The machine must be disarmed, disabled and not commissioning. For every selected axis, the saved anchor's pair, revision, coordinate identity, drive identity and absolute source must match current evidence, and the core checks them again independently. Set ROSIE_RT_ANCHOR_DIR to the same directory for rt-control (write) and the core (read).
On success the reply carries the restore receipt in sequence and a RecoveryStatus read after it, with the selected bits set in home_valid_mask. Restoring never enables or arms.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | restore_anchor. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | Yes | Non-zero mask of configured axes to restore. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, axis_mask.
Response#
sequence holds the native command sequence and data is a RecoveryStatus.
| Name | Type | Required | Description |
|---|---|---|---|
home_valid_mask | uint32 | Yes | Native per-axis home evidence remaining after observed recovery. |
faults | FaultRecovery[] | Yes | Currently latched fault bits with axis masks and recovery policy. |
reset_sequence | uint64 | Yes | Exact native command sequence of the observed reset, zero before any reset; response sequence must match for reset_fault. |
reason | string | Yes | Native recovery summary: empty when no fault persists, otherwise fault_persists; FaultResetRecovery refuses a persistent fault. |
outcomes | FaultRecovery[] | Yes | Per-bit outcomes of the correlated reset; never inferred from elapsed time. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "restore_anchor",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 511
}{
"schema": "rosie.rt-control.response.v1",
"operation": "restore_anchor",
"sequence": 21,
"data": {
"home_valid_mask": 511,
"faults": [],
"reset_sequence": 0,
"reason": "",
"outcomes": []
}
}Reason codes#
| Reason | When |
|---|---|
invalid_axis_mask | axis_mask is 0 or names an axis outside the configured group. |
mode_conflict | The machine is armed, enabled or commissioning. |
anchor_missing | No saved anchor exists for a selected axis. Run Home. |
anchor_identity_mismatch | The anchor was saved under another pair, revision, configuration, drive identity or Home epoch. |
anchor_source_invalid | The drive reports no valid absolute source for the axis. |
anchor_disagrees | The current absolute source disagrees with the anchor beyond tolerance. Investigate, then Home. |
anchor_store_io | The anchor directory could not be read. |
recovery_observation_unavailable | No matching native observation arrived within 1 s of the receipt. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.RestoreAnchor. C++: restore_anchor().
reset_fault#
/v1/control Clear latched execution faults (interim). Ends the session. State: interim. Lease: session and generation.
reset_fault is labelled interim. It needs an inhibited, idle machine: not armed, no active jog, no commissioning, no native Home and no executing program. It submits one native fault reset for axis_mask (0 means every configured axis) and reports the correlated result: sequence, native_result and a RecoveryStatus whose reset_sequence matches.
A submitted reset retires your session, even when the core refuses it. Acquire again afterwards. Any persistent condition refuses the whole reset (fault_persists); there is no partial clear. Reset never starts motion and never grants Home. See fault recovery.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | reset_fault. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | No | Axes to reset. Default 0: all configured axes. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
sequence holds the native command sequence and data is a RecoveryStatus. native_result carries the native CommandResult of the reset.
| Name | Type | Required | Description |
|---|---|---|---|
home_valid_mask | uint32 | Yes | Native per-axis home evidence remaining after observed recovery. |
faults | FaultRecovery[] | Yes | Currently latched fault bits with axis masks and recovery policy. |
reset_sequence | uint64 | Yes | Exact native command sequence of the observed reset, zero before any reset; response sequence must match for reset_fault. |
reason | string | Yes | Native recovery summary: empty when no fault persists, otherwise fault_persists; FaultResetRecovery refuses a persistent fault. |
outcomes | FaultRecovery[] | Yes | Per-bit outcomes of the correlated reset; never inferred from elapsed time. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "reset_fault",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 0
}{
"schema": "rosie.rt-control.response.v1",
"operation": "reset_fault",
"sequence": 22,
"native_result": {
"Sequence": 22,
"Handle": 0,
"Generation": 5,
"Operation": 260,
"Result": 0,
"Reason": 0,
"AxisMask": 511
},
"data": {
"home_valid_mask": 511,
"faults": [],
"reset_sequence": 22,
"reason": "",
"outcomes": []
}
}Reason codes#
| Reason | When |
|---|---|
program_already_executing | A trajectory or program is still executing. Stop first. |
reset_requires_inhibited | The machine is armed, jogging, commissioning or homing, or no fresh observation arrived within 1 s. |
recovery_observation_unavailable | No correlated recovery publication arrived within 1 s of the receipt. |
fault_persists | At least one selected fault condition is still present. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.ResetFault. C++: reset_fault().
recovery_status#
/v1/control Read the latched faults and their recovery classes. Changes nothing. State: implemented. Lease: session and generation.
Requires the same inhibited, idle machine as reset_fault, but clears nothing and keeps the session. Each faults[] entry names the fault bit, the affected axes and its recovery class.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | recovery_status. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
data is a RecoveryStatus.
| Name | Type | Required | Description |
|---|---|---|---|
home_valid_mask | uint32 | Yes | Native per-axis home evidence remaining after observed recovery. |
faults | FaultRecovery[] | Yes | Currently latched fault bits with axis masks and recovery policy. |
reset_sequence | uint64 | Yes | Exact native command sequence of the observed reset, zero before any reset; response sequence must match for reset_fault. |
reason | string | Yes | Native recovery summary: empty when no fault persists, otherwise fault_persists; FaultResetRecovery refuses a persistent fault. |
outcomes | FaultRecovery[] | Yes | Per-bit outcomes of the correlated reset; never inferred from elapsed time. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "recovery_status",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "recovery_status",
"data": {
"home_valid_mask": 511,
"faults": [
{
"bit": 5,
"name": "following_error",
"axis_mask": 4,
"recovery": "reset_after_condition_clears",
"outcome": "persists",
"rehome_axis_mask": 0
}
],
"reset_sequence": 0,
"reason": "fault_persists",
"outcomes": []
}
}Reason codes#
| Reason | When |
|---|---|
program_already_executing | A trajectory or program is executing. |
reset_requires_inhibited | The machine is armed, jogging, commissioning or homing, or no fresh observation arrived within 1 s. |
recovery_observation_unavailable | The core published no recovery status within 1 s. |
Also the common envelope and authority reasons.
Client libraries. Go: Client.Command with Operation "recovery_status". C++: recovery_status().
io_arm#
/v1/control Grant fenced permission for configured, non-torch cell outputs. State: implemented. Lease: session and generation.
Cell I/O outputs are only driven after an explicit io_arm under a fresh grant, with valid OFF readback observed after the last Stop. Stop commands every output OFF. Torch-class outputs are refused everywhere: see Process I/O and sensing.
The receipt confirms native permission only. It does not establish physical feedback.
The contract describes it as: “Native cell I/O permission; torch remains unqualified.”
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | io_arm. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "io_arm",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "io_arm",
"sequence": 23
}Reason codes#
| Reason | When |
|---|---|
capability_unimplemented | The native client has no cell I/O support. |
no_grant | Native cell I/O refusal: no current grant. |
wrong_generation | Native cell I/O refusal: generation mismatch. |
inhibited | Native cell I/O refusal: outputs are inhibited. |
io_not_configured | No cell I/O is configured. |
io_not_armed | An ON intent needs io_arm first. |
io_fast_input_unsatisfied | A cyclic fast input contact is invalid or not satisfied. |
io_readback_disagreement | Physical feedback disagrees with the commanded output. |
io_torch_unqualified | A torch-class output was requested. Always refused. |
io_marker_late | A process marker missed its one-cycle delivery bound. |
io_exchange_lost | Cell I/O has no current complete exchange. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.IOArm. C++: io_arm().
io_disarm#
/v1/control Withdraw cell-output permission and intent. State: implemented. Lease: session and generation.
Clears output permission and intent in the native cycle.
The contract describes it as: “Native cell I/O permission; torch remains unqualified.”
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | io_disarm. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "io_disarm",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3
}{
"schema": "rosie.rt-control.response.v1",
"operation": "io_disarm",
"sequence": 24
}Reason codes#
| Reason | When |
|---|---|
capability_unimplemented | The native client has no cell I/O support. |
no_grant | Native cell I/O refusal: no current grant. |
wrong_generation | Native cell I/O refusal: generation mismatch. |
inhibited | Native cell I/O refusal: outputs are inhibited. |
io_not_configured | No cell I/O is configured. |
io_not_armed | An ON intent needs io_arm first. |
io_fast_input_unsatisfied | A cyclic fast input contact is invalid or not satisfied. |
io_readback_disagreement | Physical feedback disagrees with the commanded output. |
io_torch_unqualified | A torch-class output was requested. Always refused. |
io_marker_late | A process marker missed its one-cycle delivery bound. |
io_exchange_lost | Cell I/O has no current complete exchange. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.IODisarm. C++: io_disarm().
mark_telemetry#
/v1/control Write a labelled marker into the telemetry stream. State: implemented. Lease: session and generation.
Adds a diagnostic mark. An accepted mark publishes one telemetry_mark event carrying the label, the native sequence and the grant generation. It does not take the motion lock, so it works during a long Home. A receipt does not mean anything was written to disk.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | mark_telemetry. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
label | string | Yes | Free text, 1..128 bytes of valid UTF-8. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, label.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "mark_telemetry",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"label": "before weld 3"
}{
"schema": "rosie.rt-control.response.v1",
"operation": "mark_telemetry",
"sequence": 25
}Reason codes#
| Reason | When |
|---|---|
telemetry_label_invalid | label is empty, longer than 128 bytes or not valid UTF-8. |
capability_unimplemented | The native client cannot mark telemetry. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.Command with Operation "mark_telemetry". C++: command() with operation mark_telemetry.
Jog#
Jogging uses its own lane with its own generation and input deadlines. The JSON calls open and close a jog session; the velocity updates themselves are binary frames.
begin_jog#
/v1/control Open an independent jog session and get its jog generation. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Reserves native jog mode for axis_mask. Get clock_incarnation from GET /v1/jog/clock. source_origin_host_ns is when your input was captured and deadline_host_ns is when it must stop applying, both in that host clock. The deadline is never extended by admission or renewal.
The reply's handle is the new jog generation. Send velocities with update_jog, then close with end_jog. Jog velocities are joint-space, in each axis's logical unit per second.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | begin_jog. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | Yes | Axes this jog session may move. |
source_origin_host_ns | uint64 | Yes | Input capture time, host CLOCK_MONOTONIC ns. |
deadline_host_ns | uint64 | Yes | Absolute input deadline, host CLOCK_MONOTONIC ns, after the origin. |
clock_incarnation | string | Yes | incarnation from GET /v1/jog/clock. Must match exactly. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, axis_mask, source_origin_host_ns, deadline_host_ns, clock_incarnation.
Response#
handle holds the result. handle is the jog generation.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "begin_jog",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 1,
"source_origin_host_ns": 81234567890123,
"deadline_host_ns": 81234667890123,
"clock_incarnation": "0f3c9a…"
}{
"schema": "rosie.rt-control.response.v1",
"operation": "begin_jog",
"handle": 4
}Reason codes#
| Reason | When |
|---|---|
jog_clock_incarnation_mismatch | clock_incarnation is empty or is not the current host clock incarnation. |
independent_jog_unavailable | The native client offers no independent jog lane. |
mode_conflict | A trajectory, program or commissioning is active (native jog reason 2). |
outside_limits_outward | An axis is outside its limits (native jog reason 15). |
Also the common envelope and authority reasons.
Other native jog refusals return the diagnostic RTCore rejected jog (reason N) with native_jog_result set; see native jog reasons.
Client libraries. Go: Client.NewJogSession, Client.PrepareJogSession, Client.BeginJog. C++: RtJogProducer, begin_jog().
update_jog#
jog.sockSend the latest jog velocity: a binary frame, not an HTTP request. State: implemented. Lease: session and generation.
/v1/jog Same operation, alternative transport.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Updates are 224-byte little-endian local_jog_update frames. Local producers send them as Unix datagrams to jog.sock, next to control.sock. Remote producers send them as binary WebSocket frames on /v1/jog over mutual TLS (see Remote access). Build frames with the SDK (BuildJogFrame, RtJogProducer) rather than by hand.
Each frame carries the session, grant generation, jog generation, a strictly increasing non-zero source_sequence, its own origin and deadline, an axis mask and a finite velocity vector. deadline_host_ns − origin_host_ns may not exceed the cell's max_jog_input_age_ns (250 ms on LAN). Only the newest valid frame in a burst is applied, and a refused frame never extends the previous input's deadline. Local datagrams get no reply: read refusals from GET /v1/jog/ingress.
Request#
A 224-byte little-endian local_jog_update frame, defined in protocol/control.json. Reserved bytes are zero.
| Name | Type | Offset (bytes) | Description |
|---|---|---|---|
session_id | u8[32] | 0 | The 32 bytes of the session token (its 64 hex characters, decoded). |
clock_incarnation | u8[16] | 32 | The 16 bytes of the jog clock incarnation (hex-decoded). On WSS the server maps source time instead. |
grant_generation | u64 | 48 | Current grant generation. |
jog_generation | u64 | 56 | Jog generation from begin_jog. |
source_sequence | u64 | 64 | Strictly increasing, non-zero. |
origin_host_ns | u64 | 72 | Input capture time, host ns (source clock on WSS). |
deadline_host_ns | u64 | 80 | Absolute deadline; at most the cell's input-age ceiling after the origin. |
axis_mask | u32 | 88 | Axes in this frame; a subset of the Begin mask. |
reserved | u32 | 92 | Zero. |
velocity | f64[16] | 96 | Per-axis velocity in Describe order, rad/s or m/s. Axes outside the mask must be 0. |
Response#
No reply on jog.sock. On WSS, only refusals are answered, as {"type":"rejected","seq":N,"reason":"…"}.
Reason codes#
| Reason | When |
|---|---|
jog_session_stale | The frame's session, grant generation or jog generation is not the current one (WSS). |
jog_session_or_sequence_stale | No open jog session for this generation, or source_sequence did not increase. |
jog_publisher_busy | Another producer is publishing. Replace your unsent input with a fresh sample. |
jog_invalid_frame | The binary frame could not be decoded (WSS). |
jog_stream_idle | No complete WSS frame arrived within the cell's input-age ceiling; rt-control ends the jog and closes. |
control_session_stale | Sent on WSS just before closing, when the grant was stopped or expired. |
jog_clock_unqualified | Remote clock qualification is disabled (the --remote-jog-* flags are 0) or the calibration exchange is incomplete. |
jog_clock_invalid_budget_or_exchange | A malformed calibration or Begin message, or an invalid timing budget. |
jog_clock_incarnation_mismatch | The source clock incarnation changed during the WSS session. |
jog_clock_mapping_generation_mismatch | The frame was mapped with an out-of-date clock mapping. |
jog_clock_moved_backwards | A source timestamp went backwards, or input predates the Begin sample. |
jog_clock_arithmetic_range | Clock conversion would overflow. |
jog_clock_uncertainty_exceeded | The calibrated offset interval is wider than --remote-jog-max-uncertainty-ns. |
jog_clock_calibration_expired | The last calibration is older than --remote-jog-calibration-max-age-ns. Recalibrate. |
jog_clock_exchange_inconsistent | The calibration timestamps are not causally consistent. |
jog_input_too_old | The conservatively mapped input age exceeds the cell ceiling. |
jog_input_entirely_future | The whole input interval lies in the host's future. |
jog_input_deadline_expired | The input deadline has already passed. |
session_principal_mismatch | The WSS connection's TLS principal does not own the session. |
independent_jog_unavailable | No independent jog lane, or the remote listener is shutting down (HTTP 503 before upgrade). |
A frame refused by the native lane is answered on WSS as jog_native_rejected_<n>, where n is the native jog reason. On jog.sock, every refusal is only counted in /v1/jog/ingress.
Client libraries. Go: JogSession.Update / UpdateAt, RemoteJogSession.Update. C++: RtJogProducer::update, RtJogRemoteProducer::update.
end_jog#
/v1/control End a jog generation. Motion ramps to a hold. State: implemented. Lease: session and generation.
Revokes input for jog_generation before waiting for the native receipt, then the core ramps the jog to a stop. The reply's handle echoes the generation. end_jog does not release authority: call release separately. Ending during the expiry ramp can return a native closed refusal.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | end_jog. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
jog_generation | uint64 | Yes | The current non-zero jog generation from begin_jog. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, jog_generation.
Response#
handle holds the result. handle echoes the ended jog generation.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "end_jog",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"jog_generation": 4
}{
"schema": "rosie.rt-control.response.v1",
"operation": "end_jog",
"handle": 4
}Reason codes#
| Reason | When |
|---|---|
jog_session_stale | No jog session is open, or jog_generation is not the current one. |
independent_jog_unavailable | The native client offers no independent jog lane. |
Also the common envelope and authority reasons.
Native jog refusals return RTCore rejected jog (reason N) with native_jog_result.
Client libraries. Go: JogSession.End, Client.EndJog. C++: RtJogProducer::end, end_jog().
jog#
/v1/control Legacy JSON velocity jog. Test only. State: test_only. Lease: session and generation.
Labelled test_only: it is kept for test fixtures. Applications use begin_jog, update_jog and end_jog instead.
The contract describes it as: “Legacy velocity jog is test-only for oracle ports and fixtures. Consumers use begin_jog/update_jog/end_jog; update_jog uses jog.sock or WSS /v1/jog.”
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | jog. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | Yes | Axes to jog. |
velocity | []float64 | Yes | Finite velocities in Describe axis order, rad/s or m/s. |
timeout_ms | uint32 | Yes | Input lifetime, 1..250 ms. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, axis_mask, velocity, timeout_ms.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "jog",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 1,
"velocity": [
0.01,
0,
0,
0,
0,
0,
0,
0,
0
],
"timeout_ms": 100
}{
"schema": "rosie.rt-control.response.v1",
"operation": "jog",
"sequence": 26
}Reason codes#
| Reason | When |
|---|---|
mode_conflict | A program is executing. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.Jog. C++: jog().
Trajectories#
A low-level point-list path, used by tests and short moves. Programs from the planner use Programs.
prepare_trajectory#
/v1/control Upload a point list and get an inert handle. State: implemented. Lease: session and generation.
Stages 2..250000 Point records for axis_mask and returns a handle in the prepared state. Nothing moves until start_trajectory. The first point's time_ns is 0 and times strictly increase; positions and optional velocities are in Describe axis order and logical rad or m units. Native limits and continuity are enforced at Prepare, and again at Start.
For a large body, put schema, operation, session and a non-zero generation before points, within the first 16384 bytes, so rt-control can check the fence before reading the rest. Do not use a key-sorting JSON encoder. One JSON upload is admitted at a time across all listeners, and the whole body is capped at 222516384 bytes. This is the low-level path for tests and short moves; production programs use prepare_program.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | prepare_trajectory. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
axis_mask | uint32 | Yes | Axes the trajectory commands. |
points | Point[] | Yes | 2..250000 points. See Point for units. |
identity | Identity | No | Immutable identity checked again at Start. Default: all zero. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, axis_mask, points.
Response#
handle is the new handle and data is its HandleRecord.
| Name | Type | Required | Description |
|---|---|---|---|
handle | uint64 | Yes | — |
state | string | Yes | One of the handle_states labels; terminal states never regain permission. |
generation | uint64 | Yes | Application grant generation that prepared this handle. |
execution_generation | uint64 | Yes | Count of acknowledged native Starts when this handle started; zero before Start. |
native_sequence | uint64 | Yes | Correlated native Start sequence; zero before Start. |
identity | Identity | No | Immutable raw trajectory identity supplied at Prepare and checked at Start; echoed unchanged through terminal observation. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "prepare_trajectory",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"axis_mask": 1,
"points": [
{
"time_ns": 0,
"position": [
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
{
"time_ns": 1000000000,
"position": [
0.05,
0,
0,
0,
0,
0,
0,
0,
0
]
}
]
}{
"schema": "rosie.rt-control.response.v1",
"operation": "prepare_trajectory",
"handle": 7,
"data": {
"handle": 7,
"state": "prepared",
"generation": 3,
"execution_generation": 0,
"native_sequence": 0,
"identity": {}
}
}Reason codes#
| Reason | When |
|---|---|
busy | Another JSON upload holds the preparation slot, or the lifecycle lock is busy. |
Also the common envelope, authority, native and cell I/O reasons.
A native invalid_trajectory refusal (reason 6) retires every prepared handle and the prepared program.
Client libraries. Go: Client.PrepareTrajectory. C++: prepare_trajectory().
start_trajectory#
/v1/control Start a prepared handle. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
Starts handle if it is still prepared and belongs to this grant. The full motion start gate is evaluated in the core: lease, Arm, bus, faults, configuration, Home, limits, CSP mode, enable and a first point continuous with the held position.
A definite not_ready or mode_conflict refusal restores the prepared plan so you can retry. Any uncertain outcome retires the handle: prepare again rather than replay. Completion is observed in Status and events, never inferred from the receipt.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | start_trajectory. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
handle | uint64 | Yes | Non-zero handle from prepare_trajectory. |
identity | Identity | No | Must equal the identity supplied at Prepare (all zero if none was). |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, handle.
Response#
sequence holds the native command sequence and data is a HandleRecord.
| Name | Type | Required | Description |
|---|---|---|---|
handle | uint64 | Yes | — |
state | string | Yes | One of the handle_states labels; terminal states never regain permission. |
generation | uint64 | Yes | Application grant generation that prepared this handle. |
execution_generation | uint64 | Yes | Count of acknowledged native Starts when this handle started; zero before Start. |
native_sequence | uint64 | Yes | Correlated native Start sequence; zero before Start. |
identity | Identity | No | Immutable raw trajectory identity supplied at Prepare and checked at Start; echoed unchanged through terminal observation. |
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "start_trajectory",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"handle": 7
}{
"schema": "rosie.rt-control.response.v1",
"operation": "start_trajectory",
"sequence": 27,
"data": {
"handle": 7,
"state": "started",
"generation": 3,
"execution_generation": 1,
"native_sequence": 27,
"identity": {}
}
}Reason codes#
| Reason | When |
|---|---|
unknown_handle | No such handle in this adapter incarnation. |
trajectory_identity_mismatch | identity differs from the one given at Prepare. |
handle_started | The handle has already started. |
handle_consumed | The handle completed, or a later execution replaced it. |
handle_discarded | The handle was discarded. |
handle_superseded | A newer preparation replaced it. |
handle_retired | Stop, grant loss or an uncertain outcome retired it. Prepare again. |
mode_conflict | A program is executing, or the core reports another active mode. The handle is kept. |
not_ready | The start gate failed. The handle is kept; fix readiness and retry. |
fence | Authority was revoked or the request cancelled while starting. The handle is retired. |
Also the common envelope, authority and native reasons.
Client libraries. Go: Client.StartTrajectory. C++: start_trajectory().
discard_trajectory#
/v1/control Discard a prepared handle and free its native storage. State: implemented. Lease: session and generation.
Discards a prepared handle. Discarding an already discarded handle is a no-op. A started handle cannot be discarded: you get handle_active; use Halt or Stop instead.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | discard_trajectory. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
handle | uint64 | Yes | Non-zero handle to discard. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, handle.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "discard_trajectory",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"handle": 7
}{
"schema": "rosie.rt-control.response.v1",
"operation": "discard_trajectory",
"sequence": 28
}Reason codes#
| Reason | When |
|---|---|
unknown_handle | No such handle in this adapter incarnation. |
handle_active | The handle has started. Discard is refused; end it with Halt or Stop. |
Also the common envelope, authority and native reasons.
When native cleanup fails, the error reads discard preparation <handle>: <cause>.
Client libraries. Go: Client.DiscardTrajectory. C++: discard_trajectory().
Programs#
The production path for planned weld programs: upload a verified .rdt, then start it by identity.
prepare_program#
/v1/program Upload a dense .rdt program. It stays inert until start_program. State: implemented. Lease: session and generation headers.
The body is the raw .rdt bytes (see the .rdt format); authority travels in headers. rt-control decodes and validates the whole file (format, digests, time grid, continuity, native position, velocity and declared acceleration limits, axis mapping and process markers) before staging it. It replaces any previously prepared program.
The reply's Program carries the full Identity. Echo it unchanged to start_program. prepare_program has no request_id deduplication: never replay an uncertain upload; inspect Describe or Status, or Stop, first. One binary upload is admitted at a time, and the body is capped at 39298580 bytes.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
X-Control-Session (header) | string | Yes | Current session token. |
X-Control-Generation (header) | uint64 | Yes | Current grant generation, as decimal text. |
Content-Type (header) | string | No | application/octet-stream (sent by the SDKs). |
Body: Binary .rdt blob.
Required: X-Control-Session, X-Control-Generation.
Response#
data is a Program.
| Name | Type | Required | Description |
|---|---|---|---|
process_markers | ProcessMarker[] | Yes | Process-I/O markers in the program. |
identity | Identity | Yes | Echo this unchanged to start_program. |
requires_process_io | bool | Yes | True if the program has output markers. |
segments | int | Yes | Segment count. |
samples | int | Yes | Source sample count. |
normalised_samples | int | Yes | Exact execution sample count after coincident segment endpoints are shared. |
axis_mask | uint32 | Yes | Axes the program commands. |
Example#
POST /v1/program HTTP/1.1
Host: localhost
Content-Type: application/octet-stream
X-Control-Session: 8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e
X-Control-Generation: 3
Content-Length: 1530412
<.rdt bytes>{
"schema": "rosie.rt-control.response.v1",
"operation": "prepare_program",
"data": {
"process_markers": [],
"identity": {
"plan_id": "weld-demo:1a2b3c4d5e6f",
"program_id": "weld-demo",
"program_digest": "sha256:…",
"trajectory_digest": "sha256:…",
"source_digest": "sha256:…",
"normalised_digest": "sha256:…",
"manifest_revision": 1,
"plan_revision": 1
},
"requires_process_io": false,
"segments": 3,
"samples": 10002,
"normalised_samples": 10000,
"axis_mask": 511
}
}Reason codes#
| Reason | When |
|---|---|
invalid_control_generation | X-Control-Generation is missing or not a decimal uint64. |
body_too_large | The body exceeds 39298580 bytes. HTTP 413. |
session_principal_mismatch | The session belongs to another principal. |
busy | Another .rdt upload is in progress, the lifecycle lock is busy, or the core has no free plan slot (then native_result.Reason is 5, capacity). |
program_already_executing | A program is executing. Stop it or wait. |
manifest_revision_mismatch | The program's manifest_revision is not the adapter's pair revision. |
process_io_executor_not_qualified | The program sets the torch flag. Always refused. |
program_identity_missing | The .rdt header lacks a required identity field. |
dense_axis_map_requires_nine_ids | The cell describes more rotary axes than the nine-column format carries. |
invalid_dense_axis_map | The cell's rotary axes cannot be mapped onto the dense columns. |
unmapped_dense_axis | A commanded dense column has no native axis. The error reads unmapped_dense_axis: <axis>. |
native_limit_exceeded | A sample exceeds a native position, velocity or declared acceleration limit. data.limit_violation names it. |
native_segment_rate_exceeded | An interpolated segment exceeds a velocity limit. data.limit_violation names it. |
outside_limits_outward | A recovery segment would bow further outside the limits. |
segment_boundary_discontinuous | Adjacent moving segments do not meet. |
io_not_configured | The program has process markers but no cell I/O is configured. |
io_torch_unqualified | A marker names a torch-class output. |
io_marker_invalid | A marker names an unknown output or does not land on a sample. |
axis_count_mismatch | The .rdt file failed format validation. |
blob_length_mismatch | The .rdt file failed format validation. |
block_layout_invalid | The .rdt file failed format validation. |
block_sha256_mismatch | The .rdt file failed format validation. |
dense_schema_mismatch | The .rdt file failed format validation. |
duration_mismatch | The .rdt file failed format validation. |
header_json_invalid | The .rdt file failed format validation. |
header_truncated | The .rdt file failed format validation. |
kind_invalid | The .rdt file failed format validation. |
limits_invalid | The .rdt file failed format validation. |
nonfinite_sample | The .rdt file failed format validation. |
q_step_exceeded | The .rdt file failed format validation. |
qd_limit_exceeded | The .rdt file failed format validation. |
reserved_flags_set | The .rdt file failed format validation. |
sample_count_overflow | The .rdt file failed format validation. |
sample_encoding_mismatch | The .rdt file failed format validation. |
segment_index_out_of_order | The .rdt file failed format validation. |
segment_too_short | The .rdt file failed format validation. |
segments_empty | The .rdt file failed format validation. |
time_grid_invalid | The .rdt file failed format validation. |
torch_outside_weld | The .rdt file failed format validation. |
total_sample_count_mismatch | The .rdt file failed format validation. |
trajectory_digest_mismatch | The .rdt file failed format validation. |
boundary_q_discontinuity | The .rdt file failed format validation. |
boundary_qd_nonzero | The .rdt file failed format validation. |
Also the common authority and native reasons.
The dense format reasons are defined with the .rdt format. Every one of them is a catalogue label.
Client libraries. Go: Client.PrepareProgram. C++: prepare_program().
start_program#
/v1/control Start the prepared program by its exact identity. State: implemented. Lease: session and generation.
Warning
This call can energise the drives or move the robot. Keep the hardware E-stop within reach. See the safety model.
identity must equal the prepared program's Identity field for field. The same start gate as start_trajectory applies. Record sequence; completion appears in Status as execution.state: completed for the next execution.generation, or faulted with native_execution_failed.
To retry a lost receipt, resend the same request with the same request_id. A new ID is a new command.
Request#
| Name | Type | Required | Description |
|---|---|---|---|
schema | string | Yes | rosie.rt-control.request.v1. |
operation | string | Yes | start_program. |
session | string | Yes | Session token from the current Grant. |
generation | uint64 | Yes | Current grant generation. |
identity | Identity | Yes | The complete Identity returned by prepare_program. |
request_id | string | No | Idempotence key, 1..64 printable ASCII bytes. See retries. |
The contract's semantically required fields: schema, operation, session, generation, identity.
Response#
sequence holds the native command sequence. There is no data.
Example#
POST /v1/control HTTP/1.1
Host: localhost
Content-Type: application/json
{
"schema": "rosie.rt-control.request.v1",
"operation": "start_program",
"session": "8c2f4e1a9b7d3c5e0f6a2b4c8d1e3f5a7b9c0d2e4f6a8b1c3d5e7f9a0b2c4d6e",
"generation": 3,
"request_id": "9b2e41c07d5f4a3e8c6b1d0f2a4e6c8b",
"identity": {
"plan_id": "weld-demo:1a2b3c4d5e6f",
"program_id": "weld-demo",
"program_digest": "sha256:…",
"trajectory_digest": "sha256:…",
"source_digest": "sha256:…",
"normalised_digest": "sha256:…",
"manifest_revision": 1,
"plan_revision": 1
}
}{
"schema": "rosie.rt-control.response.v1",
"operation": "start_program",
"sequence": 29
}Reason codes#
| Reason | When |
|---|---|
program_identity_mismatch | No program is prepared, or identity differs from it. |
program_already_executing | A program is already executing. |
process_io_executor_not_qualified | The program requires torch output. Always refused. |
unknown_handle | No such handle in this adapter incarnation. |
handle_started | The handle has already started. |
handle_consumed | The handle completed, or a later execution replaced it. |
handle_discarded | The handle was discarded. |
handle_superseded | A newer preparation replaced it. |
handle_retired | Stop, grant loss or an uncertain outcome retired it. Prepare again. |
mode_conflict | A program is executing, or the core reports another active mode. The handle is kept. |
not_ready | The start gate failed. The handle is kept; fix readiness and retry. |
fence | Authority was revoked or the request cancelled while starting. The handle is retired. |
Also the common envelope, authority, native and cell I/O reasons.
Client libraries. Go: Client.StartProgram. C++: start_program().
Reserved operations#
Named in the contract so clients can detect them, but they perform no operation.
abort#
/v1/control Reserved. Not implemented. State: unimplemented. Lease: none.
Advertised as unimplemented, with transport none. Sending operation: "abort" performs nothing and returns capability_unimplemented with the CapabilityInfo in data. Use stop or halt.
Request#
The standard envelope with operation set to the operation name. No other fields.
Response#
Always refused; see below.
Reason codes#
| Reason | When |
|---|---|
capability_unimplemented | Always. |
readiness#
/v1/control Reserved. Not implemented. State: unimplemented. Lease: none.
Advertised as unimplemented. Returns capability_unimplemented. Read per-axis readiness from GET /v1/status instead.
Request#
The standard envelope with operation set to the operation name. No other fields.
Response#
Always refused; see below.
Reason codes#
| Reason | When |
|---|---|
capability_unimplemented | Always. |
Types#
Every type in the contract, generated from types in the schema. Required is the codec designation; which fields an operation needs is in its request table. JSON integers are exact uint64 values: parse them without converting to floating point. Fields of native receipts (CommandResult, JogObservation, GrantObservation) keep their case-sensitive native names.
Authority#
Fence#
| Name | Type | Required | Description |
|---|---|---|---|
session | string | Yes | Current unguessable session token; acquire omits the fence. Tokens issued by the adapter are 64 lowercase hexadecimal characters. |
generation | uint64 | Yes | Nonzero uint64 grant generation. Motion requires exact equality; renew and stop accept an older nonzero generation not above the current one for the same session. |
Binding#
| Name | Type | Required | Description |
|---|---|---|---|
pair_id | string | Yes | Exact configured nonempty pair ID. |
revision | uint64 | Yes | Nonzero uint64 equal to configured pair revision. |
configuration_sha256 | string | Yes | Exact configured native SHA-256 label. |
machine_sha256 | string | No | Machine-semantics digest; omitted by clients that only know the whole-artifact digest. |
Grant#
| Name | Type | Required | Description |
|---|---|---|---|
stopping | bool | Yes | True means renewal keeps the lease alive while Stop is in flight; it grants no movement permission. |
deadline_host_ns | uint64 | Yes | Uint64 absolute lease deadline in host monotonic nanoseconds. |
session | string | Yes | 64-character unpredictable lowercase hexadecimal token while owned; empty after release/expiry. |
generation | uint64 | Yes | Monotonically increasing uint64 application generation, fenced by Stop and acquisition. |
controller | string | Yes | The controller label sent to acquire. |
binding | Binding | Yes | The binding, completed with the adapter's digests. |
lease_ms | int | Yes | Effective negotiated lease in whole milliseconds: min(client requested lease, compiled cell ceiling); zero/omitted request retains 500 ms capped by the cell. Renew preserves this value. Longer leases increase worst-case unattended-stop delay after link loss. Unverified absolute bound: 10000 ms. |
GrantObservation#
| Name | Type | Required | Description |
|---|---|---|---|
Ticket | uint64 | Yes | — |
ConnectionId | uint64 | Yes | — |
NativeGeneration | uint64 | Yes | — |
AppGrantGeneration | uint64 | Yes | — |
CapabilityId | uint8[16] | Yes | — |
DeadlineHostNs | uint64 | Yes | — |
NowHostNs | uint64 | Yes | — |
ConfigurationEpoch | uint64 | Yes | — |
HomeEpoch | uint64 | Yes | — |
StopAckId | uint64 | Yes | — |
GrantReason | uint32 | Yes | — |
GrantActive | uint32 | Yes | — |
AxisMask | uint32 | Yes | — |
Reserved | uint32 | Yes | — |
Reserved1 | uint64 | Yes | — |
Reserved2 | uint64 | Yes | — |
Reserved3 | uint64 | Yes | — |
Requests and responses#
Request#
| Name | Type | Required | Description |
|---|---|---|---|
request_id | string | No | Optional, non-null string of 1..64 printable ASCII bytes (0x20..0x7e). |
schema | string | Yes | Exactly rosie.rt-control.request.v1. |
operation | string | Yes | Exact capability name; only POST /v1/control operations dispatch here. Unknown names are rejected. |
| (embedded) | Fence | Yes | All fields of Fence appear at this level of the object. |
label | string | No | mark_telemetry requires 1..128 UTF-8 bytes; free-text dump label. |
controller | string | No | Acquire requires 1..63 bytes; opaque controller name. |
binding | Binding | No | Acquire requires exact equality with the configured Binding. |
axis_mask | uint32 | No | Uint32 configured axis group mask; interpretation is native operation-specific; reset_fault defaults zero to all axes. |
velocity | float64[] | No | Finite logical velocities in described axis order for legacy jog; native vector and velocity-limit validation applies. |
timeout_ms | uint32 | No | Legacy jog requires an integer 1..250 milliseconds. |
handle | uint64 | No | Nonzero opaque uint64 handle for start/discard, owned by the current daemon incarnation and grant. |
points | Point[] | No | 2..250000 Point records; declared axis order, native limits and continuity apply. Large bodies require the envelope before this array. |
identity | Identity | No | Exact prepared program Identity for start_program. |
jog_generation | uint64 | No | EndJog requires the exact current nonzero independent jog generation. |
source_sequence | uint64 | No | Accepted envelope field retained for compatibility; current /v1/control dispatch does not consume it. Independent updates use the binary lane. |
source_origin_host_ns | uint64 | No | BeginJog origin in the negotiated host monotonic clock, uint64 nanoseconds; native freshness validation applies. |
deadline_host_ns | uint64 | No | BeginJog producer deadline in host monotonic nanoseconds; after origin and never extended by admission or renewal. |
clock_incarnation | string | No | BeginJog requires exact equality with GET /v1/jog/clock incarnation. |
requested_lease_ms | int | No | Acquire requested lease in whole ms, 1..10000; omitted or zero retains the LAN default capped by the cell. Adapter returns min(request, cell ceiling) in Grant.lease_ms. Clients require at least three measured round trips plus renewal cadence. |
Response#
| Name | Type | Required | Description |
|---|---|---|---|
native_jog_result | JogObservation | No | Native jog observation on a jog refusal. |
native_result | CommandResult | No | Native receipt on a native refusal. |
schema | string | Yes | rosie.rt-control.response.v1. |
operation | string | Yes | The operation this reply answers. |
sequence | uint64 | No | Native command sequence, when returned. |
handle | uint64 | No | Handle or jog generation, when returned. |
data | any | No | The operation's result type. |
error | string | No | Reason code or diagnostic, on failure only. |
RawResponse#
| Name | Type | Required | Description |
|---|---|---|---|
native_jog_result | JogObservation | No | Native jog observation on a jog refusal. |
native_result | CommandResult | No | Native receipt on a native refusal. |
schema | string | Yes | rosie.rt-control.response.v1. |
operation | string | Yes | The operation this reply answers. |
sequence | uint64 | No | Native command sequence, when returned. |
handle | uint64 | No | Handle or jog generation, when returned. |
data | object | No | Undecoded result JSON. |
error | string | No | Reason code or diagnostic, on failure only. |
CommandResult#
| Name | Type | Required | Description |
|---|---|---|---|
Sequence | uint64 | Yes | Native command sequence. |
Handle | uint64 | Yes | Native handle, when relevant. |
Generation | uint64 | Yes | Native control generation. |
Operation | uint32 | Yes | Native message code (MSG_CMD_*). |
Result | uint32 | Yes | 0 accepted, 1 rejected, 2 prepared. |
Reason | uint32 | Yes | Native command reason; see native command reasons. |
AxisMask | uint32 | Yes | Axes the result applies to. |
CapabilityInfo#
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Canonical capability name. |
state | string | Yes | implemented, interim, test_only or unimplemented. test_only operations are retained for oracle ports and fixtures; consumers use implemented operations. |
transport | string | Yes | Actual ingress; unimplemented has no transport. |
Motion#
Point#
| Name | Type | Required | Description |
|---|---|---|---|
time_ns | int64 | Yes | Signed int64 nanoseconds from plan start; first point zero, later timestamps strictly increasing. |
position | float64[] | Yes | Finite logical rad/m positions in described axis order, within native configured bounds. |
velocity | float64[] | No | Optional finite logical rad/s or m/s velocities in described axis order; nil/empty omits feedforward. |
io_mask | uint32 | No | Eight-bit mask in configured output order; set bits require configured non-torch outputs. |
io_values | uint32 | No | Eight-bit output intents; every set bit must also be set in io_mask. Physical readback is independent. |
Identity#
| Name | Type | Required | Description |
|---|---|---|---|
plan_id | string | Yes | Plan identifier from the .rdt header. |
program_id | string | Yes | Program identifier from the .rdt header. |
program_digest | string | Yes | Program digest from the .rdt header. |
trajectory_digest | string | Yes | Content digest of the dense trajectory. |
source_digest | string | Yes | Verified source trajectory digest; start_program must echo the prepared value exactly. |
normalised_digest | string | Yes | Canonical segment-record digest including local clocks and process bits; start_program must echo the prepared value exactly. |
manifest_revision | uint64 | Yes | Must equal the pair revision rt-control was started with. |
plan_revision | uint64 | Yes | Plan revision from the .rdt header. |
HandleRecord#
| Name | Type | Required | Description |
|---|---|---|---|
handle | uint64 | Yes | — |
state | string | Yes | One of the handle_states labels; terminal states never regain permission. |
generation | uint64 | Yes | Application grant generation that prepared this handle. |
execution_generation | uint64 | Yes | Count of acknowledged native Starts when this handle started; zero before Start. |
native_sequence | uint64 | Yes | Correlated native Start sequence; zero before Start. |
identity | Identity | No | Immutable raw trajectory identity supplied at Prepare and checked at Start; echoed unchanged through terminal observation. |
Execution#
| Name | Type | Required | Description |
|---|---|---|---|
handles | HandleRecord[] | Yes | Every handle this adapter knows, with its state. |
generation | uint64 | Yes | Count of acknowledged native Starts; distinct from native control generation. |
state | string | Yes | Application execution state: empty before observation, prepared, executing, completed, faulted, cancelled, discarded or released. |
identity | Identity | Yes | Identity of the prepared or running program. |
segment | int | Yes | Current zero-based program segment when a program is observed. |
native_sequence | uint64 | Yes | Native sequence of the program Start. |
error | string | No | Failure detail, for example native_execution_failed. |
MotionState#
| Name | Type | Required | Description |
|---|---|---|---|
mode | uint32 | Yes | 0 idle, 2 trajectory, 3 jog. |
state | uint32 | Yes | Native execution state: 0 idle, 1 accepted, 2 queued, 3 executing, 4 completed, 5 aborted, 6 faulted, 7 underrun. |
trajectory_id | uint64 | Yes | Active trajectory handle. |
point_index | uint32 | Yes | Current point index. |
queue_depth | uint32 | Yes | — |
last_event | uint32 | Yes | — |
done | bool | Yes | True when the active execution has finished. |
command_sequence | uint64 | Yes | Native command sequence of the active or last motion. |
time_ns | uint64 | Yes | Native observation time, ns. |
Program#
| Name | Type | Required | Description |
|---|---|---|---|
process_markers | ProcessMarker[] | Yes | Process-I/O markers in the program. |
identity | Identity | Yes | Echo this unchanged to start_program. |
requires_process_io | bool | Yes | True if the program has output markers. |
segments | int | Yes | Segment count. |
samples | int | Yes | Source sample count. |
normalised_samples | int | Yes | Exact execution sample count after coincident segment endpoints are shared. |
axis_mask | uint32 | Yes | Axes the program commands. |
ProcessMarker#
| Name | Type | Required | Description |
|---|---|---|---|
time_ns | int64 | Yes | Marker time from program start, ns. |
segment | int | Yes | Segment index. |
sample | int | Yes | Sample index. |
action | string | Yes | Output name. |
value | bool | Yes | Requested output value. |
ProgramLimitData#
| Name | Type | Required | Description |
|---|---|---|---|
limit_violation | ProgramLimitViolation | Yes | Logical joint-limit diagnostic for native_limit_exceeded or native_segment_rate_exceeded; supplements the unchanged refusal reason and is not a native command receipt. |
ProgramLimitViolation#
| Name | Type | Required | Description |
|---|---|---|---|
kind | string | Yes | Diagnostic quantity: position or velocity. |
segment | int | Yes | Zero-based source segment index, matching the refusal detail. |
sample | int | Yes | Zero-based source sample index, matching the refusal detail. |
axis | string | Yes | Canonical joint identifier reported by admission, for example J6. |
value | float64 | Yes | Finite logical joint position or peak velocity in unit; command-count direction and Home offset have been removed. |
limit | float64 | Yes | Finite logical admission bound in unit; invalid numeric details are omitted as a whole without discarding the refusal. |
unit | string | Yes | rad for position; rad/s for velocity. |
PlanCursor#
| Name | Type | Required | Description |
|---|---|---|---|
time_ns | uint64 | Yes | — |
active_handle | uint64 | Yes | — |
sample_index | uint32 | Yes | — |
native_clock_ns | uint64 | Yes | — |
BufferHealth#
| Name | Type | Required | Description |
|---|---|---|---|
time_ns | uint64 | Yes | — |
slots_free | uint32 | Yes | — |
staging_in_progress | bool | Yes | — |
ring_drops | uint64 | Yes | — |
native_slot_occupancy | object | Yes | — |
Jog#
LocalJogClock#
| Name | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | CLOCK_MONOTONIC. |
incarnation | string | Yes | Clock incarnation; pass it to begin_jog. |
mapping_generation | uint64 | Yes | Clock mapping generation (1 for the local lane). |
now_host_ns | uint64 | Yes | Current host monotonic time, ns. |
JogObservation#
| Name | Type | Required | Description |
|---|---|---|---|
Ticket | uint64 | Yes | — |
ConnectionId | uint64 | Yes | — |
NativeGeneration | uint64 | Yes | — |
CapabilityId | uint8[16] | Yes | — |
AppGrantGeneration | uint64 | Yes | — |
ConfigurationEpoch | uint64 | Yes | — |
HomeEpoch | uint64 | Yes | — |
ClockMappingGeneration | uint64 | Yes | — |
JogGeneration | uint64 | Yes | Current jog generation. |
SourceSequence | uint64 | Yes | Sequence of the latest applied input. |
InputDeadlineHostNs | uint64 | Yes | Deadline of the latest applied input, host ns. |
NowHostNs | uint64 | Yes | Publication time, host ns. |
ObservedSourceSequence | uint64 | Yes | — |
ObservedOriginHostNs | uint64 | Yes | — |
FirstObservedHostNs | uint64 | Yes | — |
ControlReason | uint32 | Yes | — |
ControlAccepted | uint32 | Yes | — |
UpdateReason | uint32 | Yes | — |
StateReason | uint32 | Yes | Native jog reason for the current state. |
AxisMask | uint32 | Yes | Axes of the jog session. |
Open | uint32 | Yes | 1 while the jog session accepts input. |
HasInput | uint32 | Yes | 1 once an input has been applied. |
VelocityScalePpm | uint32 | Yes | — |
JogIngressObservation#
| Name | Type | Required | Description |
|---|---|---|---|
source_sequence | uint64 | Yes | — |
reason | uint32 | Yes | — |
now_host_ns | uint64 | Yes | — |
refused | uint64 | Yes | Cumulative refused ingress count for this adapter process; accepted frames do not increment it. |
refused_by_reason | uint64[15] | Yes | Cumulative refusal counts indexed by protocol/control.json jog reason 0..14; index 0 remains zero. Unverified fixed capacity: 15 reason slots. |
latest_refusal | JogIngressRefusal | Yes | Most recent refusal across all ingress transports; zero before any refusal and preserved through acceptance and grant changes. |
JogIngressRefusal#
| Name | Type | Required | Description |
|---|---|---|---|
source_sequence | uint64 | Yes | Refused source sequence; zero when no complete input frame is available. |
reason | uint32 | Yes | Typed native jog reason; zero only before the first refusal. |
now_host_ns | uint64 | Yes | Host monotonic ns when the adapter recorded the refusal; not an RT application timestamp. |
Description#
Description#
| Name | Type | Required | Description |
|---|---|---|---|
| (embedded) | NativeDescription | Yes | All fields of NativeDescription appear at this level of the object. |
contract_version | uint32 | Yes | Exactly 1. |
capabilities_digest | string | Yes | Lowercase SHA-256 of the exact committed UTF-8 LF schema file bytes, including its final newline; no self-referential digest field. |
capabilities | CapabilityInfo[] | Yes | Every target capability with its implementation state and transport. |
control_idle_timeout_ns | uint64 | No | Compiled link idle timeout in ns; clients keep reserved connections alive at one third of this bound, independently of grants. Unverified LAN and internet policy: 90000000000 ns. An omitted legacy field uses 30000000000 ns. |
program | Program | No | Detached prepared program metadata including both identity digests; absent when no program is prepared. |
robot | RobotDescription | No | Null when no robot definition is bound or no compiled artefact is loaded; never guessed from axis count. |
drives | DriveDescription[] | Yes | Per-axis compiled drive configuration and current verified bring-up identity; empty without a compiled artefact. |
NativeDescription#
| Name | Type | Required | Description |
|---|---|---|---|
backend | string | Yes | Core backend, for example simulation. |
schema | string | Yes | — |
protocol_major | uint32 | Yes | Native protocol major version. |
protocol_minor | uint32 | Yes | Native protocol minor version. |
configuration_sha256 | string | Yes | Digest of the compiled configuration. |
machine_sha256 | string | Yes | Canonical machine-semantics digest recomputed by the daemon at startup. |
deployment_sha256 | string | Yes | Deployment identity digest (host, NIC, CPUs, sockets, pair, users). |
max_trajectory_points | uint32 | Yes | Maximum points per trajectory. |
resident_plans | uint32 | Yes | Native plan slots. |
cycle_ns | uint64 | Yes | Cycle period, ns. |
interpolation | string | Yes | — |
stop | string | Yes | — |
axes | AxisDescription[] | Yes | Axes in native index order. |
bus | object | Yes | Current native bus policy and held_slaves inventory; the machine digest binds configured policy and declarations, not discovered devices. A declared cell I/O terminal has disposition io_terminal and contributes one required responding slave. Its declared identity and presence remain mandatory under both hold and refuse; after activation it must be OP or admission reports io_terminal_not_operational. Held devices alone receive no PDOs or output capability. |
max_grant_lease_ns | uint64 | Yes | Compiled cell lease ceiling in ns; a longer effective lease increases unattended-stop delay after link loss. |
max_jog_input_age_ns | uint64 | Yes | Compiled cell capture-age and lifetime ceiling in ns; longer ages prolong stale velocity application before the existing expiry ramp. |
io | object | No | Configured cell I/O terminal identity, torch_qualified=false, named input classes and polarities, and output classes, OFF safe states, expiry_ns budgets and independent readback wiring. Omitted when no terminal is configured; this policy is separate from NativeStatus.io observations. |
AxisDescription#
| Name | Type | Required | Description |
|---|---|---|---|
completion_tolerance | float64 | Yes | Settle tolerance at the final sample, in position_unit. |
feedback_fields | string[] | Yes | — |
index | uint32 | Yes | Native index; the bit position in every axis mask. |
id | string | Yes | Axis identifier, for example J1. |
position_unit | string | Yes | rad or m. |
counts_per_unit | float64 | Yes | Drive counts per position_unit, compiled from the robot definition. |
sign | int | Yes | Command direction, +1 or −1. |
feedback_wrap | bool | Yes | — |
command_wrap | bool | Yes | — |
velocity_command_mapped | bool | Yes | — |
native_home | bool | Yes | True if the axis supports native Home. |
require_home | bool | Yes | True if motion requires a valid Home. |
min_position | float64 | Yes | Lower position limit, in position_unit. |
max_position | float64 | Yes | Upper position limit, in position_unit. |
max_velocity | float64 | Yes | Velocity limit, position_unit/s. |
jog_acceleration | float64 | Yes | Jog acceleration, position_unit/s². |
max_target_lead | float64 | Yes | Largest allowed command lead over feedback, in position_unit. |
following_error | float64 | Yes | Following-error bound, in position_unit. |
following_error_timeout_ns | uint64 | Yes | How long a following error may persist, ns. |
completion_timeout_ns | uint64 | Yes | Settle deadline after the final sample, ns. |
interpolation | string | Yes | hermite_position_with_velocity, linear_without: cubic Hermite q when both knots supply qd, otherwise linear q; configured shortest-step command wrapping applies. |
feedforward | string | Yes | qd_optional: both supplied knot velocities shape Hermite position; feedforward is its derivative. If either knot lacks qd, feedforward is the linear segment slope. Endpoint hold velocity is zero. |
checks | object | Yes | Object with exactly position: declared, velocity: declared, acceleration: declared or not_declared, jerk: unsupported. Prepare checks position range and supplied qd/segment velocity. With max_acceleration, check consecutive qd differences per segment or second q differences across segment midpoints when qd is absent; mixed qd presence rejects. Without the profile field acceleration is not_declared. Sampled derivatives give no continuous acceleration guarantee at linear corners or endpoint hold. Jerk is never checked. |
endpoint | string | Yes | hold_last_sample_then_settle: hold final q with zero velocity; fresh ready feedback within completion_tolerance by completion_timeout_ns, as evaluated by completion.hpp. |
max_acceleration | float64 | No | Positive finite profile bound in position units per s^2; absent only when acceleration is not_declared. |
brake_override_reason | string | No | Nonempty reason for an explicit bench brake override (effective present=false); absent without an override. Does not claim the physical brake is absent or qualified. |
RobotDescription#
| Name | Type | Required | Description |
|---|---|---|---|
model_id | string | Yes | The robot description's model id: the directory name under robot_description/robots/ the machine was compiled with. |
robot_description_sha256 | string | Yes | sha256:<64 lowercase hex>, the description's manifest identity over the resources it registers (docs/ROBOT-DESCRIPTION-CONTRACT.md); the identity a plan's header must carry. |
machine_planning_calibration_sha256 | string | Yes | sha256:<64 lowercase hex> of the served machine_planning_calibration.json bytes, this machine's deviation from the description; the identity a plan's header must carry. |
resources | ResourceInfo[] | Yes | The description's manifest and every file it registers, by description-relative path, plus machine_planning_calibration.json; unverified maximum 1024 entries and 134217728 distinct bytes. |
ResourceInfo#
| Name | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Description-relative path (robot_description_manifest.json, robot.urdf, meshes/<file>, rtcore_definition.json, ...) or machine_planning_calibration.json. Never a server filesystem path. |
sha256 | string | Yes | Lowercase SHA-256 of the exact resource bytes. |
bytes | uint64 | Yes | Exact resource byte count; unverified maximum 33554432 bytes. |
media_type | string | Yes | application/json, application/xml, model/vnd.collada+xml, model/stl or application/octet-stream. |
DriveDescription#
| Name | Type | Required | Description |
|---|---|---|---|
axis | string | Yes | Configured axis ID in native axis order. |
config_name | string | Yes | Compiled drive configuration name. |
config_sha256 | string | Yes | SHA-256 of canonical drive configuration content used in the compiled identity. |
slave_position | uint16 | Yes | Configured EtherCAT slave position. |
verified_identity | DriveIdentity | No | Null unless current native configuration verification and CoE revision readback are valid. Vendor/product are configured expectations, revision is observed. Simulation synthesizes vendor/product from the profile and cannot independently inject their mismatch. |
DriveIdentity#
| Name | Type | Required | Description |
|---|---|---|---|
expected_vendor_id | uint32 | Yes | Configured vendor expectation used by IgH slave matching; not an independent vendor readback. |
expected_product_code | uint32 | Yes | Configured product expectation used by IgH slave matching; not an independent product readback. |
observed_coe_revision | uint32 | Yes | Observed CoE 0x1018:3 firmware revision; distinct from the configured SII revision and never substituted from configuration. |
Status#
ProcessStatus#
| Name | Type | Required | Description |
|---|---|---|---|
daemon_incarnation | string | Yes | Core process identity for this snapshot. |
adapter_incarnation | string | Yes | rt-control process identity. |
grant | GrantObservation | Yes | Native grant observation. |
jog | JogObservation | Yes | Native jog observation. |
jog_ingress | JogIngressObservation | Yes | Adapter-lifetime ingress outcomes across datagram, WSS and UpdateJog; counters and latest refusal match GET /v1/jog/ingress. |
core | NativeStatus | Yes | Native core status. |
motion | MotionState | Yes | Native motion state. |
execution | Execution | Yes | Program and handle lifecycle. |
time_ns | uint64 | Yes | Native publication time, ns. |
axes | LogicalAxisStatus[] | Yes | Per-axis logical status, in Describe order. |
generations | StatusGenerations | Yes | Current generations and epochs. |
plan_cursor | PlanCursor | Yes | Native plan cursor. |
buffer_health | BufferHealth | Yes | Native buffer health. |
adapter | AdapterStatus | Yes | Adapter runtime observations; not native motion state. |
NativeStatus#
| Name | Type | Required | Description |
|---|---|---|---|
daemon_incarnation | string | Yes | Identity of this core process. |
rt_cpu | uint32 | Yes | Configured RT CPU index as an exact uint32 integer. |
housekeeping_cpus | string | Yes | Effective Linux CPU-list mask for housekeeping workers, excluding the RT CPU. |
affinity_applied | object | Yes | Worker name to affinity-application success; false is not qualified placement and null means no observations. |
recovery | RecoveryStatus | Yes | Latched faults and recovery classes. |
time_ns | uint64 | Yes | Native publication time, ns. |
backend | string | Yes | Core backend. |
configuration_sha256 | string | Yes | Digest of the compiled configuration. |
control_generation | uint64 | Yes | Native control generation (the core's fence). |
lease_valid | uint32 | Yes | 1 while the core holds a valid lease. |
config_verified_mask | uint32 | Yes | Axes whose drive configuration is verified. |
home_valid_mask | uint32 | Yes | Axes with valid Home evidence. |
home_epoch | uint64 | Yes | Increments when Home evidence changes. |
commissioning_phase | uint32 | Yes | 0 when no Home or commissioning is running. |
safety_fault_mask | uint32 | Yes | Non-zero blocks all motion. |
execution_fault_reasons | uint32 | Yes | Latched execution fault bits; see error codes. |
last_bus_failure_operation | uint32 | Yes | — |
last_bus_failure_code | int64 | Yes | — |
armed | uint32 | Yes | 1 when armed. |
axis_enable_mask | uint32 | Yes | Axes that are enabled. |
native_home_active_axis_mask | uint32 | Yes | Axes running native Home. |
axes | AxisStatus[] | Yes | Per-axis native status. |
configuration_epoch | uint64 | Yes | — |
buffer_health | BufferHealth | Yes | — |
plan_cursor | PlanCursor | Yes | — |
bus | object | Yes | Native bus policy and held_slaves with retained, observed and expected declared identities, presence, AL state and disposition; unreadable identity fields are null. Dispositions: held for an undeclared device allowed by hold; declared_unused for a matching declaration; refused_unknown for an undeclared device under refuse; refused_identity for a declared identity mismatch; identity_unreadable for an unavailable SII identity; refused_missing for a missing required declaration; identity_changed for a post-admission identity change under hold; disappeared for a missing unused device under hold; refused_state for a held device outside PREOP or INIT, or a configured terminal outside OP after activation. Refuse continuously requires declared identities and presence; post-admission refusal latches a readiness fault and inhibits outputs before submission, requiring public reset_fault (FaultReset), reacquisition of the application session, then explicit Enable and Arm after restoring the device and verified readiness. Enable before reset is rejected with native not_ready (reason 2); reset clears the readiness fault (reason 128) and safety mask while keeping outputs inhibited and retiring the session. Lost Home evidence requires separate qualified recovery before motion. Hold reports post-admission unused-device identity or presence changes and continues axes while axis readiness remains valid. Admission reason and reason_position identify identity_unreadable, unknown_slave, declared_identity_mismatch, declared_slave_missing, unsafe_held_state or capacity_exceeded; none means no observed refusal. No output capability is granted to held devices. A declared cell I/O terminal has disposition io_terminal and contributes one required responding slave. Its declared identity and presence remain mandatory under both hold and refuse; after activation it must be OP or admission reports io_terminal_not_operational. Held devices alone receive no PDOs or output capability. |
io | IoState | Yes | — |
AxisStatus#
| Name | Type | Required | Description |
|---|---|---|---|
drive_alarm | string | Yes | Drive display alarm code decoded from the drive's error-code objects; unresolved bus candidates joined by |; empty when clear, unmapped, or another drive family. |
drive_alarm_text | string | Yes | Text meaning of drive_alarm; multiple candidates joined by | in matching order. |
drive_alarm_aux_code | uint32 | Yes | Raw auxiliary alarm word read from the drive. Retained for the current nonzero drive error event and configuration epoch, zero when invalid or cleared. Separate from manufacturer_error_code, which carries the cyclic manufacturer_err PDO. |
drive_alarm_aux_valid | bool | Yes | True only for an admitted auxiliary reply matching the current nonzero drive error event and configuration epoch; false when missing, stale, or cleared, preventing zero from being mistaken for a valid reply. |
logical_position | float64 | Yes | — |
logical_valid | bool | Yes | — |
coordinate_counts | int64 | Yes | — |
absolute_source_counts | int32 | Yes | — |
independent_anchor_source | IndependentAnchorSource | No | Fresh independent raw acquisition; does not grant a command-frame binding or Home. |
coordinate_valid | uint32 | Yes | — |
coordinate_source_valid | uint32 | Yes | — |
pdo_fresh | uint32 | Yes | — |
native_home_position_offset | int32 | Yes | — |
observed_revision_no | uint32 | Yes | — |
revision_readback_valid | uint32 | Yes | — |
serial_no | uint32 | Yes | — |
serial_readback_valid | uint32 | Yes | — |
anchor_period_counts | uint32 | Yes | — |
anchor_tolerance_counts | uint64 | Yes | — |
coordinate_reason | uint32 | Yes | — |
coordinate_identity_sha256 | string | Yes | Canonical coordinate digest; empty means persisted anchors are unavailable. |
coordinate_identity | string | Yes | Canonical per-axis fields; empty means persisted anchors are unavailable. |
anchor_identity_changed_field | string | Yes | Differing identity component for anchor_identity_mismatch, or empty. |
anchor_reason | string | Yes | — |
restored_anchor_home_epoch | uint64 | Yes | — |
pos_counts | int32 | Yes | — |
statusword | uint16 | Yes | — |
error_code | uint16 | Yes | — |
vendor_id | uint32 | Yes | — |
product_code | uint32 | Yes | — |
slave_position | uint16 | Yes | — |
time_ns | uint64 | Yes | — |
logical_target | float64 | Yes | — |
readiness | string | Yes | — |
brake_state | uint32 | Yes | — |
home_valid | bool | Yes | — |
logical_velocity | float64 | No | — |
velocity_actual_counts_per_s | int32 | Yes | Drive 0x606C signed reference counts/s in the position frame, sampled each cycle. Diagnostics only; never a speed-safety certification or an execution guard. |
following_error_counts | int32 | Yes | Drive 0x60F4 signed reference counts in the position frame; preferred input to the configured collision watchdog. |
velocity_actual_valid | bool | Yes | True only when velocity_actual is mapped and this cycle has fresh PDO feedback. An absent signal is zero with false validity. |
following_error_valid | bool | Yes | True only when following_error is mapped and this cycle has fresh PDO feedback. An absent signal is zero with false validity. |
max_abs_velocity_actual_counts_per_s | uint32 | Yes | Maximum absolute valid drive velocity in counts/s since the last accepted Arm(true); zero before Arm. Retained through Stop/disarm; INT32_MIN has magnitude 2147483648. |
max_abs_following_error_counts | uint32 | Yes | Maximum absolute valid drive following error in counts since the last accepted Arm(true); zero before Arm. Retained through Stop/disarm; INT32_MIN has magnitude 2147483648. |
di_bits | uint32 | Yes | Current 0x60FD DI logic bits; interpret only when di_valid. |
di_valid | bool | Yes | True only for a fresh PDO and verified digital-input mapping. |
external_enable_active | bool | Yes | Drive servo-on (S-ON) input active; interpret only when external_enable_valid. Diagnostics only; does not prove STO or torque state. |
external_enable_valid | bool | Yes | True only with valid DI feedback and exactly one explicitly configured, verified S-ON digital-input function. |
torque_raw | int32 | Yes | Drive 0x6077 raw per-mille of rated torque; use only with fresh PDO feedback. |
collision_watchdog | CollisionWatchdogStatus | Yes | Native cycle evaluation and latched trip evidence for this axis. |
calibration_valid | bool | No | Persistent calibration applicability; null/absent means legacy unknown. |
position_state | string | No | Native state: unverified, recovering, trusted or lost; empty means legacy unknown. |
position_reason | string | No | Native CoordinateReason name; none means no coordinate refusal; absent means legacy unknown. |
audit_status | string | No | Last stationary audit: pending, verified or unavailable; never motion authority. |
audit_reason | string | No | Native SampleInvalidity name; none means no reported audit failure; absent means legacy unknown. |
audit_last_verified_ns | uint64 | No | Monotonic acquisition completion of last accepted independent evidence; zero means never. |
LogicalAxisStatus#
| Name | Type | Required | Description |
|---|---|---|---|
drive_alarm | string | Yes | Drive display alarm code decoded from the drive's error-code objects; unresolved bus candidates joined by |; empty when clear, unmapped, or another drive family. |
drive_alarm_text | string | Yes | Text meaning of drive_alarm; multiple candidates joined by | in matching order. |
drive_alarm_aux_code | uint32 | Yes | Raw auxiliary alarm word read from the drive. Retained for the current nonzero drive error event and configuration epoch, zero when invalid or cleared. Separate from manufacturer_error_code, which carries the cyclic manufacturer_err PDO. |
drive_alarm_aux_valid | bool | Yes | True only for an admitted auxiliary reply matching the current nonzero drive error event and configuration epoch; false when missing, stale, or cleared, preventing zero from being mistaken for a valid reply. |
time_ns | uint64 | Yes | — |
logical_position | float64 | Yes | — |
logical_valid | bool | Yes | — |
logical_target | float64 | Yes | — |
logical_velocity | float64 | No | — |
readiness | string | Yes | ready or first failing axis gate in this order: faulted, mode_mismatch, home_required, coordinate_invalid, not_enabled, not_operation_enabled, brake_wait; group authority still applies. |
position_counts | int32 | Yes | — |
statusword | uint16 | Yes | — |
brake_state | uint32 | Yes | — |
home_valid | bool | Yes | — |
velocity_actual_counts_per_s | int32 | Yes | Drive 0x606C signed reference counts/s in the position frame, sampled each cycle. Diagnostics only; never a speed-safety certification or an execution guard. |
following_error_counts | int32 | Yes | Drive 0x60F4 signed reference counts in the position frame; preferred input to the configured collision watchdog. |
velocity_actual_valid | bool | Yes | True only when velocity_actual is mapped and this cycle has fresh PDO feedback. An absent signal is zero with false validity. |
following_error_valid | bool | Yes | True only when following_error is mapped and this cycle has fresh PDO feedback. An absent signal is zero with false validity. |
max_abs_velocity_actual_counts_per_s | uint32 | Yes | Maximum absolute valid drive velocity in counts/s since the last accepted Arm(true); zero before Arm. Retained through Stop/disarm; INT32_MIN has magnitude 2147483648. |
max_abs_following_error_counts | uint32 | Yes | Maximum absolute valid drive following error in counts since the last accepted Arm(true); zero before Arm. Retained through Stop/disarm; INT32_MIN has magnitude 2147483648. |
di_bits | uint32 | Yes | Current 0x60FD DI logic bits; interpret only when di_valid. |
di_valid | bool | Yes | True only for a fresh PDO and verified digital-input mapping. |
external_enable_active | bool | Yes | Drive servo-on (S-ON) input active; interpret only when external_enable_valid. Diagnostics only; does not prove STO or torque state. |
external_enable_valid | bool | Yes | True only with valid DI feedback and exactly one explicitly configured, verified S-ON digital-input function. |
torque_raw | int32 | Yes | Drive 0x6077 raw per-mille of rated torque; use only with fresh PDO feedback. |
collision_watchdog | CollisionWatchdogStatus | Yes | Native cycle evaluation and latched trip evidence for this axis. |
calibration_valid | bool | No | Persistent calibration applicability; null/absent means legacy unknown. |
position_state | string | No | Native state: unverified, recovering, trusted or lost; empty means legacy unknown. |
position_reason | string | No | Native CoordinateReason name; none means no coordinate refusal; absent means legacy unknown. |
audit_status | string | No | Last stationary audit: pending, verified or unavailable; never motion authority. |
audit_reason | string | No | Native SampleInvalidity name; none means no reported audit failure; absent means legacy unknown. |
audit_last_verified_ns | uint64 | No | Monotonic acquisition completion of last accepted independent evidence; zero means never. |
StatusGenerations#
| Name | Type | Required | Description |
|---|---|---|---|
time_ns | uint64 | Yes | — |
native | uint64 | Yes | — |
configuration_epoch | uint64 | Yes | — |
home_epoch | uint64 | Yes | — |
execution | uint64 | Yes | Adapter handle execution generation; correlated native Start acknowledgement. |
jog | uint64 | Yes | — |
grant | uint64 | Yes | — |
grant_time_ns | uint64 | Yes | Daemon fast-grant publication timestamp; zero if grant observation is unavailable. Independent of metrics time_ns. |
jog_time_ns | uint64 | Yes | Daemon jog publication timestamp; zero if jog observation is unavailable. Independent of metrics time_ns. |
AdapterStatus#
| Name | Type | Required | Description |
|---|---|---|---|
heap_inuse | uint64 | Yes | Go runtime bytes at request observation. |
sys | uint64 | Yes | Go runtime bytes at request observation. |
goroutines | uint32 | Yes | Go runtime goroutine count at request observation. |
open_preparation_slots | uint32 | Yes | Available adapter preparation admissions, from the two atomic reservations. |
CollisionWatchdogStatus#
| Name | Type | Required | Description |
|---|---|---|---|
armed | bool | Yes | True only while enabled, armed and receiving valid feedback; false after a trip. |
torque_cycles | uint32 | Yes | Consecutive torque breaches; equality resets. Frozen at trip. |
following_error_cycles | uint32 | Yes | Consecutive following-error breaches independent of torque. Frozen at trip. |
peak_torque_raw | uint32 | Yes | Peak absolute 0x6077 raw per-mille since arm; frozen at trip. |
peak_following_error_counts | uint64 | Yes | Peak absolute counts since arm; drive 0x60F4 when valid, otherwise prior wire target minus feedback with configured wrap handling. |
last_trip_quantity | string | Yes | none, torque, following_error or torque_and_following_error; retained across explicit reset. |
trip_sustained_cycles | uint32 | Yes | Configured consecutive count reached at last trip, 2..1000. |
trip_count | uint64 | Yes | Monotonic per-axis trip sequence for the daemon incarnation. |
samples | uint64 | Yes | Fresh normal armed/enabled cycles accumulated since arm, even if the watchdog is disabled; peaks include pre-motion hold. Frozen after trip or disarm. |
last_trip_peak_torque_raw | uint32 | Yes | Peak absolute torque at last trip, retained across reset and rearm. |
last_trip_peak_following_error_counts | uint64 | Yes | Peak absolute following error at last trip, retained across reset and rearm. |
IndependentAnchorSource#
| Name | Type | Required | Description |
|---|---|---|---|
valid | bool | Yes | Native acquisition validity; never motion permission. |
encoder_counts | int64 | Yes | Independent signed raw encoder count. |
completed_ns | uint64 | Yes | Host-monotonic acquisition completion timestamp in nanoseconds. |
maximum_age_ns | uint64 | Yes | Configured acquisition freshness bound in nanoseconds. |
Recovery#
RecoveryStatus#
| Name | Type | Required | Description |
|---|---|---|---|
home_valid_mask | uint32 | Yes | Native per-axis home evidence remaining after observed recovery. |
faults | FaultRecovery[] | Yes | Currently latched fault bits with axis masks and recovery policy. |
reset_sequence | uint64 | Yes | Exact native command sequence of the observed reset, zero before any reset; response sequence must match for reset_fault. |
reason | string | Yes | Native recovery summary: empty when no fault persists, otherwise fault_persists; FaultResetRecovery refuses a persistent fault. |
outcomes | FaultRecovery[] | Yes | Per-bit outcomes of the correlated reset; never inferred from elapsed time. |
FaultRecovery#
| Name | Type | Required | Description |
|---|---|---|---|
bit | uint32 | Yes | Native execution-fault bit index. |
name | string | Yes | Native fault name for that bit. |
axis_mask | uint32 | Yes | Affected axis evidence mask. |
recovery | string | Yes | Native recovery-policy label for the fault bit. |
outcome | string | Yes | Native per-bit outcome: persists, cleared or rehome_required. |
rehome_axis_mask | uint32 | Yes | Axes requiring qualified re-home after this outcome. |
Events#
Event#
| Name | Type | Required | Description |
|---|---|---|---|
sequence | uint64 | Yes | Strictly increasing within adapter_incarnation; drop records use last_lost_sequence; no renumbering. |
time_ns | uint64 | Yes | Native observation host time, except telemetry_mark uses adapter host monotonic time after native acceptance; never proof of motion or disk output. |
type | string | Yes | grant_acquired, grant_renewed, grant_released, grant_expired, grant_revoked, enable_changed, arm_changed, handle_transition, execution_started, execution_completed, execution_faulted, execution_aborted, jog_begin, jog_end, jog_expired, jog_ramping, jog_limited, fault_latched, fault_cleared, home_epoch_changed, daemon_incarnation_changed, adapter_incarnation_changed, publisher_overflow, events_dropped, telemetry_mark |
daemon_incarnation | string | Yes | — |
adapter_incarnation | string | Yes | — |
grant | GrantEvent | No | — |
handle | HandleTransitionEvent | No | — |
execution | ExecutionEvent | No | — |
jog | JogEvent | No | — |
fault | FaultEvent | No | — |
enable | EnableEvent | No | — |
epoch | EpochEvent | No | — |
incarnation | IncarnationEvent | No | — |
overflow | PublisherOverflowEvent | No | — |
events_dropped | EventsDropped | No | — |
mark | TelemetryMarkEvent | No | Present for telemetry_mark only, once per accepted mark command; rejected commands produce no mark event. |
EventBatch#
| Name | Type | Required | Description |
|---|---|---|---|
events | Event[] | Yes | At most 64 records, including at most one leading events_dropped record; 256 retained events. |
next_sequence | uint64 | Yes | Resume cursor after the last returned event; unchanged when empty. |
latest_sequence | uint64 | Yes | Newest retained sequence at batch capture. |
adapter_incarnation | string | Yes | — |
GrantEvent#
| Name | Type | Required | Description |
|---|---|---|---|
generation | uint64 | Yes | — |
stopping | bool | Yes | True for a local keepalive while Stop drains; does not confer native authority. |
HandleTransitionEvent#
| Name | Type | Required | Description |
|---|---|---|---|
handle | uint64 | Yes | — |
from | string | Yes | — |
to | string | Yes | — |
execution_generation | uint64 | Yes | — |
native_sequence | uint64 | Yes | — |
identity | Identity | No | Immutable raw trajectory identity supplied at Prepare and checked at Start; echoed unchanged through terminal observation. |
generation | uint64 | No | Application grant generation that owns this immutable preparation. |
ExecutionEvent#
| Name | Type | Required | Description |
|---|---|---|---|
handle | uint64 | Yes | — |
generation | uint64 | Yes | — |
native_sequence | uint64 | Yes | — |
fault_bits | uint32 | Yes | — |
recovery | FaultRecovery[] | Yes | — |
identity | Identity | No | Immutable raw trajectory identity supplied at Prepare and checked at Start; echoed unchanged through terminal observation. |
JogEvent#
| Name | Type | Required | Description |
|---|---|---|---|
generation | uint64 | Yes | — |
reason | uint32 | Yes | — |
axis_mask | uint32 | Yes | — |
velocity_scale_ppm | uint32 | Yes | — |
FaultEvent#
| Name | Type | Required | Description |
|---|---|---|---|
bit | uint32 | Yes | — |
axis_mask | uint32 | Yes | — |
recovery_class | string | Yes | — |
EnableEvent#
| Name | Type | Required | Description |
|---|---|---|---|
enabled_mask | uint32 | Yes | — |
armed | bool | Yes | — |
EpochEvent#
| Name | Type | Required | Description |
|---|---|---|---|
previous | uint64 | Yes | — |
current | uint64 | Yes | — |
IncarnationEvent#
| Name | Type | Required | Description |
|---|---|---|---|
previous | string | Yes | — |
current | string | Yes | — |
PublisherOverflowEvent#
| Name | Type | Required | Description |
|---|---|---|---|
previous_drops | uint64 | Yes | — |
total_drops | uint64 | Yes | — |
EventsDropped#
| Name | Type | Required | Description |
|---|---|---|---|
first_lost_sequence | uint64 | Yes | Inclusive first missing event. |
last_lost_sequence | uint64 | Yes | Inclusive last missing event; synthetic drop event sequence equals this cursor, so retained sequences are never renumbered. |
TelemetryMarkEvent#
| Name | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Accepted mark label, 1..128 UTF-8 bytes; receipt of queued dump work, not proof of disk output. |
native_sequence | uint64 | Yes | Accepted mark command sequence returned by POST /v1/control; distinct from event and telemetry sample cursors. |
generation | uint64 | Yes | Authorizing application grant generation; session capability is never published. |
Telemetry#
TelemetryBatch#
A binary transport type: it is never encoded as JSON. The fields below are the decoded header plus the record body.
| Name | Type | Required | Description |
|---|---|---|---|
daemon_incarnation | string | Yes | 32 lowercase hex bytes identifying the daemon owning these sequences; reconnect must reconcile changes. |
adapter_incarnation | string | Yes | 32 lowercase hex bytes identifying the adapter incarnation. |
machine_sha256 | string | Yes | 64 lowercase hex machine digest bytes. |
deployment_sha256 | string | Yes | 64 lowercase hex deployment digest bytes. |
cycle_period_ns | uint64 | Yes | Cycle period in ns. |
axis_count | uint32 | Yes | Active axes, 1 through 16. |
record_layout_digest | string | Yes | 64 ASCII hex bytes from the generated transitive CycleCaptureRecordV2 layout digest. |
first_sequence | uint64 | Yes | First included sequence; zero when empty. |
last_sequence | uint64 | Yes | Last included sequence or after+dropped when empty; resume cursor. |
dropped | uint64 | Yes | Exact number of records lost after the requested cursor and before this batch. |
record_count | uint32 | Yes | Number of complete records, at most min(ring capacity,4096). |
records | bytes | Yes | Opaque binary body; never encoded as JSON or base64. Each CycleCaptureAxisV2 appends velocity_actual_counts_per_s (i32), following_error_counts (i32), velocity_actual_valid (u32 0/1), following_error_valid (u32 0/1). Drive position-frame counts/s and counts; following error also feeds the configured collision watchdog. No speed-safety certification. |
Cell I/O#
IoState#
| Name | Type | Required | Description |
|---|---|---|---|
time_ns | uint64 | Yes | — |
cycle | uint64 | Yes | — |
armed | bool | Yes | — |
reason | uint32 | Yes | — |
inputs | IoInput[] | Yes | — |
outputs | IoOutput[] | Yes | — |
IoInput#
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | — |
value | bool | Yes | — |
valid | bool | Yes | — |
observed_ns | uint64 | Yes | — |
bit | uint32 | Yes | — |
fast | bool | Yes | — |
IoOutput#
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | — |
intent | bool | Yes | — |
commanded | bool | Yes | — |
readback | bool | Yes | — |
valid | bool | Yes | — |
expiry_ns | uint64 | Yes | — |
observed_ns | uint64 | Yes | — |
changed_ns | uint64 | Yes | — |
marker_sample_ns | uint64 | Yes | — |
marker_cycle | uint64 | Yes | — |
bit | uint32 | Yes | — |
torch | bool | Yes | — |
Related pages#
- Control authority: leases, fences and the jog lane.
- Events and telemetry: SSE events, cursors and the binary telemetry layout.
- Remote access (mTLS): the remote listener, PKI and WSS jog.
- Go SDK, C++ client and TypeScript contracts.
- Error codes and fault states.