Architecture
On this page
A RosieOS cell is a small set of processes around one controller. The real-time core, rosie-rt-core, owns the drives. The Go adapter rt-control is the only public way to command it. Every client, whether the offline programming app, a pendant, a motion server or your own code, goes through rt-control and needs its lease to move anything.
Processes#
| Process | Runs on | Role | Listens on |
|---|---|---|---|
rosie-rt-core | Cell host | 1 kHz cyclic controller: EtherCAT master, CiA402 drive state, the motion start gate and the final output permit | Private native socket, /run/rosie-rt-core/native/ipc.sock when installed |
rosie-rt-core-sim | Any Linux host | The same state machine over a simulated bus | Private native socket |
rt-control | Cell host | The public control API: lease and fence, jog lane, trajectories and programs, events, telemetry | control.sock and jog.sock (Unix), plus an optional mutual-TLS listener |
rt-natspublisher | Cell host | Republishes status and telemetry to NATS. It has no command authority. | None (reads control.sock) |
robot-v4-cartesiand | Cell host, and inside OLP | Cartesian motion server: Cartesian jog and position moves on the rt-core jog lane. OLP also runs it in --resolve-only mode to turn Cartesian twists into joint velocities. | UDP intent listener (--udp-listen) |
joint_trajectory_daemon | Cell host | Stores dense .rdt programs and plays them through rt-control | TCP 127.0.0.1:8797 |
| OLP server | Operator PC, or headless on the Deck | Offline programming backend: programs, planning broker, local simulator, machine session | HTTP 127.0.0.1:8794 |
| OLP UI | Browser | The programming and operating app | Vite on :5189 |
| Weld planner | Operator PC with an NVIDIA GPU | Turns a .weldplan into verified joint trajectories and dense .rdt files | HTTP :8796 |
| Pendant v5 | Steam Deck | Native Qt teach pendant. It runs OLP's TypeScript program logic and talks only to a headless OLP server on the Deck. | None |
| Pendant v4 | Steam Deck | Earlier native pendant, kept as a rollback. It talks to rt-control directly. | None |
| Virtual pendant | Operator PC | Browser skin of the v4 pendant plus a loopback bridge, for simulation only | UI :51711, bridge 127.0.0.1:51712 |
Ports, socket paths and environment variables are all listed in Ports, sockets and environment.
Public and private interfaces#
- Public:
rt-control. This is HTTP/JSON over the Unix socketcontrol.sock, with jog datagrams onjog.sockin the same directory. With--remote-listenit also serves the same API over mutual TLS on TCP, plus a WebSocket jog lane. Deployed cells pin that listener to127.0.0.1:8443. The contract isrt-core/protocol/application-v1.schema.json, and the Go, C++ and TypeScript clients are generated from it. See rt-control HTTP API. - Private: native IPC.
rt-controltalks to the core over a Unix socket plus shared-memory rings and a fast-control region. The layout is specified inrt-core/protocol/control.jsonand can change between releases. Never program against it. - Service APIs. The OLP server, the weld planner and the dense daemon each have their own interface. They are clients of
rt-control, not alternatives to it.
When installed with the host units, rosie-rt-core runs as user rosie-rt and rt-control as rosie-ctl. The public sockets live in /run/rosie-rt-core/public/, with symlinks at /run/rosie-rt-core/control.sock and /run/rosie-rt-core/jog.sock.
How motion reaches the drives#
There are three ways to move the robot. Each ends at the same motion start gate in the core. See the safety model.
Jog#
A jog is a stream of velocity updates, each with its own deadline. The client opens a jog generation with begin_jog, then sends 224-byte datagrams on jog.sock, or WebSocket frames on a remote cell. When the updates stop, the core ramps the axis to a hold.
| Client | Path |
|---|---|
| OLP joint jog | OLP server → Go SDK jog session → jog.sock |
| OLP Cartesian jog | OLP server → robot-v4-cartesiand --resolve-only (twist to joint velocities) → the same jog session |
| Cartesian motion server | UDP intent packet → robot-v4-cartesiand → C++ client jog producer → jog.sock |
| Pendant v4 | mutual TLS → WebSocket jog on /v1/jog |
| Virtual pendant (simulation) | Browser → bridge on :51712 → Go SDK jog session → jog.sock |
Point-list moves#
A client can upload a short list of timed points with prepare_trajectory. Positions are in rad or m and times in ns from the plan start. The client then starts it with start_trajectory. OLP uses this for its joint and Cartesian moves. rtctl prepare and rtctl start send the same operations from a file.
Dense weld programs#
A planned weld program travels as an immutable dense trajectory, a .rdt file.
- The OLP server sends a
.weldplanto the weld planner. - The planner plans each seam and each connecting move, runs the verifier, and writes a
.rdtonly if every segment passes. - OLP's Load fetches the
.rdtby digest from the planner and checks it against the robot and the cell. It then uploads it tort-controlwithPOST /v1/program(prepare_program). - Play sends
start_program. rt-core interpolates the samples in the cycle.
The dense daemon offers the same upload-then-play path for other clients: TCP ingest on :8797, with play and stop over NATS under a leader lease. Programs that arrive through it are not re-verified.
See Motion paths and planning and Weld planning and verification.
Identity ties it together#
Several digests keep every process agreeing on which robot it is talking to:
- The robot description (
robot_description/robots/<model>/) has a SHA-256 identity over the files its manifest registers. - A machine config pins that description, and
rtctl compileturns it into an immutableconfiguration_sha256. rt-controlis started with that digest and a pair binding (pair id and revision). Everyacquiremust present the same binding.- The planner stamps the robot and cell identity into each
.rdtheader. OLP refuses to load a plan made against a different robot or cell.
See Cells, machines and positioners and Robot description and coordinate frames.
Observation#
Anyone with access to the socket can read state without taking control:
GET /v1/describe,GET /v1/status- events from
/v1/events, or as Server-Sent Events from/v1/events/stream - binary telemetry batches from
/v1/telemetry
On a remote listener, a client certificate is still required. rt-natspublisher republishes status and telemetry to NATS subjects robot/v4/rtcore.<host>.status and robot/v4/rtcore.<host>.telemetry.batch, for displays and archiving. Those subjects carry no command authority.
Maturity#
| Status | Components |
|---|---|
| Production source | rt-core (core, rt-control, SDKs, rtctl), both motion servers, OLP dense execution and the local simulator, the weld planner, robot descriptions |
| Current, not qualified | Pendant v5 (not qualified on physical input or real motion). reset_fault is interim. |
| Simulation only | Virtual pendant |
| Experimental | mujoco-sim/v1, an independent MuJoCo model. It is not a controller stand-in. |
| Legacy, off by default | OLP connected execution over NATS (--enable-connected-execution), and older versioned trees |