9 """ 2 dimensional group of rigid body transformations """
12 """ internally represented by a unit complex number z and a translation
19 """ exponential map """
21 so2 = sophus.So2.exp(theta)
23 a = so2.z.imag / theta
24 b = (1 - so2.z.real) / theta
26 t = sophus.Vector2(a * v[0] - b * v[1],
32 halftheta = 0.5 * theta
33 a = -(halftheta * self.
so2.z.imag) / (self.
so2.z.real - 1)
35 V_inv = sympy.Matrix([[a, halftheta],
37 upsilon = V_inv * self.
t
38 return sophus.Vector3(upsilon[0], upsilon[1], theta)
41 return "Se2: [" + repr(self.
so2) +
" " + repr(self.
t)
45 upsilon = sophus.Vector2(v[0], v[1])
47 return sophus.So2.hat(theta).\
49 col_join(sympy.Matrix.zeros(1, 3))
52 """ returns matrix representation """
54 return (R.row_join(self.
t)).col_join(sympy.Matrix(1, 3, [0, 0, 1]))
57 """ left-multiplication
58 either rotation concatenation or point-transform """
59 if isinstance(right, sympy.Matrix):
60 assert right.shape == (2, 1), right.shape
61 return self.
so2 * right + self.
t
62 elif isinstance(right, Se2):
63 return Se2(self.
so2 * right.so2,
64 self.
t + self.
so2 * right.t)
65 assert False,
"unsupported type: {0}".format(type(right))
68 """ We use the following convention [q0, q1, q2, q3, t0, t1, t2] """
69 assert (key >= 0
and key < 4)
73 return self.
t[key - 2]
77 return sympy.Matrix(4, 3,
lambda r, c:
78 sympy.diff(Se2.exp(x)[r], x[c]))
82 return sympy.Matrix([[0, 0, 0],
89 return sympy.Matrix(4, 3,
lambda r, c:
90 sympy.diff((self * Se2.exp(x))[r], x[c])). \
91 subs(x[0], 0).subs(x[1], 0).limit(x[2], 0)
95 return Se2.calc_Dx_exp_x(x).subs(x[0], 0).subs(x[1], 0).limit(x[2], 0)
100 return sophus.So2.Dxi_x_matrix(x, i).\
101 row_join(sympy.Matrix.zeros(2, 1)).\
102 col_join(sympy.Matrix.zeros(1, 3))
103 M = sympy.Matrix.zeros(3, 3)
109 return sympy.Matrix(3, 3,
lambda r, c:
110 sympy.diff(x.matrix()[r, c], x[i]))
115 Dx_exp_x = Se2.calc_Dx_exp_x(x)
116 l = [Dx_exp_x[j, i] * Se2.Dxi_x_matrix(T, j)
for j
in range(0, 4)]
117 return functools.reduce((
lambda a, b: a + b), l)
121 return sympy.Matrix(3, 3,
lambda r, c:
122 sympy.diff(Se2.exp(x).
matrix()[r, c], x[i]))
126 v = sophus.ZeroVector3()
132 return sympy.Matrix(3, 3,
lambda r, c:
133 sympy.diff(Se2.exp(x).
matrix()[r, c], x[i])
134 ).subs(x[0], 0).subs(x[1], 0).limit(x[2], 0)
139 upsilon0, upsilon1, theta = sympy.symbols(
140 'upsilon[0], upsilon[1], theta',
142 x, y = sympy.symbols(
'c[0] c[1]', real=
True)
143 p0, p1 = sympy.symbols(
'p0 p1', real=
True)
144 t0, t1 = sympy.symbols(
't[0] t[1]', real=
True)
146 upsilon0, upsilon1, theta)
147 self.
t = sophus.Vector2(t0, t1)
149 self.
p = sophus.Vector2(p0, p1)
152 for v
in [sophus.Vector3(0., 1, 0.5),
153 sophus.Vector3(0.1, 0.1, 0.1),
154 sophus.Vector3(0.01, 0.2, 0.03)]:
156 for i
in range(0, 3):
157 self.assertAlmostEqual(v[i], w[i])
161 Tmat_foo_bar = T_foo_bar.matrix()
163 p1_foo = T_foo_bar * point_bar
164 p2_foo = sophus.proj(Tmat_foo_bar * sophus.unproj(point_bar))
165 self.assertEqual(sympy.simplify(p1_foo - p2_foo),
166 sophus.ZeroVector2())
169 self.assertEqual(sympy.simplify(
171 Se2.Dx_exp_x_at_0()),
172 sympy.Matrix.zeros(4, 3))
173 for i
in range(0, 4):
174 self.assertEqual(sympy.simplify(Se2.calc_Dxi_x_matrix(self.
a, i) -
175 Se2.Dxi_x_matrix(self.
a, i)),
176 sympy.Matrix.zeros(3, 3))
177 for i
in range(0, 3):
178 self.assertEqual(sympy.simplify(
181 sympy.Matrix.zeros(3, 3))
182 self.assertEqual(sympy.simplify(
183 Se2.Dxi_exp_x_matrix_at_0(i) -
185 sympy.Matrix.zeros(3, 3))
189 filename =
"cpp_gencode/Se2_Dx_exp_x.cpp"
193 file = open(filename,
"w")
198 file = open(filename,
"r")
199 file_lines = file.readlines()
200 for i, line
in enumerate(stream):
201 self.assertEqual(line, file_lines[i])
207 filename =
"cpp_gencode/Se2_Dx_this_mul_exp_x_at_0.cpp"
210 file = open(filename,
"w")
215 file = open(filename,
"r")
216 file_lines = file.readlines()
217 for i, line
in enumerate(stream):
218 self.assertEqual(line, file_lines[i])
223 if __name__ ==
'__main__':