3 from pathlib
import Path
5 sys.path.append(str(Path(__file__).parent.parent))
9 import pinocchio
as pin
12 from test_case
import PinocchioTestCase
as TestCase
17 self.
cR0 = SX.sym(
"R0", 3, 3)
18 self.
cR1 = SX.sym(
"R1", 3, 3)
19 self.
dv0 = SX.sym(
"v0", 3)
20 self.
dv1 = SX.sym(
"v1", 3)
22 self.
cv2 = SX.sym(
"v2", 3)
23 self.
cdv2 = SX.sym(
"dv", 3)
29 self.
cM0 = SX.sym(
"M0", 4, 4)
30 self.
cM1 = SX.sym(
"M1", 4, 4)
31 self.
cdw0 = SX.sym(
"dm0", 6)
32 self.
cdw1 = SX.sym(
"dm1", 6)
33 self.
cw2 = SX.sym(
"w2", 6)
34 self.
cdw2 = SX.sym(
"dw2", 6)
39 """Test the exp map and its derivative."""
41 exp_expr = self.
cR0_i @ cpin.exp3(self.
cv2 + dw)
44 return casadi.substitute(e, casadi.vertcat(self.
dv0, dw), np.zeros(6))
46 exp_eval = casadi.Function(
"exp", [self.
cR0, self.
cv2], [repl_dargs(exp_expr)])
48 diff_expr = cpin.log3(exp_eval(self.
cR0, self.
cv2).T @ exp_expr)
49 Jexp_expr = casadi.jacobian(diff_expr, casadi.vertcat(self.
dv0, dw))
50 Jexp_eval = casadi.Function(
51 "exp", [self.
cR0, self.
cv2], [repl_dargs(Jexp_expr)]
55 w1 = np.random.randn(3)
56 w2 = np.array([np.pi, 0, 0])
57 w3 = np.array([-np.pi, 0, 0])
62 self.assertApprox(exp_eval(R0, np.zeros(3)).full(), R0)
63 self.assertApprox(exp_eval(R0, w1).full(), R1)
64 self.assertApprox(exp_eval(R0, -w1).full(), R1.T)
65 self.assertApprox(exp_eval(R1, -w1).full(), R0)
66 self.assertApprox(exp_eval(R0, w2).full(), R2)
79 self.assertApprox(Jexp_eval(R0, w0).full(), np.hstack([R0.T, J0]))
80 self.assertApprox(Jexp_eval(R0, w1).full(), np.hstack([R1.T, J1]))
81 self.assertApprox(Jexp_eval(R0, w2).full(), np.hstack([R2.T, J2]))
82 self.assertApprox(Jexp_eval(R0, w3).full(), np.hstack([R3.T, J3]))
83 self.assertApprox(Jexp_eval(R1, w0).full(), np.hstack([R0.T, J0]))
84 self.assertApprox(Jexp_eval(R1, w2).full(), np.hstack([R2.T, J2]))
87 log_expr = cpin.log3(self.
cR0_i.T @ self.
cR1_i)
88 log_eval = casadi.Function(
91 [casadi.substitute(log_expr, self.
v_all, np.zeros(6))],
94 Jlog_expr = casadi.jacobian(log_expr, self.
v_all)
95 Jlog_eval = casadi.Function(
98 [casadi.substitute(Jlog_expr, self.
v_all, np.zeros(6))],
102 vr = np.random.randn(3)
104 R2 = pin.exp3(np.array([np.pi, 0, 0]))
105 v3 = np.array([0, np.pi, 0])
108 self.assertApprox(log_eval(R0, R0).full().squeeze(), np.zeros(3))
109 self.assertApprox(log_eval(R0, R1).full().squeeze(), vr)
110 self.assertApprox(log_eval(R1, R1).full().squeeze(), np.zeros(3))
111 self.assertApprox(log_eval(R0, R2).full().squeeze(), np.array([np.pi, 0, 0]))
112 self.assertApprox(log_eval(R0, R3).full().squeeze(), v3)
115 jac_identity = np.hstack([-J0, J0])
116 self.assertApprox(Jlog_eval(R0, R0).full(), jac_identity)
119 self.assertApprox(Jlog_eval(R0, R1).full(), np.hstack([-R1.T @ J1, J1]))
122 self.assertApprox(Jlog_eval(R0, R2).full(), np.hstack([-R2.T @ J2, J2]))
125 cquat = SX.sym(
"quat", 4)
126 cdv = SX.sym(
"dv", 3)
127 SO3 = cpin.liegroups.SO3()
130 return casadi.substitute(e, cdv, np.zeros(3))
132 cquat_i = SO3.integrate(cquat, cdv)
134 clog = cpin.log3(cquat_i)
135 cJlog = casadi.jacobian(clog, cdv)
136 clog_eval = casadi.Function(
"log", [cquat], [repl_dargs(clog)])
137 cJlog_eval = casadi.Function(
"Jlog", [cquat], [repl_dargs(cJlog)])
139 q0 = np.array([0.0, 0.0, 0.0, 1.0])
140 q1 = np.array([0.0, 1.0, 0.0, 0.0])
141 q2 = np.array([0.0, 0.0, 1.0, 0.0])
142 q3 = np.array([1.0, 0.0, 0.0, 0.0])
144 self.assertApprox(clog_eval(q0).full().squeeze(), np.zeros(3))
145 self.assertApprox(cJlog_eval(q0).full().squeeze(), np.eye(3))
147 clog_fun = casadi.dot(clog, clog)
148 cJlog_fun = casadi.jacobian(clog_fun, cdv)
149 clog_fun_eval = casadi.Function(
"normlog", [cquat], [repl_dargs(clog_fun)])
150 cJlog_fun_eval = casadi.Function(
"Jnormlog", [cquat], [repl_dargs(cJlog_fun)])
152 self.assertApprox(clog_fun_eval(q0).full().squeeze(), np.zeros(1))
153 self.assertApprox(cJlog_fun_eval(q0).full(), np.zeros(3))
156 cJlog_fun_eval(q1).full(), 2 * np.pi * np.array([0.0, 1.0, 0.0])
159 cJlog_fun_eval(q2).full(), 2 * np.pi * np.array([0.0, 0.0, 1.0])
162 cJlog_fun_eval(q3).full(), 2 * np.pi * np.array([1.0, 0.0, 0.0])
164 print(
"log3 quat done")
167 exp_expr = cpin.exp6(self.
cw2 + self.
cdw2)
170 return casadi.substitute(e, self.
cdw2, np.zeros(6))
172 exp_eval = casadi.Function(
"exp6", [self.
cw2], [repl_dargs(exp_expr.np)])
174 diff_expr = cpin.log6(cpin.SE3(exp_eval(self.
cw2)).actInv(exp_expr)).np
175 Jexp_expr = casadi.jacobian(diff_expr, self.
cdw2)
177 Jexp_eval = casadi.Function(
"exp6", [self.
cw2], [repl_dargs(Jexp_expr)])
180 w1 = np.array([0.0, 0.0, 0.0, np.pi, 0.0, 0.0])
181 w2 = np.random.randn(6)
182 w3 = np.array([0.0, 0.0, 0.0, np.pi / 2, 0.0, 0.0])
187 self.assertApprox(exp_eval(w0).full(), M0.np)
188 self.assertApprox(exp_eval(w1).full(), M1.np)
189 self.assertApprox(exp_eval(w2).full(), M2.np)
190 self.assertApprox(exp_eval(w3).full(), M3.np)
192 np.set_printoptions(precision=3)
194 self.assertApprox(Jexp_eval(w0).full(), J0)
196 self.assertApprox(Jexp_eval(w1).full(), J1)
198 self.assertApprox(Jexp_eval(w2).full(), J2)
201 log_expr = cpin.log6(self.
cM0_i.actInv(self.
cM1_i))
204 return casadi.substitute(
205 e, casadi.vertcat(self.
cdw0, self.
cdw1), np.zeros(12)
208 log_eval = casadi.Function(
209 "log6", [self.
cM0, self.
cM1], [repl_dargs(log_expr.np)]
212 Jlog_expr = casadi.jacobian(log_expr.np, casadi.vertcat(self.
cdw0, self.
cdw1))
213 Jlog_eval = casadi.Function(
214 "Jlog6", [self.
cM0, self.
cM1], [repl_dargs(Jlog_expr)]
218 M0 = pin.exp6(np.zeros(6))
219 w1 = np.array([0, 0, 0, np.pi, 0.0, 0.0])
221 w2 = np.random.randn(6)
224 self.assertApprox(log_eval(M0.np, M0.np).full(), w0)
225 self.assertApprox(log_eval(M1.np, M1.np).full(), w0)
226 self.assertApprox(log_eval(M0.np, M1.np).full(), w1)
227 self.assertApprox(log_eval(M0.np, M2.np).full(), w2)
232 self.assertApprox(Jlog_eval(M0.np, M0.np).full(), np.hstack([-J0, J0]))
234 Jlog_eval(M0.np, M1.np).full(), np.hstack([-M1.dualAction.T @ J1, J1])
237 Jlog_eval(M0.np, M2.np).full(), np.hstack([-M2.dualAction.T @ J2, J2])
241 cq0 = SX.sym(
"q0", 7)
242 cv0 = SX.sym(
"q0", 6)
245 return casadi.substitute(e, cv0, np.zeros(6))
247 SE3 = cpin.liegroups.SE3()
249 cq0_i = SE3.integrate(cq0, cv0)
250 clog = cpin.log6_quat(cq0_i).vector
251 clog_eval = casadi.Function(
"log", [cq0], [repl_dargs(clog)])
253 cJlog = casadi.jacobian(clog, cv0)
254 cJlog_eval = casadi.Function(
"Jlog", [cq0], [repl_dargs(cJlog)])
256 q0 = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0])
257 q1 = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0])
258 q2 = np.array([0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0])
259 q3 = np.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0])
260 self.assertApprox(clog_eval(q0).full().squeeze(), np.zeros(6))
261 self.assertApprox(cJlog_eval(q0).full(), np.eye(6))
263 print(
"log6 with quats")
264 print(clog_eval(q1).full())
265 print(cJlog_eval(q1).full())
267 clog_fun = casadi.dot(clog, clog)
268 clog_fun = casadi.dot(clog, clog)
269 cJlog_fun = casadi.jacobian(clog_fun, cv0)
270 clog_fun_eval = casadi.Function(
"normlog", [cq0], [repl_dargs(clog_fun)])
271 cJlog_fun_eval = casadi.Function(
"Jnormlog", [cq0], [repl_dargs(cJlog_fun)])
273 print(clog_fun_eval(q0).full().squeeze())
274 print(cJlog_fun_eval(q0).full())
276 print(clog_fun_eval(q1).full().squeeze())
277 print(cJlog_fun_eval(q1).full())
279 print(clog_fun_eval(q2).full().squeeze())
280 print(cJlog_fun_eval(q2).full())
282 print(clog_fun_eval(q3).full().squeeze())
283 print(cJlog_fun_eval(q3).full())
286 if __name__ ==
"__main__":