5 from pathlib
import Path
7 import gepetto.corbaserver
8 import matplotlib.pyplot
as plt
10 import pinocchio
as pin
11 import plot_utils
as plut
14 from numpy.linalg
import norm
as norm
16 sys.path += [Path.cwd().parent /
"exercizes"]
18 np.set_printoptions(precision=3, linewidth=200, suppress=
True)
21 print(
"".
center(LINE_WIDTH,
"#"))
22 print(
" Test TSID with Quadruped Robot ".
center(LINE_WIDTH,
"#"))
23 print(
"".
center(LINE_WIDTH,
"#"),
"\n")
28 contact_frames = [
"BL_contact",
"BR_contact",
"FL_contact",
"FR_contact"]
29 contactNormal = np.array(
46 filename = str(Path(__file__).resolve().parent)
47 path = filename +
"/../models"
48 urdf = path +
"/quadruped/urdf/quadruped.urdf"
49 vector = pin.StdVec_StdString()
50 vector.extend(item
for item
in path)
51 robot = tsid.RobotWrapper(urdf, vector, pin.JointModelFreeFlyer(),
False)
54 robot_display = pin.RobotWrapper.BuildFromURDF(
59 pin.JointModelFreeFlyer(),
61 n = subprocess.getstatusoutput(
"ps aux |grep 'gepetto-gui'|grep -v 'grep'|wc -l")
63 os.system(
"gepetto-gui &")
65 cl = gepetto.corbaserver.Client()
67 robot_display.initViewer(loadModel=
True)
74 q = np.zeros(robot.nq)
80 v = np.zeros(robot.nv)
82 robot_display.displayCollisions(
False)
83 robot_display.displayVisuals(
True)
84 robot_display.display(q)
86 assert [robot.model().existFrame(name)
for name
in contact_frames]
90 invdyn.computeProblemData(t, q, v)
94 id_contact = robot_display.model.getFrameId(contact_frames[0])
95 q[2] -= robot.framePosition(data, id_contact).translation[2]
96 robot.computeAllTerms(data, q, v)
99 for i, name
in enumerate(contact_frames):
100 contacts[i] = tsid.ContactPoint(name, robot, name, contactNormal, mu, fMin, fMax)
101 contacts[i].setKp(kp_contact * np.ones(3))
102 contacts[i].setKd(2.0 * np.sqrt(kp_contact) * np.ones(3))
103 H_rf_ref = robot.framePosition(data, robot.model().getFrameId(name))
104 contacts[i].setReference(H_rf_ref)
105 contacts[i].useLocalFrame(
False)
106 invdyn.addRigidContact(contacts[i], w_forceRef, 1.0, 1)
108 comTask = tsid.TaskComEquality(
"task-com", robot)
109 comTask.setKp(kp_com * np.ones(3))
110 comTask.setKd(2.0 * np.sqrt(kp_com) * np.ones(3))
111 invdyn.addMotionTask(comTask, w_com, 1, 0.0)
113 postureTask = tsid.TaskJointPosture(
"task-posture", robot)
114 postureTask.setKp(kp_posture * np.ones(robot.nv - 6))
115 postureTask.setKd(2.0 * np.sqrt(kp_posture) * np.ones(robot.nv - 6))
116 invdyn.addMotionTask(postureTask, w_posture, 1, 0.0)
118 com_ref = robot.com(data)
119 trajCom = tsid.TrajectoryEuclidianConstant(
"traj_com", com_ref)
120 sampleCom = trajCom.computeNext()
123 trajPosture = tsid.TrajectoryEuclidianConstant(
"traj_joint", q_ref)
126 "Create QP solver with ",
132 " inequality constraints",
134 solver = tsid.SolverHQuadProgFast(
"qp solver")
135 solver.resize(invdyn.nVar, invdyn.nEq, invdyn.nIn)
137 com_pos = np.empty((3, N_SIMULATION)) * nan
138 com_vel = np.empty((3, N_SIMULATION)) * nan
139 com_acc = np.empty((3, N_SIMULATION)) * nan
141 com_pos_ref = np.empty((3, N_SIMULATION)) * nan
142 com_vel_ref = np.empty((3, N_SIMULATION)) * nan
143 com_acc_ref = np.empty((3, N_SIMULATION)) * nan
145 np.empty((3, N_SIMULATION)) * nan
148 offset = robot.com(data) + np.array([0.0, 0.0, 0.0])
149 amp = np.array([0.0, 0.03, 0.0])
150 two_pi_f = 2 * np.pi * np.array([0.0, 2.0, 0.7])
151 two_pi_f_amp = np.multiply(two_pi_f, amp)
152 two_pi_f_squared_amp = np.multiply(two_pi_f, two_pi_f_amp)
154 for i
in range(0, N_SIMULATION):
155 time_start = time.time()
157 sampleCom.pos(offset + np.multiply(amp, np.sin(two_pi_f * t)))
158 sampleCom.vel(np.multiply(two_pi_f_amp, np.cos(two_pi_f * t)))
159 sampleCom.acc(np.multiply(two_pi_f_squared_amp, -np.sin(two_pi_f * t)))
161 comTask.setReference(sampleCom)
162 samplePosture = trajPosture.computeNext()
163 postureTask.setReference(samplePosture)
165 HQPData = invdyn.computeProblemData(t, q, v)
169 sol = solver.solve(HQPData)
171 print(f
"[{i}] QP problem could not be solved! Error code", sol.status)
174 tau = invdyn.getActuatorForces(sol)
175 dv = invdyn.getAccelerations(sol)
177 com_pos[:, i] = robot.com(invdyn.data())
178 com_vel[:, i] = robot.com_vel(invdyn.data())
179 com_acc[:, i] = comTask.getAcceleration(dv)
180 com_pos_ref[:, i] = sampleCom.pos()
181 com_vel_ref[:, i] = sampleCom.vel()
182 com_acc_ref[:, i] = sampleCom.acc()
183 com_acc_des[:, i] = comTask.getDesiredAcceleration
186 print(f
"Time {t:.3f}")
187 print(
"\tNormal forces: ", end=
" ")
188 for contact
in contacts:
189 if invdyn.checkContact(contact.name, sol):
190 f = invdyn.getContactForce(contact.name, sol)
191 print(f
"{contact.getNormalForce(f):4.1f}", end=
" ")
194 "\n\ttracking err {}: {:.3f}".format(
195 comTask.name.ljust(20,
"."), norm(comTask.position_error, 2)
198 print(f
"\t||v||: {norm(v, 2):.3f}\t ||dv||: {norm(dv):.3f}")
200 v_mean = v + 0.5 * dt * dv
202 q = pin.integrate(robot.model(), q, dt * v_mean)
205 if i % DISPLAY_N == 0:
206 robot_display.display(q)
208 time_spent = time.time() - time_start
210 time.sleep(dt - time_spent)
213 time = np.arange(0.0, N_SIMULATION * dt, dt)
215 (f, ax) = plut.create_empty_figure(3, 1)
217 ax[i].
plot(time, com_pos[i, :], label=
"CoM " + str(i))
218 ax[i].
plot(time, com_pos_ref[i, :],
"r:", label=
"CoM Ref " + str(i))
219 ax[i].set_xlabel(
"Time [s]")
220 ax[i].set_ylabel(
"CoM [m]")
222 leg.get_frame().set_alpha(0.5)
224 (f, ax) = plut.create_empty_figure(3, 1)
226 ax[i].
plot(time, com_vel[i, :], label=
"CoM Vel " + str(i))
227 ax[i].
plot(time, com_vel_ref[i, :],
"r:", label=
"CoM Vel Ref " + str(i))
228 ax[i].set_xlabel(
"Time [s]")
229 ax[i].set_ylabel(
"CoM Vel [m/s]")
231 leg.get_frame().set_alpha(0.5)
233 (f, ax) = plut.create_empty_figure(3, 1)
235 ax[i].
plot(time, com_acc[i, :], label=
"CoM Acc " + str(i))
236 ax[i].
plot(time, com_acc_ref[i, :],
"r:", label=
"CoM Acc Ref " + str(i))
237 ax[i].
plot(time, com_acc_des[i, :],
"g--", label=
"CoM Acc Des " + str(i))
238 ax[i].set_xlabel(
"Time [s]")
239 ax[i].set_ylabel(
"CoM Acc [m/s^2]")
241 leg.get_frame().set_alpha(0.5)