MAKIINASDK

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

Python
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 metres

Positions, 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:

Python
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:

Python
robot.sensors.get_joints_timed()    # {"J01-R": (0.0012, 4817.206), ...}
robot.state_timestamp               # 4817.221, the newest state message

Each 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):

Python
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:

Python
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:

Python
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

Python
robot.ping_ms           # round trip in ms
robot.status            # link state and network path