testTransformBtwRobotsUnaryFactorEM.cpp
Go to the documentation of this file.
1 
8 
9 
11 #include <gtsam/geometry/Pose2.h>
12 #include <gtsam/nonlinear/Values.h>
14 
16 
20 
21 
22 using namespace std;
23 using namespace gtsam;
24 
25 /* ************************************************************************* */
28  values.insert(key, org1_T_org2);
29  return factor.whitenedError(values);
30 }
31 
32 /* ************************************************************************* */
33 //Vector predictionError_standard(const Pose2& p1, const Pose2& p2, const gtsam::Key& keyA, const gtsam::Key& keyB, const BetweenFactor<gtsam::Pose2>& factor){
34 // gtsam::Values values;
35 // values.insert(keyA, p1);
36 // values.insert(keyB, p2);
37 // // Vector err = factor.whitenedError(values);
38 // // return err;
39 // return Vector::Expmap(factor.whitenedError(values));
40 //}
41 
42 /* ************************************************************************* */
43 TEST( TransformBtwRobotsUnaryFactorEM, ConstructorAndEquals)
44 {
45  gtsam::Key key(0);
46  gtsam::Key keyA(1);
47  gtsam::Key keyB(2);
48 
49  gtsam::Pose2 p1(10.0, 15.0, 0.1);
50  gtsam::Pose2 p2(15.0, 15.0, 0.3);
51  gtsam::Pose2 noise(0.5, 0.4, 0.01);
52  gtsam::Pose2 rel_pose_ideal = p1.between(p2);
53  gtsam::Pose2 rel_pose_msr = rel_pose_ideal.compose(noise);
54 
55  SharedGaussian model_inlier(noiseModel::Diagonal::Sigmas(Vector3(0.5, 0.5, 0.05)));
56  SharedGaussian model_outlier(noiseModel::Diagonal::Sigmas(Vector3(5, 5, 1.0)));
57 
58  double prior_outlier = 0.5;
59  double prior_inlier = 0.5;
60 
61  gtsam::Values valA, valB;
62  valA.insert(keyA, p1);
63  valB.insert(keyB, p2);
64 
65  // Constructor
66  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g(key, rel_pose_msr, keyA, keyB, valA, valB,
67  model_inlier, model_outlier,prior_inlier, prior_outlier);
68  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> h(key, rel_pose_msr, keyA, keyB, valA, valB,
69  model_inlier, model_outlier,prior_inlier, prior_outlier);
70 
71  // Equals
72  CHECK(assert_equal(g, h, 1e-5));
73 }
74 
75 /* ************************************************************************* */
77 {
78  gtsam::Key key(0);
79  gtsam::Key keyA(1);
80  gtsam::Key keyB(2);
81 
82  gtsam::Pose2 orgA_T_1(10.0, 15.0, 0.1);
83  gtsam::Pose2 orgB_T_2(15.0, 15.0, 0.3);
84 
85  gtsam::Pose2 orgA_T_orgB(100.0, 45.0, 1.8);
86 
87  gtsam::Pose2 orgA_T_2 = orgA_T_orgB.compose(orgB_T_2);
88 
89  gtsam::Pose2 rel_pose_ideal = orgA_T_1.between(orgA_T_2);
90  gtsam::Pose2 rel_pose_msr = rel_pose_ideal;
91 
92  SharedGaussian model_inlier(noiseModel::Diagonal::Sigmas(Vector3(0.5, 0.5, 0.05)));
93  SharedGaussian model_outlier(noiseModel::Diagonal::Sigmas(Vector3(5, 5, 1.0)));
94 
95  double prior_outlier = 0.01;
96  double prior_inlier = 0.99;
97 
98  gtsam::Values valA, valB;
99  valA.insert(keyA, orgA_T_1);
100  valB.insert(keyB, orgB_T_2);
101 
102  // Constructor
103  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g(key, rel_pose_msr, keyA, keyB, valA, valB,
104  model_inlier, model_outlier,prior_inlier, prior_outlier);
105 
107  values.insert(key, orgA_T_orgB);
108  Vector err = g.unwhitenedError(values);
109 
110  // Equals
111  CHECK(assert_equal(err, Z_3x1, 1e-5));
112 }
113 
114 /* ************************************************************************* */
116 {
117  gtsam::Key key(0);
118  gtsam::Key keyA(1);
119  gtsam::Key keyB(2);
120 
121  gtsam::Pose2 orgA_T_currA(0.0, 0.0, 0.0);
122  gtsam::Pose2 orgB_T_currB(-10.0, 15.0, 0.1);
123 
124  gtsam::Pose2 orgA_T_orgB(0.0, 0.0, 0.0);
125 
126  gtsam::Pose2 orgA_T_currB = orgA_T_orgB.compose(orgB_T_currB);
127 
128  gtsam::Pose2 rel_pose_ideal = orgA_T_currA.between(orgA_T_currB);
129  gtsam::Pose2 rel_pose_msr = rel_pose_ideal;
130 
131  SharedGaussian model_inlier(noiseModel::Diagonal::Sigmas(Vector3(0.5, 0.5, 0.05)));
132  SharedGaussian model_outlier(noiseModel::Diagonal::Sigmas(Vector3(5, 5, 1.0)));
133 
134  double prior_outlier = 0.01;
135  double prior_inlier = 0.99;
136 
137  gtsam::Values valA, valB;
138  valA.insert(keyA, orgA_T_currA);
139  valB.insert(keyB, orgB_T_currB);
140 
141  // Constructor
142  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g(key, rel_pose_msr, keyA, keyB, valA, valB,
143  model_inlier, model_outlier,prior_inlier, prior_outlier);
144 
146  values.insert(key, orgA_T_orgB);
147  Vector err = g.unwhitenedError(values);
148 
149  // Equals
150  CHECK(assert_equal(err, Z_3x1, 1e-5));
151 }
152 
153 /* ************************************************************************* */
155 {
156  gtsam::Key key(0);
157  gtsam::Key keyA(1);
158  gtsam::Key keyB(2);
159 
160  gtsam::Pose2 orgA_T_currA(0.0, 0.0, 0.0);
161  gtsam::Pose2 orgB_T_currB(1.0, 2.0, 0.05);
162 
163  gtsam::Pose2 orgA_T_orgB_tr(10.0, -15.0, 0.0);
164  gtsam::Pose2 orgA_T_currB_tr = orgA_T_orgB_tr.compose(orgB_T_currB);
165  gtsam::Pose2 currA_T_currB_tr = orgA_T_currA.between(orgA_T_currB_tr);
166 
167  // some error in measurements
168  // gtsam::Pose2 currA_Tmsr_currB1 = currA_T_currB_tr.compose(gtsam::Pose2(0.1, 0.02, 0.01));
169  // gtsam::Pose2 currA_Tmsr_currB2 = currA_T_currB_tr.compose(gtsam::Pose2(-0.1, 0.02, 0.01));
170  // gtsam::Pose2 currA_Tmsr_currB3 = currA_T_currB_tr.compose(gtsam::Pose2(0.1, -0.02, 0.01));
171  // gtsam::Pose2 currA_Tmsr_currB4 = currA_T_currB_tr.compose(gtsam::Pose2(0.1, 0.02, -0.01));
172 
173  // ideal measurements
174  gtsam::Pose2 currA_Tmsr_currB1 = currA_T_currB_tr.compose(gtsam::Pose2(0.0, 0.0, 0.0));
175  gtsam::Pose2 currA_Tmsr_currB2 = currA_Tmsr_currB1;
176  gtsam::Pose2 currA_Tmsr_currB3 = currA_Tmsr_currB1;
177  gtsam::Pose2 currA_Tmsr_currB4 = currA_Tmsr_currB1;
178 
179  SharedGaussian model_inlier(noiseModel::Diagonal::Sigmas(Vector3(0.5, 0.5, 0.05)));
180  SharedGaussian model_outlier(noiseModel::Diagonal::Sigmas(Vector3(5, 5, 1.0)));
181 
182  double prior_outlier = 0.01;
183  double prior_inlier = 0.99;
184 
185  gtsam::Values valA, valB;
186  valA.insert(keyA, orgA_T_currA);
187  valB.insert(keyB, orgB_T_currB);
188 
189  // Constructor
190  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g1(key, currA_Tmsr_currB1, keyA, keyB, valA, valB,
191  model_inlier, model_outlier,prior_inlier, prior_outlier);
192 
193  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g2(key, currA_Tmsr_currB2, keyA, keyB, valA, valB,
194  model_inlier, model_outlier,prior_inlier, prior_outlier);
195 
196  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g3(key, currA_Tmsr_currB3, keyA, keyB, valA, valB,
197  model_inlier, model_outlier,prior_inlier, prior_outlier);
198 
199  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g4(key, currA_Tmsr_currB4, keyA, keyB, valA, valB,
200  model_inlier, model_outlier,prior_inlier, prior_outlier);
201 
203  values.insert(key, gtsam::Pose2());
204 
206  graph.push_back(g1);
207  graph.push_back(g2);
208  graph.push_back(g3);
209  graph.push_back(g4);
210 
212  gtsam::GaussNewtonOptimizer optimizer(graph, values, params);
213  gtsam::Values result = optimizer.optimize();
214 
215  gtsam::Pose2 orgA_T_orgB_opt = result.at<gtsam::Pose2>(key);
216 
217  CHECK(assert_equal(orgA_T_orgB_opt, orgA_T_orgB_tr, 1e-5));
218 }
219 
220 
221 /* ************************************************************************* */
223 {
224  gtsam::Key key(0);
225  gtsam::Key keyA(1);
226  gtsam::Key keyB(2);
227 
228  gtsam::Pose2 orgA_T_1(10.0, 15.0, 0.1);
229  gtsam::Pose2 orgB_T_2(15.0, 15.0, 0.3);
230 
231  gtsam::Pose2 orgA_T_orgB(100.0, 45.0, 1.8);
232 
233  gtsam::Pose2 orgA_T_2 = orgA_T_orgB.compose(orgB_T_2);
234 
235  gtsam::Pose2 noise(0.5, 0.4, 0.01);
236 
237  gtsam::Pose2 rel_pose_ideal = orgA_T_1.between(orgA_T_2);
238  gtsam::Pose2 rel_pose_msr = rel_pose_ideal.compose(noise);
239 
240  SharedGaussian model_inlier(noiseModel::Diagonal::Sigmas(Vector3(0.5, 0.5, 0.05)));
241  SharedGaussian model_outlier(noiseModel::Diagonal::Sigmas(Vector3(5, 5, 1.0)));
242 
243  double prior_outlier = 0.5;
244  double prior_inlier = 0.5;
245 
246  gtsam::Values valA, valB;
247  valA.insert(keyA, orgA_T_1);
248  valB.insert(keyB, orgB_T_2);
249 
250  // Constructor
251  TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> g(key, rel_pose_msr, keyA, keyB, valA, valB,
252  model_inlier, model_outlier,prior_inlier, prior_outlier);
253 
255  values.insert(key, orgA_T_orgB);
256 
257  std::vector<gtsam::Matrix> H_actual(1);
258  Vector actual_err_wh = g.whitenedError(values, H_actual);
259 
260  Matrix H1_actual = H_actual[0];
261 
262  double stepsize = 1.0e-9;
263  Matrix H1_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, _1, key, g), orgA_T_orgB, stepsize);
264 // CHECK( assert_equal(H1_expected, H1_actual, 1e-5));
265 }
267 //TEST (TransformBtwRobotsUnaryFactorEM, jacobian ) {
268 //
269 // gtsam::Key keyA(1);
270 // gtsam::Key keyB(2);
271 //
272 // // Inlier test
273 // gtsam::Pose2 p1(10.0, 15.0, 0.1);
274 // gtsam::Pose2 p2(15.0, 15.0, 0.3);
275 // gtsam::Pose2 noise(0.5, 0.4, 0.01);
276 // gtsam::Pose2 rel_pose_ideal = p1.between(p2);
277 // gtsam::Pose2 rel_pose_msr = rel_pose_ideal.compose(noise);
278 //
279 // SharedGaussian model_inlier(noiseModel::Diagonal::Sigmas(gtsam::Vector3(0.5, 0.5, 0.05)));
280 // SharedGaussian model_outlier(noiseModel::Diagonal::Sigmas(gtsam::Vector3(50.0, 50.0, 10.0)));
281 //
282 // gtsam::Values values;
283 // values.insert(keyA, p1);
284 // values.insert(keyB, p2);
285 //
286 // double prior_outlier = 0.0;
287 // double prior_inlier = 1.0;
288 //
289 // TransformBtwRobotsUnaryFactorEM<gtsam::Pose2> f(keyA, keyB, rel_pose_msr, model_inlier, model_outlier,
290 // prior_inlier, prior_outlier);
291 //
292 // std::vector<gtsam::Matrix> H_actual(2);
293 // Vector actual_err_wh = f.whitenedError(values, H_actual);
294 //
295 // Matrix H1_actual = H_actual[0];
296 // Matrix H2_actual = H_actual[1];
297 //
298 // // compare to standard between factor
299 // BetweenFactor<gtsam::Pose2> h(keyA, keyB, rel_pose_msr, model_inlier );
300 // Vector actual_err_wh_stnd = h.whitenedError(values);
301 // Vector actual_err_wh_inlier = (Vector(3) << actual_err_wh[0], actual_err_wh[1], actual_err_wh[2]);
302 // CHECK( assert_equal(actual_err_wh_stnd, actual_err_wh_inlier, 1e-8));
303 // std::vector<gtsam::Matrix> H_actual_stnd_unwh(2);
304 // (void)h.unwhitenedError(values, H_actual_stnd_unwh);
305 // Matrix H1_actual_stnd_unwh = H_actual_stnd_unwh[0];
306 // Matrix H2_actual_stnd_unwh = H_actual_stnd_unwh[1];
307 // Matrix H1_actual_stnd = model_inlier->Whiten(H1_actual_stnd_unwh);
308 // Matrix H2_actual_stnd = model_inlier->Whiten(H2_actual_stnd_unwh);
311 //
312 // double stepsize = 1.0e-9;
313 // Matrix H1_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, _1, p2, keyA, keyB, f), p1, stepsize);
314 // Matrix H2_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, p1, _1, keyA, keyB, f), p2, stepsize);
315 //
316 //
317 // // try to check numerical derivatives of a standard between factor
318 // Matrix H1_expected_stnd = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError_standard, _1, p2, keyA, keyB, h), p1, stepsize);
319 // CHECK( assert_equal(H1_expected_stnd, H1_actual_stnd, 1e-5));
320 //
321 //
322 // CHECK( assert_equal(H1_expected, H1_actual, 1e-8));
323 // CHECK( assert_equal(H2_expected, H2_actual, 1e-8));
324 //
325 //}
326 
327 /* ************************************************************************* */
328  int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
329 /* ************************************************************************* */
#define CHECK(condition)
Definition: Test.h:109
static const Eigen::MatrixBase< Vector3 >::ConstantReturnType Z_3x1
Definition: Vector.h:46
virtual const Values & optimize()
static int runAllTests(TestResult &result)
Eigen::Vector3d Vector3
Definition: Vector.h:43
A non-templated config holding any types of Manifold-group elements.
Vector3f p1
Factor Graph consisting of non-linear factors.
void insert(Key j, const Value &val)
Definition: Values.cpp:140
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:43
TEST(TransformBtwRobotsUnaryFactorEM, ConstructorAndEquals)
leaf::MyValues values
Vector whitenedError(const Values &x, boost::optional< std::vector< Matrix > & > H=boost::none) const
Definition: Half.h:150
Some functions to compute numerical derivatives.
IsDerived< DERIVEDFACTOR > push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:166
NonlinearFactorGraph graph
void g(const string &key, int i)
Definition: testBTree.cpp:43
Class compose(const Class &g) const
Definition: Lie.h:47
Eigen::VectorXd Vector
Definition: Vector.h:38
Values result
const ValueType at(Key j) const
Definition: Values-inl.h:342
Unary factor for determining transformation between given trajectories of two robots.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
static SmartStereoProjectionParams params
traits
Definition: chartTesting.h:28
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:42
const double h
Pose3 g1(Rot3(), Point3(100.0, 0.0, 300.0))
Class between(const Class &g) const
Definition: Lie.h:51
static Point3 p2
2D Pose
Pose3 g2(g1.expmap(h *V1_g1))
Base class and parameters for nonlinear optimization algorithms.
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61
Vector predictionError(const Pose2 &org1_T_org2, const gtsam::Key &key, const TransformBtwRobotsUnaryFactorEM< gtsam::Pose2 > &factor)
noiseModel::Gaussian::shared_ptr SharedGaussian
Definition: NoiseModel.h:735


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:50:02