|
16 | 16 | from gtsam.utils.test_case import GtsamTestCase |
17 | 17 |
|
18 | 18 | import gtsam |
19 | | -from gtsam import Point3, Pose3, Rot3, Similarity3 |
| 19 | +from gtsam import Point3, Pose3, Rot3, Similarity3, BetweenFactorSimilarity3, NonlinearFactorGraph, Values, LevenbergMarquardtOptimizer, LevenbergMarquardtParams |
20 | 20 |
|
21 | 21 |
|
22 | 22 | class TestSim3(GtsamTestCase): |
@@ -130,6 +130,65 @@ def test_align_poses_scaled_squares(self): |
130 | 130 | for aTi, bTi in zip(aTi_list, bTi_list): |
131 | 131 | self.gtsamAssertEquals(aTi, aSb.transformFrom(bTi)) |
132 | 132 |
|
| 133 | + def test_sim3_optimization(self)->None: |
| 134 | + # Create a PriorFactor with a Sim3 prior |
| 135 | + prior = Similarity3(Rot3.Ypr(0.1, 0.2, 0.3), Point3(1, 2, 3), 4) |
| 136 | + model = gtsam.noiseModel.Isotropic.Sigma(7, 1) |
| 137 | + |
| 138 | + # Create graph |
| 139 | + graph = NonlinearFactorGraph() |
| 140 | + graph.addPriorSimilarity3(1, prior, model) |
| 141 | + |
| 142 | + # Create initial estimate with Identity transform |
| 143 | + initial = Values() |
| 144 | + initial.insert(1, Similarity3()) |
| 145 | + |
| 146 | + # Optimize |
| 147 | + params = LevenbergMarquardtParams() |
| 148 | + params.setVerbosityLM("TRYCONFIG") |
| 149 | + result = LevenbergMarquardtOptimizer(graph, initial).optimize() |
| 150 | + |
| 151 | + # After optimization, result should be prior |
| 152 | + self.gtsamAssertEquals(prior, result.atSimilarity3(1), 1e-4) |
| 153 | + |
| 154 | + def test_sim3_optimization2(self) -> None: |
| 155 | + prior = Similarity3() |
| 156 | + m1 = Similarity3(Rot3.Ypr(np.pi / 4.0, 0, 0), Point3(2.0, 0, 0), 1.0) |
| 157 | + m2 = Similarity3(Rot3.Ypr(np.pi / 2.0, 0, 0), Point3(np.sqrt(8) * 0.9, 0, 0), 1.0) |
| 158 | + m3 = Similarity3(Rot3.Ypr(3 * np.pi / 4.0, 0, 0), Point3(np.sqrt(32) * 0.8, 0, 0), 1.0) |
| 159 | + m4 = Similarity3(Rot3.Ypr(np.pi / 2.0, 0, 0), Point3(6 * 0.7, 0, 0), 1.0) |
| 160 | + loop = Similarity3(1.42) |
| 161 | + |
| 162 | + priorNoise = gtsam.noiseModel.Isotropic.Sigma(7, 0.01) |
| 163 | + betweenNoise = gtsam.noiseModel.Diagonal.Sigmas(np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 10])) |
| 164 | + betweenNoise2 = gtsam.noiseModel.Diagonal.Sigmas(np.array([ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 1.0])) |
| 165 | + b1 = BetweenFactorSimilarity3(1, 2, m1, betweenNoise) |
| 166 | + b2 = BetweenFactorSimilarity3(2, 3, m2, betweenNoise) |
| 167 | + b3 = BetweenFactorSimilarity3(3, 4, m3, betweenNoise) |
| 168 | + b4 = BetweenFactorSimilarity3(4, 5, m4, betweenNoise) |
| 169 | + lc = BetweenFactorSimilarity3(5, 1, loop, betweenNoise2) |
| 170 | + |
| 171 | + # Create graph |
| 172 | + graph = NonlinearFactorGraph() |
| 173 | + graph.addPriorSimilarity3(1, prior, priorNoise) |
| 174 | + graph.add(b1) |
| 175 | + graph.add(b2) |
| 176 | + graph.add(b3) |
| 177 | + graph.add(b4) |
| 178 | + graph.add(lc) |
| 179 | + |
| 180 | + # graph.print("Full Graph\n"); |
| 181 | + initial=Values() |
| 182 | + initial.insert(1, prior) |
| 183 | + initial.insert(2, Similarity3(Rot3.Ypr(np.pi / 2.0, 0, 0), Point3(1, 0, 0), 1.1)) |
| 184 | + initial.insert(3, Similarity3(Rot3.Ypr(2.0 * np.pi / 2.0, 0, 0), Point3(0.9, 1.1, 0), 1.2)) |
| 185 | + initial.insert(4, Similarity3(Rot3.Ypr(3.0 * np.pi / 2.0, 0, 0), Point3(0, 1, 0), 1.3)) |
| 186 | + initial.insert(5, Similarity3(Rot3.Ypr(4.0 * np.pi / 2.0, 0, 0), Point3(0, 0, 0), 1.0)) |
| 187 | + |
| 188 | + |
| 189 | + result = LevenbergMarquardtOptimizer(graph, initial).optimizeSafely() |
| 190 | + self.gtsamAssertEquals(Similarity3(0.7), result.atSimilarity3(5), 0.4) |
| 191 | + |
133 | 192 | def test_align_via_Sim3_to_poses_skydio32(self) -> None: |
134 | 193 | """Ensure scale estimate of Sim(3) object is non-negative. |
135 | 194 |
|
|
0 commit comments