Python API (Dynamic Graph Head)#
Once we have started the dynamic graph mananger (DGM), we can access the shared memory and write our controll in Python.
The main control loop evolves over reading the sensor data from the shared memory and writing control commands to the shared memory. From FrankaDynamicGraphHead we can perform these two operations by calling read_states and write_command. If we take a look at the content of read_states
def read_states(self):
# Get the sensor values from the shared memory
self.head.read()
T = self.head.get_sensor("joint_torques").copy()
q = self.head.get_sensor("joint_positions").copy()
dq = self.head.get_sensor("joint_velocities").copy()
return [q, dq, T]
we can see that it is reading the joint torques, positions, and velocities from the shared memory. Then, for write_command, in the kinematic interface (velocity control), we have
def write_command(self, cmd):
# Write the sensor values to the shared memory
assert max(cmd.shape) == 7, "The control command should be a vector of 7 numbers!"
self.head.set_control("ctrl_joint_velocities", cmd.reshape(7,1))
self.head.set_control("ctrl_stamp", np.array(self.trigger_timestamp).reshape(1,1)/1000000)
self.head.write()
self.cmd_log = cmd
it is writing the commanded joint velocities and the timestamp of the last trigger signal to the shared memory. This control command will be read by the robot, which is on the other side of the DGM architecture.
The for loop that controls the robot would then look like
for i in range(100000):
# control at 100 Hz
time.sleep(0.01)
# read states
state = franka_dgh.read_states()
q, dq, T = state
# user defined controller
vel = controller(time.time(), q, dq)
# send control command
franka_dgh.cmd = vel
franka_dgh.write_command(vel)