33 #include <boost/bind.hpp> 40 static boost::shared_ptr<PreintegrationParams>
Params() {
41 auto p = PreintegrationParams::MakeSharedD(
kGravity);
44 p->integrationCovariance = 0.0001 * I_3x3;
57 factor.
evaluateError(pose_i, vel_i, pose_j, vel_j, bias).head(3));
99 const double a = 0.2,
v = 50;
104 const Point3 initial_position(10, 20, 0);
105 const Vector3 initial_velocity(
v, 0, 0);
110 const double T = 3.0;
123 const double a = 0.1,
w =
M_PI / 100.0;
129 Vector3 expectedDeltaR1(
w * deltaT, 0.0, 0.0);
130 Vector3 expectedDeltaP1(0.5 * a * deltaT*deltaT, 0, 0);
131 Vector3 expectedDeltaV1(0.05, 0.0, 0.0);
149 boost::function<Vector9(const NavState&, const NavState&, const Bias&)>
f =
150 boost::bind(&PreintegrationBase::computeError, actual, _1, _2, _3,
151 boost::none, boost::none, boost::none);
158 Vector3 expectedDeltaR2(2.0 * 0.5 *
M_PI / 100.0, 0.0, 0.0);
159 Vector3 expectedDeltaP2(0.025 + expectedDeltaP1(0) + 0.5 * 0.1 * 0.5 * 0.5, 0, 0);
195 p->omegaCoriolis =
Vector3(0.02, 0.03, 0.04);
196 p->use2ndOrderCoriolis =
true;
205 Matrix expectedH = numericalDerivative11<Vector9, Bias>(
206 boost::bind(&PreintegrationBase::biasCorrectedDelta, pim, _1,
213 Matrix eH1 = numericalDerivative11<NavState, NavState>(
214 boost::bind(&PreintegrationBase::predict, pim, _1,
kZeroBias, boost::none,
217 Matrix eH2 = numericalDerivative11<NavState, Bias>(
218 boost::bind(&PreintegrationBase::predict, pim, state1, _1, boost::none,
255 expectedError << 0, 0, 0, 0, 0, 0, 0, 0, 0;
269 double diffDelta = 1
e-7;
273 Matrix H1a, H2a, H3a, H4a, H5a;
279 Matrix H1Rot3 = numericalDerivative11<Rot3, Pose3>(
280 boost::bind(&evaluateRotationError, factor, _1, v1,
x2,
v2,
kZeroBias),
284 Matrix H3Rot3 = numericalDerivative11<Rot3, Pose3>(
285 boost::bind(&evaluateRotationError, factor, x1, v1, _1,
v2,
kZeroBias),
292 expectedError << 0, 0, 0, 0, 0, 0, -0.0724744871, -0.040715657, -0.151952901;
301 Vector whitened = R * expectedError;
319 measuredOmega << 0, 0,
M_PI / 10.0 + 0.3;
334 Matrix expectedH = numericalDerivative11<Vector9, Bias>(
335 boost::bind(&PreintegrationBase::biasCorrectedDelta, pim, _1,
350 double diffDelta = 1
e-7;
365 measuredOmega << 0, 0,
M_PI / 10.0 + 0.3;
372 p->use2ndOrderCoriolis =
true;
389 double diffDelta = 1
e-7;
402 auto evaluateRotation = [=](
const Vector3 biasOmega) {
403 return Rot3::Expmap((measuredOmega - biasOmega) * deltaT);
407 Matrix expectedDelRdelBiasOmega =
408 numericalDerivative11<Rot3, Vector3>(evaluateRotation, biasOmega);
411 Rot3::ExpmapDerivative((measuredOmega - biasOmega) * deltaT);
413 Matrix3 actualdelRdelBiasOmega = -Jr *
deltaT;
427 auto evaluateLogRotation = [=](
const Vector3 deltatheta) {
433 Matrix expectedDelFdeltheta =
434 numericalDerivative11<Vector, Vector3>(evaluateLogRotation, deltatheta);
436 Matrix3 actualDelFdeltheta = Rot3::LogmapDerivative(thetahat);
456 const Matrix3 Jr = Rot3::ExpmapDerivative(
457 (measuredOmega - biasOmega) * deltaT);
459 Matrix3 delRdelBiasOmega = -Jr *
deltaT;
462 (measuredOmega - biasOmega - deltabiasOmega) * deltaT).matrix();
464 const Matrix3 hatRot =
465 Rot3::Expmap((measuredOmega - biasOmega) * deltaT).matrix();
466 const Matrix3 actualRot = hatRot
467 *
Rot3::Expmap(delRdelBiasOmega * deltabiasOmega).matrix();
498 const double T = 3.0;
515 const Vector3 accNoiseVar2(0.01, 0.02, 0.03);
516 const Vector3 omegaNoiseVar2(0.03, 0.01, 0.02);
520 Matrix3 D_correctedAcc_measuredOmega = Z_3x3;
522 boost::none, D_correctedAcc_measuredOmega, boost::none);
523 Matrix3 expectedD = numericalDerivative11<Vector3, Vector3>(
568 double diffDelta = 1
e-8;
574 gttic(PredictPositionAndVelocity);
579 measuredOmega << 0, 0, 0;
582 double deltaT = 0.001;
587 for (
int i = 0;
i < 1000; ++
i)
603 gttic(PredictRotation);
608 measuredOmega << 0, 0,
M_PI / 10;
611 double deltaT = 0.001;
616 for (
int i = 0;
i < 1000; ++
i)
630 gttic(PredictArbitrary);
637 const double T = 3.0;
654 p->integrationCovariance = Z_3x3;
661 for (
int i = 0;
i < 1000; ++
i)
672 +0.903715275, -0.250741668, 0.347026393,
673 +0.347026393, 0.903715275, -0.250741668,
674 -0.250741668, 0.347026393, 0.903715275);
676 Vector3 expectedV(-1.62337767, 1.57954409, 0.343833571);
683 gttic(bodyPSensorNoBias);
701 for (
int i = 0;
i < 1000; ++
i)
713 Vector3 expectedVelocity(0, 0, 0);
724 gttic(bodyPSensorWithBias);
729 Vector6 noiseBetweenBiasSigma;
732 SharedDiagonal biasNoiseModel = Diagonal::Sigmas(noiseBetweenBiasSigma);
745 p->accelerometerCovariance = 1
e-7 * I_3x3;
746 p->gyroscopeCovariance = 1
e-8 * I_3x3;
747 p->integrationCovariance = 1
e-9 * I_3x3;
748 double deltaT = 0.005;
751 Vector6 priorNoisePoseSigmas(
752 (
Vector(6) << 0.001, 0.001, 0.001, 0.01, 0.01, 0.01).finished());
753 Vector3 priorNoiseVelSigmas((
Vector(3) << 0.1, 0.1, 0.1).finished());
754 Vector6 priorNoiseBiasSigmas(
755 (
Vector(6) << 0.1, 0.1, 0.1, 0.5
e-1, 0.5
e-1, 0.5
e-1).finished());
756 SharedDiagonal priorNoisePose = Diagonal::Sigmas(priorNoisePoseSigmas);
757 SharedDiagonal priorNoiseVel = Diagonal::Sigmas(priorNoiseVelSigmas);
758 SharedDiagonal priorNoiseBias = Diagonal::Sigmas(priorNoiseBiasSigmas);
759 Vector3 zeroVel(0, 0, 0);
768 graph.
addPrior(
V(0), zeroVel, priorNoiseVel);
775 graph.
addPrior(
B(0), priorBias, priorNoiseBias);
776 values.
insert(
B(0), priorBias);
780 for (
int i = 1;
i < numFactors;
i++) {
783 for (
int j = 0;
j < 200; ++
j)
797 Bias biasActual = results.
at<Bias>(
B(numFactors - 1));
805 #ifdef GTSAM_TANGENT_PREINTEGRATION 806 static const double kVelocity = 2.0, kAngularVelocity =
M_PI / 6;
808 struct ImuFactorMergeTest {
809 boost::shared_ptr<PreintegrationParams> p_;
813 : p_(PreintegrationParams::MakeSharedU(
kGravity)),
815 loop_(
Vector3(0, -kAngularVelocity, 0),
Vector3(kVelocity, 0, 0)) {
817 p_->gyroscopeCovariance = I_3x3 * 0.01;
818 p_->accelerometerCovariance = I_3x3 * 0.02;
819 p_->accelerometerCovariance = I_3x3 * 0.03;
822 int TestScenario(
TestResult& result_,
const std::string& name_,
825 const Bias& bias12,
double tol) {
832 double deltaT = 0.01;
835 for (
int i = 0;
i < 100;
i++) {
847 auto actual_pim02 = ImuFactor::Merge(pim01, pim12);
849 actual_pim02.preintegrated(),
tol));
853 boost::make_shared<ImuFactor>(
X(0),
V(0),
X(1),
V(1),
B(0), pim01);
855 boost::make_shared<ImuFactor>(
X(1),
V(1),
X(2),
V(2),
B(0), pim12);
857 X(0),
V(0),
X(2),
V(2),
B(0), pim02_expected);
864 void TestScenarios(
TestResult& result_,
const std::string& name_,
866 const Bias& bias12,
double tol) {
867 for (
auto scenario : {forward_, loop_})
868 TestScenario(result_, name_, scenario, bias01, bias12, tol);
875 ImuFactorMergeTest mergeTest;
881 ImuFactorMergeTest mergeTest;
883 mergeTest.TestScenarios(result_, name_, bias, bias, 1
e-4);
888 ImuFactorMergeTest mergeTest;
889 mergeTest.TestScenarios(result_, name_,
896 ImuFactorMergeTest mergeTest;
897 mergeTest.p_->omegaCoriolis =
Vector3(0.1, 0.2, -0.1);
905 gttic(CheckCovariance);
914 expected << 1.0577e-08, 0, 0, 0, 0, 0, 0, 0, 0,
915 0, 1.0577e-08, 0, 0, 0, 0, 0, 0, 0,
916 0, 0, 1.0577e-08, 0, 0, 0, 0, 0, 0,
917 0, 0, 0, 5.00868e-05, 0, 0, 3.47222e-07, 0, 0,
918 0, 0, 0, 0, 5.00868e-05, 0, 0, 3.47222e-07, 0,
919 0, 0, 0, 0, 0, 5.00868e-05, 0, 0, 3.47222e-07,
920 0, 0, 0, 3.47222e-07, 0, 0, 1.38889e-06, 0, 0,
921 0, 0, 0, 0, 3.47222e-07, 0, 0, 1.38889e-06, 0,
922 0, 0, 0, 0, 0, 3.47222e-07, 0, 0, 1.38889e-06;
static const Bias kZeroBiasHat
const imuBias::ConstantBias & biasHat() const
void integrateMeasurement(const Vector3 &measuredAcc, const Vector3 &measuredOmega, const double dt) override
Provides additional testing facilities for common data structures.
double error(const Values &c) const override
Vector3 correctedAcc(const PreintegratedImuMeasurements &pim, const Vector3 &measuredAcc, const Vector3 &measuredOmega)
Vector unwhitenedError(const Values &x, boost::optional< std::vector< Matrix > & > H=boost::none) const override
void integrateMeasurements(const Matrix &measuredAccs, const Matrix &measuredOmegas, const Matrix &dts)
Add multiple measurements, in matrix columns.
static const Eigen::MatrixBase< Vector3 >::ConstantReturnType Z_3x1
Vector3 actualSpecificForce(double t) const
virtual const Values & optimize()
static int runAllTests(TestResult &result)
A non-templated config holding any types of Manifold-group elements.
Vector9 biasCorrectedDelta(const imuBias::ConstantBias &bias_i, OptionalJacobian< 9, 6 > H=boost::none) const override
Factor Graph consisting of non-linear factors.
void insert(Key j, const Value &val)
#define DOUBLES_EQUAL(expected, actual, threshold)
Rot2 R(Rot2::fromAngle(0.1))
Point3 unrotate(const Point3 &p, OptionalJacobian< 3, 3 > H1=boost::none, OptionalJacobian< 3, 3 > H2=boost::none) const
rotate point from world to rotated frame
Pose2_ Expmap(const Vector3_ &xi)
static const Velocity3 kVelocity(0.4, 0.5, 0.6)
internal::FixedSizeMatrix< Y, X3 >::type numericalDerivative33(boost::function< Y(const X1 &, const X2 &, const X3 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
Some functions to compute numerical derivatives.
static const Vector3 kGravityAlongNavZDown(0, 0, kGravity)
internal::FixedSizeMatrix< Y, X1 >::type numericalDerivative31(boost::function< Y(const X1 &, const X2 &, const X3 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
const Point3 & translation(OptionalJacobian< 3, 6 > Hself=boost::none) const
get translation
Evaluate derivatives of a nonlinear factor numerically.
static const Vector3 v2(Vector3(0.5, 0.0, 0.0))
Common testing infrastructure.
Vector9 computeError(const NavState &state_i, const NavState &state_j, const imuBias::ConstantBias &bias_i, OptionalJacobian< 9, 9 > H1, OptionalJacobian< 9, 9 > H2, OptionalJacobian< 9, 6 > H3) const
Calculate error given navStates.
static const NavState state1(x1, v1)
NonlinearFactorGraph graph
Matrix< SCALARB, Dynamic, Dynamic > B
PreintegratedImuMeasurements integrate(double T, const Bias &estimatedBias=Bias(), bool corrupted=false) const
Integrate measurements for T seconds into a PIM.
std::pair< Vector3, Vector3 > correctMeasurementsBySensorPose(const Vector3 &unbiasedAcc, const Vector3 &unbiasedOmega, OptionalJacobian< 3, 3 > correctedAcc_H_unbiasedAcc=boost::none, OptionalJacobian< 3, 3 > correctedAcc_H_unbiasedOmega=boost::none, OptionalJacobian< 3, 3 > correctedOmega_H_unbiasedOmega=boost::none) const
Matrix RtR(const Matrix &A)
T compose(const T &t1, const T &t2)
Point2 expectedT(-0.0446635, 0.29552)
NavState predict(const NavState &state_i, const imuBias::ConstantBias &bias_i, OptionalJacobian< 9, 9 > H1=boost::none, OptionalJacobian< 9, 6 > H2=boost::none) const
Predict state at time j.
static const Vector3 kNonZeroOmegaCoriolis(0, 0.1, 0.1)
void addPrior(Key key, const T &prior, const SharedNoiseModel &model=nullptr)
static const Bias kZeroBias
internal::FixedSizeMatrix< Y, X2 >::type numericalDerivative32(boost::function< Y(const X1 &, const X2 &, const X3 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
static const Pose3 x2(Rot3::RzRyRx(M_PI/12.0+w, M_PI/6.0, M_PI/4.0), Point3(5.5, 1.0, 0))
Vector3 deltaPij() const override
IsDerived< DERIVEDFACTOR > emplace_shared(Args &&...args)
Emplace a shared pointer to factor of given type.
Vector evaluateError(const Pose3 &pose_i, const Vector3 &vel_i, const Pose3 &pose_j, const Vector3 &vel_j, const imuBias::ConstantBias &bias_i, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none, boost::optional< Matrix & > H3=boost::none, boost::optional< Matrix & > H4=boost::none, boost::optional< Matrix & > H5=boost::none) const override
vector of errors
const ValueType at(Key j) const
Vector3 deltaVij() const override
void resetIntegrationAndSetBias(const Bias &biasHat)
static const double kAccelSigma
static const NavState state2(x2, v2)
#define EXPECT(condition)
Matrix preintMeasCov() const
Return pre-integrated measurement covariance.
Vector3 correctAccelerometer(const Vector3 &measurement, OptionalJacobian< 3, 6 > H1=boost::none, OptionalJacobian< 3, 3 > H2=boost::none) const
boost::shared_ptr< ImuFactor > shared_ptr
static const double deltaT
static const Vector3 kZero
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Matrix9 estimateCovariance(double T, size_t N=1000, const Bias &estimatedBias=Bias()) const
Compute a Monte Carlo estimate of the predict covariance using N samples.
A nonlinear optimizer that uses the Levenberg-Marquardt trust-region scheme.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
static boost::shared_ptr< PreintegratedCombinedMeasurements::Params > Params()
static const Vector3 measuredAcc
sampling from a NoiseModel
ConstantTwistScenario scenario(Z_3x1, Vector3(v, 0, 0))
Pose3 pose(double t) const override
pose at time t
Simple trajectory simulator.
noiseModel::Diagonal::shared_ptr SharedDiagonal
const Velocity3 & velocity(OptionalJacobian< 3, 9 > H=boost::none) const
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
static const Pose3 x1(Rot3::RzRyRx(M_PI/12.0, M_PI/6.0, M_PI/4.0), Point3(5.0, 1.0, 0))
static const Vector3 measuredOmega(w, 0, 0)
Vector3 actualAngularVelocity(double t) const
static const Vector3 v1(Vector3(0.5, 0.0, 0.0))
imuBias::ConstantBias Bias
Simple class to test navigation scenarios.
std::map< std::string, Array< float, 1, 8, DontAlign|RowMajor > > results
#define EXPECT_CORRECT_FACTOR_JACOBIANS(factor, values, numerical_derivative_step, tolerance)
Check the Jacobians produced by a factor against finite differences.
Rot3 deltaRij() const override
static noiseModel::Diagonal::shared_ptr Diagonal(const Matrix &covariance)
Vector3 correctGyroscope(const Vector3 &measurement, OptionalJacobian< 3, 6 > H1=boost::none, OptionalJacobian< 3, 3 > H2=boost::none) const
void update(Key j, const Value &val)
A class for computing marginals in a NonlinearFactorGraph.
static const double kGyroSigma
TEST(ImuFactor, PreintegratedMeasurementsConstruction)
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
void resetIntegration() override
Re-initialize PreintegratedIMUMeasurements.
NavState predict(const PreintegratedImuMeasurements &pim, const Bias &estimatedBias=Bias()) const
Predict predict given a PIM.
Accelerating from an arbitrary initial state, with optional rotation.
const Rot3 & rotation(OptionalJacobian< 3, 6 > Hself=boost::none) const
get rotation