Advanced Metal Research
GitHub Contact AMR

Motion paths and planning

On this page
  1. The three kinds of motion request
  2. The four motion owners
  3. Offline programming
  4. Cartesian motion server
  5. Dense trajectory daemon
  6. Your own client
  7. What is checked, and where
  8. Starting from rest
  9. Stopping
  10. Related pages

Every motion in RosieOS reaches the drives the same way: a client holds the rt-control lease, sends one of three kinds of motion request, and the 1 kHz core decides at its motion start gate whether the motion may begin. What differs between the paths is who the client is, how it gets its authority, and how much checking happens before the request reaches rt-control.

Warning

Energised motion. This moves the robot. RosieOS has no software E-stop: keep the hardware E-stop within reach and clear the cell before you arm. Jog, moves and Home are checked against joint limits only, not against collisions. See the safety model.

SOURCE MOTION OWNER PUBLIC API CORE, 1 kHz OLP UI or pendant v5 HTTP to :8794 OLP server dense-execution API programs need a verifier PASS UDP intent source plus NATS commands Cartesian motion server robot-v4-cartesiand NATS leader lease .rdt producer TCP :8797, NATS play Dense trajectory daemon joint_trajectory_daemon NATS leader lease Your code Go or C++ client rt-control one lease, one fence jog lane trajectory program rosie-rt-core motion start gate and output permit all three jog, trajectory program direct, any operation Every path acquires the same rt-control lease, so only one of them can command the robot at a time.
Four motion owners, one public API, one start gate. The red edge is the core's motion start gate, which every motion passes.

The three kinds of motion request#

rt-control accepts motion in three forms. Each one ends at the same motion start gate.

LaneOperationsWhat the client sendsUsed by
Jogbegin_jog, datagrams on jog.sock (or WebSocket frames on a remote cell), end_jogPer-axis velocities in rad/s or m/s, each update with its own deadlineOLP joint and Cartesian jog, the Cartesian motion server
Trajectoryprepare_trajectory, start_trajectoryA short list of timed points: time_ns, positions in rad or mOLP joint and Cartesian moves, the Cartesian motion server's position moves
Programprepare_program (POST /v1/program), start_programAn immutable dense trajectory in the .rdt formatOLP Load and Play, the dense trajectory daemon

Home is a fourth, separate operation (home). It runs the drive's native homing on the named axes.

The operations themselves are documented in the rt-control HTTP API. Their lease and fence rules are in Control authority.

The four motion owners#

PathOwner processHow a client reaches itExtra authority layerrt-control lanes
Offline programmingOLP serverHTTP on 127.0.0.1:8794Selected-target generation headersJog, trajectory, program, Home
Cartesian motion serverrobot-v4-cartesiandUDP intent packets and NATS commandsNATS leader leaseJog, trajectory, Home
Dense trajectory daemonjoint_trajectory_daemonTCP on 127.0.0.1:8797 for bytes, NATS for playNATS leader leaseProgram, Home
Your own clientYour processThe Go or C++ clientNone beyond the rt-control leaseAny

The owners share one rt-control. Whichever holds the lease is the only one that can move the robot; the others are refused with control_already_owned until it releases. See One controller at a time.

Offline programming#

The OLP server is the operator path, and the only one with plan-time verification. It holds the rt-control lease on behalf of a browser or the v5 pendant and exposes the machine-control routes under /api/offline-programming/v1/dense-execution/.

  • Programs. Load fetches a .rdt by digest from the weld planner. The planner writes one only when every seam and connecting move passes its verifier, so a program that failed verification has nothing to load. Load then checks the plan's identity and robot, requires Home on every configured axis, acquires the lease and calls prepare_program. Play calls start_program. See What is verified before motion.
  • Joint jog. One axis at a time, at a fraction of that axis's described maximum velocity. The browser sends a hold every 50 ms. Each hold lives for the cell's jog input age (250 ms on a LAN cell), then the axis ramps to a hold.
  • Cartesian jog. A base- or tool-frame twist. OLP asks robot-v4-cartesiand --resolve-only for joint velocities from the measured pose, scales them to the joint ceilings, and sends them on the same jog lane.
  • Joint and Cartesian moves. A bounded displacement, planned by OLP as a per-joint trapezoid (joint moves) or as IK waypoints at 1 mm or 0.25° spacing (Cartesian moves), then sent with prepare_trajectory and start_trajectory.
  • Home. Native Home on all configured axes or on a subset.

Joint jog, moves and Cartesian jog all plan at 75% of each axis's described maximum velocity, times the operator's speed fraction. The 75% is a measured reserve for drive overshoot.

A mutating request must carry the selected target's generation and cell ID in X-RT-Target-Generation and X-RT-Target-Cell, so a request that a browser issued against one cell cannot land on another. OLP also requires a browser heartbeat: if none arrives for 5 s while OLP holds the lease, it stops the machine with ui_heartbeat_lost.

See the Offline programming HTTP API and the guide Connect to a cell and run a program.

Cartesian motion server#

robot-v4-cartesiand turns a stream of UDP intent packets into Cartesian jog. Each packet carries six normalised axis values in [-1, 1] and a speed scale. The server maps them to at most 0.2 m/s linear and π rad/s angular, slews them at 0.75 m/s² and 540°/s², resolves joint velocities through a damped Jacobian with joint-limit and singularity scaling, and streams them on the rt-control jog lane. Each output's deadline is at most 250 ms after the packet arrived.

Its authority has two layers. It holds the rt-control lease itself, and it grants its own NATS leader lease to one controller at a time. Every motion packet and NATS command must carry the current leader lease ID and fence epoch. Releasing the deadman, a neutral packet, a stale packet or a fence mismatch halts the jog. Joint jog, go-home without an admitted run, and weld I/O are refused on the rt_core backend.

See the Cartesian motion server.

Dense trajectory daemon#

joint_trajectory_daemon is a store-and-play path for .rdt programs that come from somewhere other than OLP. The data plane is TCP: upload stores and validates a blob and never moves anything. The control plane is NATS: a controller acquires the daemon's leader lease, then sends play with the exact six-field plan identity.

On leader_acquire the daemon takes the rt-control lease. On preload it calls prepare_program. On play it runs native Home on any axis whose Home is not valid (or restores the saved anchor, if configured), enables and arms the axes, waits for readiness, and calls start_program.

Note

Programs played through the dense daemon are checked against the .rdt format rules and rt-core's native limits only. The daemon does not ask the weld planner or check the plan's robot and cell identity. Treat it as a direct path.

See the Dense trajectory daemon.

Your own client#

Your code can call rt-control directly through the Go SDK or the C++ client. Use one of these for anything that moves. The SDKs renew the lease in the background.

rtctl cannot drive motion in practice. It never renews the 500 ms lease, so the lease expires between commands and outputs are inhibited. Use rtctl for inspection and one-off setup, not motion. Your first motion walks through a complete SDK program against the simulator.

What is checked, and where#

CheckWeld program through OLPProgram through the dense daemonJogOLP movesHome
Weld planner verifier: collisions, penetration, limits, trackingYesNoNoNoNo
Plan identity and robot/cell identityYes, at LoadPlan identity only, at preload and playn/an/an/a
Planned at 75% of described velocityPlanner's own limitsProducer's own limitsYes (OLP); 0.2 m/s and π rad/s caps (motion server)Yesn/a
.rdt format validationYesYesn/an/an/a
rt-core native admission: position limits, velocity, continuityYesYesPer updateYesn/a
Motion start gate and per-cycle output permitYesYesYesYesYes

rt-core checks joint limits and rates. It does not check collisions with the cell, the positioner or the part. Only the weld planner's verifier does that, and only for planned weld programs.

Starting from rest#

A trajectory or program must continue from the held position. If the robot is at rest and the first point is within the axis's completion tolerance of the held position, the core inserts a short, bounded alignment ramp to the first point. Any larger gap is refused. So the first point of a motion may be slightly offset from the reported position, but never by more than that tolerance.

Inside a dense program, segments hand over in place: each segment starts and ends at rest, and the next one starts where the last one ended. The core never interpolates across a segment boundary. See Segments.

Stopping#

Every path ends in the same software stops: Stop, Halt, Release and lease expiry. Release runs Stop and then gives up the session. The owners add their own triggers:

PathAlso stops on
OLPBrowser heartbeat lost for 5 s, lease renewal lost, a refused or failed operation (OLP runs Stop and Release before it reports the refusal; a slow or unsent request is the exception), a new target selection
Cartesian motion serverDeadman released, neutral or invalid packet, leader lease lost or changed, NATS stop or disarm
Dense daemonNATS stop (always accepted, never fenced), leader lease released or replaced, any native refusal

None of these is an emergency stop. See Software stops.