so2.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 So2:
9  """ 2 dimensional group of orthogonal matrices with determinant 1 """
10 
11  def __init__(self, z):
12  """ internally represented by a unit complex number z """
13  self.z = z
14 
15  @staticmethod
16  def exp(theta):
17  """ exponential map """
18  return So2(
20  sympy.cos(theta),
21  sympy.sin(theta)))
22 
23  def log(self):
24  """ logarithmic map"""
25  return sympy.atan2(self.z.imag, self.z.real)
26 
27  def __repr__(self):
28  return "So2:" + repr(self.z)
29 
30  @staticmethod
31  def hat(theta):
32  return sympy.Matrix([[0, -theta],
33  [theta, 0]])
34 
35  def matrix(self):
36  """ returns matrix representation """
37  return sympy.Matrix([
38  [self.z.real, -self.z.imag],
39  [self.z.imag, self.z.real]])
40 
41  def __mul__(self, right):
42  """ left-multiplication
43  either rotation concatenation or point-transform """
44  if isinstance(right, sympy.Matrix):
45  assert right.shape == (2, 1), right.shape
46  return self.matrix() * right
47  elif isinstance(right, So2):
48  return So2(self.z * right.z)
49  assert False, "unsupported type: {0}".format(type(right))
50 
51  def __getitem__(self, key):
52  return self.z[key]
53 
54  @staticmethod
55  def calc_Dx_exp_x(x):
56  return sympy.Matrix(2, 1, lambda r, c:
57  sympy.diff(So2.exp(x)[r], x))
58 
59  @staticmethod
61  return sympy.Matrix([0, 1])
62 
63  @staticmethod
65  return So2.calc_Dx_exp_x(x).limit(x, 0)
66 
68  return sympy.Matrix(2, 1, lambda r, c:
69  sympy.diff((self * So2.exp(x))[r], x))\
70  .limit(x, 0)
71 
72  @staticmethod
73  def Dxi_x_matrix(x, i):
74  if i == 0:
75  return sympy.Matrix([[1, 0],
76  [0, 1]])
77  if i == 1:
78  return sympy.Matrix([[0, -1],
79  [1, 0]])
80 
81  @staticmethod
82  def calc_Dxi_x_matrix(x, i):
83  return sympy.Matrix(2, 2, lambda r, c:
84  sympy.diff(x.matrix()[r, c], x[i]))
85 
86  @staticmethod
88  R = So2.exp(x)
89  Dx_exp_x = So2.calc_Dx_exp_x(x)
90  l = [Dx_exp_x[j] * So2.Dxi_x_matrix(R, j) for j in [0, 1]]
91  return functools.reduce((lambda a, b: a + b), l)
92 
93  @staticmethod
95  return sympy.Matrix(2, 2, lambda r, c:
96  sympy.diff(So2.exp(x).matrix()[r, c], x))
97 
98  @staticmethod
100  return So2.hat(1)
101 
102  @staticmethod
104  return sympy.Matrix(2, 2, lambda r, c:
105  sympy.diff(So2.exp(x).matrix()[r, c], x)
106  ).limit(x, 0)
107 
108 
109 class TestSo2(unittest.TestCase):
110  def setUp(self):
111  self.theta = sympy.symbols(
112  'theta', real=True)
113  x, y = sympy.symbols('c[0] c[1]', real=True)
114  p0, p1 = sympy.symbols('p0 p1', real=True)
115  self.a = So2(sophus.Complex(x, y))
116  self.p = sophus.Vector2(p0, p1)
117 
118  def test_exp_log(self):
119  for theta in [0., 0.5, 0.1]:
120  w = So2.exp(theta).log()
121  self.assertAlmostEqual(theta, w)
122 
123  def test_matrix(self):
124  R_foo_bar = So2.exp(self.theta)
125  Rmat_foo_bar = R_foo_bar.matrix()
126  point_bar = self.p
127  p1_foo = R_foo_bar * point_bar
128  p2_foo = Rmat_foo_bar * point_bar
129  self.assertEqual(sympy.simplify(p1_foo - p2_foo),
130  sophus.ZeroVector2())
131 
132  def test_derivatives(self):
133  self.assertEqual(sympy.simplify(So2.calc_Dx_exp_x_at_0(self.theta) -
134  So2.Dx_exp_x_at_0()),
135  sympy.Matrix.zeros(2, 1))
136  for i in [0, 1]:
137  self.assertEqual(sympy.simplify(So2.calc_Dxi_x_matrix(self.a, i) -
138  So2.Dxi_x_matrix(self.a, i)),
139  sympy.Matrix.zeros(2, 2))
140 
141  self.assertEqual(sympy.simplify(
142  So2.Dx_exp_x_matrix(self.theta) -
143  So2.calc_Dx_exp_x_matrix(self.theta)),
144  sympy.Matrix.zeros(2, 2))
145  self.assertEqual(sympy.simplify(
146  So2.Dx_exp_x_matrix_at_0() -
147  So2.calc_Dx_exp_x_matrix_at_0(self.theta)),
148  sympy.Matrix.zeros(2, 2))
149 
150  def test_codegen(self):
151  stream = sophus.cse_codegen(So2.calc_Dx_exp_x(self.theta))
152  filename = "cpp_gencode/So2_Dx_exp_x.cpp"
153  # set to true to generate codegen files
154  if False:
155  file = open(filename, "w")
156  for line in stream:
157  file.write(line)
158  file.close()
159  else:
160  file = open(filename, "r")
161  file_lines = file.readlines()
162  for i, line in enumerate(stream):
163  self.assertEqual(line, file_lines[i])
164  file.close()
165  stream.close
166 
167  stream = sophus.cse_codegen(
168  self.a.calc_Dx_this_mul_exp_x_at_0(self.theta))
169  filename = "cpp_gencode/So2_Dx_this_mul_exp_x_at_0.cpp"
170  # set to true to generate codegen files
171  if False:
172  file = open(filename, "w")
173  for line in stream:
174  file.write(line)
175  file.close()
176  else:
177  file = open(filename, "r")
178  file_lines = file.readlines()
179  for i, line in enumerate(stream):
180  self.assertEqual(line, file_lines[i])
181  file.close()
182  stream.close
183 
184 
185 if __name__ == '__main__':
186  unittest.main()
sophus.so2.So2.__getitem__
def __getitem__(self, key)
Definition: so2.py:51
sophus.so2.So2.log
def log(self)
Definition: so2.py:23
sophus.so2.So2.calc_Dx_exp_x_at_0
def calc_Dx_exp_x_at_0(x)
Definition: so2.py:64
sophus.so2.TestSo2.setUp
def setUp(self)
Definition: so2.py:110
sophus.so2.So2.Dx_exp_x_at_0
def Dx_exp_x_at_0()
Definition: so2.py:60
sophus.so2.So2.calc_Dx_exp_x_matrix
def calc_Dx_exp_x_matrix(x)
Definition: so2.py:94
sophus.so2.So2
Definition: so2.py:8
sophus.so2.So2.exp
def exp(theta)
Definition: so2.py:16
sophus.so2.TestSo2.test_matrix
def test_matrix(self)
Definition: so2.py:123
sophus.so2.TestSo2.test_exp_log
def test_exp_log(self)
Definition: so2.py:118
sophus.so2.So2.calc_Dx_exp_x
def calc_Dx_exp_x(x)
Definition: so2.py:55
sophus.so2.So2.__mul__
def __mul__(self, right)
Definition: so2.py:41
sophus.cse_codegen
Definition: cse_codegen.py:1
sophus.so2.So2.hat
def hat(theta)
Definition: so2.py:31
sophus.so2.So2.z
z
Definition: so2.py:13
sophus.so2.TestSo2.theta
theta
Definition: so2.py:111
sophus.so2.TestSo2.a
a
Definition: so2.py:115
sophus.complex.Complex
Definition: complex.py:7
sophus.so2.So2.Dx_exp_x_matrix_at_0
def Dx_exp_x_matrix_at_0()
Definition: so2.py:99
sophus.so2.So2.Dx_exp_x_matrix
def Dx_exp_x_matrix(x)
Definition: so2.py:87
sophus.so2.So2.__repr__
def __repr__(self)
Definition: so2.py:27
sophus.so2.So2.calc_Dxi_x_matrix
def calc_Dxi_x_matrix(x, i)
Definition: so2.py:82
sophus.so2.So2.Dxi_x_matrix
def Dxi_x_matrix(x, i)
Definition: so2.py:73
sophus.so2.TestSo2.test_codegen
def test_codegen(self)
Definition: so2.py:150
sophus.so2.So2.__init__
def __init__(self, z)
Definition: so2.py:11
sophus.so2.TestSo2.p
p
Definition: so2.py:116
sophus.so2.So2.calc_Dx_this_mul_exp_x_at_0
def calc_Dx_this_mul_exp_x_at_0(self, x)
Definition: so2.py:67
sophus.so2.So2.matrix
def matrix(self)
Definition: so2.py:35
sophus.so2.So2.calc_Dx_exp_x_matrix_at_0
def calc_Dx_exp_x_matrix_at_0(x)
Definition: so2.py:103
sophus.so2.TestSo2
Definition: so2.py:109
sophus.so2.TestSo2.test_derivatives
def test_derivatives(self)
Definition: so2.py:132


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