gtsam/tests/testRot3Optimization.cpp

132 lines
4.3 KiB
C++

/* ----------------------------------------------------------------------------
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415
* All Rights Reserved
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
* See LICENSE for the license information
* -------------------------------------------------------------------------- */
/**
* @file testRot3.cpp
* @brief Unit tests for Rot3Q class
* @author Richard Roberts
*/
#include <CppUnitLite/TestHarness.h>
#include <gtsam/base/Testable.h>
#include <boost/math/constants/constants.hpp>
#include <gtsam/base/numericalDerivative.h>
#include <gtsam/base/lieProxies.h>
#include <gtsam/geometry/Point3.h>
#include <gtsam/geometry/Rot3.h>
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
#include <gtsam/nonlinear/Values.h>
#include <gtsam/nonlinear/NonlinearOptimization.h>
#include <gtsam/slam/BetweenFactor.h>
#include <gtsam/slam/PriorFactor.h>
using namespace gtsam;
typedef TypedSymbol<Rot3Q, 'r'> KeyQ;
typedef Values<KeyQ> ValuesQ;
typedef PriorFactor<ValuesQ, KeyQ> PriorQ;
typedef BetweenFactor<ValuesQ, KeyQ> BetweenQ;
typedef NonlinearFactorGraph<ValuesQ> GraphQ;
typedef TypedSymbol<Rot3M, 'r'> KeyM;
typedef Values<KeyM> ValuesM;
typedef PriorFactor<ValuesM, KeyM> PriorM;
typedef BetweenFactor<ValuesM, KeyM> BetweenM;
typedef NonlinearFactorGraph<ValuesM> GraphM;
/* ************************************************************************* */
TEST(Rot3, optimize1) {
// Compare Rot3Q and Rot3M optimization
GraphQ fgQ;
fgQ.add(PriorQ(0, Rot3Q(), sharedSigma(3, 0.01)));
fgQ.add(BetweenQ(0, 1, Rot3Q::Rz(M_PI/3.0), sharedSigma(3, 0.01)));
fgQ.add(BetweenQ(1, 0, Rot3Q::Rz(5.0*M_PI/3.0), sharedSigma(3, 0.01)));
GraphM fgM;
fgM.add(PriorM(0, Rot3M(), sharedSigma(3, 0.01)));
fgM.add(BetweenM(0, 1, Rot3M::Rz(M_PI/3.0), sharedSigma(3, 0.01)));
fgM.add(BetweenM(1, 0, Rot3M::Rz(5.0*M_PI/3.0), sharedSigma(3, 0.01)));
ValuesQ initialQ;
initialQ.insert(0, Rot3Q::Rz(0.0));
initialQ.insert(1, Rot3Q::Rz(M_PI/3.0 + 0.1));
ValuesM initialM;
initialM.insert(0, Rot3M::Rz(0.0));
initialM.insert(1, Rot3M::Rz(M_PI/3.0 + 0.1));
ValuesQ truthQ;
truthQ.insert(0, Rot3Q::Rz(0.0));
truthQ.insert(1, Rot3Q::Rz(M_PI/3.0));
ValuesM truthM;
truthM.insert(0, Rot3M::Rz(0.0));
truthM.insert(1, Rot3M::Rz(M_PI/3.0));
// Compare Matrix and Quaternion between
Matrix H1M, H2M;
Rot3M betwM = initialM[1].between(initialM[0], H1M, H2M);
Matrix H1Q, H2Q;
Rot3Q betwQ = initialM[1].between(initialM[0], H1Q, H2Q);
EXPECT(assert_equal(betwM.matrix(), betwQ.matrix()));
EXPECT(assert_equal(H1M, H1Q));
EXPECT(assert_equal(H2M, H2Q));
Point3 x1(1.0,0.0,0.0), x2(0.0,1.0,0.0);
EXPECT(assert_equal(betwM*x1, betwQ*x1));
EXPECT(assert_equal(betwM*x2, betwQ*x2));
// Compare Matrix and Quaternion logmap
Vector logM = initialM[1].localCoordinates(initialM[0]);
Vector logQ = initialQ[1].localCoordinates(initialQ[0]);
EXPECT(assert_equal(logM, logQ));
// Compare Matrix and Quaternion linear graph
Ordering ordering; ordering += KeyQ(0), KeyQ(1);
GaussianFactorGraph gfgQ(*fgQ.linearize(initialQ, ordering));
GaussianFactorGraph gfgM(*fgM.linearize(initialM, ordering));
EXPECT(assert_equal(gfgQ, gfgM, 1e-5));
NonlinearOptimizationParameters params;
//params.verbosity_ = NonlinearOptimizationParameters::TRYLAMBDA;
ValuesQ final = optimize(fgQ, initialQ, params);
EXPECT(assert_equal(truthQ, final, 1e-5));
}
/* ************************************************************************* */
TEST(Rot3, optimize) {
// Optimize a circle
ValuesQ truth;
ValuesQ initial;
GraphQ fg;
fg.add(PriorQ(0, Rot3Q(), sharedSigma(3, 0.01)));
for(int j=0; j<6; ++j) {
truth.insert(j, Rot3Q::Rz(M_PI/3.0 * double(j)));
initial.insert(j, Rot3Q::Rz(M_PI/3.0 * double(j) + 0.1 * double(j%2)));
fg.add(BetweenQ(j, (j+1)%6, Rot3Q::Rz(M_PI/3.0), sharedSigma(3, 0.01)));
}
NonlinearOptimizationParameters params;
ValuesQ final = optimize(fg, initial, params);
EXPECT(assert_equal(truth, final, 1e-5));
}
/* ************************************************************************* */
int main() {
TestResult tr;
return TestRegistry::runAllTests(tr);
}
/* ************************************************************************* */