se2.py
Go to the documentation of this file.
1 import sympy
2 import sys
3 import unittest
4 import sophus
5 import functools
6 
7 
8 class Se2:
9  """ 2 dimensional group of rigid body transformations """
10 
11  def __init__(self, so2, t):
12  """ internally represented by a unit complex number z and a translation
13  2-vector """
14  self.so2 = so2
15  self.t = t
16 
17  @staticmethod
18  def exp(v):
19  """ exponential map """
20  theta = v[2]
21  so2 = sophus.So2.exp(theta)
22 
23  a = so2.z.imag / theta
24  b = (1 - so2.z.real) / theta
25 
26  t = sophus.Vector2(a * v[0] - b * v[1],
27  b * v[0] + a * v[1])
28  return Se2(so2, t)
29 
30  def log(self):
31  theta = self.so2.log()
32  halftheta = 0.5 * theta
33  a = -(halftheta * self.so2.z.imag) / (self.so2.z.real - 1)
34 
35  V_inv = sympy.Matrix([[a, halftheta],
36  [-halftheta, a]])
37  upsilon = V_inv * self.t
38  return sophus.Vector3(upsilon[0], upsilon[1], theta)
39 
40  def __repr__(self):
41  return "Se2: [" + repr(self.so2) + " " + repr(self.t)
42 
43  @staticmethod
44  def hat(v):
45  upsilon = sophus.Vector2(v[0], v[1])
46  theta = v[2]
47  return sophus.So2.hat(theta).\
48  row_join(upsilon).\
49  col_join(sympy.Matrix.zeros(1, 3))
50 
51  def matrix(self):
52  """ returns matrix representation """
53  R = self.so2.matrix()
54  return (R.row_join(self.t)).col_join(sympy.Matrix(1, 3, [0, 0, 1]))
55 
56  def __mul__(self, right):
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))
66 
67  def __getitem__(self, key):
68  """ We use the following convention [q0, q1, q2, q3, t0, t1, t2] """
69  assert (key >= 0 and key < 4)
70  if key < 2:
71  return self.so2[key]
72  else:
73  return self.t[key - 2]
74 
75  @staticmethod
76  def calc_Dx_exp_x(x):
77  return sympy.Matrix(4, 3, lambda r, c:
78  sympy.diff(Se2.exp(x)[r], x[c]))
79 
80  @staticmethod
82  return sympy.Matrix([[0, 0, 0],
83  [0, 0, 1],
84  [1, 0, 0],
85  [0, 1, 0]])
86 
88  v = Se2.exp(x)
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)
92 
93  @staticmethod
95  return Se2.calc_Dx_exp_x(x).subs(x[0], 0).subs(x[1], 0).limit(x[2], 0)
96 
97  @staticmethod
98  def Dxi_x_matrix(x, i):
99  if i < 2:
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)
104  M[i - 2, 2] = 1
105  return M
106 
107  @staticmethod
108  def calc_Dxi_x_matrix(x, i):
109  return sympy.Matrix(3, 3, lambda r, c:
110  sympy.diff(x.matrix()[r, c], x[i]))
111 
112  @staticmethod
113  def Dxi_exp_x_matrix(x, i):
114  T = Se2.exp(x)
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)
118 
119  @staticmethod
121  return sympy.Matrix(3, 3, lambda r, c:
122  sympy.diff(Se2.exp(x).matrix()[r, c], x[i]))
123 
124  @staticmethod
126  v = sophus.ZeroVector3()
127  v[i] = 1
128  return Se2.hat(v)
129 
130  @staticmethod
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)
135 
136 
137 class TestSe2(unittest.TestCase):
138  def setUp(self):
139  upsilon0, upsilon1, theta = sympy.symbols(
140  'upsilon[0], upsilon[1], theta',
141  real=True)
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)
145  self.upsilon_theta = sophus.Vector3(
146  upsilon0, upsilon1, theta)
147  self.t = sophus.Vector2(t0, t1)
148  self.a = Se2(sophus.So2(sophus.Complex(x, y)), self.t)
149  self.p = sophus.Vector2(p0, p1)
150 
151  def test_exp_log(self):
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)]:
155  w = Se2.exp(v).log()
156  for i in range(0, 3):
157  self.assertAlmostEqual(v[i], w[i])
158 
159  def test_matrix(self):
160  T_foo_bar = Se2.exp(self.upsilon_theta)
161  Tmat_foo_bar = T_foo_bar.matrix()
162  point_bar = self.p
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())
167 
168  def test_derivatives(self):
169  self.assertEqual(sympy.simplify(
170  Se2.calc_Dx_exp_x_at_0(self.upsilon_theta) -
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(
179  Se2.Dxi_exp_x_matrix(self.upsilon_theta, i) -
180  Se2.calc_Dxi_exp_x_matrix(self.upsilon_theta, i)),
181  sympy.Matrix.zeros(3, 3))
182  self.assertEqual(sympy.simplify(
183  Se2.Dxi_exp_x_matrix_at_0(i) -
184  Se2.calc_Dxi_exp_x_matrix_at_0(self.upsilon_theta, i)),
185  sympy.Matrix.zeros(3, 3))
186 
187  def test_codegen(self):
188  stream = sophus.cse_codegen(Se2.calc_Dx_exp_x(self.upsilon_theta))
189  filename = "cpp_gencode/Se2_Dx_exp_x.cpp"
190 
191  # set to true to generate codegen files
192  if False:
193  file = open(filename, "w")
194  for line in stream:
195  file.write(line)
196  file.close()
197  else:
198  file = open(filename, "r")
199  file_lines = file.readlines()
200  for i, line in enumerate(stream):
201  self.assertEqual(line, file_lines[i])
202  file.close()
203  stream.close
204 
205  stream = sophus.cse_codegen(self.a.calc_Dx_this_mul_exp_x_at_0(
206  self.upsilon_theta))
207  filename = "cpp_gencode/Se2_Dx_this_mul_exp_x_at_0.cpp"
208  # set to true to generate codegen files
209  if False:
210  file = open(filename, "w")
211  for line in stream:
212  file.write(line)
213  file.close()
214  else:
215  file = open(filename, "r")
216  file_lines = file.readlines()
217  for i, line in enumerate(stream):
218  self.assertEqual(line, file_lines[i])
219  file.close()
220  stream.close
221 
222 
223 if __name__ == '__main__':
224  unittest.main()
sophus.se2.TestSe2.test_derivatives
def test_derivatives(self)
Definition: se2.py:168
sophus.se2.Se2.Dx_exp_x_at_0
def Dx_exp_x_at_0()
Definition: se2.py:81
sophus.se2.Se2.so2
so2
Definition: se2.py:14
sophus.se2.TestSe2.upsilon_theta
upsilon_theta
Definition: se2.py:145
sophus.se2.TestSe2.test_codegen
def test_codegen(self)
Definition: se2.py:187
sophus.so2.So2
Definition: so2.py:8
sophus.se2.Se2.exp
def exp(v)
Definition: se2.py:18
sophus.se2.Se2.__repr__
def __repr__(self)
Definition: se2.py:40
sophus.se2.Se2.log
def log(self)
Definition: se2.py:30
sophus.se2.Se2.t
t
Definition: se2.py:15
sophus.se2.Se2.hat
def hat(v)
Definition: se2.py:44
sophus.cse_codegen
Definition: cse_codegen.py:1
sophus.se2.Se2.matrix
def matrix(self)
Definition: se2.py:51
sophus.se2.TestSe2
Definition: se2.py:137
sophus.se2.Se2.calc_Dx_exp_x
def calc_Dx_exp_x(x)
Definition: se2.py:76
sophus.se2.TestSe2.t
t
Definition: se2.py:147
sophus.se2.TestSe2.test_matrix
def test_matrix(self)
Definition: se2.py:159
sophus.se2.Se2
Definition: se2.py:8
sophus.se2.TestSe2.a
a
Definition: se2.py:148
sophus.se2.Se2.Dxi_exp_x_matrix_at_0
def Dxi_exp_x_matrix_at_0(i)
Definition: se2.py:125
sophus.se2.Se2.__init__
def __init__(self, so2, t)
Definition: se2.py:11
sophus.se2.Se2.calc_Dxi_exp_x_matrix
def calc_Dxi_exp_x_matrix(x, i)
Definition: se2.py:120
sophus.complex.Complex
Definition: complex.py:7
sophus.se2.Se2.__getitem__
def __getitem__(self, key)
Definition: se2.py:67
sophus.se2.Se2.calc_Dx_exp_x_at_0
def calc_Dx_exp_x_at_0(x)
Definition: se2.py:94
sophus.se2.Se2.__mul__
def __mul__(self, right)
Definition: se2.py:56
sophus.se2.Se2.Dxi_exp_x_matrix
def Dxi_exp_x_matrix(x, i)
Definition: se2.py:113
sophus.se2.Se2.calc_Dx_this_mul_exp_x_at_0
def calc_Dx_this_mul_exp_x_at_0(self, x)
Definition: se2.py:87
sophus.se2.Se2.calc_Dxi_x_matrix
def calc_Dxi_x_matrix(x, i)
Definition: se2.py:108
sophus.se2.Se2.Dxi_x_matrix
def Dxi_x_matrix(x, i)
Definition: se2.py:98
sophus.se2.TestSe2.setUp
def setUp(self)
Definition: se2.py:138
sophus.se2.Se2.calc_Dxi_exp_x_matrix_at_0
def calc_Dxi_exp_x_matrix_at_0(x, i)
Definition: se2.py:131
sophus.se2.TestSe2.test_exp_log
def test_exp_log(self)
Definition: se2.py:151
sophus.se2.TestSe2.p
p
Definition: se2.py:149


sophus
Author(s): Hauke Strasdat
autogenerated on Wed Mar 2 2022 01:01:48