se3.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 
3 # Copyright 2010 CNRS
4 # Author: Florent Lamiraux
5 #
6 # Release under LGPL license: see COPYING.LESSER at root of the project.
7 #
8 
9 from functools import reduce
10 from math import cos, pi, sin, sqrt
11 
12 import numpy
13 
14 
15 class R(object):
16  def __init__(self, value):
17  self.value = value
18 
19  def __mul__(self, other):
20  if isinstance(other, R3):
21  return other.multiplyByConstant(self.value)
22  if isinstance(other, float):
23  return R(self.value * other)
24  if isinstance(other, R):
25  return R(self.value * other.value)
26  raise TypeError(
27  "cannot multiply instances of type R and type " + str(type(other))
28  )
29 
30  def __str__(self):
31  return str(self.value)
32 
33 
34 class R3(object):
35  """
36  Vectors of real number of dimension 3.
37  """
38 
39  def __init__(self, *args):
40  if len(args) == 1:
41  if isinstance(args[0], R3):
42  # copy constructor
43  self.value = args[0].value
44  # constructor by tuple
45  else:
46  self.value = numpy.array(map(float, args[0]))
47  elif len(args) == 3:
48  self.value = numpy.array(map(float, args))
49  else:
50  raise TypeError(
51  "constructor of R3 takes either three float,"
52  + ", an instance of R or a tuple of three float."
53  )
54  self.check()
55 
56  def check(self):
57  """
58  Check that instance is well defined.
59  """
60  if len(self.value) != 3:
61  raise TypeError("R3 object should be of length 3")
62 
63  def checkOther(self, other, operator):
64  """
65  Check that argument is of type R3
66  """
67  if not isinstance(other, R3):
68  raise TypeError(
69  "second argument of operator "
70  + operator
71  + " should be an instance of R3."
72  )
73 
74  def crossprod(self, other):
75  """
76  Cross product
77  """
78  self.checkOther(other, "crossprod")
79  cp = []
80  cp.append(self.value[1] * other.value[2] - self.value[2] * other.value[1])
81  cp.append(self.value[2] * other.value[0] - self.value[0] * other.value[2])
82  cp.append(self.value[0] * other.value[1] - self.value[1] * other.value[0])
83  return R3(tuple(cp))
84 
85  def __add__(self, other):
86  """
87  Operator +
88  """
89  self.checkOther(other, "+")
90  return R3(tuple(map(lambda x: x[0] + x[1], zip(self, other))))
91 
92  def __sub__(self, other):
93  """
94  Operator -
95  """
96  self.checkOther(other, "-")
97  return R3(tuple(map(lambda x: x[0] - x[1], zip(self, other))))
98 
99  def __mul__(self, other):
100  """
101  Operator *: inner product
102  """
103  self.checkOther(other, "*")
104  return reduce(lambda x, y: x + y[0] * y[1], zip(self, other), 0.0)
105 
106  def __rmul__(self, number):
107  """
108  Operator * by a float
109  """
110  return R3(tuple(map(lambda x: number * x, self)))
111 
112  def __str__(self):
113  """
114  Output as a string
115  """
116  return "({0},{1},{2})".format(*self.value)
117 
118  def __getitem__(self, index):
119  """
120  Access by []
121  """
122  return self.value[index]
123 
124  def __setitem__(self, index, value):
125  """
126  Access by []
127  """
128  self.value[index] = value
129 
130  def multiplyByConstant(self, constant):
131  """
132  Multiply vector by a constant value
133  """
134  return R3(tuple(map(lambda x: constant * x, self)))
135 
136  def toTuple(self):
137  return self.value
138 
139  def __array__(self):
140  return numpy.array(self.value)
141 
142 
143 class SO3(object):
144  """
145  Rotation matrix
146  """
147 
148  def __init__(self, matrix):
149  if isinstance(matrix, SO3):
150  self.value = matrix.value
151  else:
152  self.value = self.fromTuple(matrix)
153 
154  def fromTuple(self, matrix):
155  if len(matrix) != 3:
156  raise TypeError(
157  "expecting a tuple of "
158  + "3 tuples of 3 float, got a tuple of length %i." % len(matrix)
159  )
160  m = []
161  for r in matrix:
162  if len(r) != 3:
163  raise TypeError("expecting tuple of 3 float or instance of R3.")
164  m.append(R3(r[0], r[1], r[2]))
165  return tuple(m)
166 
167  def inverse(self):
168  """
169  Return the inverse of the matrix
170  """
171  return self.transpose()
172 
173  def transpose(self):
174  """
175  Return the transpose of the matrix
176  """
177  return SO3(tuple(zip(*self)))
178 
179  def __str__(self):
180  """
181  Output as a string
182  """
183  return "(%s,%s,%s)" % self.value
184 
185  def __getitem__(self, index):
186  """
187  Access by []
188  """
189  return self.value[index]
190 
191  def __mul__(self, other):
192  """
193  Operator *
194 
195  second argument is either
196  - an instance of SO3 or
197  - an instance of R3.
198  """
199  if isinstance(other, SO3):
200  return self.multiplyBySO3(other)
201  if isinstance(other, R3):
202  return self.multiplyByR3(other)
203  raise TypeError(
204  "Cannot multiply instance of SO3 by instance of " + str(type(other)) + "."
205  )
206 
207  def multiplyByR3(self, other):
208  return R3(self[0] * other, self[1] * other, self[2] * other)
209 
210  def multiplyBySO3(self, other):
211  return SO3(
212  reduce(lambda m, col: m + (tuple(self * col),), other.transpose(), ())
213  ).transpose()
214 
215 
216 class SE3(object):
217  def __init__(self, *args):
218  """
219  Constructor
220  - by rotation matrix and translation vector,
221  - by homogeneous matrix
222  - without argument: return identity matrix
223  """
224  if len(args) == 2:
225  # expecting translation and rotation
226  self.rotation = SO3(args[0])
227  self.translation = R3(args[1])
228  elif len(args) == 1:
229  # expecting homogeneous matrix
230  matrix = args[0]
231  self.rotation = SO3(tuple(map(lambda row: row[:3], matrix[:3])))
232  self.translation = R3(tuple(map(lambda row: row[3], matrix[:3])))
233  elif len(args) == 0:
234  self.rotation = SO3(
235  ((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)),
236  )
237  self.translation = R3(0.0, 0.0, 0.0)
238  else:
239  raise ValueError("two many arguments.")
240 
241  def __str__(self):
242  """
243  Output as a string
244  """
245  return "((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.,0.,0.,1.))" % (
246  self.rotation[0][0],
247  self.rotation[0][1],
248  self.rotation[0][2],
249  self.translation[0],
250  self.rotation[1][0],
251  self.rotation[1][1],
252  self.rotation[1][2],
253  self.translation[1],
254  self.rotation[2][0],
255  self.rotation[2][1],
256  self.rotation[2][2],
257  self.translation[2],
258  )
259 
260  def inverse(self):
261  trRot = self.rotation.transpose()
262  return SE3(trRot, R(-1.0) * (trRot * self.translation))
263 
264  def __mul__(self, other):
265  """
266  Operator *
267 
268  other argument is either
269  - an instance of SE3 or,
270  - an instance of R3.
271  """
272  if isinstance(other, SE3):
273  return self.multiplyBySE3(other)
274  if isinstance(other, R3):
275  return self.multiplyByR3(other)
276  raise TypeError(
277  "cannot multiply instance of SE3 by instance of " + str(type(other))
278  )
279 
280  def multiplyBySE3(self, other):
281  return SE3(
282  self.rotation * other.rotation,
283  self.rotation * other.translation + self.translation,
284  )
285 
286  def multiplyByR3(self, other):
287  return R3(self.rotation * other + self.translation)
288 
289  def __getitem__(self, index):
290  if index == 3:
291  return (0.0, 0.0, 0.0, 1.0)
292  else:
293  return tuple(self.rotation[index]) + (self.translation[index],)
294 
295  def toMatrix(self):
296  r = self.rotation
297  t = self.translation
298  return (
299  (r[0][0], r[0][1], r[0][2], t[0]),
300  (r[1][0], r[1][1], r[1][2], t[1]),
301  (r[2][0], r[2][1], r[2][2], t[2]),
302  (0.0, 0.0, 0.0, 1.0),
303  )
304 
305 
306 if __name__ == "__main__":
307  a = R(2.0)
308  u = R3(1.0, 2.0, 3.0)
309  v = R3(2.0, 3.0, 4.0)
310  print("a = " + str(a))
311  print("u = " + str(u))
312  print("v = " + str(v))
313  print("a*a = " + str(a * a))
314  print("a*u = " + str(a * u))
315  print("u*u = " + str(u * u))
316  print("u-v = " + str(u - v))
317  print("u*v = " + str(u * v))
318 
319  for i, x in zip(range(3), u):
320  print("u[%i] = %f" % (i, x))
321 
322  rot = (
323  (cos(pi / 6), -sin(pi / 6), 0.0),
324  (sin(pi / 6), cos(pi / 6), 0.0),
325  (0.0, 0.0, 1.0),
326  )
327  m1 = SO3(rot)
328  print("m1 = " + str(m1))
329  print("")
330  rot = (
331  (cos(pi / 6), 0.0, -sin(pi / 6)),
332  (0.0, 1.0, 0.0),
333  (sin(pi / 6), 0.0, cos(pi / 6)),
334  )
335 
336  m2 = SO3(rot)
337  print("m2 = " + str(m2))
338  print("")
339 
340  print("m1*m2 = " + str(m1 * m2))
341  print(
342  "should be ((%f,%f,%f),(%f,%f,%f),(%f,%f,%f))"
343  % (
344  0.75,
345  -0.5,
346  -sqrt(3) / 4,
347  sqrt(3) / 4,
348  sqrt(3) / 2,
349  -0.25,
350  0.5,
351  0.0,
352  sqrt(3) / 2,
353  )
354  )
355  print("")
356  m3 = SE3(m1 * m2, u)
357  print("m3 = " + str(m3))
358  print("")
359 
360  for i in range(4):
361  for j in range(4):
362  print("m3[%i][%i] = %f" % (i, j, m3[i][j]))
363  print("")
364 
365  m3inv = m3.inverse()
366  print("m3.inverse() = " + str(m3inv))
367  print("")
368 
369  print("m3inv * m3 = " + str(m3inv * m3))
370  print("")
371  print("m3 * m3inv = " + str(m3 * m3inv))
se3.R
Definition: se3.py:15
se3.SE3.__getitem__
def __getitem__(self, index)
Definition: se3.py:289
se3.SO3.fromTuple
def fromTuple(self, matrix)
Definition: se3.py:154
se3.SO3.__str__
def __str__(self)
Definition: se3.py:179
se3.R.__str__
def __str__(self)
Definition: se3.py:30
se3.R.value
value
Definition: se3.py:17
se3.R3.__rmul__
def __rmul__(self, number)
Definition: se3.py:106
se3.SO3.multiplyBySO3
def multiplyBySO3(self, other)
Definition: se3.py:210
se3.SO3
Definition: se3.py:143
se3.R3
Definition: se3.py:34
se3.R3.__getitem__
def __getitem__(self, index)
Definition: se3.py:118
se3.R3.__array__
def __array__(self)
Definition: se3.py:139
se3.R3.checkOther
def checkOther(self, other, operator)
Definition: se3.py:63
se3.SE3.__init__
def __init__(self, *args)
Definition: se3.py:217
se3.SO3.__getitem__
def __getitem__(self, index)
Definition: se3.py:185
se3.R.__init__
def __init__(self, value)
Definition: se3.py:16
se3.R3.value
value
Definition: se3.py:43
se3.R3.__setitem__
def __setitem__(self, index, value)
Definition: se3.py:124
se3.SE3.__str__
def __str__(self)
Definition: se3.py:241
se3.R3.check
def check(self)
Definition: se3.py:56
se3.SO3.__mul__
def __mul__(self, other)
Definition: se3.py:191
se3.SE3.rotation
rotation
Definition: se3.py:226
se3.R3.multiplyByConstant
def multiplyByConstant(self, constant)
Definition: se3.py:130
se3.R.__mul__
def __mul__(self, other)
Definition: se3.py:19
se3.SE3.__mul__
def __mul__(self, other)
Definition: se3.py:264
se3.SO3.inverse
def inverse(self)
Definition: se3.py:167
se3.R3.__mul__
def __mul__(self, other)
Definition: se3.py:99
se3.R3.__sub__
def __sub__(self, other)
Definition: se3.py:92
se3.SE3.inverse
def inverse(self)
Definition: se3.py:260
se3.SO3.__init__
def __init__(self, matrix)
Definition: se3.py:148
se3.R3.toTuple
def toTuple(self)
Definition: se3.py:136
se3.R3.crossprod
def crossprod(self, other)
Definition: se3.py:74
se3.R3.__add__
def __add__(self, other)
Definition: se3.py:85
se3.SO3.transpose
def transpose(self)
Definition: se3.py:173
se3.SE3.multiplyByR3
def multiplyByR3(self, other)
Definition: se3.py:286
se3.SO3.multiplyByR3
def multiplyByR3(self, other)
Definition: se3.py:207
se3.R3.__init__
def __init__(self, *args)
Definition: se3.py:39
se3.SE3
Definition: se3.py:216
se3.SE3.translation
translation
Definition: se3.py:227
se3.SO3.value
value
Definition: se3.py:150
se3.R3.__str__
def __str__(self)
Definition: se3.py:112
se3.SE3.toMatrix
def toMatrix(self)
Definition: se3.py:295
se3.SE3.multiplyBySE3
def multiplyBySE3(self, other)
Definition: se3.py:280


sot-tools
Author(s): Mehdi Benallegue, Francois Keith, Florent Lamiraux, Thomas Moulard, Olivier Stasse, Jorrit T'Hooft
autogenerated on Wed Aug 2 2023 02:35:13