2 GTSAM Copyright 2010-2019, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
6 See LICENSE for the license information
13 from typing
import List, Optional
19 from gtsam
import Point3, Pose3, Rot3, Similarity3, BetweenFactorSimilarity3, NonlinearFactorGraph, Values, LevenbergMarquardtOptimizer, LevenbergMarquardtParams
23 """Test selected Sim3 methods."""
26 """Test Pose3 Align method.
30 same scale (no gauge ambiguity)
31 world frame has poses rotated about x-axis (90 degree roll)
32 world and egovehicle frame translated by 15 meters w.r.t. each other
34 Rx90 = Rot3.Rx(np.deg2rad(90))
39 eTo1 =
Pose3(
Rot3(), np.array([10, 0, 0]))
40 eTo2 =
Pose3(
Rot3(), np.array([15, 0, 0]))
42 eToi_list = [eTo0, eTo1, eTo2]
46 wTo0 =
Pose3(Rx90, np.array([-10, 0, 0]))
47 wTo1 =
Pose3(Rx90, np.array([-5, 0, 0]))
48 wTo2 =
Pose3(Rx90, np.array([0, 0, 0]))
50 wToi_list = [wTo0, wTo1, wTo2]
52 we_pairs =
list(zip(wToi_list, eToi_list))
55 wSe = Similarity3.Align(we_pairs)
57 for wToi, eToi
in zip(wToi_list, eToi_list):
61 """Test if Pose3 Align method can account for gauge ambiguity.
65 with gauge ambiguity (2x scale)
66 world frame has poses rotated about z-axis (90 degree yaw)
67 world and egovehicle frame translated by 11 meters w.r.t. each other
69 Rz90 = Rot3.Rz(np.deg2rad(90))
77 eToi_list = [eTo0, eTo1, eTo2]
81 wTo0 =
Pose3(Rz90, np.array([0, 12, 0]))
82 wTo1 =
Pose3(Rz90, np.array([0, 14, 0]))
83 wTo2 =
Pose3(Rz90, np.array([0, 18, 0]))
85 wToi_list = [wTo0, wTo1, wTo2]
87 we_pairs =
list(zip(wToi_list, eToi_list))
90 wSe = Similarity3.Align(we_pairs)
92 for wToi, eToi
in zip(wToi_list, eToi_list):
96 """Test if Pose3 Align method can account for gauge ambiguity.
98 Make sure a big and small square can be aligned.
99 The u's represent a big square (10x10), and v's represents a small square (4x4).
103 with gauge ambiguity (2.5x scale)
106 R0 = Rot3.Rz(np.deg2rad(0))
107 R90 = Rot3.Rz(np.deg2rad(90))
108 R180 = Rot3.Rz(np.deg2rad(180))
109 R270 = Rot3.Rz(np.deg2rad(270))
111 aTi0 =
Pose3(R0, np.array([2, 3, 0]))
112 aTi1 =
Pose3(R90, np.array([12, 3, 0]))
113 aTi2 =
Pose3(R180, np.array([12, 13, 0]))
114 aTi3 =
Pose3(R270, np.array([2, 13, 0]))
116 aTi_list = [aTi0, aTi1, aTi2, aTi3]
118 bTi0 =
Pose3(R0, np.array([4, 3, 0]))
119 bTi1 =
Pose3(R90, np.array([8, 3, 0]))
120 bTi2 =
Pose3(R180, np.array([8, 7, 0]))
121 bTi3 =
Pose3(R270, np.array([4, 7, 0]))
123 bTi_list = [bTi0, bTi1, bTi2, bTi3]
125 ab_pairs =
list(zip(aTi_list, bTi_list))
128 aSb = Similarity3.Align(ab_pairs)
130 for aTi, bTi
in zip(aTi_list, bTi_list):
140 graph.addPriorSimilarity3(1, prior, model)
148 params.setVerbosityLM(
"TRYCONFIG")
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)
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)
173 graph.addPriorSimilarity3(1, prior, priorNoise)
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))
193 """Ensure scale estimate of Sim(3) object is non-negative.
195 Comes from real data (from Skydio-32 Crane Mast sequence with a SIFT front-end).
201 [0.696305769, -0.0106830792, -0.717665705],
202 [0.00546412488, 0.999939148, -0.00958346857],
203 [0.717724415, 0.00275160848, 0.696321772],
206 Point3(5.83077801, -0.94815149, 0.397751679),
211 [0.692272397, -0.00529704529, -0.721616549],
212 [0.00634689669, 0.999979075, -0.00125157022],
213 [0.721608079, -0.0037136016, 0.692291531],
216 Point3(5.03853323, -0.97547405, -0.348177392),
221 [0.945991981, -0.00633548292, -0.324128225],
222 [0.00450436485, 0.999969379, -0.00639931046],
223 [0.324158843, 0.00459370582, 0.945991552],
226 Point3(4.13186176, -0.956364218, -0.796029527),
231 [0.999553623, -0.00346470207, -0.0296740626],
232 [0.00346104216, 0.999993995, -0.00017469881],
233 [0.0296744897, 7.19175654e-05, 0.999559612],
236 Point3(3.1113898, -0.928583423, -0.90539337),
241 [0.967850252, -0.00144846042, 0.251522892],
242 [0.000254511591, 0.999988546, 0.00477934325],
243 [-0.251526934, -0.00456167299, 0.967839535],
246 Point3(2.10584013, -0.921303194, -0.809322971),
251 [0.969854065, 0.000629052774, 0.243685716],
252 [0.000387180179, 0.999991428, -0.00412234326],
253 [-0.243686221, 0.00409242166, 0.969845508],
256 Point3(1.0753788, -0.913035975, -0.616584091),
261 [0.998189342, 0.00110235337, 0.0601400045],
262 [-0.00110890447, 0.999999382, 7.55559042e-05],
263 [-0.060139884, -0.000142108649, 0.998189948],
266 Point3(0.029993558, -0.951495122, -0.425525143),
271 [0.999999996, -2.62868666e-05, -8.67178281e-05],
272 [2.62791334e-05, 0.999999996, -8.91767396e-05],
273 [8.67201719e-05, 8.91744604e-05, 0.999999992],
276 Point3(-0.973569417, -0.936340994, -0.253464928),
281 [0.99481227, -0.00153645011, 0.101716252],
282 [0.000916919443, 0.999980747, 0.00613725239],
283 [-0.101723724, -0.00601214847, 0.994794525],
286 Point3(-2.02071256, -0.955446292, -0.240707879),
291 [0.89795602, -0.00978591184, 0.43997636],
292 [0.00645921401, 0.999938116, 0.00905779513],
293 [-0.440037771, -0.00529159974, 0.89796366],
296 Point3(-2.94096695, -0.939974858, 0.0934225593),
301 [0.726299119, -0.00916784876, 0.687318077],
302 [0.00892018672, 0.999952563, 0.0039118575],
303 [-0.687321336, 0.00328981905, 0.726346444],
306 Point3(-3.72843416, -0.897889251, 0.685129502),
311 [0.506756029, -0.000331706105, 0.862089858],
312 [0.00613841257, 0.999975964, -0.00322354286],
313 [-0.862068067, 0.00692541035, 0.506745885],
316 Point3(-4.3909926, -0.890883291, 1.43029524),
321 [0.129316352, -0.00206958814, 0.991601896],
322 [0.00515932597, 0.999985691, 0.00141424797],
323 [-0.991590634, 0.00493310721, 0.129325179],
326 Point3(-4.58510846, -0.922534227, 2.36884523),
331 [0.599853194, -0.00890004681, -0.800060263],
332 [0.00313716318, 0.999956608, -0.00877161373],
333 [0.800103615, 0.00275175707, 0.599855085],
336 Point3(5.71559638, 0.486863076, 0.279141372),
341 [0.762552447, 0.000836438681, -0.646926069],
342 [0.00211337894, 0.999990607, 0.00378404105],
343 [0.646923157, -0.00425272942, 0.762543517],
346 Point3(5.00243443, 0.513321893, -0.466921769),
351 [0.930381645, -0.00340164355, -0.36657678],
352 [0.00425636616, 0.999989781, 0.00152338305],
353 [0.366567852, -0.00297761145, 0.930386617],
356 Point3(4.05404984, 0.493385291, -0.827904571),
361 [0.999996073, -0.00278379707, -0.000323508543],
362 [0.00278790921, 0.999905063, 0.0134941517],
363 [0.000285912831, -0.0134950006, 0.999908897],
366 Point3(3.04724478, 0.491451306, -0.989571061),
371 [0.968578343, -0.002544616, 0.248695527],
372 [0.000806130148, 0.999974526, 0.00709200332],
373 [-0.248707238, -0.0066686795, 0.968555721],
376 Point3(2.05737869, 0.46840177, -0.546344594),
381 [0.968827882, 0.000182770584, 0.247734722],
382 [-0.000558107079, 0.9999988, 0.00144484904],
383 [-0.24773416, -0.00153807255, 0.968826821],
386 Point3(1.14019947, 0.469674641, -0.0491053805),
391 [0.991647805, 0.00197867892, 0.128960146],
392 [-0.00247518407, 0.999990129, 0.00368991165],
393 [-0.128951572, -0.00397829284, 0.991642914],
396 Point3(0.150270471, 0.457867448, 0.103628642),
401 [0.992244594, 0.00477781876, -0.124208847],
402 [-0.0037682125, 0.999957938, 0.00836195891],
403 [0.124243574, -0.00782906317, 0.992220862],
406 Point3(-0.937954641, 0.440532658, 0.154265069),
411 [0.999591078, 0.00215462857, -0.0285137564],
412 [-0.00183807224, 0.999936443, 0.0111234301],
413 [0.028535911, -0.0110664711, 0.999531507],
416 Point3(-1.95622231, 0.448914367, -0.0859439782),
421 [0.931835342, 0.000956922238, 0.362880212],
422 [0.000941640753, 0.99998678, -0.00505501434],
423 [-0.362880252, 0.00505214382, 0.931822122],
426 Point3(-2.85557418, 0.434739285, 0.0793777177),
431 [0.781615218, -0.0109886966, 0.623664238],
432 [0.00516954657, 0.999924591, 0.011139446],
433 [-0.623739616, -0.00548270158, 0.781613084],
436 Point3(-3.67524552, 0.444074681, 0.583718622),
441 [0.521291761, 0.00264805046, 0.853374051],
442 [0.00659087718, 0.999952868, -0.00712898365],
443 [-0.853352707, 0.00934076542, 0.521249738],
446 Point3(-4.35541796, 0.413479707, 1.31179007),
451 [0.320164205, -0.00890839482, 0.947319884],
452 [0.00458409304, 0.999958649, 0.007854118],
453 [-0.947350678, 0.00182799903, 0.320191803],
456 Point3(-4.71617526, 0.476674479, 2.16502998),
461 [0.464861609, 0.0268597443, -0.884976415],
462 [-0.00947397841, 0.999633409, 0.0253631906],
463 [0.885333239, -0.00340614699, 0.464945663],
466 Point3(6.11772094, 1.63029238, 0.491786626),
471 [0.691647251, 0.0216006293, -0.721912024],
472 [-0.0093228132, 0.999736395, 0.020981541],
473 [0.722174939, -0.00778156302, 0.691666308],
476 Point3(5.46912979, 1.68759322, -0.288499782),
481 [0.921208931, 0.00622640471, -0.389018433],
482 [-0.00686296262, 0.999976419, -0.000246683913],
483 [0.389007724, 0.00289706631, 0.92122994],
486 Point3(4.70156942, 1.72186229, -0.806181015),
491 [0.822397705, 0.00276497594, 0.568906142],
492 [0.00804891535, 0.999831556, -0.016494662],
493 [-0.568855921, 0.0181442503, 0.822236923],
496 Point3(-3.51368714, 1.59619714, 0.437437437),
501 [0.726822937, -0.00545541524, 0.686803193],
502 [0.00913794245, 0.999956756, -0.00172754968],
503 [-0.686764068, 0.00753159111, 0.726841357],
506 Point3(-4.29737821, 1.61462527, 1.11537749),
511 [0.402595481, 0.00697612855, 0.915351441],
512 [0.0114113638, 0.999855006, -0.0126391687],
513 [-0.915306892, 0.0155338804, 0.4024575],
516 Point3(-4.6516433, 1.6323107, 1.96579585),
520 unaligned_pose_dict = {
524 [-0.681949, -0.568276, 0.460444],
525 [0.572389, -0.0227514, 0.819667],
526 [-0.455321, 0.822524, 0.34079],
529 Point3(-1.52189, 0.78906, -1.60608),
534 [-0.817805393, -0.575044816, 0.022755196],
535 [0.0478829397, -0.0285875849, 0.998443776],
536 [-0.573499401, 0.81762229, 0.0509139174],
539 Point3(-1.22653168, 0.686485651, -1.39294168),
544 [-0.783051568, -0.571905041, 0.244448085],
545 [0.314861464, -0.0255673164, 0.948793218],
546 [-0.536369743, 0.819921299, 0.200091385],
549 Point3(-1.37620079, 0.721408674, -1.49945316),
554 [-0.818916586, -0.572896131, 0.0341415873],
555 [0.0550548476, -0.0192038786, 0.99829864],
556 [-0.571265778, 0.819402974, 0.0472670839],
559 Point3(-1.06370243, 0.663084159, -1.27672831),
564 [-0.798825521, -0.571995242, 0.186277293],
565 [0.243311017, -0.0240196245, 0.969650869],
566 [-0.550161372, 0.819905178, 0.158360233],
569 Point3(-0.896250742, 0.640768239, -1.16984756),
574 [-0.786416666, -0.570215296, 0.237493882],
575 [0.305475635, -0.0248440676, 0.951875732],
576 [-0.536873788, 0.821119534, 0.193724669],
579 Point3(-0.740385043, 0.613956842, -1.05908579),
584 [-0.806252832, -0.57019757, 0.157578877],
585 [0.211046715, -0.0283979846, 0.977063375],
586 [-0.55264424, 0.821016617, 0.143234279],
589 Point3(-0.58333517, 0.549832698, -0.9542864),
594 [-0.821191354, -0.557772774, -0.120558255],
595 [-0.125347331, -0.0297958331, 0.991665395],
596 [-0.556716092, 0.829458703, -0.0454472483],
599 Point3(-0.436483039, 0.55003923, -0.850733187),
604 [-0.778607603, -0.575075476, 0.251114312],
605 [0.334920968, -0.0424301164, 0.941290407],
606 [-0.53065822, 0.816999316, 0.225641247],
609 Point3(-0.736735967, 0.571415247, -0.738663611),
614 [-0.818569806, -0.573904529, 0.0240221722],
615 [0.0512889176, -0.0313725422, 0.998190969],
616 [-0.572112681, 0.818321059, 0.0551155579],
619 Point3(-1.36150982, 0.724829031, -1.16055631),
624 [-0.812668105, -0.582027424, 0.0285417146],
625 [0.0570298244, -0.0306936169, 0.997900547],
626 [-0.579929436, 0.812589675, 0.0581366453],
629 Point3(-1.20484771, 0.762370343, -1.05057127),
634 [-0.748446406, -0.580905382, 0.319963926],
635 [0.416860654, -0.0368374152, 0.908223651],
636 [-0.515805363, 0.813137099, 0.269727429],
639 Point3(569.449421, -907.892555, -794.585647),
644 [-0.826878177, -0.559495019, -0.0569017041],
645 [-0.0452256802, -0.0346974602, 0.99837404],
646 [-0.560559647, 0.828107125, 0.00338702978],
649 Point3(-0.591431172, 0.55422253, -0.654656597),
654 [-0.785759779, -0.574532433, -0.229115805],
655 [-0.246020939, -0.049553424, 0.967996981],
656 [-0.567499134, 0.81698038, -0.102409921],
659 Point3(69.4916073, 240.595227, -493.278045),
664 [-0.783524382, -0.548569702, -0.291823276],
665 [-0.316457553, -0.051878563, 0.94718701],
666 [-0.534737468, 0.834493797, -0.132950906],
669 Point3(-5.93496204, 41.9304933, -3.06881633),
674 [-0.766833992, -0.537641809, -0.350580824],
675 [-0.389506676, -0.0443270797, 0.919956336],
676 [-0.510147213, 0.84200736, -0.175423563],
679 Point3(234.185458, 326.007989, -691.769777),
684 [-0.754844165, -0.559278755, -0.342662459],
685 [-0.375790683, -0.0594160018, 0.92479787],
686 [-0.537579435, 0.826847636, -0.165321923],
689 Point3(-5.93398168, 41.9107972, -3.07385081),
693 unaligned_pose_list = []
695 wTi = unaligned_pose_dict.get(i,
None)
696 unaligned_pose_list.append(wTi)
699 assert rSe.scale() >= 0
703 """Align by similarity transformation, but allow missing estimated poses in the input.
705 Note: this is a wrapper for align_poses_sim3() that allows for missing poses/dropped cameras.
706 This is necessary, as align_poses_sim3() requires a valid pose for every input pair.
708 We force SIM(3) alignment rather than SE(3) alignment.
709 We assume the two trajectories are of the exact same length.
712 aTi_list: reference poses in frame "a" which are the targets for alignment
713 bTi_list: input poses which need to be aligned to frame "a"
716 aSb: Similarity(3) object that aligns the two pose graphs.
718 assert len(aTi_list) ==
len(bTi_list)
721 corresponding_aTi_list = []
722 valid_camera_idxs = []
724 for i, bTi
in enumerate(bTi_list):
726 valid_camera_idxs.append(i)
727 valid_bTi_list.append(bTi)
728 corresponding_aTi_list.append(aTi_list[i])
730 aSb =
align_poses_sim3(aTi_list=corresponding_aTi_list, bTi_list=valid_bTi_list)
735 """Align two pose graphs via similarity transformation. Note: poses cannot be missing/invalid.
737 We force SIM(3) alignment rather than SE(3) alignment.
738 We assume the two trajectories are of the exact same length.
741 aTi_list: reference poses in frame "a" which are the targets for alignment
742 bTi_list: input poses which need to be aligned to frame "a"
745 aSb: Similarity(3) object that aligns the two pose graphs.
747 n_to_align =
len(aTi_list)
748 assert len(aTi_list) ==
len(bTi_list)
749 assert n_to_align >= 2,
"SIM(3) alignment uses at least 2 frames"
751 ab_pairs =
list(zip(aTi_list, bTi_list))
753 aSb = Similarity3.Align(ab_pairs)
755 if np.isnan(aSb.scale())
or aSb.scale() == 0:
761 aSb =
Similarity3(aSb.rotation(), np.zeros((3,)), 1.0)
762 aTi_list_rot_aligned = [aSb.transformFrom(bTi)
for bTi
in bTi_list]
765 aTi_centroid = np.array([aTi.translation()
for aTi
in aTi_list]).
mean(axis=0)
766 aTi_rot_aligned_centroid = np.array([aTi.translation()
for aTi
in aTi_list_rot_aligned]).
mean(axis=0)
769 aSb =
Similarity3(aSb.rotation(), aTi_centroid - aTi_rot_aligned_centroid, 1.0)
774 if __name__ ==
"__main__":