demo_tsid_talos_gripper_closed_kinematic_chain.py
Go to the documentation of this file.
1 """Simple demo of usage of ContactTwoFramePositions in TSID
2 Make the Talos gripper model works with closed kinematic chains
3 (c) MIPT
4 """
5 
6 import time
7 from pathlib import Path
8 
9 import numpy as np
10 import pinocchio as pin
11 import tsid
12 from numpy.linalg import norm as norm
13 
14 np.set_printoptions(precision=3, linewidth=200, suppress=True)
15 
16 LINE_WIDTH = 60
17 print("".center(LINE_WIDTH, "#"))
18 print(
19  " Demo of TSID with Closed Kinematic Chains via ContactTwoFramePositions".center(
20  LINE_WIDTH, "#"
21  )
22 )
23 print("".center(LINE_WIDTH, "#"), "\n")
24 
25 w_ee = 1.0 # weight of end effector task
26 w_posture = 1e-3 # weight of joint posture task
27 
28 kp_ee = 10.0 # proportional gain of end effector task
29 kp_posture = 10.0 # proportional gain of joint posture task
30 
31 dt = 0.001 # controller time step
32 PRINT_N = 500 # print every PRINT_N time steps
33 DISPLAY_N = 25 # update robot configuration in viwewer every DISPLAY_N time steps
34 N_SIMULATION = 6000 # number of time steps simulated
35 
36 # Loading Talos gripper model modified with extra links to mark the position of contact creation
37 # Talos gripepr model (c) 2016, PAL Robotics, S.L.
38 # Please use https://github.com/egordv/tsid_demo_closed_kinematic_chain repo for the model files
39 
40 filename = str(Path(__file__).resolve().parent)
41 path = filename + "../../tsid_demo_closed_kinematic_chain/models/talos_gripper"
42 urdf = path + "../../tsid_demo_closed_kinematic_chain/urdf/talos_gripper_half.urdf"
43 vector = pin.StdVec_StdString()
44 vector.extend(item for item in path)
45 
46 robot = tsid.RobotWrapper(urdf, vector, False) # Load with fixed base
47 
48 # for viewer
49 robot_display = pin.RobotWrapper.BuildFromURDF(urdf, [path])
50 robot_display.initViewer(loadModel=True)
51 
52 model = robot.model()
53 q = np.zeros(robot.nq)
54 v = np.zeros(robot.nv)
55 
56 viz = pin.visualize.MeshcatVisualizer(
57  robot_display.model,
58  robot_display.collision_model,
59  robot_display.visual_model,
60 )
61 viz.initViewer(loadModel=True, open=True)
62 
63 t = 0.0 # time
64 invdyn = tsid.InverseDynamicsFormulationAccForce("tsid", robot, False)
65 invdyn.computeProblemData(t, q, v)
66 data = invdyn.data()
67 
68 
69 fingertip_name = "gripper_left_fingertip_3_link"
70 H_fingertip_ref = robot.framePosition(invdyn.data(), model.getFrameId(fingertip_name))
71 
72 fingertipPositionTask = tsid.TaskSE3Equality(
73  "task-fingertip-position", robot, fingertip_name
74 )
75 fingertipPositionTask.useLocalFrame(False)
76 fingertipPositionTask.setKp(kp_ee * np.ones(6))
77 fingertipPositionTask.setKd(2.0 * np.sqrt(kp_ee) * np.ones(6))
78 trajFingertipPosition = tsid.TrajectorySE3Constant(
79  "traj-fingertip-position", H_fingertip_ref
80 )
81 sampleFingertipPosition = trajFingertipPosition.computeNext()
82 fingertipPositionTask.setReference(sampleFingertipPosition)
83 invdyn.addMotionTask(fingertipPositionTask, w_ee, 1, 0.0)
84 
85 postureTask = tsid.TaskJointPosture("task-posture", robot)
86 postureTask.setKp(kp_posture * np.ones(robot.nv))
87 postureTask.setKd(2.0 * np.sqrt(kp_posture) * np.ones(robot.nv))
88 invdyn.addMotionTask(postureTask, w_posture, 1, 0.0)
89 
90 
91 # Creating a closed kinematic chain in TSID formulation by creating a contact between two frames, for which there are special links in URDF
92 ContactTwoFramePositionsFingertipBottomAxis = tsid.ContactTwoFramePositions(
93  "contact-two-frame-positions-fingertip-bottom-axis",
94  robot,
95  "gripper_left_motor_single_link_ckc_axis",
96  "gripper_left_fingertip_3_link_ckc_axis",
97  -1000,
98  1000,
99 )
100 twoFramesContact_Kp = 300
101 ContactTwoFramePositionsFingertipBottomAxis.setKp(twoFramesContact_Kp * np.ones(3))
102 ContactTwoFramePositionsFingertipBottomAxis.setKd(
103  2.0 * np.sqrt(twoFramesContact_Kp) * np.ones(3)
104 )
105 
106 twoFramesContact_w_forceRef = 1e-5
107 invdyn.addRigidContact(
108  ContactTwoFramePositionsFingertipBottomAxis, twoFramesContact_w_forceRef, 1.0, 1
109 )
110 
111 # Setting actuation to zero for passive joints in kinematic chain via TaskActuationBounds
112 tau_max = model.effortLimit[-robot.na :]
113 # setting gripper_left_inner_single_joint to passive contstrainig it's actuation bounds to zero
114 tau_max[0] = 0.0
115 # setting gripper_left_fingertip_3_joint to passive contstrainig it's actuation bounds to zero
116 tau_max[1] = 0.0
117 tau_min = -tau_max
118 actuationBoundsTask = tsid.TaskActuationBounds("task-actuation-bounds", robot)
119 actuationBoundsTask.setBounds(tau_min, tau_max)
120 invdyn.addActuationTask(actuationBoundsTask, 1.0, 0, 0.0)
121 
122 q_ref = q
123 trajPosture = tsid.TrajectoryEuclidianConstant("traj_joint", q_ref)
124 
125 print(
126  "Create QP solver with ",
127  invdyn.nVar,
128  " variables, ",
129  invdyn.nEq,
130  " equality and ",
131  invdyn.nIn,
132  " inequality constraints",
133 )
134 solver = tsid.SolverHQuadProgFast("qp solver")
135 solver.resize(invdyn.nVar, invdyn.nEq, invdyn.nIn)
136 
137 offset = sampleFingertipPosition.pos()
138 offset[:3] += np.array([0, -0.04, 0])
139 amp = np.array([0.0, 0.04, 0.0])
140 two_pi_f = 2 * np.pi * np.array([0.0, 0.5, 0.0])
141 two_pi_f_amp = np.multiply(two_pi_f, amp)
142 two_pi_f_squared_amp = np.multiply(two_pi_f, two_pi_f_amp)
143 
144 pEE = offset.copy()
145 vEE = np.zeros(6)
146 aEE = np.zeros(6)
147 
148 i = 0
149 while True:
150  time_start = time.time()
151 
152  # Setting gripper finger task target to sine motion
153  pEE[:3] = offset[:3] + amp * np.sin(two_pi_f * t)
154  vEE[:3] = two_pi_f_amp * np.cos(two_pi_f * t)
155  aEE[:3] = -two_pi_f_squared_amp * np.sin(two_pi_f * t)
156  sampleFingertipPosition.value(pEE)
157  sampleFingertipPosition.derivative(vEE)
158  sampleFingertipPosition.second_derivative(aEE)
159 
160  fingertipPositionTask.setReference(sampleFingertipPosition)
161 
162  samplePosture = trajPosture.computeNext()
163  postureTask.setReference(samplePosture)
164 
165  # Computing HQP
166  HQPData = invdyn.computeProblemData(t, q, v)
167  if i == 0:
168  HQPData.print_all()
169 
170  sol = solver.solve(HQPData)
171  if sol.status != 0:
172  print(f"[{i}] QP problem could not be solved! Error code:", sol.status)
173  break
174 
175  tau = invdyn.getActuatorForces(sol)
176  dv = invdyn.getAccelerations(sol)
177 
178  if i % PRINT_N == 0:
179  print(f"Time {t:.3f}")
180 
181  v_mean = v + 0.5 * dt * dv
182  v += dt * dv
183  q = pin.integrate(robot.model(), q, dt * v_mean)
184  t += dt
185 
186  if i % DISPLAY_N == 0:
187  viz.display(q)
188 
189  time_spent = time.time() - time_start
190  if time_spent < dt:
191  time.sleep(dt - time_spent)
192 
193  i = i + 1
center
Vec3f center
tsid::InverseDynamicsFormulationAccForce
Definition: inverse-dynamics-formulation-acc-force.hpp:40


tsid
Author(s): Andrea Del Prete, Justin Carpentier
autogenerated on Sat May 3 2025 02:48:16