-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtrajectory_execution.py
63 lines (48 loc) · 2.83 KB
/
trajectory_execution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import numpy as np
from airo_robots.manipulators.bimanual_position_manipulator import DualArmPositionManipulator
from pydrake.trajectories import Trajectory
def ensure_dual_arm_at_joint_configuration(dual_arm, joints_left, joints_right, tolerance=0.1) -> None:
"""Sanity check that the arm are were you expect them to be,
e.g. close to that start of a path you are about to execute.
Raises ValueError if the arms are not at the expected joints.
"""
current_joints_left = dual_arm.left_manipulator.get_joint_configuration()
current_joints_right = dual_arm.right_manipulator.get_joint_configuration()
left_distance = np.linalg.norm(current_joints_left - joints_left)
right_distance = np.linalg.norm(current_joints_right - joints_right)
if left_distance > tolerance:
raise ValueError(
f"Left arm is at {current_joints_left} but should be at {joints_left}, distance: {left_distance}"
)
if right_distance > tolerance:
raise ValueError(
f"Right arm is at {current_joints_right} but should be at {joints_right}, distance: {right_distance}"
)
def execute_dual_arm_drake_trajectory(dual_arm: DualArmPositionManipulator, joint_trajectory: Trajectory):
# TODO don't receive joint and time trajectory separately, but as a single PathParametrizedTrajectory
# TODO create and use discretize_dual_arm_trajectory
assert joint_trajectory.start_time() == 0.0
start_joints = joint_trajectory.value(0).squeeze()
start_joints_left = start_joints[0:6]
start_joints_right = start_joints[6:12]
ensure_dual_arm_at_joint_configuration(dual_arm, start_joints_left, start_joints_right)
period = 0.005
duration = joint_trajectory.end_time()
n_servos = int(np.ceil(duration / period))
period_adjusted = duration / n_servos # can be slightly different from period due to rounding
for t in np.linspace(0, duration, n_servos):
joints = joint_trajectory.value(t).squeeze()
joints_left = joints[0:6]
joints_right = joints[6:12]
left_servo = dual_arm.left_manipulator.servo_to_joint_configuration(joints_left, period_adjusted)
right_servo = dual_arm.right_manipulator.servo_to_joint_configuration(joints_right, period_adjusted)
left_servo.wait()
right_servo.wait()
# This avoids the abrupt stop and "thunk" sounds at the end of paths that end with non-zero velocity
# However, I believe these functions are blocking, so right only stops after left has stopped.
dual_arm.left_manipulator.rtde_control.servoStop(2.0)
dual_arm.right_manipulator.rtde_control.servoStop(2.0)
left_finished = dual_arm.left_manipulator.move_to_joint_configuration(joints_left)
right_finished = dual_arm.right_manipulator.move_to_joint_configuration(joints_right)
left_finished.wait()
right_finished.wait()