test_Sim2.py
Go to the documentation of this file.
1 """
2 GTSAM Copyright 2010-2019, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
4 All Rights Reserved
5 
6 See LICENSE for the license information
7 
8 Sim3 unit tests.
9 Author: John Lambert
10 """
11 # pylint: disable=no-name-in-module
12 import unittest
13 
14 import numpy as np
15 from gtsam.utils.test_case import GtsamTestCase
16 
17 from gtsam import Pose2, Rot2, Similarity2
18 
19 
21  """Test selected Sim2 methods."""
22 
24  """Test Align of list of Pose2Pair.
25 
26  Scenario:
27  3 object poses
28  same scale (no gauge ambiguity)
29  world frame has poses rotated about 180 degrees.
30  world and egovehicle frame translated by 15 meters w.r.t. each other
31  """
32  R180 = Rot2.fromDegrees(180)
33 
34  # Create source poses (three objects o1, o2, o3 living in the egovehicle "e" frame)
35  # Suppose they are 3d cuboids detected by an onboard sensor in the egovehicle frame
36  eTo0 = Pose2(Rot2(), np.array([5, 0]))
37  eTo1 = Pose2(Rot2(), np.array([10, 0]))
38  eTo2 = Pose2(Rot2(), np.array([15, 0]))
39 
40  eToi_list = [eTo0, eTo1, eTo2]
41 
42  # Create destination poses
43  # (same three objects, but instead living in the world "w" frame)
44  wTo0 = Pose2(R180, np.array([-10, 0]))
45  wTo1 = Pose2(R180, np.array([-5, 0]))
46  wTo2 = Pose2(R180, np.array([0, 0]))
47 
48  wToi_list = [wTo0, wTo1, wTo2]
49 
50  we_pairs = list(zip(wToi_list, eToi_list))
51 
52  # Recover the transformation wSe (i.e. world_S_egovehicle)
53  wSe = Similarity2.Align(we_pairs)
54 
55  for wToi, eToi in zip(wToi_list, eToi_list):
56  self.gtsamAssertEquals(wToi, wSe.transformFrom(eToi))
57 
59  """Test if Pose2 Align method can account for gauge ambiguity.
60 
61  Scenario:
62  3 object poses
63  with gauge ambiguity (2x scale)
64  world frame has poses rotated by 90 degrees.
65  world and egovehicle frame translated by 11 meters w.r.t. each other
66  """
67  R90 = Rot2.fromDegrees(90)
68 
69  # Create source poses (three objects o1, o2, o3 living in the egovehicle "e" frame)
70  # Suppose they are 3d cuboids detected by an onboard sensor in the egovehicle frame
71  eTo0 = Pose2(Rot2(), np.array([1, 0]))
72  eTo1 = Pose2(Rot2(), np.array([2, 0]))
73  eTo2 = Pose2(Rot2(), np.array([4, 0]))
74 
75  eToi_list = [eTo0, eTo1, eTo2]
76 
77  # Create destination poses
78  # (same three objects, but instead living in the world/city "w" frame)
79  wTo0 = Pose2(R90, np.array([0, 12]))
80  wTo1 = Pose2(R90, np.array([0, 14]))
81  wTo2 = Pose2(R90, np.array([0, 18]))
82 
83  wToi_list = [wTo0, wTo1, wTo2]
84 
85  we_pairs = list(zip(wToi_list, eToi_list))
86 
87  # Recover the transformation wSe (i.e. world_S_egovehicle)
88  wSe = Similarity2.Align(we_pairs)
89 
90  for wToi, eToi in zip(wToi_list, eToi_list):
91  self.gtsamAssertEquals(wToi, wSe.transformFrom(eToi))
92 
94  """Test if Align method can account for gauge ambiguity.
95 
96  Make sure a big and small square can be aligned.
97  The u's represent a big square (10x10), and v's represents a small square (4x4).
98 
99  Scenario:
100  4 object poses
101  with gauge ambiguity (2.5x scale)
102  """
103  # 0, 90, 180, and 270 degrees yaw
104  R0 = Rot2.fromDegrees(0)
105  R90 = Rot2.fromDegrees(90)
106  R180 = Rot2.fromDegrees(180)
107  R270 = Rot2.fromDegrees(270)
108 
109  aTi0 = Pose2(R0, np.array([2, 3]))
110  aTi1 = Pose2(R90, np.array([12, 3]))
111  aTi2 = Pose2(R180, np.array([12, 13]))
112  aTi3 = Pose2(R270, np.array([2, 13]))
113 
114  aTi_list = [aTi0, aTi1, aTi2, aTi3]
115 
116  bTi0 = Pose2(R0, np.array([4, 3]))
117  bTi1 = Pose2(R90, np.array([8, 3]))
118  bTi2 = Pose2(R180, np.array([8, 7]))
119  bTi3 = Pose2(R270, np.array([4, 7]))
120 
121  bTi_list = [bTi0, bTi1, bTi2, bTi3]
122 
123  ab_pairs = list(zip(aTi_list, bTi_list))
124 
125  # Recover the transformation wSe (i.e. world_S_egovehicle)
126  aSb = Similarity2.Align(ab_pairs)
127 
128  for aTi, bTi in zip(aTi_list, bTi_list):
129  self.gtsamAssertEquals(aTi, aSb.transformFrom(bTi))
130 
131  def test_constructor(self) -> None:
132  """Sim(2) to perform p_b = bSa * p_a"""
133  bRa = Rot2()
134  bta = np.array([1, 2])
135  bsa = 3.0
136  bSa = Similarity2(R=bRa, t=bta, s=bsa)
137  self.assertIsInstance(bSa, Similarity2)
138  np.testing.assert_allclose(bSa.rotation().matrix(), bRa.matrix())
139  np.testing.assert_allclose(bSa.translation(), bta)
140  np.testing.assert_allclose(bSa.scale(), bsa)
141 
142  def test_is_eq(self) -> None:
143  """Ensure object equality works properly (are equal)."""
144  bSa = Similarity2(R=Rot2(), t=np.array([1, 2]), s=3.0)
145  bSa_ = Similarity2(R=Rot2(), t=np.array([1.0, 2.0]), s=3)
146  self.gtsamAssertEquals(bSa, bSa_)
147 
148  def test_not_eq_translation(self) -> None:
149  """Ensure object equality works properly (not equal translation)."""
150  bSa = Similarity2(R=Rot2(), t=np.array([2, 1]), s=3.0)
151  bSa_ = Similarity2(R=Rot2(), t=np.array([1.0, 2.0]), s=3)
152  self.assertNotEqual(bSa, bSa_)
153 
154  def test_not_eq_rotation(self) -> None:
155  """Ensure object equality works properly (not equal rotation)."""
156  bSa = Similarity2(R=Rot2(), t=np.array([2, 1]), s=3.0)
157  bSa_ = Similarity2(R=Rot2.fromDegrees(180), t=np.array([2.0, 1.0]), s=3)
158  self.assertNotEqual(bSa, bSa_)
159 
160  def test_not_eq_scale(self) -> None:
161  """Ensure object equality works properly (not equal scale)."""
162  bSa = Similarity2(R=Rot2(), t=np.array([2, 1]), s=3.0)
163  bSa_ = Similarity2(R=Rot2(), t=np.array([2.0, 1.0]), s=1.0)
164  self.assertNotEqual(bSa, bSa_)
165 
166  def test_rotation(self) -> None:
167  """Ensure rotation component is returned properly."""
168  R = Rot2.fromDegrees(90)
169  t = np.array([1, 2])
170  bSa = Similarity2(R=R, t=t, s=3.0)
171 
172  # evaluates to [[0, -1], [1, 0]]
173  expected_R = Rot2.fromDegrees(90)
174  np.testing.assert_allclose(expected_R.matrix(), bSa.rotation().matrix())
175 
176  def test_translation(self) -> None:
177  """Ensure translation component is returned properly."""
178  R = Rot2.fromDegrees(90)
179  t = np.array([1, 2])
180  bSa = Similarity2(R=R, t=t, s=3.0)
181 
182  expected_t = np.array([1, 2])
183  np.testing.assert_allclose(expected_t, bSa.translation())
184 
185  def test_scale(self) -> None:
186  """Ensure the scale factor is returned properly."""
187  bRa = Rot2()
188  bta = np.array([1, 2])
189  bsa = 3.0
190  bSa = Similarity2(R=bRa, t=bta, s=bsa)
191  self.assertEqual(bSa.scale(), 3.0)
192 
193 
194 if __name__ == "__main__":
195  unittest.main()
def test_translation(self)
Definition: test_Sim2.py:176
def gtsamAssertEquals(self, actual, expected, tol=1e-9)
Definition: test_case.py:18
def test_scale(self)
Definition: test_Sim2.py:185
def test_not_eq_translation(self)
Definition: test_Sim2.py:148
def test_is_eq(self)
Definition: test_Sim2.py:142
def test_not_eq_rotation(self)
Definition: test_Sim2.py:154
def test_align_poses_along_straight_line(self)
Definition: test_Sim2.py:23
def test_rotation(self)
Definition: test_Sim2.py:166
def test_align_poses_scaled_squares(self)
Definition: test_Sim2.py:93
def test_not_eq_scale(self)
Definition: test_Sim2.py:160
Definition: pytypes.h:1979
def test_constructor(self)
Definition: test_Sim2.py:131
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
def test_align_poses_along_straight_line_gauge(self)
Definition: test_Sim2.py:58


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:37:46