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?"
| Property | Type | Getter |
|---|---|---|
is_connected | bool | Is Connected |
joint_positions | np.ndarray(ndof,) | Get Joint Positions |
joint_velocities | np.ndarray(ndof,) | Get Joint Velocities |
joint_torques | np.ndarray(ndof,) | Get Joint Torques |
tcp_pose | np.ndarray(6,) | Get Cartesian Pose |
tcp_speed | np.ndarray(6,) | Get TCP Speed |
tcp_force | np.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.
| Property | Type | Getter |
|---|---|---|
target_joint_positions | np.ndarray(ndof,) | Get Target Joint Positions |
target_joint_velocities | np.ndarray(ndof,) | Get Target Joint Velocities |
target_joint_accelerations | np.ndarray(ndof,) | Get Target Joint Accelerations |
target_tcp_pose | np.ndarray(6,) | Get Target TCP Pose |
target_tcp_speed | np.ndarray(6,) | Get Target TCP Speed |
Timestamp
| Property | Type | Getter |
|---|---|---|
timestamp | float | Get 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 refreshestcp_posevia FK.set_cartesian_pose(pose)solves IK forq, 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.
ManipulatorStateis 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.

