Skip to content

Manipulator States

Every Synapse manipulator owns a single state object for its lifetime. The state is the canonical source of truth for joint positions, TCP pose, velocities, torques, and forces - and it behaves identically across every supported brand.

INFO

On connecting to real hardware, the state is overridden by live controller values.

connect() switches into live mode, disconnect() returns to commanded-cache mode while keeping the last live values in the cache.

Unit

All angles are in degrees, distances in meters. TCP pose uses Synapse convention [x, y, z, rx, ry, rz] with Euler XYZ orientation in degrees.

State Reference

Each property below maps to a dedicated getter skill. The same property is read in both offline and live modes. When connected to hardware, all states are updated from the controller.

Live state - "what is the robot doing right now?"

PropertyTypeGetter
is_connectedboolIs Connected
joint_positionsnp.ndarray(ndof,)Get Joint Positions
joint_velocitiesnp.ndarray(ndof,)Get Joint Velocities
joint_torquesnp.ndarray(ndof,)Get Joint Torques
tcp_posenp.ndarray(6,)Get Cartesian Pose
tcp_speednp.ndarray(6,)Get TCP Speed
tcp_forcenp.ndarray(6,)Get TCP Force

Target state - "what is the controller commanding right now?"

For offline mode, they return the last values set by the set_* skills. For live mode, they reflect the controller's current target - the next waypoint it's trying to reach, the speed it's trying to achieve, etc.

PropertyTypeGetter
target_joint_positionsnp.ndarray(ndof,)Get Target Joint Positions
target_joint_velocitiesnp.ndarray(ndof,)Get Target Joint Velocities
target_joint_accelerationsnp.ndarray(ndof,)Get Target Joint Accelerations
target_tcp_posenp.ndarray(6,)Get Target TCP Pose
target_tcp_speednp.ndarray(6,)Get Target TCP Speed

Timestamp

PropertyTypeGetter
timestampfloatGet Timestamp

OFFLINE ZEROS

Velocity, torque, force, and target-velocity/-acceleration channels return correctly-shaped zero arrays when the robot is not connected - there is no synthesised value. If you depend on these signals (force mode, contact detection, control-loop dampers, etc.), the manipulator must be connected to real hardware.

Offline Mode (Not Connected)

When a manipulator is created but not connected to hardware, its state is seeded with default joint configurations and the corresponding TCP pose via FK.

When the manipulator is not connected to hardware, the states are purely a cache of the last values set by the set_* skills. For example:

  • set_joint_positions(q) updates the cached joint positions and refreshes tcp_pose via FK.
  • set_cartesian_pose(pose) solves IK for q, then updates both the joint and TCP caches.
  • Velocity / torque / force properties return zeros as described in the table above.

This is what makes offline kinematics workflows work end-to-end: you can call get_cartesian_pose(), get_link_transforms(), forward_kinematics(...), etc. without ever connecting to a controller.

Live Mode (Connected)

robot.connect(ip=...) attaches a brand-specific hardware adapter to the state. The adapter wraps the controller's native telemetry (RTDE on Universal Robots, FCI on Franka, etc.) and converts every read into Synapse conventions before returning. After connect():

  • All state reads forward to the adapter and return live controller values.
  • set_* skills issue motion commands to the controller; the cache is still written but the adapter is the source of truth.
  • Velocities, torques, forces, and targets become observable (no longer zero-filled).

robot.disconnect() runs the inverse: it captures the most recent live values into the commanded cache, then clears the adapter so subsequent reads continue to report where the robot just was rather than snapping back to the startup defaults.

Notes

  • Active development. ManipulatorState is under active development - property names, defaults, and the offline-vs-live semantics may change between releases.
  • Defaults are deliberate. Pick a default joint configuration far from singularities and joint limits - both the offline TCP pose and the implicit IK seed derive from it.
  • disconnect() does not reset. State reads after a disconnect continue to report the last live values, not the startup defaults. This keeps offline analysis right after a teardown meaningful.
  • Velocities and forces are zero offline. If you depend on these signals, the manipulator must be connected.
  • One state per manipulator. Two robot = UniversalRobotsUR10E() instances are independent and own separate state objects.