GuidesRead sensors
Read joints, currents and poses
Read the measured state of every joint, know when each value was measured, and record a few seconds of it to a plot.
Everything the robot measures is in robot.sensors, and reading it never waits on the hardware. This guide shows what you can read, how fresh it is, and how to record and plot it.
Read the state
robot.sensors.get_joints() # {"J01-R": 0.0, ...} positions, rad
robot.sensors.get_velocities() # rad/s
robot.sensors.get_currents() # q-axis current per joint, A
robot.sensors.get_grippers() # gripper finger joints
robot.sensors.get_head() # head yaw, rad (robots with a head)
robot.sensors.get_ee_poses() # gripper poses, 4x4 in metresPositions, velocities and currents of one joint come from the same state frame, so they belong to the same instant. get_joints() is where the joints are; robot.control.get_commanded_joints() is where you told them to go.
To get the joints under their part names instead of the wire names:
robot.sensors.get_joints(by="part") # {"right_J1": 0.0, ..., "left_J6": 0.0}Know how fresh a value is
Nobody polls the drives. Each drive sends its own state on the CAN bus at a fixed rate, 60 Hz by default, and the robot server keeps the newest frame of every joint. A read returns that newest frame straight away, which is why reading is instant and never slows the bus down.
When timing matters, ask for the measurement times too:
robot.sensors.get_joints_timed() # {"J01-R": (0.0012, 4817.206), ...}
robot.state_timestamp # 4817.221, the newest state messageEach value comes with the time it was measured, on the robot's clock, which is the same clock as robot.state_timestamp. Joints are measured at slightly different moments, and a value can be a few frames older than the message that carried it. When you plot or interpolate, use these times rather than the moment your script read the value.
Record a few seconds and plot them
Move the arm by hand while this runs (turn the torque off first, and hold the arm):
import time
import numpy as np
import matplotlib.pyplot as plt
t, q, i = [], [], []
t0 = time.time()
while time.time() - t0 < 5.0:
t.append(time.time() - t0)
q.append(list(robot.sensors.get_joints().values()))
i.append(list(robot.sensors.get_currents().values()))
time.sleep(0.02)
names = robot.model.joint_names()
fig, ax = plt.subplots(2, 1, sharex=True, figsize=(9, 6))
ax[0].plot(t, np.array(q)); ax[0].set_ylabel("position [rad]")
ax[1].plot(t, np.array(i)); ax[1].set_ylabel("current [A]")
ax[1].set_xlabel("time [s]"); ax[0].legend(names, ncol=6, fontsize=8)
plt.show()Sampling at 50 Hz is enough for a plot. For every frame at the drive's own rate, use a single actuator's broadcast stream (Drive a single actuator).
Read what the drives are set to
The measured state tells you what the joints do. To see the settings the drives run with, read them back from the boards:
params = robot.control.get_actuator_parameters()
params["J02-R"]["kp_angle"], params["J02-R"]["max_current"], params["J02-R"]["firmware"]Tune the joints live explains the settings.
Watch the robot's own log
The robot server prints what it is doing: boot progress, CAN errors, camera errors. Stream that log into your session:
robot.control.set_console_stream(True)
for line in robot.console_tail():
print(line)It is on by default while the robot boots and off afterwards, to keep the state messages small.
Session health
robot.ping_ms # round trip in ms
robot.status # link state and network path