Most of LieXXX is gone, greatly simplifies code. All tests pass.
Merge remote-tracking branch 'origin/feature/BAD_noLieXX' into feature/BADrelease/4.3a0
commit
7d57d91fec
20
.cproject
20
.cproject
|
@ -736,14 +736,6 @@
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
<runAllBuilders>true</runAllBuilders>
|
<runAllBuilders>true</runAllBuilders>
|
||||||
</target>
|
</target>
|
||||||
<target name="testImuFactor.run" path="build/gtsam_unstable/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
|
||||||
<buildCommand>make</buildCommand>
|
|
||||||
<buildArguments>-j5</buildArguments>
|
|
||||||
<buildTarget>testImuFactor.run</buildTarget>
|
|
||||||
<stopOnError>true</stopOnError>
|
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
|
||||||
<runAllBuilders>true</runAllBuilders>
|
|
||||||
</target>
|
|
||||||
<target name="testInvDepthFactor3.run" path="build/gtsam_unstable/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="testInvDepthFactor3.run" path="build/gtsam_unstable/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments>-j5</buildArguments>
|
<buildArguments>-j5</buildArguments>
|
||||||
|
@ -2265,6 +2257,14 @@
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
<runAllBuilders>true</runAllBuilders>
|
<runAllBuilders>true</runAllBuilders>
|
||||||
</target>
|
</target>
|
||||||
|
<target name="testVelocityConstraint3.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments>-j5</buildArguments>
|
||||||
|
<buildTarget>testVelocityConstraint3.run</buildTarget>
|
||||||
|
<stopOnError>true</stopOnError>
|
||||||
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
|
<runAllBuilders>true</runAllBuilders>
|
||||||
|
</target>
|
||||||
<target name="testDiscreteBayesTree.run" path="build/gtsam/discrete/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="testDiscreteBayesTree.run" path="build/gtsam/discrete/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments>-j1</buildArguments>
|
<buildArguments>-j1</buildArguments>
|
||||||
|
@ -2766,10 +2766,10 @@
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
<runAllBuilders>true</runAllBuilders>
|
<runAllBuilders>true</runAllBuilders>
|
||||||
</target>
|
</target>
|
||||||
<target name="testBetweenFactor.run" path="build/gtsam/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="testPriorFactor.run" path="build/gtsam/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments>-j5</buildArguments>
|
<buildArguments>-j5</buildArguments>
|
||||||
<buildTarget>testBetweenFactor.run</buildTarget>
|
<buildTarget>testPriorFactor.run</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
<runAllBuilders>true</runAllBuilders>
|
<runAllBuilders>true</runAllBuilders>
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include <gtsam/geometry/Point3.h>
|
#include <gtsam/geometry/Point3.h>
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
|
||||||
|
@ -90,8 +89,8 @@ TEST (Point3, normalize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
LieScalar norm_proxy(const Point3& point) {
|
double norm_proxy(const Point3& point) {
|
||||||
return LieScalar(point.norm());
|
return double(point.norm());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (Point3, norm) {
|
TEST (Point3, norm) {
|
||||||
|
@ -99,7 +98,7 @@ TEST (Point3, norm) {
|
||||||
Point3 point(3,4,5); // arbitrary point
|
Point3 point(3,4,5); // arbitrary point
|
||||||
double expected = sqrt(50);
|
double expected = sqrt(50);
|
||||||
EXPECT_DOUBLES_EQUAL(expected, point.norm(actualH), 1e-8);
|
EXPECT_DOUBLES_EQUAL(expected, point.norm(actualH), 1e-8);
|
||||||
Matrix expectedH = numericalDerivative11<LieScalar, Point3>(norm_proxy, point);
|
Matrix expectedH = numericalDerivative11<double, Point3>(norm_proxy, point);
|
||||||
EXPECT(assert_equal(expectedH, actualH, 1e-8));
|
EXPECT(assert_equal(expectedH, actualH, 1e-8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,8 +276,8 @@ TEST(HessianFactor, CombineAndEliminate)
|
||||||
1.0, 0.0, 0.0,
|
1.0, 0.0, 0.0,
|
||||||
0.0, 1.0, 0.0,
|
0.0, 1.0, 0.0,
|
||||||
0.0, 0.0, 1.0);
|
0.0, 0.0, 1.0);
|
||||||
Vector b0 = (Vector(3) << 1.5, 1.5, 1.5);
|
Vector3 b0(1.5, 1.5, 1.5);
|
||||||
Vector s0 = (Vector(3) << 1.6, 1.6, 1.6);
|
Vector3 s0(1.6, 1.6, 1.6);
|
||||||
|
|
||||||
Matrix A10 = (Matrix(3,3) <<
|
Matrix A10 = (Matrix(3,3) <<
|
||||||
2.0, 0.0, 0.0,
|
2.0, 0.0, 0.0,
|
||||||
|
@ -287,15 +287,15 @@ TEST(HessianFactor, CombineAndEliminate)
|
||||||
-2.0, 0.0, 0.0,
|
-2.0, 0.0, 0.0,
|
||||||
0.0, -2.0, 0.0,
|
0.0, -2.0, 0.0,
|
||||||
0.0, 0.0, -2.0);
|
0.0, 0.0, -2.0);
|
||||||
Vector b1 = (Vector(3) << 2.5, 2.5, 2.5);
|
Vector3 b1(2.5, 2.5, 2.5);
|
||||||
Vector s1 = (Vector(3) << 2.6, 2.6, 2.6);
|
Vector3 s1(2.6, 2.6, 2.6);
|
||||||
|
|
||||||
Matrix A21 = (Matrix(3,3) <<
|
Matrix A21 = (Matrix(3,3) <<
|
||||||
3.0, 0.0, 0.0,
|
3.0, 0.0, 0.0,
|
||||||
0.0, 3.0, 0.0,
|
0.0, 3.0, 0.0,
|
||||||
0.0, 0.0, 3.0);
|
0.0, 0.0, 3.0);
|
||||||
Vector b2 = (Vector(3) << 3.5, 3.5, 3.5);
|
Vector3 b2(3.5, 3.5, 3.5);
|
||||||
Vector s2 = (Vector(3) << 3.6, 3.6, 3.6);
|
Vector3 s2(3.6, 3.6, 3.6);
|
||||||
|
|
||||||
GaussianFactorGraph gfg;
|
GaussianFactorGraph gfg;
|
||||||
gfg.add(1, A01, b0, noiseModel::Diagonal::Sigmas(s0, true));
|
gfg.add(1, A01, b0, noiseModel::Diagonal::Sigmas(s0, true));
|
||||||
|
@ -305,8 +305,8 @@ TEST(HessianFactor, CombineAndEliminate)
|
||||||
Matrix zero3x3 = zeros(3,3);
|
Matrix zero3x3 = zeros(3,3);
|
||||||
Matrix A0 = gtsam::stack(3, &A10, &zero3x3, &zero3x3);
|
Matrix A0 = gtsam::stack(3, &A10, &zero3x3, &zero3x3);
|
||||||
Matrix A1 = gtsam::stack(3, &A11, &A01, &A21);
|
Matrix A1 = gtsam::stack(3, &A11, &A01, &A21);
|
||||||
Vector b = gtsam::concatVectors(3, &b1, &b0, &b2);
|
Vector9 b; b << b1, b0, b2;
|
||||||
Vector sigmas = gtsam::concatVectors(3, &s1, &s0, &s2);
|
Vector9 sigmas; sigmas << s1, s0, s2;
|
||||||
|
|
||||||
// create a full, uneliminated version of the factor
|
// create a full, uneliminated version of the factor
|
||||||
JacobianFactor expectedFactor(0, A0, 1, A1, b, noiseModel::Diagonal::Sigmas(sigmas, true));
|
JacobianFactor expectedFactor(0, A0, 1, A1, b, noiseModel::Diagonal::Sigmas(sigmas, true));
|
||||||
|
|
|
@ -369,8 +369,8 @@ TEST(JacobianFactor, eliminate)
|
||||||
1.0, 0.0, 0.0,
|
1.0, 0.0, 0.0,
|
||||||
0.0, 1.0, 0.0,
|
0.0, 1.0, 0.0,
|
||||||
0.0, 0.0, 1.0);
|
0.0, 0.0, 1.0);
|
||||||
Vector b0 = (Vector(3) << 1.5, 1.5, 1.5);
|
Vector3 b0(1.5, 1.5, 1.5);
|
||||||
Vector s0 = (Vector(3) << 1.6, 1.6, 1.6);
|
Vector3 s0(1.6, 1.6, 1.6);
|
||||||
|
|
||||||
Matrix A10 = (Matrix(3, 3) <<
|
Matrix A10 = (Matrix(3, 3) <<
|
||||||
2.0, 0.0, 0.0,
|
2.0, 0.0, 0.0,
|
||||||
|
@ -380,15 +380,15 @@ TEST(JacobianFactor, eliminate)
|
||||||
-2.0, 0.0, 0.0,
|
-2.0, 0.0, 0.0,
|
||||||
0.0, -2.0, 0.0,
|
0.0, -2.0, 0.0,
|
||||||
0.0, 0.0, -2.0);
|
0.0, 0.0, -2.0);
|
||||||
Vector b1 = (Vector(3) << 2.5, 2.5, 2.5);
|
Vector3 b1(2.5, 2.5, 2.5);
|
||||||
Vector s1 = (Vector(3) << 2.6, 2.6, 2.6);
|
Vector3 s1(2.6, 2.6, 2.6);
|
||||||
|
|
||||||
Matrix A21 = (Matrix(3, 3) <<
|
Matrix A21 = (Matrix(3, 3) <<
|
||||||
3.0, 0.0, 0.0,
|
3.0, 0.0, 0.0,
|
||||||
0.0, 3.0, 0.0,
|
0.0, 3.0, 0.0,
|
||||||
0.0, 0.0, 3.0);
|
0.0, 0.0, 3.0);
|
||||||
Vector b2 = (Vector(3) << 3.5, 3.5, 3.5);
|
Vector3 b2(3.5, 3.5, 3.5);
|
||||||
Vector s2 = (Vector(3) << 3.6, 3.6, 3.6);
|
Vector3 s2(3.6, 3.6, 3.6);
|
||||||
|
|
||||||
GaussianFactorGraph gfg;
|
GaussianFactorGraph gfg;
|
||||||
gfg.add(1, A01, b0, noiseModel::Diagonal::Sigmas(s0, true));
|
gfg.add(1, A01, b0, noiseModel::Diagonal::Sigmas(s0, true));
|
||||||
|
@ -398,8 +398,8 @@ TEST(JacobianFactor, eliminate)
|
||||||
Matrix zero3x3 = zeros(3,3);
|
Matrix zero3x3 = zeros(3,3);
|
||||||
Matrix A0 = gtsam::stack(3, &A10, &zero3x3, &zero3x3);
|
Matrix A0 = gtsam::stack(3, &A10, &zero3x3, &zero3x3);
|
||||||
Matrix A1 = gtsam::stack(3, &A11, &A01, &A21);
|
Matrix A1 = gtsam::stack(3, &A11, &A01, &A21);
|
||||||
Vector b = gtsam::concatVectors(3, &b1, &b0, &b2);
|
Vector9 b; b << b1, b0, b2;
|
||||||
Vector sigmas = gtsam::concatVectors(3, &s1, &s0, &s2);
|
Vector9 sigmas; sigmas << s1, s0, s2;
|
||||||
|
|
||||||
JacobianFactor combinedFactor(0, A0, 1, A1, b, noiseModel::Diagonal::Sigmas(sigmas, true));
|
JacobianFactor combinedFactor(0, A0, 1, A1, b, noiseModel::Diagonal::Sigmas(sigmas, true));
|
||||||
GaussianFactorGraph::EliminationResult expected = combinedFactor.eliminate(list_of(0));
|
GaussianFactorGraph::EliminationResult expected = combinedFactor.eliminate(list_of(0));
|
||||||
|
|
|
@ -17,11 +17,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* GTSAM includes */
|
/* GTSAM includes */
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
|
||||||
#include <gtsam/linear/GaussianFactor.h>
|
|
||||||
#include <gtsam/navigation/ImuBias.h>
|
#include <gtsam/navigation/ImuBias.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
|
#include <gtsam/linear/GaussianFactor.h>
|
||||||
#include <gtsam/base/debug.h>
|
#include <gtsam/base/debug.h>
|
||||||
|
|
||||||
/* External or standard includes */
|
/* External or standard includes */
|
||||||
|
@ -46,7 +45,7 @@ namespace gtsam {
|
||||||
* [3] L. Carlone, S. Williams, R. Roberts, "Preintegrated IMU factor: Computation of the Jacobian Matrices", Tech. Report, 2013.
|
* [3] L. Carlone, S. Williams, R. Roberts, "Preintegrated IMU factor: Computation of the Jacobian Matrices", Tech. Report, 2013.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CombinedImuFactor: public NoiseModelFactor6<Pose3,LieVector,Pose3,LieVector,imuBias::ConstantBias,imuBias::ConstantBias> {
|
class CombinedImuFactor: public NoiseModelFactor6<Pose3,Vector3,Pose3,Vector3,imuBias::ConstantBias,imuBias::ConstantBias> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -214,7 +213,7 @@ namespace gtsam {
|
||||||
Matrix3 H_vel_vel = I_3x3;
|
Matrix3 H_vel_vel = I_3x3;
|
||||||
Matrix3 H_vel_angles = - deltaRij.matrix() * skewSymmetric(correctedAcc) * Jr_theta_i * deltaT;
|
Matrix3 H_vel_angles = - deltaRij.matrix() * skewSymmetric(correctedAcc) * Jr_theta_i * deltaT;
|
||||||
// analytic expression corresponding to the following numerical derivative
|
// analytic expression corresponding to the following numerical derivative
|
||||||
// Matrix H_vel_angles = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_vel, correctedOmega, correctedAcc, deltaT, _1, deltaVij), theta_i);
|
// Matrix H_vel_angles = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_vel, correctedOmega, correctedAcc, deltaT, _1, deltaVij), theta_i);
|
||||||
Matrix3 H_vel_biasacc = - deltaRij.matrix() * deltaT;
|
Matrix3 H_vel_biasacc = - deltaRij.matrix() * deltaT;
|
||||||
|
|
||||||
Matrix3 H_angles_pos = Z_3x3;
|
Matrix3 H_angles_pos = Z_3x3;
|
||||||
|
@ -222,7 +221,7 @@ namespace gtsam {
|
||||||
Matrix3 H_angles_angles = Jrinv_theta_j * Rincr.inverse().matrix() * Jr_theta_i;
|
Matrix3 H_angles_angles = Jrinv_theta_j * Rincr.inverse().matrix() * Jr_theta_i;
|
||||||
Matrix3 H_angles_biasomega =- Jrinv_theta_j * Jr_theta_incr * deltaT;
|
Matrix3 H_angles_biasomega =- Jrinv_theta_j * Jr_theta_incr * deltaT;
|
||||||
// analytic expression corresponding to the following numerical derivative
|
// analytic expression corresponding to the following numerical derivative
|
||||||
// Matrix H_angles_angles = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_angles, correctedOmega, deltaT, _1), thetaij);
|
// Matrix H_angles_angles = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_angles, correctedOmega, deltaT, _1), thetaij);
|
||||||
|
|
||||||
// overall Jacobian wrt preintegrated measurements (df/dx)
|
// overall Jacobian wrt preintegrated measurements (df/dx)
|
||||||
Matrix F(15,15);
|
Matrix F(15,15);
|
||||||
|
@ -322,7 +321,7 @@ namespace gtsam {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef CombinedImuFactor This;
|
typedef CombinedImuFactor This;
|
||||||
typedef NoiseModelFactor6<Pose3,LieVector,Pose3,LieVector,imuBias::ConstantBias,imuBias::ConstantBias> Base;
|
typedef NoiseModelFactor6<Pose3,Vector3,Pose3,Vector3,imuBias::ConstantBias,imuBias::ConstantBias> Base;
|
||||||
|
|
||||||
CombinedPreintegratedMeasurements preintegratedMeasurements_;
|
CombinedPreintegratedMeasurements preintegratedMeasurements_;
|
||||||
Vector3 gravity_;
|
Vector3 gravity_;
|
||||||
|
@ -412,7 +411,7 @@ namespace gtsam {
|
||||||
/** implement functions needed to derive from Factor */
|
/** implement functions needed to derive from Factor */
|
||||||
|
|
||||||
/** vector of errors */
|
/** vector of errors */
|
||||||
Vector evaluateError(const Pose3& pose_i, const LieVector& vel_i, const Pose3& pose_j, const LieVector& vel_j,
|
Vector evaluateError(const Pose3& pose_i, const Vector3& vel_i, const Pose3& pose_j, const Vector3& vel_j,
|
||||||
const imuBias::ConstantBias& bias_i, const imuBias::ConstantBias& bias_j,
|
const imuBias::ConstantBias& bias_i, const imuBias::ConstantBias& bias_j,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
|
@ -626,7 +625,7 @@ namespace gtsam {
|
||||||
|
|
||||||
|
|
||||||
/** predicted states from IMU */
|
/** predicted states from IMU */
|
||||||
static void Predict(const Pose3& pose_i, const LieVector& vel_i, Pose3& pose_j, LieVector& vel_j,
|
static void Predict(const Pose3& pose_i, const Vector3& vel_i, Pose3& pose_j, Vector3& vel_j,
|
||||||
const imuBias::ConstantBias& bias_i, imuBias::ConstantBias& bias_j,
|
const imuBias::ConstantBias& bias_i, imuBias::ConstantBias& bias_j,
|
||||||
const CombinedPreintegratedMeasurements& preintegratedMeasurements,
|
const CombinedPreintegratedMeasurements& preintegratedMeasurements,
|
||||||
const Vector3& gravity, const Vector3& omegaCoriolis, boost::optional<const Pose3&> body_P_sensor = boost::none,
|
const Vector3& gravity, const Vector3& omegaCoriolis, boost::optional<const Pose3&> body_P_sensor = boost::none,
|
||||||
|
@ -649,7 +648,7 @@ namespace gtsam {
|
||||||
- skewSymmetric(omegaCoriolis) * vel_i * deltaTij*deltaTij // Coriolis term - we got rid of the 2 wrt ins paper
|
- skewSymmetric(omegaCoriolis) * vel_i * deltaTij*deltaTij // Coriolis term - we got rid of the 2 wrt ins paper
|
||||||
+ 0.5 * gravity * deltaTij*deltaTij;
|
+ 0.5 * gravity * deltaTij*deltaTij;
|
||||||
|
|
||||||
vel_j = LieVector(vel_i + Rot_i.matrix() * (preintegratedMeasurements.deltaVij
|
vel_j = Vector3(vel_i + Rot_i.matrix() * (preintegratedMeasurements.deltaVij
|
||||||
+ preintegratedMeasurements.delVdelBiasAcc * biasAccIncr
|
+ preintegratedMeasurements.delVdelBiasAcc * biasAccIncr
|
||||||
+ preintegratedMeasurements.delVdelBiasOmega * biasOmegaIncr)
|
+ preintegratedMeasurements.delVdelBiasOmega * biasOmegaIncr)
|
||||||
- 2 * skewSymmetric(omegaCoriolis) * vel_i * deltaTij // Coriolis term
|
- 2 * skewSymmetric(omegaCoriolis) * vel_i * deltaTij // Coriolis term
|
||||||
|
|
|
@ -144,7 +144,7 @@ namespace imuBias {
|
||||||
/// return dimensionality of tangent space
|
/// return dimensionality of tangent space
|
||||||
inline size_t dim() const { return dimension; }
|
inline size_t dim() const { return dimension; }
|
||||||
|
|
||||||
/** Update the LieVector with a tangent space update */
|
/** Update the bias with a tangent space update */
|
||||||
inline ConstantBias retract(const Vector& v) const { return ConstantBias(biasAcc_ + v.head(3), biasGyro_ + v.tail(3)); }
|
inline ConstantBias retract(const Vector& v) const { return ConstantBias(biasAcc_ + v.head(3), biasGyro_ + v.tail(3)); }
|
||||||
|
|
||||||
/** @return the local coordinates of another object */
|
/** @return the local coordinates of another object */
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtsam/linear/GaussianFactor.h>
|
#include <gtsam/linear/GaussianFactor.h>
|
||||||
#include <gtsam/navigation/ImuBias.h>
|
#include <gtsam/navigation/ImuBias.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/debug.h>
|
#include <gtsam/base/debug.h>
|
||||||
|
|
||||||
/* External or standard includes */
|
/* External or standard includes */
|
||||||
|
@ -46,7 +45,7 @@ namespace gtsam {
|
||||||
* [3] L. Carlone, S. Williams, R. Roberts, "Preintegrated IMU factor: Computation of the Jacobian Matrices", Tech. Report, 2013.
|
* [3] L. Carlone, S. Williams, R. Roberts, "Preintegrated IMU factor: Computation of the Jacobian Matrices", Tech. Report, 2013.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ImuFactor: public NoiseModelFactor5<Pose3,LieVector,Pose3,LieVector,imuBias::ConstantBias> {
|
class ImuFactor: public NoiseModelFactor5<Pose3,Vector3,Pose3,Vector3,imuBias::ConstantBias> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -203,13 +202,13 @@ namespace gtsam {
|
||||||
Matrix H_vel_vel = I_3x3;
|
Matrix H_vel_vel = I_3x3;
|
||||||
Matrix H_vel_angles = - deltaRij.matrix() * skewSymmetric(correctedAcc) * Jr_theta_i * deltaT;
|
Matrix H_vel_angles = - deltaRij.matrix() * skewSymmetric(correctedAcc) * Jr_theta_i * deltaT;
|
||||||
// analytic expression corresponding to the following numerical derivative
|
// analytic expression corresponding to the following numerical derivative
|
||||||
// Matrix H_vel_angles = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_vel, correctedOmega, correctedAcc, deltaT, _1, deltaVij), theta_i);
|
// Matrix H_vel_angles = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_vel, correctedOmega, correctedAcc, deltaT, _1, deltaVij), theta_i);
|
||||||
|
|
||||||
Matrix H_angles_pos = Z_3x3;
|
Matrix H_angles_pos = Z_3x3;
|
||||||
Matrix H_angles_vel = Z_3x3;
|
Matrix H_angles_vel = Z_3x3;
|
||||||
Matrix H_angles_angles = Jrinv_theta_j * Rincr.inverse().matrix() * Jr_theta_i;
|
Matrix H_angles_angles = Jrinv_theta_j * Rincr.inverse().matrix() * Jr_theta_i;
|
||||||
// analytic expression corresponding to the following numerical derivative
|
// analytic expression corresponding to the following numerical derivative
|
||||||
// Matrix H_angles_angles = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_angles, correctedOmega, deltaT, _1), thetaij);
|
// Matrix H_angles_angles = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_angles, correctedOmega, deltaT, _1), thetaij);
|
||||||
|
|
||||||
// overall Jacobian wrt preintegrated measurements (df/dx)
|
// overall Jacobian wrt preintegrated measurements (df/dx)
|
||||||
Matrix F(9,9);
|
Matrix F(9,9);
|
||||||
|
@ -285,7 +284,7 @@ namespace gtsam {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef ImuFactor This;
|
typedef ImuFactor This;
|
||||||
typedef NoiseModelFactor5<Pose3,LieVector,Pose3,LieVector,imuBias::ConstantBias> Base;
|
typedef NoiseModelFactor5<Pose3,Vector3,Pose3,Vector3,imuBias::ConstantBias> Base;
|
||||||
|
|
||||||
PreintegratedMeasurements preintegratedMeasurements_;
|
PreintegratedMeasurements preintegratedMeasurements_;
|
||||||
Vector3 gravity_;
|
Vector3 gravity_;
|
||||||
|
@ -373,7 +372,7 @@ namespace gtsam {
|
||||||
/** implement functions needed to derive from Factor */
|
/** implement functions needed to derive from Factor */
|
||||||
|
|
||||||
/** vector of errors */
|
/** vector of errors */
|
||||||
Vector evaluateError(const Pose3& pose_i, const LieVector& vel_i, const Pose3& pose_j, const LieVector& vel_j,
|
Vector evaluateError(const Pose3& pose_i, const Vector3& vel_i, const Pose3& pose_j, const Vector3& vel_j,
|
||||||
const imuBias::ConstantBias& bias,
|
const imuBias::ConstantBias& bias,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
|
@ -525,7 +524,7 @@ namespace gtsam {
|
||||||
|
|
||||||
|
|
||||||
/** predicted states from IMU */
|
/** predicted states from IMU */
|
||||||
static void Predict(const Pose3& pose_i, const LieVector& vel_i, Pose3& pose_j, LieVector& vel_j,
|
static void Predict(const Pose3& pose_i, const Vector3& vel_i, Pose3& pose_j, Vector3& vel_j,
|
||||||
const imuBias::ConstantBias& bias, const PreintegratedMeasurements preintegratedMeasurements,
|
const imuBias::ConstantBias& bias, const PreintegratedMeasurements preintegratedMeasurements,
|
||||||
const Vector3& gravity, const Vector3& omegaCoriolis, boost::optional<const Pose3&> body_P_sensor = boost::none,
|
const Vector3& gravity, const Vector3& omegaCoriolis, boost::optional<const Pose3&> body_P_sensor = boost::none,
|
||||||
const bool use2ndOrderCoriolis = false)
|
const bool use2ndOrderCoriolis = false)
|
||||||
|
@ -547,7 +546,7 @@ namespace gtsam {
|
||||||
- skewSymmetric(omegaCoriolis) * vel_i * deltaTij*deltaTij // Coriolis term - we got rid of the 2 wrt ins paper
|
- skewSymmetric(omegaCoriolis) * vel_i * deltaTij*deltaTij // Coriolis term - we got rid of the 2 wrt ins paper
|
||||||
+ 0.5 * gravity * deltaTij*deltaTij;
|
+ 0.5 * gravity * deltaTij*deltaTij;
|
||||||
|
|
||||||
vel_j = LieVector(vel_i + Rot_i.matrix() * (preintegratedMeasurements.deltaVij
|
vel_j = Vector3(vel_i + Rot_i.matrix() * (preintegratedMeasurements.deltaVij
|
||||||
+ preintegratedMeasurements.delVdelBiasAcc * biasAccIncr
|
+ preintegratedMeasurements.delVdelBiasAcc * biasAccIncr
|
||||||
+ preintegratedMeasurements.delVdelBiasOmega * biasOmegaIncr)
|
+ preintegratedMeasurements.delVdelBiasOmega * biasOmegaIncr)
|
||||||
- 2 * skewSymmetric(omegaCoriolis) * vel_i * deltaTij // Coriolis term
|
- 2 * skewSymmetric(omegaCoriolis) * vel_i * deltaTij // Coriolis term
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam/geometry/Rot2.h>
|
#include <gtsam/geometry/Rot2.h>
|
||||||
#include <gtsam/geometry/Rot3.h>
|
#include <gtsam/geometry/Rot3.h>
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -165,7 +164,7 @@ public:
|
||||||
* This version uses model measured bM = scale * bRn * direction + bias
|
* This version uses model measured bM = scale * bRn * direction + bias
|
||||||
* and optimizes for both scale, direction, and the bias.
|
* and optimizes for both scale, direction, and the bias.
|
||||||
*/
|
*/
|
||||||
class MagFactor3: public NoiseModelFactor3<LieScalar, Unit3, Point3> {
|
class MagFactor3: public NoiseModelFactor3<double, Unit3, Point3> {
|
||||||
|
|
||||||
const Point3 measured_; ///< The measured magnetometer values
|
const Point3 measured_; ///< The measured magnetometer values
|
||||||
const Rot3 bRn_; ///< The assumed known rotation from nav to body
|
const Rot3 bRn_; ///< The assumed known rotation from nav to body
|
||||||
|
@ -175,7 +174,7 @@ public:
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
MagFactor3(Key key1, Key key2, Key key3, const Point3& measured,
|
MagFactor3(Key key1, Key key2, Key key3, const Point3& measured,
|
||||||
const Rot3& nRb, const SharedNoiseModel& model) :
|
const Rot3& nRb, const SharedNoiseModel& model) :
|
||||||
NoiseModelFactor3<LieScalar, Unit3, Point3>(model, key1, key2, key3), //
|
NoiseModelFactor3<double, Unit3, Point3>(model, key1, key2, key3), //
|
||||||
measured_(measured), bRn_(nRb.inverse()) {
|
measured_(measured), bRn_(nRb.inverse()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +189,7 @@ public:
|
||||||
* @param nM (unknown) local earth magnetic field vector, in nav frame
|
* @param nM (unknown) local earth magnetic field vector, in nav frame
|
||||||
* @param bias (unknown) 3D bias
|
* @param bias (unknown) 3D bias
|
||||||
*/
|
*/
|
||||||
Vector evaluateError(const LieScalar& scale, const Unit3& direction,
|
Vector evaluateError(double scale, const Unit3& direction,
|
||||||
const Point3& bias, boost::optional<Matrix&> H1 = boost::none,
|
const Point3& bias, boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none, boost::optional<Matrix&> H3 =
|
boost::optional<Matrix&> H2 = boost::none, boost::optional<Matrix&> H3 =
|
||||||
boost::none) const {
|
boost::none) const {
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtsam/navigation/CombinedImuFactor.h>
|
#include <gtsam/navigation/CombinedImuFactor.h>
|
||||||
#include <gtsam/navigation/ImuBias.h>
|
#include <gtsam/navigation/ImuBias.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/TestableAssertions.h>
|
#include <gtsam/base/TestableAssertions.h>
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
@ -143,9 +142,9 @@ TEST( CombinedImuFactor, ErrorWithBiases )
|
||||||
imuBias::ConstantBias bias(Vector3(0.2, 0, 0), Vector3(0, 0, 0.3)); // Biases (acc, rot)
|
imuBias::ConstantBias bias(Vector3(0.2, 0, 0), Vector3(0, 0, 0.3)); // Biases (acc, rot)
|
||||||
imuBias::ConstantBias bias2(Vector3(0.2, 0.2, 0), Vector3(1, 0, 0.3)); // Biases (acc, rot)
|
imuBias::ConstantBias bias2(Vector3(0.2, 0.2, 0), Vector3(1, 0, 0.3)); // Biases (acc, rot)
|
||||||
Pose3 x1(Rot3::Expmap(Vector3(0, 0, M_PI/4.0)), Point3(5.0, 1.0, -50.0));
|
Pose3 x1(Rot3::Expmap(Vector3(0, 0, M_PI/4.0)), Point3(5.0, 1.0, -50.0));
|
||||||
LieVector v1((Vector(3) << 0.5, 0.0, 0.0));
|
Vector3 v1(0.5, 0.0, 0.0);
|
||||||
Pose3 x2(Rot3::Expmap(Vector3(0, 0, M_PI/4.0 + M_PI/10.0)), Point3(5.5, 1.0, -50.0));
|
Pose3 x2(Rot3::Expmap(Vector3(0, 0, M_PI/4.0 + M_PI/10.0)), Point3(5.5, 1.0, -50.0));
|
||||||
LieVector v2((Vector(3) << 0.5, 0.0, 0.0));
|
Vector3 v2(0.5, 0.0, 0.0);
|
||||||
|
|
||||||
// Measurements
|
// Measurements
|
||||||
Vector3 gravity; gravity << 0, 0, 9.81;
|
Vector3 gravity; gravity << 0, 0, 9.81;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
@ -62,7 +63,8 @@ NonlinearFactor::shared_ptr NonlinearFactor::rekey(
|
||||||
void NoiseModelFactor::print(const std::string& s,
|
void NoiseModelFactor::print(const std::string& s,
|
||||||
const KeyFormatter& keyFormatter) const {
|
const KeyFormatter& keyFormatter) const {
|
||||||
Base::print(s, keyFormatter);
|
Base::print(s, keyFormatter);
|
||||||
noiseModel_->print(" noise model: ");
|
if (noiseModel_)
|
||||||
|
noiseModel_->print(" noise model: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -76,18 +78,19 @@ bool NoiseModelFactor::equals(const NonlinearFactor& f, double tol) const {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
static void check(const SharedNoiseModel& noiseModel, size_t m) {
|
static void check(const SharedNoiseModel& noiseModel, size_t m) {
|
||||||
if (!noiseModel)
|
if (noiseModel && m != noiseModel->dim())
|
||||||
throw std::invalid_argument("NoiseModelFactor: no NoiseModel.");
|
|
||||||
if (m != noiseModel->dim())
|
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
"NoiseModelFactor was created with a NoiseModel of incorrect dimension.");
|
boost::str(
|
||||||
|
boost::format(
|
||||||
|
"NoiseModelFactor: NoiseModel has dimension %1% instead of %2%.")
|
||||||
|
% noiseModel->dim() % m));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Vector NoiseModelFactor::whitenedError(const Values& c) const {
|
Vector NoiseModelFactor::whitenedError(const Values& c) const {
|
||||||
const Vector b = unwhitenedError(c);
|
const Vector b = unwhitenedError(c);
|
||||||
check(noiseModel_, b.size());
|
check(noiseModel_, b.size());
|
||||||
return noiseModel_->whiten(b);
|
return noiseModel_ ? noiseModel_->whiten(b) : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -95,7 +98,10 @@ double NoiseModelFactor::error(const Values& c) const {
|
||||||
if (active(c)) {
|
if (active(c)) {
|
||||||
const Vector b = unwhitenedError(c);
|
const Vector b = unwhitenedError(c);
|
||||||
check(noiseModel_, b.size());
|
check(noiseModel_, b.size());
|
||||||
return 0.5 * noiseModel_->distance(b);
|
if (noiseModel_)
|
||||||
|
return 0.5 * noiseModel_->distance(b);
|
||||||
|
else
|
||||||
|
return 0.5 * b.squaredNorm();
|
||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +121,8 @@ boost::shared_ptr<GaussianFactor> NoiseModelFactor::linearize(
|
||||||
check(noiseModel_, b.size());
|
check(noiseModel_, b.size());
|
||||||
|
|
||||||
// Whiten the corresponding system now
|
// Whiten the corresponding system now
|
||||||
noiseModel_->WhitenSystem(A, b);
|
if (noiseModel_)
|
||||||
|
noiseModel_->WhitenSystem(A, b);
|
||||||
|
|
||||||
// Fill in terms, needed to create JacobianFactor below
|
// Fill in terms, needed to create JacobianFactor below
|
||||||
std::vector<std::pair<Key, Matrix> > terms(size());
|
std::vector<std::pair<Key, Matrix> > terms(size());
|
||||||
|
@ -125,7 +132,7 @@ boost::shared_ptr<GaussianFactor> NoiseModelFactor::linearize(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO pass unwhitened + noise model to Gaussian factor
|
// TODO pass unwhitened + noise model to Gaussian factor
|
||||||
if (noiseModel_->is_constrained())
|
if (noiseModel_ && noiseModel_->is_constrained())
|
||||||
return GaussianFactor::shared_ptr(
|
return GaussianFactor::shared_ptr(
|
||||||
new JacobianFactor(terms, b,
|
new JacobianFactor(terms, b,
|
||||||
boost::static_pointer_cast<noiseModel::Constrained>(noiseModel_)->unit()));
|
boost::static_pointer_cast<noiseModel::Constrained>(noiseModel_)->unit()));
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam/linear/HessianFactor.h>
|
#include <gtsam/linear/HessianFactor.h>
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -126,7 +125,7 @@ namespace gtsam {
|
||||||
|
|
||||||
/// Calculate the error of the factor, typically equal to log-likelihood
|
/// Calculate the error of the factor, typically equal to log-likelihood
|
||||||
inline double error(const Values& x) const {
|
inline double error(const Values& x) const {
|
||||||
return f(z_, x.at<LieScalar>(meanKey_), x.at<LieScalar>(precisionKey_));
|
return f(z_, x.at<double>(meanKey_), x.at<double>(precisionKey_));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,8 +154,8 @@ namespace gtsam {
|
||||||
|
|
||||||
/// linearize returns a Hessianfactor that is an approximation of error(p)
|
/// linearize returns a Hessianfactor that is an approximation of error(p)
|
||||||
virtual boost::shared_ptr<GaussianFactor> linearize(const Values& x) const {
|
virtual boost::shared_ptr<GaussianFactor> linearize(const Values& x) const {
|
||||||
double u = x.at<LieScalar>(meanKey_);
|
double u = x.at<double>(meanKey_);
|
||||||
double p = x.at<LieScalar>(precisionKey_);
|
double p = x.at<double>(precisionKey_);
|
||||||
Key j1 = meanKey_;
|
Key j1 = meanKey_;
|
||||||
Key j2 = precisionKey_;
|
Key j2 = precisionKey_;
|
||||||
return linearize(z_, u, p, j1, j2);
|
return linearize(z_, u, p, j1, j2);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/base/TestableAssertions.h>
|
#include <gtsam/base/TestableAssertions.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <boost/assign/std/list.hpp> // for operator +=
|
#include <boost/assign/std/list.hpp> // for operator +=
|
||||||
|
@ -74,7 +73,7 @@ struct dimension<TestValue> : public boost::integral_constant<int, 0> {};
|
||||||
TEST( Values, equals1 )
|
TEST( Values, equals1 )
|
||||||
{
|
{
|
||||||
Values expected;
|
Values expected;
|
||||||
LieVector v((Vector(3) << 5.0, 6.0, 7.0));
|
Vector3 v(5.0, 6.0, 7.0);
|
||||||
|
|
||||||
expected.insert(key1, v);
|
expected.insert(key1, v);
|
||||||
Values actual;
|
Values actual;
|
||||||
|
@ -86,8 +85,8 @@ TEST( Values, equals1 )
|
||||||
TEST( Values, equals2 )
|
TEST( Values, equals2 )
|
||||||
{
|
{
|
||||||
Values cfg1, cfg2;
|
Values cfg1, cfg2;
|
||||||
LieVector v1((Vector(3) << 5.0, 6.0, 7.0));
|
Vector3 v1(5.0, 6.0, 7.0);
|
||||||
LieVector v2((Vector(3) << 5.0, 6.0, 8.0));
|
Vector3 v2(5.0, 6.0, 8.0);
|
||||||
|
|
||||||
cfg1.insert(key1, v1);
|
cfg1.insert(key1, v1);
|
||||||
cfg2.insert(key1, v2);
|
cfg2.insert(key1, v2);
|
||||||
|
@ -99,8 +98,8 @@ TEST( Values, equals2 )
|
||||||
TEST( Values, equals_nan )
|
TEST( Values, equals_nan )
|
||||||
{
|
{
|
||||||
Values cfg1, cfg2;
|
Values cfg1, cfg2;
|
||||||
LieVector v1((Vector(3) << 5.0, 6.0, 7.0));
|
Vector3 v1(5.0, 6.0, 7.0);
|
||||||
LieVector v2((Vector(3) << inf, inf, inf));
|
Vector3 v2(inf, inf, inf);
|
||||||
|
|
||||||
cfg1.insert(key1, v1);
|
cfg1.insert(key1, v1);
|
||||||
cfg2.insert(key1, v2);
|
cfg2.insert(key1, v2);
|
||||||
|
@ -112,10 +111,10 @@ TEST( Values, equals_nan )
|
||||||
TEST( Values, insert_good )
|
TEST( Values, insert_good )
|
||||||
{
|
{
|
||||||
Values cfg1, cfg2, expected;
|
Values cfg1, cfg2, expected;
|
||||||
LieVector v1((Vector(3) << 5.0, 6.0, 7.0));
|
Vector3 v1(5.0, 6.0, 7.0);
|
||||||
LieVector v2((Vector(3) << 8.0, 9.0, 1.0));
|
Vector3 v2(8.0, 9.0, 1.0);
|
||||||
LieVector v3((Vector(3) << 2.0, 4.0, 3.0));
|
Vector3 v3(2.0, 4.0, 3.0);
|
||||||
LieVector v4((Vector(3) << 8.0, 3.0, 7.0));
|
Vector3 v4(8.0, 3.0, 7.0);
|
||||||
|
|
||||||
cfg1.insert(key1, v1);
|
cfg1.insert(key1, v1);
|
||||||
cfg1.insert(key2, v2);
|
cfg1.insert(key2, v2);
|
||||||
|
@ -134,10 +133,10 @@ TEST( Values, insert_good )
|
||||||
TEST( Values, insert_bad )
|
TEST( Values, insert_bad )
|
||||||
{
|
{
|
||||||
Values cfg1, cfg2;
|
Values cfg1, cfg2;
|
||||||
LieVector v1((Vector(3) << 5.0, 6.0, 7.0));
|
Vector3 v1(5.0, 6.0, 7.0);
|
||||||
LieVector v2((Vector(3) << 8.0, 9.0, 1.0));
|
Vector3 v2(8.0, 9.0, 1.0);
|
||||||
LieVector v3((Vector(3) << 2.0, 4.0, 3.0));
|
Vector3 v3(2.0, 4.0, 3.0);
|
||||||
LieVector v4((Vector(3) << 8.0, 3.0, 7.0));
|
Vector3 v4(8.0, 3.0, 7.0);
|
||||||
|
|
||||||
cfg1.insert(key1, v1);
|
cfg1.insert(key1, v1);
|
||||||
cfg1.insert(key2, v2);
|
cfg1.insert(key2, v2);
|
||||||
|
@ -151,16 +150,16 @@ TEST( Values, insert_bad )
|
||||||
TEST( Values, update_element )
|
TEST( Values, update_element )
|
||||||
{
|
{
|
||||||
Values cfg;
|
Values cfg;
|
||||||
LieVector v1((Vector(3) << 5.0, 6.0, 7.0));
|
Vector3 v1(5.0, 6.0, 7.0);
|
||||||
LieVector v2((Vector(3) << 8.0, 9.0, 1.0));
|
Vector3 v2(8.0, 9.0, 1.0);
|
||||||
|
|
||||||
cfg.insert(key1, v1);
|
cfg.insert(key1, v1);
|
||||||
CHECK(cfg.size() == 1);
|
CHECK(cfg.size() == 1);
|
||||||
CHECK(assert_equal(v1, cfg.at<LieVector>(key1)));
|
CHECK(assert_equal((Vector)v1, cfg.at<Vector3>(key1)));
|
||||||
|
|
||||||
cfg.update(key1, v2);
|
cfg.update(key1, v2);
|
||||||
CHECK(cfg.size() == 1);
|
CHECK(cfg.size() == 1);
|
||||||
CHECK(assert_equal(v2, cfg.at<LieVector>(key1)));
|
CHECK(assert_equal((Vector)v2, cfg.at<Vector3>(key1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -168,10 +167,10 @@ TEST(Values, basic_functions)
|
||||||
{
|
{
|
||||||
Values values;
|
Values values;
|
||||||
const Values& values_c = values;
|
const Values& values_c = values;
|
||||||
values.insert(2, LieVector());
|
values.insert(2, Vector3());
|
||||||
values.insert(4, LieVector());
|
values.insert(4, Vector3());
|
||||||
values.insert(6, LieVector());
|
values.insert(6, Vector3());
|
||||||
values.insert(8, LieVector());
|
values.insert(8, Vector3());
|
||||||
|
|
||||||
// find
|
// find
|
||||||
EXPECT_LONGS_EQUAL(4, values.find(4)->key);
|
EXPECT_LONGS_EQUAL(4, values.find(4)->key);
|
||||||
|
@ -195,8 +194,8 @@ TEST(Values, basic_functions)
|
||||||
//TEST(Values, dim_zero)
|
//TEST(Values, dim_zero)
|
||||||
//{
|
//{
|
||||||
// Values config0;
|
// Values config0;
|
||||||
// config0.insert(key1, LieVector((Vector(2) << 2.0, 3.0));
|
// config0.insert(key1, Vector2((Vector(2) << 2.0, 3.0));
|
||||||
// config0.insert(key2, LieVector((Vector(3) << 5.0, 6.0, 7.0));
|
// config0.insert(key2, Vector3(5.0, 6.0, 7.0));
|
||||||
// LONGS_EQUAL(5, config0.dim());
|
// LONGS_EQUAL(5, config0.dim());
|
||||||
//
|
//
|
||||||
// VectorValues expected;
|
// VectorValues expected;
|
||||||
|
@ -209,16 +208,16 @@ TEST(Values, basic_functions)
|
||||||
TEST(Values, expmap_a)
|
TEST(Values, expmap_a)
|
||||||
{
|
{
|
||||||
Values config0;
|
Values config0;
|
||||||
config0.insert(key1, LieVector((Vector(3) << 1.0, 2.0, 3.0)));
|
config0.insert(key1, Vector3(1.0, 2.0, 3.0));
|
||||||
config0.insert(key2, LieVector((Vector(3) << 5.0, 6.0, 7.0)));
|
config0.insert(key2, Vector3(5.0, 6.0, 7.0));
|
||||||
|
|
||||||
VectorValues increment = pair_list_of<Key, Vector>
|
VectorValues increment = pair_list_of<Key, Vector>
|
||||||
(key1, (Vector(3) << 1.0, 1.1, 1.2))
|
(key1, (Vector(3) << 1.0, 1.1, 1.2))
|
||||||
(key2, (Vector(3) << 1.3, 1.4, 1.5));
|
(key2, (Vector(3) << 1.3, 1.4, 1.5));
|
||||||
|
|
||||||
Values expected;
|
Values expected;
|
||||||
expected.insert(key1, LieVector((Vector(3) << 2.0, 3.1, 4.2)));
|
expected.insert(key1, Vector3(2.0, 3.1, 4.2));
|
||||||
expected.insert(key2, LieVector((Vector(3) << 6.3, 7.4, 8.5)));
|
expected.insert(key2, Vector3(6.3, 7.4, 8.5));
|
||||||
|
|
||||||
CHECK(assert_equal(expected, config0.retract(increment)));
|
CHECK(assert_equal(expected, config0.retract(increment)));
|
||||||
}
|
}
|
||||||
|
@ -227,15 +226,15 @@ TEST(Values, expmap_a)
|
||||||
TEST(Values, expmap_b)
|
TEST(Values, expmap_b)
|
||||||
{
|
{
|
||||||
Values config0;
|
Values config0;
|
||||||
config0.insert(key1, LieVector((Vector(3) << 1.0, 2.0, 3.0)));
|
config0.insert(key1, Vector3(1.0, 2.0, 3.0));
|
||||||
config0.insert(key2, LieVector((Vector(3) << 5.0, 6.0, 7.0)));
|
config0.insert(key2, Vector3(5.0, 6.0, 7.0));
|
||||||
|
|
||||||
VectorValues increment = pair_list_of<Key, Vector>
|
VectorValues increment = pair_list_of<Key, Vector>
|
||||||
(key2, (Vector(3) << 1.3, 1.4, 1.5));
|
(key2, (Vector(3) << 1.3, 1.4, 1.5));
|
||||||
|
|
||||||
Values expected;
|
Values expected;
|
||||||
expected.insert(key1, LieVector((Vector(3) << 1.0, 2.0, 3.0)));
|
expected.insert(key1, Vector3(1.0, 2.0, 3.0));
|
||||||
expected.insert(key2, LieVector((Vector(3) << 6.3, 7.4, 8.5)));
|
expected.insert(key2, Vector3(6.3, 7.4, 8.5));
|
||||||
|
|
||||||
CHECK(assert_equal(expected, config0.retract(increment)));
|
CHECK(assert_equal(expected, config0.retract(increment)));
|
||||||
}
|
}
|
||||||
|
@ -244,16 +243,16 @@ TEST(Values, expmap_b)
|
||||||
//TEST(Values, expmap_c)
|
//TEST(Values, expmap_c)
|
||||||
//{
|
//{
|
||||||
// Values config0;
|
// Values config0;
|
||||||
// config0.insert(key1, LieVector((Vector(3) << 1.0, 2.0, 3.0)));
|
// config0.insert(key1, Vector3(1.0, 2.0, 3.0));
|
||||||
// config0.insert(key2, LieVector((Vector(3) << 5.0, 6.0, 7.0)));
|
// config0.insert(key2, Vector3(5.0, 6.0, 7.0));
|
||||||
//
|
//
|
||||||
// Vector increment = LieVector(6,
|
// Vector increment = Vector6(
|
||||||
// 1.0, 1.1, 1.2,
|
// 1.0, 1.1, 1.2,
|
||||||
// 1.3, 1.4, 1.5);
|
// 1.3, 1.4, 1.5);
|
||||||
//
|
//
|
||||||
// Values expected;
|
// Values expected;
|
||||||
// expected.insert(key1, LieVector((Vector(3) << 2.0, 3.1, 4.2)));
|
// expected.insert(key1, Vector3(2.0, 3.1, 4.2));
|
||||||
// expected.insert(key2, LieVector((Vector(3) << 6.3, 7.4, 8.5)));
|
// expected.insert(key2, Vector3(6.3, 7.4, 8.5));
|
||||||
//
|
//
|
||||||
// CHECK(assert_equal(expected, config0.retract(increment)));
|
// CHECK(assert_equal(expected, config0.retract(increment)));
|
||||||
//}
|
//}
|
||||||
|
@ -262,8 +261,8 @@ TEST(Values, expmap_b)
|
||||||
TEST(Values, expmap_d)
|
TEST(Values, expmap_d)
|
||||||
{
|
{
|
||||||
Values config0;
|
Values config0;
|
||||||
config0.insert(key1, LieVector((Vector(3) << 1.0, 2.0, 3.0)));
|
config0.insert(key1, Vector3(1.0, 2.0, 3.0));
|
||||||
config0.insert(key2, LieVector((Vector(3) << 5.0, 6.0, 7.0)));
|
config0.insert(key2, Vector3(5.0, 6.0, 7.0));
|
||||||
//config0.print("config0");
|
//config0.print("config0");
|
||||||
CHECK(equal(config0, config0));
|
CHECK(equal(config0, config0));
|
||||||
CHECK(config0.equals(config0));
|
CHECK(config0.equals(config0));
|
||||||
|
@ -280,8 +279,8 @@ TEST(Values, expmap_d)
|
||||||
TEST(Values, localCoordinates)
|
TEST(Values, localCoordinates)
|
||||||
{
|
{
|
||||||
Values valuesA;
|
Values valuesA;
|
||||||
valuesA.insert(key1, LieVector((Vector(3) << 1.0, 2.0, 3.0)));
|
valuesA.insert(key1, Vector3(1.0, 2.0, 3.0));
|
||||||
valuesA.insert(key2, LieVector((Vector(3) << 5.0, 6.0, 7.0)));
|
valuesA.insert(key2, Vector3(5.0, 6.0, 7.0));
|
||||||
|
|
||||||
VectorValues expDelta = pair_list_of<Key, Vector>
|
VectorValues expDelta = pair_list_of<Key, Vector>
|
||||||
(key1, (Vector(3) << 0.1, 0.2, 0.3))
|
(key1, (Vector(3) << 0.1, 0.2, 0.3))
|
||||||
|
@ -317,28 +316,28 @@ TEST(Values, extract_keys)
|
||||||
TEST(Values, exists_)
|
TEST(Values, exists_)
|
||||||
{
|
{
|
||||||
Values config0;
|
Values config0;
|
||||||
config0.insert(key1, LieVector((Vector(1) << 1.)));
|
config0.insert(key1, 1.0);
|
||||||
config0.insert(key2, LieVector((Vector(1) << 2.)));
|
config0.insert(key2, 2.0);
|
||||||
|
|
||||||
boost::optional<const LieVector&> v = config0.exists<LieVector>(key1);
|
boost::optional<const double&> v = config0.exists<double>(key1);
|
||||||
CHECK(assert_equal((Vector(1) << 1.),*v));
|
DOUBLES_EQUAL(1.0,*v,1e-9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST(Values, update)
|
TEST(Values, update)
|
||||||
{
|
{
|
||||||
Values config0;
|
Values config0;
|
||||||
config0.insert(key1, LieVector((Vector(1) << 1.)));
|
config0.insert(key1, 1.0);
|
||||||
config0.insert(key2, LieVector((Vector(1) << 2.)));
|
config0.insert(key2, 2.0);
|
||||||
|
|
||||||
Values superset;
|
Values superset;
|
||||||
superset.insert(key1, LieVector((Vector(1) << -1.)));
|
superset.insert(key1, -1.0);
|
||||||
superset.insert(key2, LieVector((Vector(1) << -2.)));
|
superset.insert(key2, -2.0);
|
||||||
config0.update(superset);
|
config0.update(superset);
|
||||||
|
|
||||||
Values expected;
|
Values expected;
|
||||||
expected.insert(key1, LieVector((Vector(1) << -1.)));
|
expected.insert(key1, -1.0);
|
||||||
expected.insert(key2, LieVector((Vector(1) << -2.)));
|
expected.insert(key2, -2.0);
|
||||||
CHECK(assert_equal(expected, config0));
|
CHECK(assert_equal(expected, config0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam/geometry/EssentialMatrix.h>
|
#include <gtsam/geometry/EssentialMatrix.h>
|
||||||
#include <gtsam/geometry/SimpleCamera.h>
|
#include <gtsam/geometry/SimpleCamera.h>
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -85,14 +84,13 @@ public:
|
||||||
* Binary factor that optimizes for E and inverse depth d: assumes measurement
|
* Binary factor that optimizes for E and inverse depth d: assumes measurement
|
||||||
* in image 2 is perfect, and returns re-projection error in image 1
|
* in image 2 is perfect, and returns re-projection error in image 1
|
||||||
*/
|
*/
|
||||||
class EssentialMatrixFactor2: public NoiseModelFactor2<EssentialMatrix,
|
class EssentialMatrixFactor2: public NoiseModelFactor2<EssentialMatrix, double> {
|
||||||
LieScalar> {
|
|
||||||
|
|
||||||
Point3 dP1_; ///< 3D point corresponding to measurement in image 1
|
Point3 dP1_; ///< 3D point corresponding to measurement in image 1
|
||||||
Point2 pn_; ///< Measurement in image 2, in ideal coordinates
|
Point2 pn_; ///< Measurement in image 2, in ideal coordinates
|
||||||
double f_; ///< approximate conversion factor for error scaling
|
double f_; ///< approximate conversion factor for error scaling
|
||||||
|
|
||||||
typedef NoiseModelFactor2<EssentialMatrix, LieScalar> Base;
|
typedef NoiseModelFactor2<EssentialMatrix, double> Base;
|
||||||
typedef EssentialMatrixFactor2 This;
|
typedef EssentialMatrixFactor2 This;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -149,7 +147,7 @@ public:
|
||||||
* @param E essential matrix
|
* @param E essential matrix
|
||||||
* @param d inverse depth d
|
* @param d inverse depth d
|
||||||
*/
|
*/
|
||||||
Vector evaluateError(const EssentialMatrix& E, const LieScalar& d,
|
Vector evaluateError(const EssentialMatrix& E, const double& d,
|
||||||
boost::optional<Matrix&> DE = boost::none, boost::optional<Matrix&> Dd =
|
boost::optional<Matrix&> DE = boost::none, boost::optional<Matrix&> Dd =
|
||||||
boost::none) const {
|
boost::none) const {
|
||||||
|
|
||||||
|
@ -237,7 +235,8 @@ public:
|
||||||
*/
|
*/
|
||||||
template<class CALIBRATION>
|
template<class CALIBRATION>
|
||||||
EssentialMatrixFactor3(Key key1, Key key2, const Point2& pA, const Point2& pB,
|
EssentialMatrixFactor3(Key key1, Key key2, const Point2& pA, const Point2& pB,
|
||||||
const Rot3& cRb, const SharedNoiseModel& model, boost::shared_ptr<CALIBRATION> K) :
|
const Rot3& cRb, const SharedNoiseModel& model,
|
||||||
|
boost::shared_ptr<CALIBRATION> K) :
|
||||||
EssentialMatrixFactor2(key1, key2, pA, pB, model, K), cRb_(cRb) {
|
EssentialMatrixFactor2(key1, key2, pA, pB, model, K), cRb_(cRb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +258,7 @@ public:
|
||||||
* @param E essential matrix
|
* @param E essential matrix
|
||||||
* @param d inverse depth d
|
* @param d inverse depth d
|
||||||
*/
|
*/
|
||||||
Vector evaluateError(const EssentialMatrix& E, const LieScalar& d,
|
Vector evaluateError(const EssentialMatrix& E, const double& d,
|
||||||
boost::optional<Matrix&> DE = boost::none, boost::optional<Matrix&> Dd =
|
boost::optional<Matrix&> DE = boost::none, boost::optional<Matrix&> Dd =
|
||||||
boost::none) const {
|
boost::none) const {
|
||||||
if (!DE) {
|
if (!DE) {
|
||||||
|
|
|
@ -36,7 +36,7 @@ SfM_data data;
|
||||||
bool readOK = readBAL(filename, data);
|
bool readOK = readBAL(filename, data);
|
||||||
Rot3 c1Rc2 = data.cameras[1].pose().rotation();
|
Rot3 c1Rc2 = data.cameras[1].pose().rotation();
|
||||||
Point3 c1Tc2 = data.cameras[1].pose().translation();
|
Point3 c1Tc2 = data.cameras[1].pose().translation();
|
||||||
PinholeCamera<Cal3_S2> camera2(data.cameras[1].pose(),Cal3_S2());
|
PinholeCamera<Cal3_S2> camera2(data.cameras[1].pose(), Cal3_S2());
|
||||||
EssentialMatrix trueE(c1Rc2, Unit3(c1Tc2));
|
EssentialMatrix trueE(c1Rc2, Unit3(c1Tc2));
|
||||||
double baseline = 0.1; // actual baseline of the camera
|
double baseline = 0.1; // actual baseline of the camera
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ TEST (EssentialMatrixFactor, factor) {
|
||||||
|
|
||||||
// Use numerical derivatives to calculate the expected Jacobian
|
// Use numerical derivatives to calculate the expected Jacobian
|
||||||
Matrix Hexpected;
|
Matrix Hexpected;
|
||||||
Hexpected = numericalDerivative11<Vector,EssentialMatrix>(
|
Hexpected = numericalDerivative11<Vector, EssentialMatrix>(
|
||||||
boost::bind(&EssentialMatrixFactor::evaluateError, &factor, _1,
|
boost::bind(&EssentialMatrixFactor::evaluateError, &factor, _1,
|
||||||
boost::none), trueE);
|
boost::none), trueE);
|
||||||
|
|
||||||
|
@ -164,17 +164,17 @@ TEST (EssentialMatrixFactor2, factor) {
|
||||||
Vector expected = reprojectionError.vector();
|
Vector expected = reprojectionError.vector();
|
||||||
|
|
||||||
Matrix Hactual1, Hactual2;
|
Matrix Hactual1, Hactual2;
|
||||||
LieScalar d(baseline / P1.z());
|
double d(baseline / P1.z());
|
||||||
Vector actual = factor.evaluateError(trueE, d, Hactual1, Hactual2);
|
Vector actual = factor.evaluateError(trueE, d, Hactual1, Hactual2);
|
||||||
EXPECT(assert_equal(expected, actual, 1e-7));
|
EXPECT(assert_equal(expected, actual, 1e-7));
|
||||||
|
|
||||||
// Use numerical derivatives to calculate the expected Jacobian
|
// Use numerical derivatives to calculate the expected Jacobian
|
||||||
Matrix Hexpected1, Hexpected2;
|
Matrix Hexpected1, Hexpected2;
|
||||||
boost::function<Vector(const EssentialMatrix&, const LieScalar&)> f =
|
boost::function<Vector(const EssentialMatrix&, double)> f = boost::bind(
|
||||||
boost::bind(&EssentialMatrixFactor2::evaluateError, &factor, _1, _2,
|
&EssentialMatrixFactor2::evaluateError, &factor, _1, _2, boost::none,
|
||||||
boost::none, boost::none);
|
boost::none);
|
||||||
Hexpected1 = numericalDerivative21<Vector,EssentialMatrix>(f, trueE, d);
|
Hexpected1 = numericalDerivative21<Vector, EssentialMatrix, double>(f, trueE, d);
|
||||||
Hexpected2 = numericalDerivative22<Vector,EssentialMatrix>(f, trueE, d);
|
Hexpected2 = numericalDerivative22<Vector, EssentialMatrix, double>(f, trueE, d);
|
||||||
|
|
||||||
// Verify the Jacobian is correct
|
// Verify the Jacobian is correct
|
||||||
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-8));
|
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-8));
|
||||||
|
@ -197,7 +197,7 @@ TEST (EssentialMatrixFactor2, minimization) {
|
||||||
truth.insert(100, trueE);
|
truth.insert(100, trueE);
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
Point3 P1 = data.tracks[i].p;
|
Point3 P1 = data.tracks[i].p;
|
||||||
truth.insert(i, LieScalar(baseline / P1.z()));
|
truth.insert(i, double(baseline / P1.z()));
|
||||||
}
|
}
|
||||||
EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);
|
EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ TEST (EssentialMatrixFactor2, minimization) {
|
||||||
EssentialMatrix actual = result.at<EssentialMatrix>(100);
|
EssentialMatrix actual = result.at<EssentialMatrix>(100);
|
||||||
EXPECT(assert_equal(trueE, actual, 1e-1));
|
EXPECT(assert_equal(trueE, actual, 1e-1));
|
||||||
for (size_t i = 0; i < 5; i++)
|
for (size_t i = 0; i < 5; i++)
|
||||||
EXPECT(assert_equal(truth.at<LieScalar>(i), result.at<LieScalar>(i), 1e-1));
|
EXPECT_DOUBLES_EQUAL(truth.at<double>(i), result.at<double>(i), 1e-1);
|
||||||
|
|
||||||
// Check error at result
|
// Check error at result
|
||||||
EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);
|
EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);
|
||||||
|
@ -238,17 +238,17 @@ TEST (EssentialMatrixFactor3, factor) {
|
||||||
Vector expected = reprojectionError.vector();
|
Vector expected = reprojectionError.vector();
|
||||||
|
|
||||||
Matrix Hactual1, Hactual2;
|
Matrix Hactual1, Hactual2;
|
||||||
LieScalar d(baseline / P1.z());
|
double d(baseline / P1.z());
|
||||||
Vector actual = factor.evaluateError(bodyE, d, Hactual1, Hactual2);
|
Vector actual = factor.evaluateError(bodyE, d, Hactual1, Hactual2);
|
||||||
EXPECT(assert_equal(expected, actual, 1e-7));
|
EXPECT(assert_equal(expected, actual, 1e-7));
|
||||||
|
|
||||||
// Use numerical derivatives to calculate the expected Jacobian
|
// Use numerical derivatives to calculate the expected Jacobian
|
||||||
Matrix Hexpected1, Hexpected2;
|
Matrix Hexpected1, Hexpected2;
|
||||||
boost::function<Vector(const EssentialMatrix&, const LieScalar&)> f =
|
boost::function<Vector(const EssentialMatrix&, double)> f = boost::bind(
|
||||||
boost::bind(&EssentialMatrixFactor3::evaluateError, &factor, _1, _2,
|
&EssentialMatrixFactor3::evaluateError, &factor, _1, _2, boost::none,
|
||||||
boost::none, boost::none);
|
boost::none);
|
||||||
Hexpected1 = numericalDerivative21<Vector,EssentialMatrix>(f, bodyE, d);
|
Hexpected1 = numericalDerivative21<Vector, EssentialMatrix, double>(f, bodyE, d);
|
||||||
Hexpected2 = numericalDerivative22<Vector,EssentialMatrix>(f, bodyE, d);
|
Hexpected2 = numericalDerivative22<Vector, EssentialMatrix, double>(f, bodyE, d);
|
||||||
|
|
||||||
// Verify the Jacobian is correct
|
// Verify the Jacobian is correct
|
||||||
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-8));
|
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-8));
|
||||||
|
@ -270,7 +270,7 @@ TEST (EssentialMatrixFactor3, minimization) {
|
||||||
truth.insert(100, bodyE);
|
truth.insert(100, bodyE);
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
Point3 P1 = data.tracks[i].p;
|
Point3 P1 = data.tracks[i].p;
|
||||||
truth.insert(i, LieScalar(baseline / P1.z()));
|
truth.insert(i, double(baseline / P1.z()));
|
||||||
}
|
}
|
||||||
EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);
|
EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ TEST (EssentialMatrixFactor3, minimization) {
|
||||||
EssentialMatrix actual = result.at<EssentialMatrix>(100);
|
EssentialMatrix actual = result.at<EssentialMatrix>(100);
|
||||||
EXPECT(assert_equal(bodyE, actual, 1e-1));
|
EXPECT(assert_equal(bodyE, actual, 1e-1));
|
||||||
for (size_t i = 0; i < 5; i++)
|
for (size_t i = 0; i < 5; i++)
|
||||||
EXPECT(assert_equal(truth.at<LieScalar>(i), result.at<LieScalar>(i), 1e-1));
|
EXPECT_DOUBLES_EQUAL(truth.at<double>(i), result.at<double>(i), 1e-1);
|
||||||
|
|
||||||
// Check error at result
|
// Check error at result
|
||||||
EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);
|
EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);
|
||||||
|
@ -314,7 +314,7 @@ Point2 pB(size_t i) {
|
||||||
|
|
||||||
boost::shared_ptr<Cal3Bundler> //
|
boost::shared_ptr<Cal3Bundler> //
|
||||||
K = boost::make_shared<Cal3Bundler>(500, 0, 0);
|
K = boost::make_shared<Cal3Bundler>(500, 0, 0);
|
||||||
PinholeCamera<Cal3Bundler> camera2(data.cameras[1].pose(),*K);
|
PinholeCamera<Cal3Bundler> camera2(data.cameras[1].pose(), *K);
|
||||||
|
|
||||||
Vector vA(size_t i) {
|
Vector vA(size_t i) {
|
||||||
Point2 xy = K->calibrate(pA(i));
|
Point2 xy = K->calibrate(pA(i));
|
||||||
|
@ -380,17 +380,17 @@ TEST (EssentialMatrixFactor2, extraTest) {
|
||||||
Vector expected = reprojectionError.vector();
|
Vector expected = reprojectionError.vector();
|
||||||
|
|
||||||
Matrix Hactual1, Hactual2;
|
Matrix Hactual1, Hactual2;
|
||||||
LieScalar d(baseline / P1.z());
|
double d(baseline / P1.z());
|
||||||
Vector actual = factor.evaluateError(trueE, d, Hactual1, Hactual2);
|
Vector actual = factor.evaluateError(trueE, d, Hactual1, Hactual2);
|
||||||
EXPECT(assert_equal(expected, actual, 1e-7));
|
EXPECT(assert_equal(expected, actual, 1e-7));
|
||||||
|
|
||||||
// Use numerical derivatives to calculate the expected Jacobian
|
// Use numerical derivatives to calculate the expected Jacobian
|
||||||
Matrix Hexpected1, Hexpected2;
|
Matrix Hexpected1, Hexpected2;
|
||||||
boost::function<Vector(const EssentialMatrix&, const LieScalar&)> f =
|
boost::function<Vector(const EssentialMatrix&, double)> f = boost::bind(
|
||||||
boost::bind(&EssentialMatrixFactor2::evaluateError, &factor, _1, _2,
|
&EssentialMatrixFactor2::evaluateError, &factor, _1, _2, boost::none,
|
||||||
boost::none, boost::none);
|
boost::none);
|
||||||
Hexpected1 = numericalDerivative21<Vector,EssentialMatrix>(f, trueE, d);
|
Hexpected1 = numericalDerivative21<Vector, EssentialMatrix, double>(f, trueE, d);
|
||||||
Hexpected2 = numericalDerivative22<Vector,EssentialMatrix>(f, trueE, d);
|
Hexpected2 = numericalDerivative22<Vector, EssentialMatrix, double>(f, trueE, d);
|
||||||
|
|
||||||
// Verify the Jacobian is correct
|
// Verify the Jacobian is correct
|
||||||
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-6));
|
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-6));
|
||||||
|
@ -413,7 +413,7 @@ TEST (EssentialMatrixFactor2, extraMinimization) {
|
||||||
truth.insert(100, trueE);
|
truth.insert(100, trueE);
|
||||||
for (size_t i = 0; i < data.number_tracks(); i++) {
|
for (size_t i = 0; i < data.number_tracks(); i++) {
|
||||||
Point3 P1 = data.tracks[i].p;
|
Point3 P1 = data.tracks[i].p;
|
||||||
truth.insert(i, LieScalar(baseline / P1.z()));
|
truth.insert(i, double(baseline / P1.z()));
|
||||||
}
|
}
|
||||||
EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);
|
EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ TEST (EssentialMatrixFactor2, extraMinimization) {
|
||||||
EssentialMatrix actual = result.at<EssentialMatrix>(100);
|
EssentialMatrix actual = result.at<EssentialMatrix>(100);
|
||||||
EXPECT(assert_equal(trueE, actual, 1e-1));
|
EXPECT(assert_equal(trueE, actual, 1e-1));
|
||||||
for (size_t i = 0; i < data.number_tracks(); i++)
|
for (size_t i = 0; i < data.number_tracks(); i++)
|
||||||
EXPECT(assert_equal(truth.at<LieScalar>(i), result.at<LieScalar>(i), 1e-1));
|
EXPECT_DOUBLES_EQUAL(truth.at<double>(i), result.at<double>(i), 1e-1);
|
||||||
|
|
||||||
// Check error at result
|
// Check error at result
|
||||||
EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);
|
EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);
|
||||||
|
@ -449,17 +449,17 @@ TEST (EssentialMatrixFactor3, extraTest) {
|
||||||
Vector expected = reprojectionError.vector();
|
Vector expected = reprojectionError.vector();
|
||||||
|
|
||||||
Matrix Hactual1, Hactual2;
|
Matrix Hactual1, Hactual2;
|
||||||
LieScalar d(baseline / P1.z());
|
double d(baseline / P1.z());
|
||||||
Vector actual = factor.evaluateError(bodyE, d, Hactual1, Hactual2);
|
Vector actual = factor.evaluateError(bodyE, d, Hactual1, Hactual2);
|
||||||
EXPECT(assert_equal(expected, actual, 1e-7));
|
EXPECT(assert_equal(expected, actual, 1e-7));
|
||||||
|
|
||||||
// Use numerical derivatives to calculate the expected Jacobian
|
// Use numerical derivatives to calculate the expected Jacobian
|
||||||
Matrix Hexpected1, Hexpected2;
|
Matrix Hexpected1, Hexpected2;
|
||||||
boost::function<Vector(const EssentialMatrix&, const LieScalar&)> f =
|
boost::function<Vector(const EssentialMatrix&, double)> f = boost::bind(
|
||||||
boost::bind(&EssentialMatrixFactor3::evaluateError, &factor, _1, _2,
|
&EssentialMatrixFactor3::evaluateError, &factor, _1, _2, boost::none,
|
||||||
boost::none, boost::none);
|
boost::none);
|
||||||
Hexpected1 = numericalDerivative21<Vector,EssentialMatrix>(f, bodyE, d);
|
Hexpected1 = numericalDerivative21<Vector, EssentialMatrix, double>(f, bodyE, d);
|
||||||
Hexpected2 = numericalDerivative22<Vector,EssentialMatrix>(f, bodyE, d);
|
Hexpected2 = numericalDerivative22<Vector, EssentialMatrix, double>(f, bodyE, d);
|
||||||
|
|
||||||
// Verify the Jacobian is correct
|
// Verify the Jacobian is correct
|
||||||
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-6));
|
EXPECT(assert_equal(Hexpected1, Hactual1, 1e-6));
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* @file testPriorFactor.cpp
|
||||||
|
* @brief Test PriorFactor
|
||||||
|
* @author Frank Dellaert
|
||||||
|
* @date Nov 4, 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtsam/slam/PriorFactor.h>
|
||||||
|
#include <gtsam/base/LieScalar.h>
|
||||||
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace gtsam;
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
TEST(PriorFactor, Constructor) {
|
||||||
|
SharedNoiseModel model;
|
||||||
|
PriorFactor<LieScalar> factor(1, LieScalar(1.0), model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
int main() {
|
||||||
|
TestResult tr;
|
||||||
|
return TestRegistry::runAllTests(tr);
|
||||||
|
}
|
||||||
|
/* ************************************************************************* */
|
|
@ -7,7 +7,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam_unstable/dynamics/PoseRTV.h>
|
#include <gtsam_unstable/dynamics/PoseRTV.h>
|
||||||
|
|
||||||
|
@ -29,20 +28,20 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** measurements from the IMU */
|
/** measurements from the IMU */
|
||||||
Vector accel_, gyro_;
|
Vector3 accel_, gyro_;
|
||||||
double dt_; /// time between measurements
|
double dt_; /// time between measurements
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Standard constructor */
|
/** Standard constructor */
|
||||||
FullIMUFactor(const Vector& accel, const Vector& gyro,
|
FullIMUFactor(const Vector3& accel, const Vector3& gyro,
|
||||||
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
||||||
: Base(model, key1, key2), accel_(accel), gyro_(gyro), dt_(dt) {
|
: Base(model, key1, key2), accel_(accel), gyro_(gyro), dt_(dt) {
|
||||||
assert(model->dim() == 9);
|
assert(model->dim() == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Single IMU vector - imu = [accel, gyro] */
|
/** Single IMU vector - imu = [accel, gyro] */
|
||||||
FullIMUFactor(const Vector& imu,
|
FullIMUFactor(const Vector6& imu,
|
||||||
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
||||||
: Base(model, key1, key2), accel_(imu.head(3)), gyro_(imu.tail(3)), dt_(dt) {
|
: Base(model, key1, key2), accel_(imu.head(3)), gyro_(imu.tail(3)), dt_(dt) {
|
||||||
assert(imu.size() == 6);
|
assert(imu.size() == 6);
|
||||||
|
@ -68,15 +67,15 @@ public:
|
||||||
void print(const std::string& s="", const gtsam::KeyFormatter& formatter = gtsam::DefaultKeyFormatter) const {
|
void print(const std::string& s="", const gtsam::KeyFormatter& formatter = gtsam::DefaultKeyFormatter) const {
|
||||||
std::string a = "FullIMUFactor: " + s;
|
std::string a = "FullIMUFactor: " + s;
|
||||||
Base::print(a, formatter);
|
Base::print(a, formatter);
|
||||||
gtsam::print(accel_, "accel");
|
gtsam::print((Vector)accel_, "accel");
|
||||||
gtsam::print(gyro_, "gyro");
|
gtsam::print((Vector)gyro_, "gyro");
|
||||||
std::cout << "dt: " << dt_ << std::endl;
|
std::cout << "dt: " << dt_ << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// access
|
// access
|
||||||
const Vector& gyro() const { return gyro_; }
|
const Vector3& gyro() const { return gyro_; }
|
||||||
const Vector& accel() const { return accel_; }
|
const Vector3& accel() const { return accel_; }
|
||||||
Vector z() const { return concatVectors(2, &accel_, &gyro_); }
|
Vector6 z() const { return (Vector6() << accel_, gyro_); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error evaluation with optional derivatives - calculates
|
* Error evaluation with optional derivatives - calculates
|
||||||
|
@ -85,13 +84,13 @@ public:
|
||||||
virtual Vector evaluateError(const PoseRTV& x1, const PoseRTV& x2,
|
virtual Vector evaluateError(const PoseRTV& x1, const PoseRTV& x2,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none) const {
|
boost::optional<Matrix&> H2 = boost::none) const {
|
||||||
Vector z(9);
|
Vector9 z;
|
||||||
z.head(3).operator=(accel_); // Strange syntax to work around ambiguous operator error with clang
|
z.head(3).operator=(accel_); // Strange syntax to work around ambiguous operator error with clang
|
||||||
z.segment(3, 3).operator=(gyro_); // Strange syntax to work around ambiguous operator error with clang
|
z.segment(3, 3).operator=(gyro_); // Strange syntax to work around ambiguous operator error with clang
|
||||||
z.tail(3).operator=(x2.t().vector()); // Strange syntax to work around ambiguous operator error with clang
|
z.tail(3).operator=(x2.t().vector()); // Strange syntax to work around ambiguous operator error with clang
|
||||||
if (H1) *H1 = numericalDerivative21<LieVector, PoseRTV, PoseRTV>(
|
if (H1) *H1 = numericalDerivative21<Vector9, PoseRTV, PoseRTV>(
|
||||||
boost::bind(This::predict_proxy, _1, _2, dt_), x1, x2, 1e-5);
|
boost::bind(This::predict_proxy, _1, _2, dt_), x1, x2, 1e-5);
|
||||||
if (H2) *H2 = numericalDerivative22<LieVector, PoseRTV, PoseRTV>(
|
if (H2) *H2 = numericalDerivative22<Vector9, PoseRTV, PoseRTV>(
|
||||||
boost::bind(This::predict_proxy, _1, _2, dt_), x1, x2, 1e-5);
|
boost::bind(This::predict_proxy, _1, _2, dt_), x1, x2, 1e-5);
|
||||||
return z - predict_proxy(x1, x2, dt_);
|
return z - predict_proxy(x1, x2, dt_);
|
||||||
}
|
}
|
||||||
|
@ -107,11 +106,11 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** copy of the measurement function formulated for numerical derivatives */
|
/** copy of the measurement function formulated for numerical derivatives */
|
||||||
static LieVector predict_proxy(const PoseRTV& x1, const PoseRTV& x2, double dt) {
|
static Vector9 predict_proxy(const PoseRTV& x1, const PoseRTV& x2, double dt) {
|
||||||
Vector hx(9);
|
Vector9 hx;
|
||||||
hx.head(6).operator=(x1.imuPrediction(x2, dt)); // Strange syntax to work around ambiguous operator error with clang
|
hx.head(6).operator=(x1.imuPrediction(x2, dt)); // Strange syntax to work around ambiguous operator error with clang
|
||||||
hx.tail(3).operator=(x1.translationIntegration(x2, dt).vector()); // Strange syntax to work around ambiguous operator error with clang
|
hx.tail(3).operator=(x1.translationIntegration(x2, dt).vector()); // Strange syntax to work around ambiguous operator error with clang
|
||||||
return LieVector(hx);
|
return hx;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam_unstable/dynamics/PoseRTV.h>
|
#include <gtsam_unstable/dynamics/PoseRTV.h>
|
||||||
|
|
||||||
|
@ -27,18 +26,18 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** measurements from the IMU */
|
/** measurements from the IMU */
|
||||||
Vector accel_, gyro_;
|
Vector3 accel_, gyro_;
|
||||||
double dt_; /// time between measurements
|
double dt_; /// time between measurements
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Standard constructor */
|
/** Standard constructor */
|
||||||
IMUFactor(const Vector& accel, const Vector& gyro,
|
IMUFactor(const Vector3& accel, const Vector3& gyro,
|
||||||
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
||||||
: Base(model, key1, key2), accel_(accel), gyro_(gyro), dt_(dt) {}
|
: Base(model, key1, key2), accel_(accel), gyro_(gyro), dt_(dt) {}
|
||||||
|
|
||||||
/** Full IMU vector specification */
|
/** Full IMU vector specification */
|
||||||
IMUFactor(const Vector& imu_vector,
|
IMUFactor(const Vector6& imu_vector,
|
||||||
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
double dt, const Key& key1, const Key& key2, const SharedNoiseModel& model)
|
||||||
: Base(model, key1, key2), accel_(imu_vector.head(3)), gyro_(imu_vector.tail(3)), dt_(dt) {}
|
: Base(model, key1, key2), accel_(imu_vector.head(3)), gyro_(imu_vector.tail(3)), dt_(dt) {}
|
||||||
|
|
||||||
|
@ -61,15 +60,15 @@ public:
|
||||||
void print(const std::string& s="", const gtsam::KeyFormatter& formatter = gtsam::DefaultKeyFormatter) const {
|
void print(const std::string& s="", const gtsam::KeyFormatter& formatter = gtsam::DefaultKeyFormatter) const {
|
||||||
std::string a = "IMUFactor: " + s;
|
std::string a = "IMUFactor: " + s;
|
||||||
Base::print(a, formatter);
|
Base::print(a, formatter);
|
||||||
gtsam::print(accel_, "accel");
|
gtsam::print((Vector)accel_, "accel");
|
||||||
gtsam::print(gyro_, "gyro");
|
gtsam::print((Vector)gyro_, "gyro");
|
||||||
std::cout << "dt: " << dt_ << std::endl;
|
std::cout << "dt: " << dt_ << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// access
|
// access
|
||||||
const Vector& gyro() const { return gyro_; }
|
const Vector3& gyro() const { return gyro_; }
|
||||||
const Vector& accel() const { return accel_; }
|
const Vector3& accel() const { return accel_; }
|
||||||
Vector z() const { return concatVectors(2, &accel_, &gyro_); }
|
Vector6 z() const { return (Vector6() << accel_, gyro_);}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error evaluation with optional derivatives - calculates
|
* Error evaluation with optional derivatives - calculates
|
||||||
|
@ -78,10 +77,10 @@ public:
|
||||||
virtual Vector evaluateError(const PoseRTV& x1, const PoseRTV& x2,
|
virtual Vector evaluateError(const PoseRTV& x1, const PoseRTV& x2,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none) const {
|
boost::optional<Matrix&> H2 = boost::none) const {
|
||||||
const Vector meas = z();
|
const Vector6 meas = z();
|
||||||
if (H1) *H1 = numericalDerivative21<LieVector, PoseRTV, PoseRTV>(
|
if (H1) *H1 = numericalDerivative21<Vector6, PoseRTV, PoseRTV>(
|
||||||
boost::bind(This::predict_proxy, _1, _2, dt_, meas), x1, x2, 1e-5);
|
boost::bind(This::predict_proxy, _1, _2, dt_, meas), x1, x2, 1e-5);
|
||||||
if (H2) *H2 = numericalDerivative22<LieVector, PoseRTV, PoseRTV>(
|
if (H2) *H2 = numericalDerivative22<Vector6, PoseRTV, PoseRTV>(
|
||||||
boost::bind(This::predict_proxy, _1, _2, dt_, meas), x1, x2, 1e-5);
|
boost::bind(This::predict_proxy, _1, _2, dt_, meas), x1, x2, 1e-5);
|
||||||
return predict_proxy(x1, x2, dt_, meas);
|
return predict_proxy(x1, x2, dt_, meas);
|
||||||
}
|
}
|
||||||
|
@ -96,10 +95,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** copy of the measurement function formulated for numerical derivatives */
|
/** copy of the measurement function formulated for numerical derivatives */
|
||||||
static LieVector predict_proxy(const PoseRTV& x1, const PoseRTV& x2,
|
static Vector6 predict_proxy(const PoseRTV& x1, const PoseRTV& x2,
|
||||||
double dt, const Vector& meas) {
|
double dt, const Vector6& meas) {
|
||||||
Vector hx = x1.imuPrediction(x2, dt);
|
Vector6 hx = x1.imuPrediction(x2, dt);
|
||||||
return LieVector(meas - hx);
|
return meas - hx;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -21,11 +20,11 @@ namespace gtsam {
|
||||||
* - For implicit Euler method: q_{k+1} = q_k + h*v_{k+1}
|
* - For implicit Euler method: q_{k+1} = q_k + h*v_{k+1}
|
||||||
* - For sympletic Euler method: q_{k+1} = q_k + h*v_{k+1}
|
* - For sympletic Euler method: q_{k+1} = q_k + h*v_{k+1}
|
||||||
*/
|
*/
|
||||||
class PendulumFactor1: public NoiseModelFactor3<LieScalar, LieScalar, LieScalar> {
|
class PendulumFactor1: public NoiseModelFactor3<double, double, double> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef NoiseModelFactor3<LieScalar, LieScalar, LieScalar> Base;
|
typedef NoiseModelFactor3<double, double, double> Base;
|
||||||
|
|
||||||
/** default constructor to allow for serialization */
|
/** default constructor to allow for serialization */
|
||||||
PendulumFactor1() {}
|
PendulumFactor1() {}
|
||||||
|
@ -38,7 +37,7 @@ public:
|
||||||
|
|
||||||
///Constructor. k1: q_{k+1}, k: q_k, velKey: velocity variable depending on the chosen method, h: time step
|
///Constructor. k1: q_{k+1}, k: q_k, velKey: velocity variable depending on the chosen method, h: time step
|
||||||
PendulumFactor1(Key k1, Key k, Key velKey, double h, double mu = 1000.0)
|
PendulumFactor1(Key k1, Key k, Key velKey, double h, double mu = 1000.0)
|
||||||
: Base(noiseModel::Constrained::All(LieScalar::Dim(), fabs(mu)), k1, k, velKey), h_(h) {}
|
: Base(noiseModel::Constrained::All(1, fabs(mu)), k1, k, velKey), h_(h) {}
|
||||||
|
|
||||||
/// @return a deep copy of this factor
|
/// @return a deep copy of this factor
|
||||||
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
||||||
|
@ -46,15 +45,15 @@ public:
|
||||||
gtsam::NonlinearFactor::shared_ptr(new PendulumFactor1(*this))); }
|
gtsam::NonlinearFactor::shared_ptr(new PendulumFactor1(*this))); }
|
||||||
|
|
||||||
/** q_k + h*v - q_k1 = 0, with optional derivatives */
|
/** q_k + h*v - q_k1 = 0, with optional derivatives */
|
||||||
Vector evaluateError(const LieScalar& qk1, const LieScalar& qk, const LieScalar& v,
|
Vector evaluateError(const double& qk1, const double& qk, const double& v,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
const size_t p = LieScalar::Dim();
|
const size_t p = 1;
|
||||||
if (H1) *H1 = -eye(p);
|
if (H1) *H1 = -eye(p);
|
||||||
if (H2) *H2 = eye(p);
|
if (H2) *H2 = eye(p);
|
||||||
if (H3) *H3 = eye(p)*h_;
|
if (H3) *H3 = eye(p)*h_;
|
||||||
return qk1.localCoordinates(qk.compose(LieScalar(v*h_)));
|
return (Vector(1) << qk+v*h_-qk1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // \PendulumFactor1
|
}; // \PendulumFactor1
|
||||||
|
@ -67,11 +66,11 @@ public:
|
||||||
* - For implicit Euler method: v_{k+1} = v_k - h*g/L*sin(q_{k+1})
|
* - For implicit Euler method: v_{k+1} = v_k - h*g/L*sin(q_{k+1})
|
||||||
* - For sympletic Euler method: v_{k+1} = v_k - h*g/L*sin(q_k)
|
* - For sympletic Euler method: v_{k+1} = v_k - h*g/L*sin(q_k)
|
||||||
*/
|
*/
|
||||||
class PendulumFactor2: public NoiseModelFactor3<LieScalar, LieScalar, LieScalar> {
|
class PendulumFactor2: public NoiseModelFactor3<double, double, double> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef NoiseModelFactor3<LieScalar, LieScalar, LieScalar> Base;
|
typedef NoiseModelFactor3<double, double, double> Base;
|
||||||
|
|
||||||
/** default constructor to allow for serialization */
|
/** default constructor to allow for serialization */
|
||||||
PendulumFactor2() {}
|
PendulumFactor2() {}
|
||||||
|
@ -86,7 +85,7 @@ public:
|
||||||
|
|
||||||
///Constructor. vk1: v_{k+1}, vk: v_k, qkey: q's key depending on the chosen method, h: time step
|
///Constructor. vk1: v_{k+1}, vk: v_k, qkey: q's key depending on the chosen method, h: time step
|
||||||
PendulumFactor2(Key vk1, Key vk, Key qkey, double h, double r = 1.0, double g = 9.81, double mu = 1000.0)
|
PendulumFactor2(Key vk1, Key vk, Key qkey, double h, double r = 1.0, double g = 9.81, double mu = 1000.0)
|
||||||
: Base(noiseModel::Constrained::All(LieScalar::Dim(), fabs(mu)), vk1, vk, qkey), h_(h), g_(g), r_(r) {}
|
: Base(noiseModel::Constrained::All(1, fabs(mu)), vk1, vk, qkey), h_(h), g_(g), r_(r) {}
|
||||||
|
|
||||||
/// @return a deep copy of this factor
|
/// @return a deep copy of this factor
|
||||||
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
virtual gtsam::NonlinearFactor::shared_ptr clone() const {
|
||||||
|
@ -94,15 +93,15 @@ public:
|
||||||
gtsam::NonlinearFactor::shared_ptr(new PendulumFactor2(*this))); }
|
gtsam::NonlinearFactor::shared_ptr(new PendulumFactor2(*this))); }
|
||||||
|
|
||||||
/** v_k - h*g/L*sin(q) - v_k1 = 0, with optional derivatives */
|
/** v_k - h*g/L*sin(q) - v_k1 = 0, with optional derivatives */
|
||||||
Vector evaluateError(const LieScalar& vk1, const LieScalar& vk, const LieScalar& q,
|
Vector evaluateError(const double & vk1, const double & vk, const double & q,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
const size_t p = LieScalar::Dim();
|
const size_t p = 1;
|
||||||
if (H1) *H1 = -eye(p);
|
if (H1) *H1 = -eye(p);
|
||||||
if (H2) *H2 = eye(p);
|
if (H2) *H2 = eye(p);
|
||||||
if (H3) *H3 = -eye(p)*h_*g_/r_*cos(q.value());
|
if (H3) *H3 = -eye(p)*h_*g_/r_*cos(q);
|
||||||
return vk1.localCoordinates(LieScalar(vk - h_*g_/r_*sin(q)));
|
return (Vector(1) << vk - h_ * g_ / r_ * sin(q) - vk1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // \PendulumFactor2
|
}; // \PendulumFactor2
|
||||||
|
@ -114,11 +113,11 @@ public:
|
||||||
* p_k = -D_1 L_d(q_k,q_{k+1},h) = \frac{1}{h}mr^{2}\left(q_{k+1}-q_{k}\right)+mgrh(1-\alpha)\,\sin\left((1-\alpha)q_{k}+\alpha q_{k+1}\right)
|
* p_k = -D_1 L_d(q_k,q_{k+1},h) = \frac{1}{h}mr^{2}\left(q_{k+1}-q_{k}\right)+mgrh(1-\alpha)\,\sin\left((1-\alpha)q_{k}+\alpha q_{k+1}\right)
|
||||||
* = (1/h)mr^2 (q_{k+1}-q_k) + mgrh(1-alpha) sin ((1-alpha)q_k+\alpha q_{k+1})
|
* = (1/h)mr^2 (q_{k+1}-q_k) + mgrh(1-alpha) sin ((1-alpha)q_k+\alpha q_{k+1})
|
||||||
*/
|
*/
|
||||||
class PendulumFactorPk: public NoiseModelFactor3<LieScalar, LieScalar, LieScalar> {
|
class PendulumFactorPk: public NoiseModelFactor3<double, double, double> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef NoiseModelFactor3<LieScalar, LieScalar, LieScalar> Base;
|
typedef NoiseModelFactor3<double, double, double> Base;
|
||||||
|
|
||||||
/** default constructor to allow for serialization */
|
/** default constructor to allow for serialization */
|
||||||
PendulumFactorPk() {}
|
PendulumFactorPk() {}
|
||||||
|
@ -136,7 +135,7 @@ public:
|
||||||
///Constructor
|
///Constructor
|
||||||
PendulumFactorPk(Key pKey, Key qKey, Key qKey1,
|
PendulumFactorPk(Key pKey, Key qKey, Key qKey1,
|
||||||
double h, double m = 1.0, double r = 1.0, double g = 9.81, double alpha = 0.0, double mu = 1000.0)
|
double h, double m = 1.0, double r = 1.0, double g = 9.81, double alpha = 0.0, double mu = 1000.0)
|
||||||
: Base(noiseModel::Constrained::All(LieScalar::Dim(), fabs(mu)), pKey, qKey, qKey1),
|
: Base(noiseModel::Constrained::All(1, fabs(mu)), pKey, qKey, qKey1),
|
||||||
h_(h), m_(m), r_(r), g_(g), alpha_(alpha) {}
|
h_(h), m_(m), r_(r), g_(g), alpha_(alpha) {}
|
||||||
|
|
||||||
/// @return a deep copy of this factor
|
/// @return a deep copy of this factor
|
||||||
|
@ -145,11 +144,11 @@ public:
|
||||||
gtsam::NonlinearFactor::shared_ptr(new PendulumFactorPk(*this))); }
|
gtsam::NonlinearFactor::shared_ptr(new PendulumFactorPk(*this))); }
|
||||||
|
|
||||||
/** 1/h mr^2 (qk1-qk)+mgrh (1-a) sin((1-a)pk + a*pk1) - pk = 0, with optional derivatives */
|
/** 1/h mr^2 (qk1-qk)+mgrh (1-a) sin((1-a)pk + a*pk1) - pk = 0, with optional derivatives */
|
||||||
Vector evaluateError(const LieScalar& pk, const LieScalar& qk, const LieScalar& qk1,
|
Vector evaluateError(const double & pk, const double & qk, const double & qk1,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
const size_t p = LieScalar::Dim();
|
const size_t p = 1;
|
||||||
|
|
||||||
double qmid = (1-alpha_)*qk + alpha_*qk1;
|
double qmid = (1-alpha_)*qk + alpha_*qk1;
|
||||||
double mr2_h = 1/h_*m_*r_*r_;
|
double mr2_h = 1/h_*m_*r_*r_;
|
||||||
|
@ -159,7 +158,7 @@ public:
|
||||||
if (H2) *H2 = eye(p)*(-mr2_h + mgrh*(1-alpha_)*(1-alpha_)*cos(qmid));
|
if (H2) *H2 = eye(p)*(-mr2_h + mgrh*(1-alpha_)*(1-alpha_)*cos(qmid));
|
||||||
if (H3) *H3 = eye(p)*( mr2_h + mgrh*(1-alpha_)*(alpha_)*cos(qmid));
|
if (H3) *H3 = eye(p)*( mr2_h + mgrh*(1-alpha_)*(alpha_)*cos(qmid));
|
||||||
|
|
||||||
return pk.localCoordinates(LieScalar(mr2_h*(qk1-qk) + mgrh*(1-alpha_)*sin(qmid)));
|
return (Vector(1) << mr2_h * (qk1 - qk) + mgrh * (1 - alpha_) * sin(qmid) - pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // \PendulumFactorPk
|
}; // \PendulumFactorPk
|
||||||
|
@ -170,11 +169,11 @@ public:
|
||||||
* p_k1 = D_2 L_d(q_k,q_{k+1},h) = \frac{1}{h}mr^{2}\left(q_{k+1}-q_{k}\right)-mgrh\alpha\sin\left((1-\alpha)q_{k}+\alpha q_{k+1}\right)
|
* p_k1 = D_2 L_d(q_k,q_{k+1},h) = \frac{1}{h}mr^{2}\left(q_{k+1}-q_{k}\right)-mgrh\alpha\sin\left((1-\alpha)q_{k}+\alpha q_{k+1}\right)
|
||||||
* = (1/h)mr^2 (q_{k+1}-q_k) - mgrh alpha sin ((1-alpha)q_k+\alpha q_{k+1})
|
* = (1/h)mr^2 (q_{k+1}-q_k) - mgrh alpha sin ((1-alpha)q_k+\alpha q_{k+1})
|
||||||
*/
|
*/
|
||||||
class PendulumFactorPk1: public NoiseModelFactor3<LieScalar, LieScalar, LieScalar> {
|
class PendulumFactorPk1: public NoiseModelFactor3<double, double, double> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef NoiseModelFactor3<LieScalar, LieScalar, LieScalar> Base;
|
typedef NoiseModelFactor3<double, double, double> Base;
|
||||||
|
|
||||||
/** default constructor to allow for serialization */
|
/** default constructor to allow for serialization */
|
||||||
PendulumFactorPk1() {}
|
PendulumFactorPk1() {}
|
||||||
|
@ -192,7 +191,7 @@ public:
|
||||||
///Constructor
|
///Constructor
|
||||||
PendulumFactorPk1(Key pKey1, Key qKey, Key qKey1,
|
PendulumFactorPk1(Key pKey1, Key qKey, Key qKey1,
|
||||||
double h, double m = 1.0, double r = 1.0, double g = 9.81, double alpha = 0.0, double mu = 1000.0)
|
double h, double m = 1.0, double r = 1.0, double g = 9.81, double alpha = 0.0, double mu = 1000.0)
|
||||||
: Base(noiseModel::Constrained::All(LieScalar::Dim(), fabs(mu)), pKey1, qKey, qKey1),
|
: Base(noiseModel::Constrained::All(1, fabs(mu)), pKey1, qKey, qKey1),
|
||||||
h_(h), m_(m), r_(r), g_(g), alpha_(alpha) {}
|
h_(h), m_(m), r_(r), g_(g), alpha_(alpha) {}
|
||||||
|
|
||||||
/// @return a deep copy of this factor
|
/// @return a deep copy of this factor
|
||||||
|
@ -201,11 +200,11 @@ public:
|
||||||
gtsam::NonlinearFactor::shared_ptr(new PendulumFactorPk1(*this))); }
|
gtsam::NonlinearFactor::shared_ptr(new PendulumFactorPk1(*this))); }
|
||||||
|
|
||||||
/** 1/h mr^2 (qk1-qk) - mgrh a sin((1-a)pk + a*pk1) - pk1 = 0, with optional derivatives */
|
/** 1/h mr^2 (qk1-qk) - mgrh a sin((1-a)pk + a*pk1) - pk1 = 0, with optional derivatives */
|
||||||
Vector evaluateError(const LieScalar& pk1, const LieScalar& qk, const LieScalar& qk1,
|
Vector evaluateError(const double & pk1, const double & qk, const double & qk1,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
const size_t p = LieScalar::Dim();
|
const size_t p = 1;
|
||||||
|
|
||||||
double qmid = (1-alpha_)*qk + alpha_*qk1;
|
double qmid = (1-alpha_)*qk + alpha_*qk1;
|
||||||
double mr2_h = 1/h_*m_*r_*r_;
|
double mr2_h = 1/h_*m_*r_*r_;
|
||||||
|
@ -215,7 +214,7 @@ public:
|
||||||
if (H2) *H2 = eye(p)*(-mr2_h - mgrh*(1-alpha_)*alpha_*cos(qmid));
|
if (H2) *H2 = eye(p)*(-mr2_h - mgrh*(1-alpha_)*alpha_*cos(qmid));
|
||||||
if (H3) *H3 = eye(p)*( mr2_h - mgrh*alpha_*alpha_*cos(qmid));
|
if (H3) *H3 = eye(p)*( mr2_h - mgrh*alpha_*alpha_*cos(qmid));
|
||||||
|
|
||||||
return pk1.localCoordinates(LieScalar(mr2_h*(qk1-qk) - mgrh*alpha_*sin(qmid)));
|
return (Vector(1) << mr2_h * (qk1 - qk) - mgrh * alpha_ * sin(qmid) - pk1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // \PendulumFactorPk1
|
}; // \PendulumFactorPk1
|
||||||
|
|
|
@ -57,18 +57,17 @@ void PoseRTV::print(const string& s) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
PoseRTV PoseRTV::Expmap(const Vector& v) {
|
PoseRTV PoseRTV::Expmap(const Vector9& v) {
|
||||||
assert(v.size() == 9);
|
Pose3 newPose = Pose3::Expmap(v.head<6>());
|
||||||
Pose3 newPose = Pose3::Expmap(sub(v, 0, 6));
|
Velocity3 newVel = Velocity3::Expmap(v.tail<3>());
|
||||||
Velocity3 newVel = Velocity3::Expmap(sub(v, 6, 9));
|
|
||||||
return PoseRTV(newPose, newVel);
|
return PoseRTV(newPose, newVel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Vector PoseRTV::Logmap(const PoseRTV& p) {
|
Vector9 PoseRTV::Logmap(const PoseRTV& p) {
|
||||||
Vector Lx = Pose3::Logmap(p.Rt_);
|
Vector6 Lx = Pose3::Logmap(p.Rt_);
|
||||||
Vector Lv = Velocity3::Logmap(p.v_);
|
Vector3 Lv = Velocity3::Logmap(p.v_);
|
||||||
return concatVectors(2, &Lx, &Lv);
|
return (Vector9() << Lx, Lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -84,9 +83,9 @@ PoseRTV PoseRTV::retract(const Vector& v) const {
|
||||||
Vector PoseRTV::localCoordinates(const PoseRTV& p1) const {
|
Vector PoseRTV::localCoordinates(const PoseRTV& p1) const {
|
||||||
const Pose3& x0 = pose(), &x1 = p1.pose();
|
const Pose3& x0 = pose(), &x1 = p1.pose();
|
||||||
// First order approximation
|
// First order approximation
|
||||||
Vector poseLogmap = x0.localCoordinates(x1);
|
Vector6 poseLogmap = x0.localCoordinates(x1);
|
||||||
Vector lv = rotation().unrotate(p1.velocity() - v_).vector();
|
Vector3 lv = rotation().unrotate(p1.velocity() - v_).vector();
|
||||||
return concatVectors(2, &poseLogmap, &lv);
|
return (Vector(9) << poseLogmap, lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -190,16 +189,16 @@ PoseRTV PoseRTV::generalDynamics(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Vector PoseRTV::imuPrediction(const PoseRTV& x2, double dt) const {
|
Vector6 PoseRTV::imuPrediction(const PoseRTV& x2, double dt) const {
|
||||||
// split out states
|
// split out states
|
||||||
const Rot3 &r1 = R(), &r2 = x2.R();
|
const Rot3 &r1 = R(), &r2 = x2.R();
|
||||||
const Velocity3 &v1 = v(), &v2 = x2.v();
|
const Velocity3 &v1 = v(), &v2 = x2.v();
|
||||||
|
|
||||||
Vector imu(6);
|
Vector6 imu;
|
||||||
|
|
||||||
// acceleration
|
// acceleration
|
||||||
Vector accel = v1.localCoordinates(v2) / dt;
|
Vector accel = v1.localCoordinates(v2) / dt;
|
||||||
imu.head(3) = r2.transpose() * (accel - g);
|
imu.head<3>() = r2.transpose() * (accel - g);
|
||||||
|
|
||||||
// rotation rates
|
// rotation rates
|
||||||
// just using euler angles based on matlab code
|
// just using euler angles based on matlab code
|
||||||
|
@ -211,7 +210,7 @@ Vector PoseRTV::imuPrediction(const PoseRTV& x2, double dt) const {
|
||||||
// normalize yaw in difference (as per Mitch's code)
|
// normalize yaw in difference (as per Mitch's code)
|
||||||
dR(2) = Rot2::fromAngle(dR(2)).theta();
|
dR(2) = Rot2::fromAngle(dR(2)).theta();
|
||||||
dR /= dt;
|
dR /= dt;
|
||||||
imu.tail(3) = Enb * dR;
|
imu.tail<3>() = Enb * dR;
|
||||||
// imu.tail(3) = r1.transpose() * dR;
|
// imu.tail(3) = r1.transpose() * dR;
|
||||||
|
|
||||||
return imu;
|
return imu;
|
||||||
|
|
|
@ -86,8 +86,8 @@ public:
|
||||||
* expmap/logmap are poor approximations that assume independence of components
|
* expmap/logmap are poor approximations that assume independence of components
|
||||||
* Currently implemented using the poor retract/unretract approximations
|
* Currently implemented using the poor retract/unretract approximations
|
||||||
*/
|
*/
|
||||||
static PoseRTV Expmap(const Vector& v);
|
static PoseRTV Expmap(const Vector9& v);
|
||||||
static Vector Logmap(const PoseRTV& p);
|
static Vector9 Logmap(const PoseRTV& p);
|
||||||
|
|
||||||
static PoseRTV identity() { return PoseRTV(); }
|
static PoseRTV identity() { return PoseRTV(); }
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ public:
|
||||||
/// Dynamics predictor for both ground and flying robots, given states at 1 and 2
|
/// Dynamics predictor for both ground and flying robots, given states at 1 and 2
|
||||||
/// Always move from time 1 to time 2
|
/// Always move from time 1 to time 2
|
||||||
/// @return imu measurement, as [accel, gyro]
|
/// @return imu measurement, as [accel, gyro]
|
||||||
Vector imuPrediction(const PoseRTV& x2, double dt) const;
|
Vector6 imuPrediction(const PoseRTV& x2, double dt) const;
|
||||||
|
|
||||||
/// predict measurement and where Point3 for x2 should be, as a way
|
/// predict measurement and where Point3 for x2 should be, as a way
|
||||||
/// of enforcing a velocity constraint
|
/// of enforcing a velocity constraint
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -24,10 +23,10 @@ namespace gtsam {
|
||||||
* Note: this factor is necessary if one needs to smooth the entire graph. It's not needed
|
* Note: this factor is necessary if one needs to smooth the entire graph. It's not needed
|
||||||
* in sequential update method.
|
* in sequential update method.
|
||||||
*/
|
*/
|
||||||
class Reconstruction : public NoiseModelFactor3<Pose3, Pose3, LieVector> {
|
class Reconstruction : public NoiseModelFactor3<Pose3, Pose3, Vector6> {
|
||||||
|
|
||||||
double h_; // time step
|
double h_; // time step
|
||||||
typedef NoiseModelFactor3<Pose3, Pose3, LieVector> Base;
|
typedef NoiseModelFactor3<Pose3, Pose3, Vector6> Base;
|
||||||
public:
|
public:
|
||||||
Reconstruction(Key gKey1, Key gKey, Key xiKey, double h, double mu = 1000.0) :
|
Reconstruction(Key gKey1, Key gKey, Key xiKey, double h, double mu = 1000.0) :
|
||||||
Base(noiseModel::Constrained::All(Pose3::Dim(), fabs(mu)), gKey1, gKey,
|
Base(noiseModel::Constrained::All(Pose3::Dim(), fabs(mu)), gKey1, gKey,
|
||||||
|
@ -41,7 +40,7 @@ public:
|
||||||
gtsam::NonlinearFactor::shared_ptr(new Reconstruction(*this))); }
|
gtsam::NonlinearFactor::shared_ptr(new Reconstruction(*this))); }
|
||||||
|
|
||||||
/** \f$ log((g_k\exp(h\xi_k))^{-1}g_{k+1}) = 0, with optional derivatives */
|
/** \f$ log((g_k\exp(h\xi_k))^{-1}g_{k+1}) = 0, with optional derivatives */
|
||||||
Vector evaluateError(const Pose3& gk1, const Pose3& gk, const LieVector& xik,
|
Vector evaluateError(const Pose3& gk1, const Pose3& gk, const Vector6& xik,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
|
@ -74,7 +73,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Implement the Discrete Euler-Poincare' equation:
|
* Implement the Discrete Euler-Poincare' equation:
|
||||||
*/
|
*/
|
||||||
class DiscreteEulerPoincareHelicopter : public NoiseModelFactor3<LieVector, LieVector, Pose3> {
|
class DiscreteEulerPoincareHelicopter : public NoiseModelFactor3<Vector6, Vector6, Pose3> {
|
||||||
|
|
||||||
double h_; /// time step
|
double h_; /// time step
|
||||||
Matrix Inertia_; /// Inertia tensors Inertia = [ J 0; 0 M ]
|
Matrix Inertia_; /// Inertia tensors Inertia = [ J 0; 0 M ]
|
||||||
|
@ -87,7 +86,7 @@ class DiscreteEulerPoincareHelicopter : public NoiseModelFactor3<LieVector, LieV
|
||||||
// This might be needed in control or system identification problems.
|
// This might be needed in control or system identification problems.
|
||||||
// We treat them as constant here, since the control inputs are to specify.
|
// We treat them as constant here, since the control inputs are to specify.
|
||||||
|
|
||||||
typedef NoiseModelFactor3<LieVector, LieVector, Pose3> Base;
|
typedef NoiseModelFactor3<Vector6, Vector6, Pose3> Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiscreteEulerPoincareHelicopter(Key xiKey1, Key xiKey_1, Key gKey,
|
DiscreteEulerPoincareHelicopter(Key xiKey1, Key xiKey_1, Key gKey,
|
||||||
|
@ -108,7 +107,7 @@ public:
|
||||||
* where pk = CT_TLN(h*xi_k)*Inertia*xi_k
|
* where pk = CT_TLN(h*xi_k)*Inertia*xi_k
|
||||||
* pk_1 = CT_TLN(-h*xi_k_1)*Inertia*xi_k_1
|
* pk_1 = CT_TLN(-h*xi_k_1)*Inertia*xi_k_1
|
||||||
* */
|
* */
|
||||||
Vector evaluateError(const LieVector& xik, const LieVector& xik_1, const Pose3& gk,
|
Vector evaluateError(const Vector6& xik, const Vector6& xik_1, const Pose3& gk,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
|
@ -149,7 +148,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
Vector computeError(const LieVector& xik, const LieVector& xik_1, const Pose3& gk) const {
|
Vector computeError(const Vector6& xik, const Vector6& xik_1, const Pose3& gk) const {
|
||||||
Vector pk = Pose3::dExpInv_exp(h_*xik).transpose()*Inertia_*xik;
|
Vector pk = Pose3::dExpInv_exp(h_*xik).transpose()*Inertia_*xik;
|
||||||
Vector pk_1 = Pose3::dExpInv_exp(-h_*xik_1).transpose()*Inertia_*xik_1;
|
Vector pk_1 = Pose3::dExpInv_exp(-h_*xik_1).transpose()*Inertia_*xik_1;
|
||||||
|
|
||||||
|
@ -161,13 +160,13 @@ public:
|
||||||
return hx;
|
return hx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector evaluateError(const LieVector& xik, const LieVector& xik_1, const Pose3& gk,
|
Vector evaluateError(const Vector6& xik, const Vector6& xik_1, const Pose3& gk,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
if (H1) {
|
if (H1) {
|
||||||
(*H1) = numericalDerivative31(
|
(*H1) = numericalDerivative31(
|
||||||
boost::function<Vector(const LieVector&, const LieVector&, const Pose3&)>(
|
boost::function<Vector(const Vector6&, const Vector6&, const Pose3&)>(
|
||||||
boost::bind(&DiscreteEulerPoincareHelicopter::computeError, *this, _1, _2, _3)
|
boost::bind(&DiscreteEulerPoincareHelicopter::computeError, *this, _1, _2, _3)
|
||||||
),
|
),
|
||||||
xik, xik_1, gk, 1e-5
|
xik, xik_1, gk, 1e-5
|
||||||
|
@ -175,7 +174,7 @@ public:
|
||||||
}
|
}
|
||||||
if (H2) {
|
if (H2) {
|
||||||
(*H2) = numericalDerivative32(
|
(*H2) = numericalDerivative32(
|
||||||
boost::function<Vector(const LieVector&, const LieVector&, const Pose3&)>(
|
boost::function<Vector(const Vector6&, const Vector6&, const Pose3&)>(
|
||||||
boost::bind(&DiscreteEulerPoincareHelicopter::computeError, *this, _1, _2, _3)
|
boost::bind(&DiscreteEulerPoincareHelicopter::computeError, *this, _1, _2, _3)
|
||||||
),
|
),
|
||||||
xik, xik_1, gk, 1e-5
|
xik, xik_1, gk, 1e-5
|
||||||
|
@ -183,7 +182,7 @@ public:
|
||||||
}
|
}
|
||||||
if (H3) {
|
if (H3) {
|
||||||
(*H3) = numericalDerivative33(
|
(*H3) = numericalDerivative33(
|
||||||
boost::function<Vector(const LieVector&, const LieVector&, const Pose3&)>(
|
boost::function<Vector(const Vector6&, const Vector6&, const Pose3&)>(
|
||||||
boost::bind(&DiscreteEulerPoincareHelicopter::computeError, *this, _1, _2, _3)
|
boost::bind(&DiscreteEulerPoincareHelicopter::computeError, *this, _1, _2, _3)
|
||||||
),
|
),
|
||||||
xik, xik_1, gk, 1e-5
|
xik, xik_1, gk, 1e-5
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
/**
|
/**
|
||||||
* @file VelocityConstraint3.h
|
* @file VelocityConstraint3.h
|
||||||
* @brief A simple 3-way factor constraining LieScalar poses and velocity
|
* @brief A simple 3-way factor constraining double poses and velocity
|
||||||
* @author Duy-Nguyen Ta
|
* @author Duy-Nguyen Ta
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
class VelocityConstraint3 : public NoiseModelFactor3<LieScalar, LieScalar, LieScalar> {
|
class VelocityConstraint3 : public NoiseModelFactor3<double, double, double> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef NoiseModelFactor3<LieScalar, LieScalar, LieScalar> Base;
|
typedef NoiseModelFactor3<double, double, double> Base;
|
||||||
|
|
||||||
/** default constructor to allow for serialization */
|
/** default constructor to allow for serialization */
|
||||||
VelocityConstraint3() {}
|
VelocityConstraint3() {}
|
||||||
|
@ -28,7 +27,7 @@ public:
|
||||||
|
|
||||||
///TODO: comment
|
///TODO: comment
|
||||||
VelocityConstraint3(Key key1, Key key2, Key velKey, double dt, double mu = 1000.0)
|
VelocityConstraint3(Key key1, Key key2, Key velKey, double dt, double mu = 1000.0)
|
||||||
: Base(noiseModel::Constrained::All(LieScalar::Dim(), fabs(mu)), key1, key2, velKey), dt_(dt) {}
|
: Base(noiseModel::Constrained::All(1, fabs(mu)), key1, key2, velKey), dt_(dt) {}
|
||||||
virtual ~VelocityConstraint3() {}
|
virtual ~VelocityConstraint3() {}
|
||||||
|
|
||||||
/// @return a deep copy of this factor
|
/// @return a deep copy of this factor
|
||||||
|
@ -37,15 +36,15 @@ public:
|
||||||
gtsam::NonlinearFactor::shared_ptr(new VelocityConstraint3(*this))); }
|
gtsam::NonlinearFactor::shared_ptr(new VelocityConstraint3(*this))); }
|
||||||
|
|
||||||
/** x1 + v*dt - x2 = 0, with optional derivatives */
|
/** x1 + v*dt - x2 = 0, with optional derivatives */
|
||||||
Vector evaluateError(const LieScalar& x1, const LieScalar& x2, const LieScalar& v,
|
Vector evaluateError(const double& x1, const double& x2, const double& v,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none) const {
|
boost::optional<Matrix&> H3 = boost::none) const {
|
||||||
const size_t p = LieScalar::Dim();
|
const size_t p = 1;
|
||||||
if (H1) *H1 = eye(p);
|
if (H1) *H1 = eye(p);
|
||||||
if (H2) *H2 = -eye(p);
|
if (H2) *H2 = -eye(p);
|
||||||
if (H3) *H3 = eye(p)*dt_;
|
if (H3) *H3 = eye(p)*dt_;
|
||||||
return x2.localCoordinates(x1.compose(LieScalar(v*dt_)));
|
return (Vector(1) << x1+v*dt_-x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -62,10 +62,9 @@ TEST( testIMUSystem, optimize_chain ) {
|
||||||
|
|
||||||
// create measurements
|
// create measurements
|
||||||
SharedDiagonal model = noiseModel::Unit::Create(6);
|
SharedDiagonal model = noiseModel::Unit::Create(6);
|
||||||
Vector imu12(6), imu23(6), imu34(6);
|
Vector6 imu12 = pose1.imuPrediction(pose2, dt);
|
||||||
imu12 = pose1.imuPrediction(pose2, dt);
|
Vector6 imu23 = pose2.imuPrediction(pose3, dt);
|
||||||
imu23 = pose2.imuPrediction(pose3, dt);
|
Vector6 imu34 = pose3.imuPrediction(pose4, dt);
|
||||||
imu34 = pose3.imuPrediction(pose4, dt);
|
|
||||||
|
|
||||||
// assemble simple graph with IMU measurements and velocity constraints
|
// assemble simple graph with IMU measurements and velocity constraints
|
||||||
NonlinearFactorGraph graph;
|
NonlinearFactorGraph graph;
|
||||||
|
@ -109,10 +108,9 @@ TEST( testIMUSystem, optimize_chain_fullfactor ) {
|
||||||
|
|
||||||
// create measurements
|
// create measurements
|
||||||
SharedDiagonal model = noiseModel::Isotropic::Sigma(9, 1.0);
|
SharedDiagonal model = noiseModel::Isotropic::Sigma(9, 1.0);
|
||||||
Vector imu12(6), imu23(6), imu34(6);
|
Vector6 imu12 = pose1.imuPrediction(pose2, dt);
|
||||||
imu12 = pose1.imuPrediction(pose2, dt);
|
Vector6 imu23 = pose2.imuPrediction(pose3, dt);
|
||||||
imu23 = pose2.imuPrediction(pose3, dt);
|
Vector6 imu34 = pose3.imuPrediction(pose4, dt);
|
||||||
imu34 = pose3.imuPrediction(pose4, dt);
|
|
||||||
|
|
||||||
// assemble simple graph with IMU measurements and velocity constraints
|
// assemble simple graph with IMU measurements and velocity constraints
|
||||||
NonlinearFactorGraph graph;
|
NonlinearFactorGraph graph;
|
||||||
|
|
|
@ -18,8 +18,8 @@ namespace {
|
||||||
const double g = 9.81, l = 1.0;
|
const double g = 9.81, l = 1.0;
|
||||||
|
|
||||||
const double deg2rad = M_PI/180.0;
|
const double deg2rad = M_PI/180.0;
|
||||||
LieScalar origin, q1(deg2rad*30.0), q2(deg2rad*31.0);
|
double q1(deg2rad*30.0), q2(deg2rad*31.0);
|
||||||
LieScalar v1(deg2rad*1.0/h), v2((v1-h*g/l*sin(q1)));
|
double v1(deg2rad*1.0/h), v2((v1-h*g/l*sin(q1)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ TEST( testPendulumFactorPk, evaluateError) {
|
||||||
// hard constraints don't need a noise model
|
// hard constraints don't need a noise model
|
||||||
PendulumFactorPk constraint(P(1), Q(1), Q(2), h);
|
PendulumFactorPk constraint(P(1), Q(1), Q(2), h);
|
||||||
|
|
||||||
LieScalar pk( 1/h * (q2-q1) + h*g*sin(q1) );
|
double pk( 1/h * (q2-q1) + h*g*sin(q1) );
|
||||||
|
|
||||||
// verify error function
|
// verify error function
|
||||||
EXPECT(assert_equal(zero(1), constraint.evaluateError(pk, q1, q2), tol));
|
EXPECT(assert_equal(zero(1), constraint.evaluateError(pk, q1, q2), tol));
|
||||||
|
@ -57,7 +57,7 @@ TEST( testPendulumFactorPk1, evaluateError) {
|
||||||
// hard constraints don't need a noise model
|
// hard constraints don't need a noise model
|
||||||
PendulumFactorPk1 constraint(P(2), Q(1), Q(2), h);
|
PendulumFactorPk1 constraint(P(2), Q(1), Q(2), h);
|
||||||
|
|
||||||
LieScalar pk1( 1/h * (q2-q1) );
|
double pk1( 1/h * (q2-q1) );
|
||||||
|
|
||||||
// verify error function
|
// verify error function
|
||||||
EXPECT(assert_equal(zero(1), constraint.evaluateError(pk1, q1, q2), tol));
|
EXPECT(assert_equal(zero(1), constraint.evaluateError(pk1, q1, q2), tol));
|
||||||
|
|
|
@ -8,23 +8,16 @@
|
||||||
#include <gtsam/inference/Symbol.h>
|
#include <gtsam/inference/Symbol.h>
|
||||||
#include <gtsam_unstable/dynamics/VelocityConstraint3.h>
|
#include <gtsam_unstable/dynamics/VelocityConstraint3.h>
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
using namespace gtsam::symbol_shorthand;
|
||||||
namespace {
|
|
||||||
|
|
||||||
const double tol=1e-5;
|
|
||||||
const double dt = 1.0;
|
|
||||||
|
|
||||||
LieScalar origin,
|
|
||||||
x1(1.0), x2(2.0), v(1.0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
// evaluateError
|
||||||
TEST( testVelocityConstraint3, evaluateError) {
|
TEST( testVelocityConstraint3, evaluateError) {
|
||||||
|
|
||||||
using namespace gtsam::symbol_shorthand;
|
const double tol = 1e-5;
|
||||||
|
const double dt = 1.0;
|
||||||
|
double x1(1.0), x2(2.0), v(1.0);
|
||||||
|
|
||||||
// hard constraints don't need a noise model
|
// hard constraints don't need a noise model
|
||||||
VelocityConstraint3 constraint(X(1), X(2), V(1), dt);
|
VelocityConstraint3 constraint(X(1), X(2), V(1), dt);
|
||||||
|
@ -33,7 +26,9 @@ TEST( testVelocityConstraint3, evaluateError) {
|
||||||
EXPECT(assert_equal(zero(1), constraint.evaluateError(x1, x2, v), tol));
|
EXPECT(assert_equal(zero(1), constraint.evaluateError(x1, x2, v), tol));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
int main() {
|
||||||
|
TestResult tr;
|
||||||
|
return TestRegistry::runAllTests(tr);
|
||||||
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/serialization/nvp.hpp>
|
#include <boost/serialization/nvp.hpp>
|
||||||
#include <gtsam/base/Vector.h>
|
#include <gtsam/base/Vector.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/LieScalar.h>
|
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
#include <gtsam/geometry/Point2.h>
|
#include <gtsam/geometry/Point2.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
|
@ -71,10 +69,9 @@ public:
|
||||||
* @param inv inverse depth
|
* @param inv inverse depth
|
||||||
* @return Point3
|
* @return Point3
|
||||||
*/
|
*/
|
||||||
static gtsam::Point3 invDepthTo3D(const gtsam::LieVector& pw, const gtsam::LieScalar& inv) {
|
static gtsam::Point3 invDepthTo3D(const Vector5& pw, double rho) {
|
||||||
gtsam::Point3 ray_base(pw.vector().segment(0,3));
|
gtsam::Point3 ray_base(pw.segment(0,3));
|
||||||
double theta = pw(3), phi = pw(4);
|
double theta = pw(3), phi = pw(4);
|
||||||
double rho = inv.value(); // inverse depth
|
|
||||||
gtsam::Point3 m(cos(theta)*cos(phi),sin(theta)*cos(phi),sin(phi));
|
gtsam::Point3 m(cos(theta)*cos(phi),sin(theta)*cos(phi),sin(phi));
|
||||||
return ray_base + m/rho;
|
return ray_base + m/rho;
|
||||||
}
|
}
|
||||||
|
@ -84,15 +81,14 @@ public:
|
||||||
* @param H1 is the jacobian w.r.t. [pose3 calibration]
|
* @param H1 is the jacobian w.r.t. [pose3 calibration]
|
||||||
* @param H2 is the jacobian w.r.t. inv_depth_landmark
|
* @param H2 is the jacobian w.r.t. inv_depth_landmark
|
||||||
*/
|
*/
|
||||||
inline gtsam::Point2 project(const gtsam::LieVector& pw,
|
inline gtsam::Point2 project(const Vector5& pw,
|
||||||
const gtsam::LieScalar& inv_depth,
|
double rho,
|
||||||
boost::optional<gtsam::Matrix&> H1 = boost::none,
|
boost::optional<gtsam::Matrix&> H1 = boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H2 = boost::none,
|
boost::optional<gtsam::Matrix&> H2 = boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H3 = boost::none) const {
|
boost::optional<gtsam::Matrix&> H3 = boost::none) const {
|
||||||
|
|
||||||
gtsam::Point3 ray_base(pw.vector().segment(0,3));
|
gtsam::Point3 ray_base(pw.segment(0,3));
|
||||||
double theta = pw(3), phi = pw(4);
|
double theta = pw(3), phi = pw(4);
|
||||||
double rho = inv_depth.value(); // inverse depth
|
|
||||||
gtsam::Point3 m(cos(theta)*cos(phi),sin(theta)*cos(phi),sin(phi));
|
gtsam::Point3 m(cos(theta)*cos(phi),sin(theta)*cos(phi),sin(phi));
|
||||||
const gtsam::Point3 landmark = ray_base + m/rho;
|
const gtsam::Point3 landmark = ray_base + m/rho;
|
||||||
|
|
||||||
|
@ -157,7 +153,7 @@ public:
|
||||||
* useful for point initialization
|
* useful for point initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline std::pair<gtsam::LieVector, gtsam::LieScalar> backproject(const gtsam::Point2& pi, const double depth) const {
|
inline std::pair<Vector5, double> backproject(const gtsam::Point2& pi, const double depth) const {
|
||||||
const gtsam::Point2 pn = k_->calibrate(pi);
|
const gtsam::Point2 pn = k_->calibrate(pi);
|
||||||
gtsam::Point3 pc(pn.x(), pn.y(), 1.0);
|
gtsam::Point3 pc(pn.x(), pn.y(), 1.0);
|
||||||
pc = pc/pc.norm();
|
pc = pc/pc.norm();
|
||||||
|
@ -166,8 +162,8 @@ public:
|
||||||
gtsam::Point3 ray = pw - pt;
|
gtsam::Point3 ray = pw - pt;
|
||||||
double theta = atan2(ray.y(), ray.x()); // longitude
|
double theta = atan2(ray.y(), ray.x()); // longitude
|
||||||
double phi = atan2(ray.z(), sqrt(ray.x()*ray.x()+ray.y()*ray.y()));
|
double phi = atan2(ray.z(), sqrt(ray.x()*ray.x()+ray.y()*ray.y()));
|
||||||
return std::make_pair(gtsam::LieVector((Vector(5) << pt.x(),pt.y(),pt.z(), theta, phi)),
|
return std::make_pair(Vector5((Vector(5) << pt.x(),pt.y(),pt.z(), theta, phi)),
|
||||||
gtsam::LieScalar(1./depth));
|
double(1./depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -30,9 +30,9 @@ TEST( InvDepthFactor, Project1) {
|
||||||
|
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
||||||
Vector5 inv_landmark((Vector(5) << 1., 0., 1., 0., 0.));
|
Vector5 inv_landmark((Vector(5) << 1., 0., 1., 0., 0.));
|
||||||
LieScalar inv_depth(1./4);
|
double inv_depth(1./4);
|
||||||
Point2 actual_uv = inv_camera.project(inv_landmark, inv_depth);
|
Point2 actual_uv = inv_camera.project(inv_landmark, inv_depth);
|
||||||
EXPECT(assert_equal(expected_uv, actual_uv));
|
EXPECT(assert_equal(expected_uv, actual_uv,1e-8));
|
||||||
EXPECT(assert_equal(Point2(640,480), actual_uv));
|
EXPECT(assert_equal(Point2(640,480), actual_uv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ TEST( InvDepthFactor, Project2) {
|
||||||
|
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
||||||
Vector5 diag_landmark((Vector(5) << 0., 0., 1., M_PI/4., atan(1.0/sqrt(2.0))));
|
Vector5 diag_landmark((Vector(5) << 0., 0., 1., M_PI/4., atan(1.0/sqrt(2.0))));
|
||||||
LieScalar inv_depth(1/sqrt(3.0));
|
double inv_depth(1/sqrt(3.0));
|
||||||
Point2 actual = inv_camera.project(diag_landmark, inv_depth);
|
Point2 actual = inv_camera.project(diag_landmark, inv_depth);
|
||||||
EXPECT(assert_equal(expected, actual));
|
EXPECT(assert_equal(expected, actual));
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ TEST( InvDepthFactor, Project3) {
|
||||||
|
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
||||||
Vector5 diag_landmark((Vector(5) << 0., 0., 0., M_PI/4., atan(2./sqrt(2.0))));
|
Vector5 diag_landmark((Vector(5) << 0., 0., 0., M_PI/4., atan(2./sqrt(2.0))));
|
||||||
LieScalar inv_depth( 1./sqrt(1.0+1+4));
|
double inv_depth( 1./sqrt(1.0+1+4));
|
||||||
Point2 actual = inv_camera.project(diag_landmark, inv_depth);
|
Point2 actual = inv_camera.project(diag_landmark, inv_depth);
|
||||||
EXPECT(assert_equal(expected, actual));
|
EXPECT(assert_equal(expected, actual));
|
||||||
}
|
}
|
||||||
|
@ -76,24 +76,24 @@ TEST( InvDepthFactor, Project4) {
|
||||||
|
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
||||||
Vector5 diag_landmark((Vector(5) << 0., 0., 0., atan(4.0/1), atan(2./sqrt(1.+16.))));
|
Vector5 diag_landmark((Vector(5) << 0., 0., 0., atan(4.0/1), atan(2./sqrt(1.+16.))));
|
||||||
LieScalar inv_depth(1./sqrt(1.+16.+4.));
|
double inv_depth(1./sqrt(1.+16.+4.));
|
||||||
Point2 actual = inv_camera.project(diag_landmark, inv_depth);
|
Point2 actual = inv_camera.project(diag_landmark, inv_depth);
|
||||||
EXPECT(assert_equal(expected, actual));
|
EXPECT(assert_equal(expected, actual));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Point2 project_(const Pose3& pose, const Vector5& landmark, const LieScalar& inv_depth) {
|
Point2 project_(const Pose3& pose, const Vector5& landmark, const double& inv_depth) {
|
||||||
return InvDepthCamera3<Cal3_S2>(pose,K).project(landmark, inv_depth); }
|
return InvDepthCamera3<Cal3_S2>(pose,K).project(landmark, inv_depth); }
|
||||||
|
|
||||||
TEST( InvDepthFactor, Dproject_pose)
|
TEST( InvDepthFactor, Dproject_pose)
|
||||||
{
|
{
|
||||||
Vector5 landmark((Vector(5) << 0.1,0.2,0.3, 0.1,0.2));
|
Vector5 landmark((Vector(5) << 0.1,0.2,0.3, 0.1,0.2));
|
||||||
LieScalar inv_depth(1./4);
|
double inv_depth(1./4);
|
||||||
Matrix expected = numericalDerivative31(project_,level_pose, landmark, inv_depth);
|
Matrix expected = numericalDerivative31(project_,level_pose, landmark, inv_depth);
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
||||||
Matrix actual;
|
Matrix actual;
|
||||||
Point2 uv = inv_camera.project(landmark, inv_depth, actual, boost::none, boost::none);
|
inv_camera.project(landmark, inv_depth, actual, boost::none, boost::none);
|
||||||
EXPECT(assert_equal(expected,actual,1e-6));
|
EXPECT(assert_equal(expected,actual,1e-6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,11 +101,11 @@ TEST( InvDepthFactor, Dproject_pose)
|
||||||
TEST( InvDepthFactor, Dproject_landmark)
|
TEST( InvDepthFactor, Dproject_landmark)
|
||||||
{
|
{
|
||||||
Vector5 landmark((Vector(5) << 0.1,0.2,0.3, 0.1,0.2));
|
Vector5 landmark((Vector(5) << 0.1,0.2,0.3, 0.1,0.2));
|
||||||
LieScalar inv_depth(1./4);
|
double inv_depth(1./4);
|
||||||
Matrix expected = numericalDerivative32(project_,level_pose, landmark, inv_depth);
|
Matrix expected = numericalDerivative32(project_,level_pose, landmark, inv_depth);
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
||||||
Matrix actual;
|
Matrix actual;
|
||||||
Point2 uv = inv_camera.project(landmark, inv_depth, boost::none, actual, boost::none);
|
inv_camera.project(landmark, inv_depth, boost::none, actual, boost::none);
|
||||||
EXPECT(assert_equal(expected,actual,1e-7));
|
EXPECT(assert_equal(expected,actual,1e-7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,11 +113,11 @@ TEST( InvDepthFactor, Dproject_landmark)
|
||||||
TEST( InvDepthFactor, Dproject_inv_depth)
|
TEST( InvDepthFactor, Dproject_inv_depth)
|
||||||
{
|
{
|
||||||
Vector5 landmark((Vector(5) << 0.1,0.2,0.3, 0.1,0.2));
|
Vector5 landmark((Vector(5) << 0.1,0.2,0.3, 0.1,0.2));
|
||||||
LieScalar inv_depth(1./4);
|
double inv_depth(1./4);
|
||||||
Matrix expected = numericalDerivative33(project_,level_pose, landmark, inv_depth);
|
Matrix expected = numericalDerivative33(project_,level_pose, landmark, inv_depth);
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
||||||
Matrix actual;
|
Matrix actual;
|
||||||
Point2 uv = inv_camera.project(landmark, inv_depth, boost::none, boost::none, actual);
|
inv_camera.project(landmark, inv_depth, boost::none, boost::none, actual);
|
||||||
EXPECT(assert_equal(expected,actual,1e-7));
|
EXPECT(assert_equal(expected,actual,1e-7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,15 +125,15 @@ TEST( InvDepthFactor, Dproject_inv_depth)
|
||||||
TEST(InvDepthFactor, backproject)
|
TEST(InvDepthFactor, backproject)
|
||||||
{
|
{
|
||||||
Vector expected((Vector(5) << 0.,0.,1., 0.1,0.2));
|
Vector expected((Vector(5) << 0.,0.,1., 0.1,0.2));
|
||||||
LieScalar inv_depth(1./4);
|
double inv_depth(1./4);
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose,K);
|
||||||
Point2 z = inv_camera.project(expected, inv_depth);
|
Point2 z = inv_camera.project(expected, inv_depth);
|
||||||
|
|
||||||
Vector5 actual_vec;
|
Vector5 actual_vec;
|
||||||
LieScalar actual_inv;
|
double actual_inv;
|
||||||
boost::tie(actual_vec, actual_inv) = inv_camera.backproject(z, 4);
|
boost::tie(actual_vec, actual_inv) = inv_camera.backproject(z, 4);
|
||||||
EXPECT(assert_equal(expected,actual_vec,1e-7));
|
EXPECT(assert_equal(expected,actual_vec,1e-7));
|
||||||
EXPECT(assert_equal(inv_depth,actual_inv,1e-7));
|
EXPECT_DOUBLES_EQUAL(inv_depth,actual_inv,1e-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -141,15 +141,15 @@ TEST(InvDepthFactor, backproject2)
|
||||||
{
|
{
|
||||||
// backwards facing camera
|
// backwards facing camera
|
||||||
Vector expected((Vector(5) << -5.,-5.,2., 3., -0.1));
|
Vector expected((Vector(5) << -5.,-5.,2., 3., -0.1));
|
||||||
LieScalar inv_depth(1./10);
|
double inv_depth(1./10);
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(Pose3(Rot3::ypr(1.5,0.1, -1.5), Point3(-5, -5, 2)),K);
|
InvDepthCamera3<Cal3_S2> inv_camera(Pose3(Rot3::ypr(1.5,0.1, -1.5), Point3(-5, -5, 2)),K);
|
||||||
Point2 z = inv_camera.project(expected, inv_depth);
|
Point2 z = inv_camera.project(expected, inv_depth);
|
||||||
|
|
||||||
Vector5 actual_vec;
|
Vector5 actual_vec;
|
||||||
LieScalar actual_inv;
|
double actual_inv;
|
||||||
boost::tie(actual_vec, actual_inv) = inv_camera.backproject(z, 10);
|
boost::tie(actual_vec, actual_inv) = inv_camera.backproject(z, 10);
|
||||||
EXPECT(assert_equal(expected,actual_vec,1e-7));
|
EXPECT(assert_equal(expected,actual_vec,1e-7));
|
||||||
EXPECT(assert_equal(inv_depth,actual_inv,1e-7));
|
EXPECT_DOUBLES_EQUAL(inv_depth,actual_inv,1e-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -515,7 +515,6 @@ virtual class PendulumFactorPk1 : gtsam::NonlinearFactor {
|
||||||
Vector evaluateError(const gtsam::LieScalar& pk1, const gtsam::LieScalar& qk, const gtsam::LieScalar& qk1) const;
|
Vector evaluateError(const gtsam::LieScalar& pk1, const gtsam::LieScalar& qk, const gtsam::LieScalar& qk1) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam_unstable/dynamics/SimpleHelicopter.h>
|
#include <gtsam_unstable/dynamics/SimpleHelicopter.h>
|
||||||
|
|
||||||
virtual class Reconstruction : gtsam::NonlinearFactor {
|
virtual class Reconstruction : gtsam::NonlinearFactor {
|
||||||
|
|
|
@ -48,12 +48,12 @@ AHRS::AHRS(const Matrix& stationaryU, const Matrix& stationaryF, double g_e,
|
||||||
|
|
||||||
F_g_ = -I3 / tau_g;
|
F_g_ = -I3 / tau_g;
|
||||||
F_a_ = -I3 / tau_a;
|
F_a_ = -I3 / tau_a;
|
||||||
Vector var_omega_w = 0 * ones(3); // TODO
|
Vector3 var_omega_w = 0 * ones(3); // TODO
|
||||||
Vector var_omega_g = (0.0034 * 0.0034) * ones(3);
|
Vector3 var_omega_g = (0.0034 * 0.0034) * ones(3);
|
||||||
Vector var_omega_a = (0.034 * 0.034) * ones(3);
|
Vector3 var_omega_a = (0.034 * 0.034) * ones(3);
|
||||||
Vector sigmas_v_g_sq = emul(sigmas_v_g, sigmas_v_g);
|
Vector3 sigmas_v_g_sq = emul(sigmas_v_g, sigmas_v_g);
|
||||||
Vector vars = concatVectors(4, &var_omega_w, &var_omega_g, &sigmas_v_g_sq,
|
Vector vars(12);
|
||||||
&var_omega_a);
|
vars << var_omega_w, var_omega_g, sigmas_v_g_sq, var_omega_a;
|
||||||
var_w_ = diag(vars);
|
var_w_ = diag(vars);
|
||||||
|
|
||||||
// Quantities needed for aiding
|
// Quantities needed for aiding
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam/linear/NoiseModel.h>
|
#include <gtsam/linear/NoiseModel.h>
|
||||||
#include <gtsam/geometry/Rot3.h>
|
#include <gtsam/geometry/Rot3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
|
|
||||||
// Using numerical derivative to calculate d(Pose3::Expmap)/dw
|
// Using numerical derivative to calculate d(Pose3::Expmap)/dw
|
||||||
|
@ -269,7 +268,7 @@ public:
|
||||||
VelDelta -= 2*skewSymmetric(world_rho + world_omega_earth)*world_V1_body * dt12;
|
VelDelta -= 2*skewSymmetric(world_rho + world_omega_earth)*world_V1_body * dt12;
|
||||||
|
|
||||||
// Predict
|
// Predict
|
||||||
return Vel1.compose( VelDelta );
|
return Vel1 + VelDelta;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +294,7 @@ public:
|
||||||
VELOCITY Vel2Pred = predictVelocity(Pose1, Vel1, Bias1);
|
VELOCITY Vel2Pred = predictVelocity(Pose1, Vel1, Bias1);
|
||||||
|
|
||||||
// Calculate error
|
// Calculate error
|
||||||
return Vel2.between(Vel2Pred);
|
return Vel2Pred-Vel2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector evaluateError(const POSE& Pose1, const VELOCITY& Vel1, const IMUBIAS& Bias1, const POSE& Pose2, const VELOCITY& Vel2,
|
Vector evaluateError(const POSE& Pose1, const VELOCITY& Vel1, const IMUBIAS& Bias1, const POSE& Pose2, const VELOCITY& Vel2,
|
||||||
|
@ -344,7 +343,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector ErrPoseVector(POSE::Logmap(evaluatePoseError(Pose1, Vel1, Bias1, Pose2, Vel2)));
|
Vector ErrPoseVector(POSE::Logmap(evaluatePoseError(Pose1, Vel1, Bias1, Pose2, Vel2)));
|
||||||
Vector ErrVelVector(VELOCITY::Logmap(evaluateVelocityError(Pose1, Vel1, Bias1, Pose2, Vel2)));
|
Vector ErrVelVector(evaluateVelocityError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
|
||||||
return concatVectors(2, &ErrPoseVector, &ErrVelVector);
|
return concatVectors(2, &ErrPoseVector, &ErrVelVector);
|
||||||
}
|
}
|
||||||
|
@ -438,18 +437,18 @@ public:
|
||||||
Matrix Z_3x3 = zeros(3,3);
|
Matrix Z_3x3 = zeros(3,3);
|
||||||
Matrix I_3x3 = eye(3,3);
|
Matrix I_3x3 = eye(3,3);
|
||||||
|
|
||||||
Matrix H_pos_pos = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_pos, msr_dt, _1, delta_vel_in_t0), delta_pos_in_t0);
|
Matrix H_pos_pos = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_pos, msr_dt, _1, delta_vel_in_t0), delta_pos_in_t0);
|
||||||
Matrix H_pos_vel = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_pos, msr_dt, delta_pos_in_t0, _1), delta_vel_in_t0);
|
Matrix H_pos_vel = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_pos, msr_dt, delta_pos_in_t0, _1), delta_vel_in_t0);
|
||||||
Matrix H_pos_angles = Z_3x3;
|
Matrix H_pos_angles = Z_3x3;
|
||||||
Matrix H_pos_bias = collect(2, &Z_3x3, &Z_3x3);
|
Matrix H_pos_bias = collect(2, &Z_3x3, &Z_3x3);
|
||||||
|
|
||||||
Matrix H_vel_vel = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_vel, msr_gyro_t, msr_acc_t, msr_dt, delta_angles, _1, flag_use_body_P_sensor, body_P_sensor, Bias_t0), delta_vel_in_t0);
|
Matrix H_vel_vel = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_vel, msr_gyro_t, msr_acc_t, msr_dt, delta_angles, _1, flag_use_body_P_sensor, body_P_sensor, Bias_t0), delta_vel_in_t0);
|
||||||
Matrix H_vel_angles = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_vel, msr_gyro_t, msr_acc_t, msr_dt, _1, delta_vel_in_t0, flag_use_body_P_sensor, body_P_sensor, Bias_t0), delta_angles);
|
Matrix H_vel_angles = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_vel, msr_gyro_t, msr_acc_t, msr_dt, _1, delta_vel_in_t0, flag_use_body_P_sensor, body_P_sensor, Bias_t0), delta_angles);
|
||||||
Matrix H_vel_bias = numericalDerivative11<LieVector, IMUBIAS>(boost::bind(&PreIntegrateIMUObservations_delta_vel, msr_gyro_t, msr_acc_t, msr_dt, delta_angles, delta_vel_in_t0, flag_use_body_P_sensor, body_P_sensor, _1), Bias_t0);
|
Matrix H_vel_bias = numericalDerivative11<Vector3, IMUBIAS>(boost::bind(&PreIntegrateIMUObservations_delta_vel, msr_gyro_t, msr_acc_t, msr_dt, delta_angles, delta_vel_in_t0, flag_use_body_P_sensor, body_P_sensor, _1), Bias_t0);
|
||||||
Matrix H_vel_pos = Z_3x3;
|
Matrix H_vel_pos = Z_3x3;
|
||||||
|
|
||||||
Matrix H_angles_angles = numericalDerivative11<LieVector, LieVector>(boost::bind(&PreIntegrateIMUObservations_delta_angles, msr_gyro_t, msr_dt, _1, flag_use_body_P_sensor, body_P_sensor, Bias_t0), delta_angles);
|
Matrix H_angles_angles = numericalDerivative11<Vector3, Vector3>(boost::bind(&PreIntegrateIMUObservations_delta_angles, msr_gyro_t, msr_dt, _1, flag_use_body_P_sensor, body_P_sensor, Bias_t0), delta_angles);
|
||||||
Matrix H_angles_bias = numericalDerivative11<LieVector, IMUBIAS>(boost::bind(&PreIntegrateIMUObservations_delta_angles, msr_gyro_t, msr_dt, delta_angles, flag_use_body_P_sensor, body_P_sensor, _1), Bias_t0);
|
Matrix H_angles_bias = numericalDerivative11<Vector3, IMUBIAS>(boost::bind(&PreIntegrateIMUObservations_delta_angles, msr_gyro_t, msr_dt, delta_angles, flag_use_body_P_sensor, body_P_sensor, _1), Bias_t0);
|
||||||
Matrix H_angles_pos = Z_3x3;
|
Matrix H_angles_pos = Z_3x3;
|
||||||
Matrix H_angles_vel = Z_3x3;
|
Matrix H_angles_vel = Z_3x3;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam/linear/NoiseModel.h>
|
#include <gtsam/linear/NoiseModel.h>
|
||||||
#include <gtsam/geometry/Rot3.h>
|
#include <gtsam/geometry/Rot3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
|
|
||||||
// Using numerical derivative to calculate d(Pose3::Expmap)/dw
|
// Using numerical derivative to calculate d(Pose3::Expmap)/dw
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
#include <gtsam/linear/NoiseModel.h>
|
#include <gtsam/linear/NoiseModel.h>
|
||||||
#include <gtsam/geometry/Rot3.h>
|
#include <gtsam/geometry/Rot3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
|
|
||||||
// Using numerical derivative to calculate d(Pose3::Expmap)/dw
|
// Using numerical derivative to calculate d(Pose3::Expmap)/dw
|
||||||
|
@ -200,7 +199,7 @@ public:
|
||||||
VELOCITY VelDelta(world_a_body*dt_);
|
VELOCITY VelDelta(world_a_body*dt_);
|
||||||
|
|
||||||
// Predict
|
// Predict
|
||||||
return Vel1.compose(VelDelta);
|
return Vel1 + VelDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
void predict(const POSE& Pose1, const VELOCITY& Vel1, const IMUBIAS& Bias1, POSE& Pose2, VELOCITY& Vel2) const {
|
void predict(const POSE& Pose1, const VELOCITY& Vel1, const IMUBIAS& Bias1, POSE& Pose2, VELOCITY& Vel2) const {
|
||||||
|
@ -221,7 +220,7 @@ public:
|
||||||
VELOCITY Vel2Pred = predictVelocity(Pose1, Vel1, Bias1);
|
VELOCITY Vel2Pred = predictVelocity(Pose1, Vel1, Bias1);
|
||||||
|
|
||||||
// Calculate error
|
// Calculate error
|
||||||
return Vel2.between(Vel2Pred);
|
return Vel2Pred - Vel2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** implement functions needed to derive from Factor */
|
/** implement functions needed to derive from Factor */
|
||||||
|
@ -271,7 +270,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector ErrPoseVector(POSE::Logmap(evaluatePoseError(Pose1, Vel1, Bias1, Pose2, Vel2)));
|
Vector ErrPoseVector(POSE::Logmap(evaluatePoseError(Pose1, Vel1, Bias1, Pose2, Vel2)));
|
||||||
Vector ErrVelVector(VELOCITY::Logmap(evaluateVelocityError(Pose1, Vel1, Bias1, Pose2, Vel2)));
|
Vector ErrVelVector(evaluateVelocityError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
|
||||||
return concatVectors(2, &ErrPoseVector, &ErrVelVector);
|
return concatVectors(2, &ErrPoseVector, &ErrVelVector);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate error h(x)-z and optionally derivatives
|
/// Evaluate error h(x)-z and optionally derivatives
|
||||||
gtsam::Vector evaluateError(const POSE& pose, const gtsam::LieVector& point, const INVDEPTH& invDepth,
|
gtsam::Vector evaluateError(const POSE& pose, const Vector5& point, const INVDEPTH& invDepth,
|
||||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H2=boost::none,
|
boost::optional<gtsam::Matrix&> H2=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H3=boost::none) const {
|
boost::optional<gtsam::Matrix&> H3=boost::none) const {
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <gtsam/geometry/Cal3_S2.h>
|
#include <gtsam/geometry/Cal3_S2.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/geometry/Point2.h>
|
#include <gtsam/geometry/Point2.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -23,7 +22,7 @@ namespace gtsam {
|
||||||
/**
|
/**
|
||||||
* Binary factor representing a visual measurement using an inverse-depth parameterization
|
* Binary factor representing a visual measurement using an inverse-depth parameterization
|
||||||
*/
|
*/
|
||||||
class InvDepthFactorVariant1: public NoiseModelFactor2<Pose3, LieVector> {
|
class InvDepthFactorVariant1: public NoiseModelFactor2<Pose3, Vector6> {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Keep a copy of measurement and calibration for I/O
|
// Keep a copy of measurement and calibration for I/O
|
||||||
|
@ -33,7 +32,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// shorthand for base class type
|
/// shorthand for base class type
|
||||||
typedef NoiseModelFactor2<Pose3, LieVector> Base;
|
typedef NoiseModelFactor2<Pose3, Vector6> Base;
|
||||||
|
|
||||||
/// shorthand for this class
|
/// shorthand for this class
|
||||||
typedef InvDepthFactorVariant1 This;
|
typedef InvDepthFactorVariant1 This;
|
||||||
|
@ -79,7 +78,7 @@ public:
|
||||||
&& this->K_->equals(*e->K_, tol);
|
&& this->K_->equals(*e->K_, tol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector inverseDepthError(const Pose3& pose, const LieVector& landmark) const {
|
Vector inverseDepthError(const Pose3& pose, const Vector6& landmark) const {
|
||||||
try {
|
try {
|
||||||
// Calculate the 3D coordinates of the landmark in the world frame
|
// Calculate the 3D coordinates of the landmark in the world frame
|
||||||
double x = landmark(0), y = landmark(1), z = landmark(2);
|
double x = landmark(0), y = landmark(1), z = landmark(2);
|
||||||
|
@ -100,7 +99,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate error h(x)-z and optionally derivatives
|
/// Evaluate error h(x)-z and optionally derivatives
|
||||||
Vector evaluateError(const Pose3& pose, const LieVector& landmark,
|
Vector evaluateError(const Pose3& pose, const Vector6& landmark,
|
||||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <gtsam/geometry/Cal3_S2.h>
|
#include <gtsam/geometry/Cal3_S2.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/geometry/Point2.h>
|
#include <gtsam/geometry/Point2.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -24,7 +23,7 @@ namespace gtsam {
|
||||||
/**
|
/**
|
||||||
* Binary factor representing a visual measurement using an inverse-depth parameterization
|
* Binary factor representing a visual measurement using an inverse-depth parameterization
|
||||||
*/
|
*/
|
||||||
class InvDepthFactorVariant2: public NoiseModelFactor2<Pose3, LieVector> {
|
class InvDepthFactorVariant2: public NoiseModelFactor2<Pose3, Vector3> {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Keep a copy of measurement and calibration for I/O
|
// Keep a copy of measurement and calibration for I/O
|
||||||
|
@ -35,7 +34,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// shorthand for base class type
|
/// shorthand for base class type
|
||||||
typedef NoiseModelFactor2<Pose3, LieVector> Base;
|
typedef NoiseModelFactor2<Pose3, Vector3> Base;
|
||||||
|
|
||||||
/// shorthand for this class
|
/// shorthand for this class
|
||||||
typedef InvDepthFactorVariant2 This;
|
typedef InvDepthFactorVariant2 This;
|
||||||
|
@ -83,7 +82,7 @@ public:
|
||||||
&& this->referencePoint_.equals(e->referencePoint_, tol);
|
&& this->referencePoint_.equals(e->referencePoint_, tol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector inverseDepthError(const Pose3& pose, const LieVector& landmark) const {
|
Vector inverseDepthError(const Pose3& pose, const Vector3& landmark) const {
|
||||||
try {
|
try {
|
||||||
// Calculate the 3D coordinates of the landmark in the world frame
|
// Calculate the 3D coordinates of the landmark in the world frame
|
||||||
double theta = landmark(0), phi = landmark(1), rho = landmark(2);
|
double theta = landmark(0), phi = landmark(1), rho = landmark(2);
|
||||||
|
@ -103,7 +102,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate error h(x)-z and optionally derivatives
|
/// Evaluate error h(x)-z and optionally derivatives
|
||||||
Vector evaluateError(const Pose3& pose, const LieVector& landmark,
|
Vector evaluateError(const Pose3& pose, const Vector3& landmark,
|
||||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <gtsam/geometry/Cal3_S2.h>
|
#include <gtsam/geometry/Cal3_S2.h>
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/geometry/Point2.h>
|
#include <gtsam/geometry/Point2.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
@ -23,7 +22,7 @@ namespace gtsam {
|
||||||
/**
|
/**
|
||||||
* Binary factor representing the first visual measurement using an inverse-depth parameterization
|
* Binary factor representing the first visual measurement using an inverse-depth parameterization
|
||||||
*/
|
*/
|
||||||
class InvDepthFactorVariant3a: public NoiseModelFactor2<Pose3, LieVector> {
|
class InvDepthFactorVariant3a: public NoiseModelFactor2<Pose3, Vector3> {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Keep a copy of measurement and calibration for I/O
|
// Keep a copy of measurement and calibration for I/O
|
||||||
|
@ -33,7 +32,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// shorthand for base class type
|
/// shorthand for base class type
|
||||||
typedef NoiseModelFactor2<Pose3, LieVector> Base;
|
typedef NoiseModelFactor2<Pose3, Vector3> Base;
|
||||||
|
|
||||||
/// shorthand for this class
|
/// shorthand for this class
|
||||||
typedef InvDepthFactorVariant3a This;
|
typedef InvDepthFactorVariant3a This;
|
||||||
|
@ -81,7 +80,7 @@ public:
|
||||||
&& this->K_->equals(*e->K_, tol);
|
&& this->K_->equals(*e->K_, tol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector inverseDepthError(const Pose3& pose, const LieVector& landmark) const {
|
Vector inverseDepthError(const Pose3& pose, const Vector3& landmark) const {
|
||||||
try {
|
try {
|
||||||
// Calculate the 3D coordinates of the landmark in the Pose frame
|
// Calculate the 3D coordinates of the landmark in the Pose frame
|
||||||
double theta = landmark(0), phi = landmark(1), rho = landmark(2);
|
double theta = landmark(0), phi = landmark(1), rho = landmark(2);
|
||||||
|
@ -103,7 +102,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate error h(x)-z and optionally derivatives
|
/// Evaluate error h(x)-z and optionally derivatives
|
||||||
Vector evaluateError(const Pose3& pose, const LieVector& landmark,
|
Vector evaluateError(const Pose3& pose, const Vector3& landmark,
|
||||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
boost::optional<gtsam::Matrix&> H2=boost::none) const {
|
||||||
|
|
||||||
|
@ -142,7 +141,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Ternary factor representing a visual measurement using an inverse-depth parameterization
|
* Ternary factor representing a visual measurement using an inverse-depth parameterization
|
||||||
*/
|
*/
|
||||||
class InvDepthFactorVariant3b: public NoiseModelFactor3<Pose3, Pose3, LieVector> {
|
class InvDepthFactorVariant3b: public NoiseModelFactor3<Pose3, Pose3, Vector3> {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Keep a copy of measurement and calibration for I/O
|
// Keep a copy of measurement and calibration for I/O
|
||||||
|
@ -152,7 +151,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// shorthand for base class type
|
/// shorthand for base class type
|
||||||
typedef NoiseModelFactor3<Pose3, Pose3, LieVector> Base;
|
typedef NoiseModelFactor3<Pose3, Pose3, Vector3> Base;
|
||||||
|
|
||||||
/// shorthand for this class
|
/// shorthand for this class
|
||||||
typedef InvDepthFactorVariant3b This;
|
typedef InvDepthFactorVariant3b This;
|
||||||
|
@ -200,7 +199,7 @@ public:
|
||||||
&& this->K_->equals(*e->K_, tol);
|
&& this->K_->equals(*e->K_, tol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector inverseDepthError(const Pose3& pose1, const Pose3& pose2, const LieVector& landmark) const {
|
Vector inverseDepthError(const Pose3& pose1, const Pose3& pose2, const Vector3& landmark) const {
|
||||||
try {
|
try {
|
||||||
// Calculate the 3D coordinates of the landmark in the Pose1 frame
|
// Calculate the 3D coordinates of the landmark in the Pose1 frame
|
||||||
double theta = landmark(0), phi = landmark(1), rho = landmark(2);
|
double theta = landmark(0), phi = landmark(1), rho = landmark(2);
|
||||||
|
@ -222,20 +221,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate error h(x)-z and optionally derivatives
|
/// Evaluate error h(x)-z and optionally derivatives
|
||||||
Vector evaluateError(const Pose3& pose1, const Pose3& pose2, const LieVector& landmark,
|
Vector evaluateError(const Pose3& pose1, const Pose3& pose2, const Vector3& landmark,
|
||||||
boost::optional<gtsam::Matrix&> H1=boost::none,
|
boost::optional<gtsam::Matrix&> H1=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H2=boost::none,
|
boost::optional<gtsam::Matrix&> H2=boost::none,
|
||||||
boost::optional<gtsam::Matrix&> H3=boost::none) const {
|
boost::optional<gtsam::Matrix&> H3=boost::none) const {
|
||||||
|
|
||||||
if(H1) {
|
if(H1)
|
||||||
(*H1) = numericalDerivative11<Vector,Pose3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, _1, pose2, landmark), pose1);
|
(*H1) = numericalDerivative11<Vector,Pose3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, _1, pose2, landmark), pose1);
|
||||||
}
|
|
||||||
if(H2) {
|
if(H2)
|
||||||
(*H2) = numericalDerivative11<Vector,Pose3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, pose1, _1, landmark), pose2);
|
(*H2) = numericalDerivative11<Vector,Pose3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, pose1, _1, landmark), pose2);
|
||||||
}
|
|
||||||
if(H3) {
|
if(H3)
|
||||||
(*H3) = numericalDerivative11<Vector,Vector3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, pose1, pose2, _1), landmark);
|
(*H3) = numericalDerivative11<Vector,Vector3>(boost::bind(&InvDepthFactorVariant3b::inverseDepthError, this, pose1, pose2, _1), landmark);
|
||||||
}
|
|
||||||
|
|
||||||
return inverseDepthError(pose1, pose2, landmark);
|
return inverseDepthError(pose1, pose2, landmark);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <gtsam_unstable/slam/BetweenFactorEM.h>
|
#include <gtsam_unstable/slam/BetweenFactorEM.h>
|
||||||
#include <gtsam/geometry/Pose2.h>
|
#include <gtsam/geometry/Pose2.h>
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
#include <gtsam/slam/BetweenFactor.h>
|
#include <gtsam/slam/BetweenFactor.h>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/inference/Key.h>
|
#include <gtsam/inference/Key.h>
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ TEST( EquivInertialNavFactor_GlobalVel, Constructor)
|
||||||
SharedGaussian imu_model = noiseModel::Gaussian::Covariance(EquivCov_Overall.block(0,0,9,9));
|
SharedGaussian imu_model = noiseModel::Gaussian::Covariance(EquivCov_Overall.block(0,0,9,9));
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
EquivInertialNavFactor_GlobalVel<Pose3, LieVector, imuBias::ConstantBias> factor(
|
EquivInertialNavFactor_GlobalVel<Pose3, Vector3, imuBias::ConstantBias> factor(
|
||||||
poseKey1, velKey1, biasKey1, poseKey2, velKey2,
|
poseKey1, velKey1, biasKey1, poseKey2, velKey2,
|
||||||
delta_pos_in_t0, delta_vel_in_t0, delta_angles, delta_t,
|
delta_pos_in_t0, delta_vel_in_t0, delta_angles, delta_t,
|
||||||
g, rho, omega_earth, imu_model, Jacobian_wrt_t0_Overall, bias1);
|
g, rho, omega_earth, imu_model, Jacobian_wrt_t0_Overall, bias1);
|
||||||
|
|
|
@ -23,86 +23,76 @@
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/inference/Key.h>
|
#include <gtsam/inference/Key.h>
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/TestableAssertions.h>
|
#include <gtsam/base/TestableAssertions.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
|
||||||
Rot3 world_R_ECEF(
|
Rot3 world_R_ECEF(0.31686, 0.51505, 0.79645, 0.85173, -0.52399, 0, 0.41733,
|
||||||
0.31686, 0.51505, 0.79645,
|
0.67835, -0.60471);
|
||||||
0.85173, -0.52399, 0,
|
|
||||||
0.41733, 0.67835, -0.60471);
|
|
||||||
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
static const Vector3 world_g(0.0, 0.0, 9.81);
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
static const Vector3 world_rho(0.0, -1.5724e-05, 0.0); // NED system
|
||||||
|
static const Vector3 ECEF_omega_earth(0.0, 0.0, 7.292115e-5);
|
||||||
|
static const Vector3 world_omega_earth = world_R_ECEF.matrix()
|
||||||
|
* ECEF_omega_earth;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Pose3 predictionErrorPose(const Pose3& p1, const LieVector& v1,
|
Pose3 predictionErrorPose(const Pose3& p1, const Vector3& v1,
|
||||||
const imuBias::ConstantBias& b1, const Pose3& p2, const LieVector& v2,
|
const imuBias::ConstantBias& b1, const Pose3& p2, const Vector3& v2,
|
||||||
const InertialNavFactor_GlobalVelocity<Pose3, LieVector,
|
const InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias>& factor) {
|
||||||
imuBias::ConstantBias>& factor) {
|
|
||||||
return Pose3::Expmap(factor.evaluateError(p1, v1, b1, p2, v2).head(6));
|
return Pose3::Expmap(factor.evaluateError(p1, v1, b1, p2, v2).head(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector predictionErrorVel(const Pose3& p1, const LieVector& v1,
|
Vector predictionErrorVel(const Pose3& p1, const Vector3& v1,
|
||||||
const imuBias::ConstantBias& b1, const Pose3& p2, const LieVector& v2,
|
const imuBias::ConstantBias& b1, const Pose3& p2, const Vector3& v2,
|
||||||
const InertialNavFactor_GlobalVelocity<Pose3, LieVector,
|
const InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias>& factor) {
|
||||||
imuBias::ConstantBias>& factor) {
|
|
||||||
return factor.evaluateError(p1, v1, b1, p2, v2).tail(3);
|
return factor.evaluateError(p1, v1, b1, p2, v2).tail(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, Constructor) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, Constructor)
|
|
||||||
{
|
|
||||||
Key Pose1(11);
|
Key Pose1(11);
|
||||||
Key Pose2(12);
|
Key Pose2(12);
|
||||||
Key Vel1(21);
|
Key Vel1(21);
|
||||||
Key Vel2(22);
|
Key Vel2(22);
|
||||||
Key Bias1(31);
|
Key Bias1(31);
|
||||||
|
|
||||||
Vector measurement_acc((Vector(3) << 0.1,0.2,0.4));
|
Vector3 measurement_acc(0.1, 0.2, 0.4);
|
||||||
Vector measurement_gyro((Vector(3) << -0.2, 0.5, 0.03));
|
Vector3 measurement_gyro(-0.2, 0.5, 0.03);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro,
|
||||||
|
measurement_dt, world_g, world_rho, world_omega_earth, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, Equals) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, Equals)
|
|
||||||
{
|
|
||||||
Key Pose1(11);
|
Key Pose1(11);
|
||||||
Key Pose2(12);
|
Key Pose2(12);
|
||||||
Key Vel1(21);
|
Key Vel1(21);
|
||||||
Key Vel2(22);
|
Key Vel2(22);
|
||||||
Key Bias1(31);
|
Key Bias1(31);
|
||||||
|
|
||||||
Vector measurement_acc((Vector(3) << 0.1,0.2,0.4));
|
Vector3 measurement_acc(0.1, 0.2, 0.4);
|
||||||
Vector measurement_gyro((Vector(3) << -0.2, 0.5, 0.03));
|
Vector3 measurement_gyro(-0.2, 0.5, 0.03);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> g(Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro,
|
||||||
|
measurement_dt, world_g, world_rho, world_omega_earth, model);
|
||||||
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> g(
|
||||||
|
Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro,
|
||||||
|
measurement_dt, world_g, world_rho, world_omega_earth, model);
|
||||||
CHECK(assert_equal(f, g, 1e-5));
|
CHECK(assert_equal(f, g, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, Predict) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, Predict)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -110,36 +100,32 @@ TEST( InertialNavFactor_GlobalVelocity, Predict)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
|
|
||||||
// First test: zero angular motion, some acceleration
|
// First test: zero angular motion, some acceleration
|
||||||
Vector measurement_acc((Vector(3) <<0.1,0.2,0.3-9.81));
|
Vector measurement_acc((Vector(3) << 0.1, 0.2, 0.3 - 9.81));
|
||||||
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0));
|
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model);
|
||||||
|
|
||||||
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
||||||
LieVector Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
Vector3 Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
Pose3 expectedPose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
Pose3 expectedPose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
||||||
LieVector expectedVel2((Vector(3) << 0.51, -0.48, 0.43));
|
Vector3 expectedVel2((Vector(3) << 0.51, -0.48, 0.43));
|
||||||
Pose3 actualPose2;
|
Pose3 actualPose2;
|
||||||
LieVector actualVel2;
|
Vector3 actualVel2;
|
||||||
f.predict(Pose1, Vel1, Bias1, actualPose2, actualVel2);
|
f.predict(Pose1, Vel1, Bias1, actualPose2, actualVel2);
|
||||||
|
|
||||||
CHECK(assert_equal(expectedPose2, actualPose2, 1e-5));
|
CHECK(assert_equal(expectedPose2, actualPose2, 1e-5));
|
||||||
CHECK(assert_equal(expectedVel2, actualVel2, 1e-5));
|
CHECK(assert_equal((Vector)expectedVel2, actualVel2, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ErrorPosVel) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ErrorPosVel)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -147,24 +133,22 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorPosVel)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
|
|
||||||
// First test: zero angular motion, some acceleration
|
// First test: zero angular motion, some acceleration
|
||||||
Vector measurement_acc((Vector(3) <<0.1,0.2,0.3-9.81));
|
Vector measurement_acc((Vector(3) << 0.1, 0.2, 0.3 - 9.81));
|
||||||
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0));
|
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model);
|
||||||
|
|
||||||
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
||||||
Pose3 Pose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
Pose3 Pose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
||||||
LieVector Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
Vector3 Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
||||||
LieVector Vel2((Vector(3) << 0.51, -0.48, 0.43));
|
Vector3 Vel2((Vector(3) << 0.51, -0.48, 0.43));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
@ -173,9 +157,7 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorPosVel)
|
||||||
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ErrorRot) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ErrorRot)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -183,23 +165,23 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRot)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
// Second test: zero angular motion, some acceleration
|
// Second test: zero angular motion, some acceleration
|
||||||
Vector measurement_acc((Vector(3) <<0.0,0.0,0.0-9.81));
|
Vector measurement_acc((Vector(3) << 0.0, 0.0, 0.0 - 9.81));
|
||||||
Vector measurement_gyro((Vector(3) << 0.1, 0.2, 0.3));
|
Vector measurement_gyro((Vector(3) << 0.1, 0.2, 0.3));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model);
|
||||||
|
|
||||||
Pose3 Pose1(Rot3(), Point3(2.0,1.0,3.0));
|
Pose3 Pose1(Rot3(), Point3(2.0, 1.0, 3.0));
|
||||||
Pose3 Pose2(Rot3::Expmap(measurement_gyro*measurement_dt), Point3(2.0,1.0,3.0));
|
Pose3 Pose2(Rot3::Expmap(measurement_gyro * measurement_dt),
|
||||||
LieVector Vel1((Vector(3) << 0.0, 0.0, 0.0));
|
Point3(2.0, 1.0, 3.0));
|
||||||
LieVector Vel2((Vector(3) << 0.0, 0.0, 0.0));
|
Vector3 Vel1((Vector(3) << 0.0, 0.0, 0.0));
|
||||||
|
Vector3 Vel2((Vector(3) << 0.0, 0.0, 0.0));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
@ -208,9 +190,7 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRot)
|
||||||
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVel) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVel)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -218,32 +198,30 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVel)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
// Second test: zero angular motion, some acceleration - generated in matlab
|
// Second test: zero angular motion, some acceleration - generated in matlab
|
||||||
Vector measurement_acc((Vector(3) << 6.501390843381716, -6.763926150509185, -2.300389940090343));
|
Vector measurement_acc(
|
||||||
|
(Vector(3) << 6.501390843381716, -6.763926150509185, -2.300389940090343));
|
||||||
Vector measurement_gyro((Vector(3) << 0.1, 0.2, 0.3));
|
Vector measurement_gyro((Vector(3) << 0.1, 0.2, 0.3));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model);
|
||||||
|
|
||||||
Rot3 R1(0.487316618, 0.125253866, 0.86419557,
|
Rot3 R1(0.487316618, 0.125253866, 0.86419557, 0.580273724, 0.693095498,
|
||||||
0.580273724, 0.693095498, -0.427669306,
|
-0.427669306, -0.652537293, 0.709880342, 0.265075427);
|
||||||
-0.652537293, 0.709880342, 0.265075427);
|
Point3 t1(2.0, 1.0, 3.0);
|
||||||
Point3 t1(2.0,1.0,3.0);
|
|
||||||
Pose3 Pose1(R1, t1);
|
Pose3 Pose1(R1, t1);
|
||||||
LieVector Vel1((Vector(3) << 0.5, -0.5, 0.4));
|
Vector3 Vel1((Vector(3) << 0.5, -0.5, 0.4));
|
||||||
Rot3 R2(0.473618898, 0.119523052, 0.872582019,
|
Rot3 R2(0.473618898, 0.119523052, 0.872582019, 0.609241153, 0.67099888,
|
||||||
0.609241153, 0.67099888, -0.422594037,
|
-0.422594037, -0.636011287, 0.731761397, 0.244979388);
|
||||||
-0.636011287, 0.731761397, 0.244979388);
|
Point3 t2 = t1.compose(Point3(Vel1 * measurement_dt));
|
||||||
Point3 t2 = t1.compose( Point3(Vel1*measurement_dt) );
|
|
||||||
Pose3 Pose2(R2, t2);
|
Pose3 Pose2(R2, t2);
|
||||||
Vector dv = measurement_dt * (R1.matrix() * measurement_acc + world_g);
|
Vector dv = measurement_dt * (R1.matrix() * measurement_acc + world_g);
|
||||||
LieVector Vel2 = Vel1.compose( dv );
|
Vector3 Vel2 = Vel1 + dv;
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
@ -253,16 +231,15 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVel)
|
||||||
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///* VADIM - START ************************************************************************* */
|
///* VADIM - START ************************************************************************* */
|
||||||
//LieVector predictionRq(const LieVector angles, const LieVector q) {
|
//Vector3 predictionRq(const Vector3 angles, const Vector3 q) {
|
||||||
// return (Rot3().RzRyRx(angles) * q).vector();
|
// return (Rot3().RzRyRx(angles) * q).vector();
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//TEST (InertialNavFactor_GlobalVelocity, Rotation_Deriv ) {
|
//TEST (InertialNavFactor_GlobalVelocity, Rotation_Deriv ) {
|
||||||
// LieVector angles((Vector(3) << 3.001, -1.0004, 2.0005));
|
// Vector3 angles((Vector(3) << 3.001, -1.0004, 2.0005));
|
||||||
// Rot3 R1(Rot3().RzRyRx(angles));
|
// Rot3 R1(Rot3().RzRyRx(angles));
|
||||||
// LieVector q((Vector(3) << 5.8, -2.2, 4.105));
|
// Vector3 q((Vector(3) << 5.8, -2.2, 4.105));
|
||||||
// Rot3 qx(0.0, -q[2], q[1],
|
// Rot3 qx(0.0, -q[2], q[1],
|
||||||
// q[2], 0.0, -q[0],
|
// q[2], 0.0, -q[0],
|
||||||
// -q[1], q[0],0.0);
|
// -q[1], q[0],0.0);
|
||||||
|
@ -270,9 +247,9 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVel)
|
||||||
//
|
//
|
||||||
// Matrix J_expected;
|
// Matrix J_expected;
|
||||||
//
|
//
|
||||||
// LieVector v(predictionRq(angles, q));
|
// Vector3 v(predictionRq(angles, q));
|
||||||
//
|
//
|
||||||
// J_expected = numericalDerivative11<LieVector, LieVector>(boost::bind(&predictionRq, _1, q), angles);
|
// J_expected = numericalDerivative11<Vector3, Vector3>(boost::bind(&predictionRq, _1, q), angles);
|
||||||
//
|
//
|
||||||
// cout<<"J_hyp"<<J_hyp<<endl;
|
// cout<<"J_hyp"<<J_hyp<<endl;
|
||||||
// cout<<"J_expected"<<J_expected<<endl;
|
// cout<<"J_expected"<<J_expected<<endl;
|
||||||
|
@ -281,8 +258,7 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVel)
|
||||||
//}
|
//}
|
||||||
///* VADIM - END ************************************************************************* */
|
///* VADIM - END ************************************************************************* */
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST (InertialNavFactor_GlobalVelocity, Jacobian ) {
|
||||||
TEST (InertialNavFactor_GlobalVelocity, Jacobian ) {
|
|
||||||
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
|
@ -291,51 +267,63 @@ TEST (InertialNavFactor_GlobalVelocity, Jacobian ) {
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.01);
|
double measurement_dt(0.01);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Vector measurement_acc((Vector(3) << 6.501390843381716, -6.763926150509185, -2.300389940090343));
|
Vector measurement_acc(
|
||||||
Vector measurement_gyro((Vector(3) << 3.14, 3.14/2, -3.14));
|
(Vector(3) << 6.501390843381716, -6.763926150509185, -2.300389940090343));
|
||||||
|
Vector measurement_gyro((Vector(3) << 3.14, 3.14 / 2, -3.14));
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> factor(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> factor(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model);
|
||||||
|
|
||||||
Rot3 R1(0.487316618, 0.125253866, 0.86419557,
|
Rot3 R1(0.487316618, 0.125253866, 0.86419557, 0.580273724, 0.693095498,
|
||||||
0.580273724, 0.693095498, -0.427669306,
|
-0.427669306, -0.652537293, 0.709880342, 0.265075427);
|
||||||
-0.652537293, 0.709880342, 0.265075427);
|
Point3 t1(2.0, 1.0, 3.0);
|
||||||
Point3 t1(2.0,1.0,3.0);
|
|
||||||
Pose3 Pose1(R1, t1);
|
Pose3 Pose1(R1, t1);
|
||||||
LieVector Vel1((Vector(3) << 0.5, -0.5, 0.4));
|
Vector3 Vel1((Vector(3) << 0.5, -0.5, 0.4));
|
||||||
Rot3 R2(0.473618898, 0.119523052, 0.872582019,
|
Rot3 R2(0.473618898, 0.119523052, 0.872582019, 0.609241153, 0.67099888,
|
||||||
0.609241153, 0.67099888, -0.422594037,
|
-0.422594037, -0.636011287, 0.731761397, 0.244979388);
|
||||||
-0.636011287, 0.731761397, 0.244979388);
|
Point3 t2(2.052670960415706, 0.977252139079380, 2.942482135362800);
|
||||||
Point3 t2(2.052670960415706, 0.977252139079380, 2.942482135362800);
|
|
||||||
Pose3 Pose2(R2, t2);
|
Pose3 Pose2(R2, t2);
|
||||||
LieVector Vel2((Vector(3) << 0.510000000000000, -0.480000000000000, 0.430000000000000));
|
Vector3 Vel2(
|
||||||
|
(Vector(3) << 0.510000000000000, -0.480000000000000, 0.430000000000000));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Matrix H1_actual, H2_actual, H3_actual, H4_actual, H5_actual;
|
Matrix H1_actual, H2_actual, H3_actual, H4_actual, H5_actual;
|
||||||
|
|
||||||
Vector ActualErr(factor.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2, H1_actual, H2_actual, H3_actual, H4_actual, H5_actual));
|
Vector ActualErr(
|
||||||
|
factor.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2, H1_actual,
|
||||||
|
H2_actual, H3_actual, H4_actual, H5_actual));
|
||||||
|
|
||||||
// Checking for Pose part in the jacobians
|
// Checking for Pose part in the jacobians
|
||||||
// ******
|
// ******
|
||||||
Matrix H1_actualPose(H1_actual.block(0,0,6,H1_actual.cols()));
|
Matrix H1_actualPose(H1_actual.block(0, 0, 6, H1_actual.cols()));
|
||||||
Matrix H2_actualPose(H2_actual.block(0,0,6,H2_actual.cols()));
|
Matrix H2_actualPose(H2_actual.block(0, 0, 6, H2_actual.cols()));
|
||||||
Matrix H3_actualPose(H3_actual.block(0,0,6,H3_actual.cols()));
|
Matrix H3_actualPose(H3_actual.block(0, 0, 6, H3_actual.cols()));
|
||||||
Matrix H4_actualPose(H4_actual.block(0,0,6,H4_actual.cols()));
|
Matrix H4_actualPose(H4_actual.block(0, 0, 6, H4_actual.cols()));
|
||||||
Matrix H5_actualPose(H5_actual.block(0,0,6,H5_actual.cols()));
|
Matrix H5_actualPose(H5_actual.block(0, 0, 6, H5_actual.cols()));
|
||||||
|
|
||||||
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
||||||
Matrix H1_expectedPose, H2_expectedPose, H3_expectedPose, H4_expectedPose, H5_expectedPose;
|
Matrix H1_expectedPose, H2_expectedPose, H3_expectedPose, H4_expectedPose,
|
||||||
H1_expectedPose = numericalDerivative11<Pose3, Pose3>(boost::bind(&predictionErrorPose, _1, Vel1, Bias1, Pose2, Vel2, factor), Pose1);
|
H5_expectedPose;
|
||||||
H2_expectedPose = numericalDerivative11<Pose3, Vector3>(boost::bind(&predictionErrorPose, Pose1, _1, Bias1, Pose2, Vel2, factor), Vel1);
|
H1_expectedPose = numericalDerivative11<Pose3, Pose3>(
|
||||||
H3_expectedPose = numericalDerivative11<Pose3, imuBias::ConstantBias>(boost::bind(&predictionErrorPose, Pose1, Vel1, _1, Pose2, Vel2, factor), Bias1);
|
boost::bind(&predictionErrorPose, _1, Vel1, Bias1, Pose2, Vel2, factor),
|
||||||
H4_expectedPose = numericalDerivative11<Pose3, Pose3>(boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, _1, Vel2, factor), Pose2);
|
Pose1);
|
||||||
H5_expectedPose = numericalDerivative11<Pose3, Vector3>(boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, Pose2, _1, factor), Vel2);
|
H2_expectedPose = numericalDerivative11<Pose3, Vector3>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, _1, Bias1, Pose2, Vel2, factor),
|
||||||
|
Vel1);
|
||||||
|
H3_expectedPose = numericalDerivative11<Pose3, imuBias::ConstantBias>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, Vel1, _1, Pose2, Vel2, factor),
|
||||||
|
Bias1);
|
||||||
|
H4_expectedPose = numericalDerivative11<Pose3, Pose3>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, _1, Vel2, factor),
|
||||||
|
Pose2);
|
||||||
|
H5_expectedPose = numericalDerivative11<Pose3, Vector3>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, Pose2, _1, factor),
|
||||||
|
Vel2);
|
||||||
|
|
||||||
// Verify they are equal for this choice of state
|
// Verify they are equal for this choice of state
|
||||||
CHECK( assert_equal(H1_expectedPose, H1_actualPose, 1e-5));
|
CHECK( assert_equal(H1_expectedPose, H1_actualPose, 1e-5));
|
||||||
|
@ -346,19 +334,30 @@ TEST (InertialNavFactor_GlobalVelocity, Jacobian ) {
|
||||||
|
|
||||||
// Checking for Vel part in the jacobians
|
// Checking for Vel part in the jacobians
|
||||||
// ******
|
// ******
|
||||||
Matrix H1_actualVel(H1_actual.block(6,0,3,H1_actual.cols()));
|
Matrix H1_actualVel(H1_actual.block(6, 0, 3, H1_actual.cols()));
|
||||||
Matrix H2_actualVel(H2_actual.block(6,0,3,H2_actual.cols()));
|
Matrix H2_actualVel(H2_actual.block(6, 0, 3, H2_actual.cols()));
|
||||||
Matrix H3_actualVel(H3_actual.block(6,0,3,H3_actual.cols()));
|
Matrix H3_actualVel(H3_actual.block(6, 0, 3, H3_actual.cols()));
|
||||||
Matrix H4_actualVel(H4_actual.block(6,0,3,H4_actual.cols()));
|
Matrix H4_actualVel(H4_actual.block(6, 0, 3, H4_actual.cols()));
|
||||||
Matrix H5_actualVel(H5_actual.block(6,0,3,H5_actual.cols()));
|
Matrix H5_actualVel(H5_actual.block(6, 0, 3, H5_actual.cols()));
|
||||||
|
|
||||||
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
||||||
Matrix H1_expectedVel, H2_expectedVel, H3_expectedVel, H4_expectedVel, H5_expectedVel;
|
Matrix H1_expectedVel, H2_expectedVel, H3_expectedVel, H4_expectedVel,
|
||||||
H1_expectedVel = numericalDerivative11<Vector, Pose3>(boost::bind(&predictionErrorVel, _1, Vel1, Bias1, Pose2, Vel2, factor), Pose1);
|
H5_expectedVel;
|
||||||
H2_expectedVel = numericalDerivative11<Vector, Vector3>(boost::bind(&predictionErrorVel, Pose1, _1, Bias1, Pose2, Vel2, factor), Vel1);
|
H1_expectedVel = numericalDerivative11<Vector, Pose3>(
|
||||||
H3_expectedVel = numericalDerivative11<Vector, imuBias::ConstantBias>(boost::bind(&predictionErrorVel, Pose1, Vel1, _1, Pose2, Vel2, factor), Bias1);
|
boost::bind(&predictionErrorVel, _1, Vel1, Bias1, Pose2, Vel2, factor),
|
||||||
H4_expectedVel = numericalDerivative11<Vector, Pose3>(boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, _1, Vel2, factor), Pose2);
|
Pose1);
|
||||||
H5_expectedVel = numericalDerivative11<Vector, Vector3>(boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, Pose2, _1, factor), Vel2);
|
H2_expectedVel = numericalDerivative11<Vector, Vector3>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, _1, Bias1, Pose2, Vel2, factor),
|
||||||
|
Vel1);
|
||||||
|
H3_expectedVel = numericalDerivative11<Vector, imuBias::ConstantBias>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, Vel1, _1, Pose2, Vel2, factor),
|
||||||
|
Bias1);
|
||||||
|
H4_expectedVel = numericalDerivative11<Vector, Pose3>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, _1, Vel2, factor),
|
||||||
|
Pose2);
|
||||||
|
H5_expectedVel = numericalDerivative11<Vector, Vector3>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, Pose2, _1, factor),
|
||||||
|
Vel2);
|
||||||
|
|
||||||
// Verify they are equal for this choice of state
|
// Verify they are equal for this choice of state
|
||||||
CHECK( assert_equal(H1_expectedVel, H1_actualVel, 1e-5));
|
CHECK( assert_equal(H1_expectedVel, H1_actualVel, 1e-5));
|
||||||
|
@ -368,12 +367,7 @@ TEST (InertialNavFactor_GlobalVelocity, Jacobian ) {
|
||||||
CHECK( assert_equal(H5_expectedVel, H5_actualVel, 1e-5));
|
CHECK( assert_equal(H5_expectedVel, H5_actualVel, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ConstructorWithTransform) {
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ConstructorWithTransform)
|
|
||||||
{
|
|
||||||
Key Pose1(11);
|
Key Pose1(11);
|
||||||
Key Pose2(12);
|
Key Pose2(12);
|
||||||
Key Vel1(21);
|
Key Vel1(21);
|
||||||
|
@ -384,22 +378,18 @@ TEST( InertialNavFactor_GlobalVelocity, ConstructorWithTransform)
|
||||||
Vector measurement_gyro((Vector(3) << -0.2, 0.5, 0.03));
|
Vector measurement_gyro((Vector(3) << -0.2, 0.5, 0.03));
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(0.0, 0.0, 0.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(0.0, 0.0, 0.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro,
|
||||||
|
measurement_dt, world_g, world_rho, world_omega_earth, model,
|
||||||
|
body_P_sensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, EqualsWithTransform) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, EqualsWithTransform)
|
|
||||||
{
|
|
||||||
Key Pose1(11);
|
Key Pose1(11);
|
||||||
Key Pose2(12);
|
Key Pose2(12);
|
||||||
Key Vel1(21);
|
Key Vel1(21);
|
||||||
|
@ -410,24 +400,23 @@ TEST( InertialNavFactor_GlobalVelocity, EqualsWithTransform)
|
||||||
Vector measurement_gyro((Vector(3) << -0.2, 0.5, 0.03));
|
Vector measurement_gyro((Vector(3) << -0.2, 0.5, 0.03));
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(0.0, 0.0, 0.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(0.0, 0.0, 0.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro,
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> g(Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
measurement_dt, world_g, world_rho, world_omega_earth, model,
|
||||||
|
body_P_sensor);
|
||||||
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> g(
|
||||||
|
Pose1, Vel1, Bias1, Pose2, Vel2, measurement_acc, measurement_gyro,
|
||||||
|
measurement_dt, world_g, world_rho, world_omega_earth, model,
|
||||||
|
body_P_sensor);
|
||||||
CHECK(assert_equal(f, g, 1e-5));
|
CHECK(assert_equal(f, g, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, PredictWithTransform) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, PredictWithTransform)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -435,39 +424,38 @@ TEST( InertialNavFactor_GlobalVelocity, PredictWithTransform)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
|
||||||
// First test: zero angular motion, some acceleration
|
// First test: zero angular motion, some acceleration
|
||||||
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0)); // Measured in ENU orientation
|
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0)); // Measured in ENU orientation
|
||||||
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
||||||
Vector measurement_acc = (Vector(3) << 0.2, 0.1, -0.3+9.81) + omega__cross*omega__cross*body_P_sensor.rotation().inverse().matrix()*body_P_sensor.translation().vector(); // Measured in ENU orientation
|
Vector measurement_acc = (Vector(3) << 0.2, 0.1, -0.3 + 9.81)
|
||||||
|
+ omega__cross * omega__cross
|
||||||
|
* body_P_sensor.rotation().inverse().matrix()
|
||||||
|
* body_P_sensor.translation().vector(); // Measured in ENU orientation
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model, body_P_sensor);
|
||||||
|
|
||||||
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
||||||
LieVector Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
Vector3 Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
Pose3 expectedPose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
Pose3 expectedPose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
||||||
LieVector expectedVel2((Vector(3) << 0.51, -0.48, 0.43));
|
Vector3 expectedVel2((Vector(3) << 0.51, -0.48, 0.43));
|
||||||
Pose3 actualPose2;
|
Pose3 actualPose2;
|
||||||
LieVector actualVel2;
|
Vector3 actualVel2;
|
||||||
f.predict(Pose1, Vel1, Bias1, actualPose2, actualVel2);
|
f.predict(Pose1, Vel1, Bias1, actualPose2, actualVel2);
|
||||||
|
|
||||||
CHECK(assert_equal(expectedPose2, actualPose2, 1e-5));
|
CHECK(assert_equal(expectedPose2, actualPose2, 1e-5));
|
||||||
CHECK(assert_equal(expectedVel2, actualVel2, 1e-5));
|
CHECK(assert_equal((Vector)expectedVel2, actualVel2, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ErrorPosVelWithTransform) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ErrorPosVelWithTransform)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -475,27 +463,28 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorPosVelWithTransform)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
|
||||||
// First test: zero angular motion, some acceleration
|
// First test: zero angular motion, some acceleration
|
||||||
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0)); // Measured in ENU orientation
|
Vector measurement_gyro((Vector(3) << 0.0, 0.0, 0.0)); // Measured in ENU orientation
|
||||||
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
||||||
Vector measurement_acc = (Vector(3) << 0.2, 0.1, -0.3+9.81) + omega__cross*omega__cross*body_P_sensor.rotation().inverse().matrix()*body_P_sensor.translation().vector(); // Measured in ENU orientation
|
Vector measurement_acc = (Vector(3) << 0.2, 0.1, -0.3 + 9.81)
|
||||||
|
+ omega__cross * omega__cross
|
||||||
|
* body_P_sensor.rotation().inverse().matrix()
|
||||||
|
* body_P_sensor.translation().vector(); // Measured in ENU orientation
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model, body_P_sensor);
|
||||||
|
|
||||||
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
Pose3 Pose1(Rot3(), Point3(2.00, 1.00, 3.00));
|
||||||
Pose3 Pose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
Pose3 Pose2(Rot3(), Point3(2.05, 0.95, 3.04));
|
||||||
LieVector Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
Vector3 Vel1((Vector(3) << 0.50, -0.50, 0.40));
|
||||||
LieVector Vel2((Vector(3) << 0.51, -0.48, 0.43));
|
Vector3 Vel2((Vector(3) << 0.51, -0.48, 0.43));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
@ -504,9 +493,7 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorPosVelWithTransform)
|
||||||
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ErrorRotWithTransform) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ErrorRotWithTransform)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -514,27 +501,31 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotWithTransform)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
|
||||||
// Second test: zero angular motion, some acceleration
|
// Second test: zero angular motion, some acceleration
|
||||||
Vector measurement_gyro((Vector(3) << 0.2, 0.1, -0.3)); // Measured in ENU orientation
|
Vector measurement_gyro((Vector(3) << 0.2, 0.1, -0.3)); // Measured in ENU orientation
|
||||||
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
||||||
Vector measurement_acc = (Vector(3) << 0.0, 0.0, 0.0+9.81) + omega__cross*omega__cross*body_P_sensor.rotation().inverse().matrix()*body_P_sensor.translation().vector(); // Measured in ENU orientation
|
Vector measurement_acc = (Vector(3) << 0.0, 0.0, 0.0 + 9.81)
|
||||||
|
+ omega__cross * omega__cross
|
||||||
|
* body_P_sensor.rotation().inverse().matrix()
|
||||||
|
* body_P_sensor.translation().vector(); // Measured in ENU orientation
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model, body_P_sensor);
|
||||||
|
|
||||||
Pose3 Pose1(Rot3(), Point3(2.0,1.0,3.0));
|
Pose3 Pose1(Rot3(), Point3(2.0, 1.0, 3.0));
|
||||||
Pose3 Pose2(Rot3::Expmap(body_P_sensor.rotation().matrix()*measurement_gyro*measurement_dt), Point3(2.0, 1.0, 3.0));
|
Pose3 Pose2(
|
||||||
LieVector Vel1((Vector(3) << 0.0,0.0,0.0));
|
Rot3::Expmap(
|
||||||
LieVector Vel2((Vector(3) << 0.0,0.0,0.0));
|
body_P_sensor.rotation().matrix() * measurement_gyro
|
||||||
|
* measurement_dt), Point3(2.0, 1.0, 3.0));
|
||||||
|
Vector3 Vel1((Vector(3) << 0.0, 0.0, 0.0));
|
||||||
|
Vector3 Vel2((Vector(3) << 0.0, 0.0, 0.0));
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
@ -543,9 +534,7 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotWithTransform)
|
||||||
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVelWithTransform) {
|
||||||
TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVelWithTransform)
|
|
||||||
{
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
Key VelKey1(21);
|
Key VelKey1(21);
|
||||||
|
@ -553,36 +542,40 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVelWithTransform)
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.1);
|
double measurement_dt(0.1);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
|
||||||
// Second test: zero angular motion, some acceleration - generated in matlab
|
// Second test: zero angular motion, some acceleration - generated in matlab
|
||||||
Vector measurement_gyro((Vector(3) << 0.2, 0.1, -0.3)); // Measured in ENU orientation
|
Vector measurement_gyro((Vector(3) << 0.2, 0.1, -0.3)); // Measured in ENU orientation
|
||||||
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
||||||
Vector measurement_acc = (Vector(3) << -6.763926150509185, 6.501390843381716, +2.300389940090343) + omega__cross*omega__cross*body_P_sensor.rotation().inverse().matrix()*body_P_sensor.translation().vector(); // Measured in ENU orientation
|
Vector measurement_acc =
|
||||||
|
(Vector(3) << -6.763926150509185, 6.501390843381716, +2.300389940090343)
|
||||||
|
+ omega__cross * omega__cross
|
||||||
|
* body_P_sensor.rotation().inverse().matrix()
|
||||||
|
* body_P_sensor.translation().vector(); // Measured in ENU orientation
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> f(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> f(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model, body_P_sensor);
|
||||||
|
|
||||||
Rot3 R1(0.487316618, 0.125253866, 0.86419557,
|
Rot3 R1(0.487316618, 0.125253866, 0.86419557, 0.580273724, 0.693095498,
|
||||||
0.580273724, 0.693095498, -0.427669306,
|
-0.427669306, -0.652537293, 0.709880342, 0.265075427);
|
||||||
-0.652537293, 0.709880342, 0.265075427);
|
Point3 t1(2.0, 1.0, 3.0);
|
||||||
Point3 t1(2.0,1.0,3.0);
|
|
||||||
Pose3 Pose1(R1, t1);
|
Pose3 Pose1(R1, t1);
|
||||||
LieVector Vel1((Vector(3) << 0.5,-0.5,0.4));
|
Vector3 Vel1((Vector(3) << 0.5, -0.5, 0.4));
|
||||||
Rot3 R2(0.473618898, 0.119523052, 0.872582019,
|
Rot3 R2(0.473618898, 0.119523052, 0.872582019, 0.609241153, 0.67099888,
|
||||||
0.609241153, 0.67099888, -0.422594037,
|
-0.422594037, -0.636011287, 0.731761397, 0.244979388);
|
||||||
-0.636011287, 0.731761397, 0.244979388);
|
Point3 t2 = t1.compose(Point3(Vel1 * measurement_dt));
|
||||||
Point3 t2 = t1.compose( Point3(Vel1*measurement_dt) );
|
|
||||||
Pose3 Pose2(R2, t2);
|
Pose3 Pose2(R2, t2);
|
||||||
Vector dv = measurement_dt * (R1.matrix() * body_P_sensor.rotation().matrix() * (Vector(3) << -6.763926150509185, 6.501390843381716, +2.300389940090343) + world_g);
|
Vector dv =
|
||||||
LieVector Vel2 = Vel1.compose( dv );
|
measurement_dt
|
||||||
|
* (R1.matrix() * body_P_sensor.rotation().matrix()
|
||||||
|
* (Vector(3) << -6.763926150509185, 6.501390843381716, +2.300389940090343)
|
||||||
|
+ world_g);
|
||||||
|
Vector3 Vel2 = Vel1 + dv;
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
Vector ActualErr(f.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2));
|
||||||
|
@ -592,8 +585,7 @@ TEST( InertialNavFactor_GlobalVelocity, ErrorRotPosVelWithTransform)
|
||||||
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
CHECK(assert_equal(ExpectedErr, ActualErr, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */TEST (InertialNavFactor_GlobalVelocity, JacobianWithTransform ) {
|
||||||
TEST (InertialNavFactor_GlobalVelocity, JacobianWithTransform ) {
|
|
||||||
|
|
||||||
Key PoseKey1(11);
|
Key PoseKey1(11);
|
||||||
Key PoseKey2(12);
|
Key PoseKey2(12);
|
||||||
|
@ -602,56 +594,68 @@ TEST (InertialNavFactor_GlobalVelocity, JacobianWithTransform ) {
|
||||||
Key BiasKey1(31);
|
Key BiasKey1(31);
|
||||||
|
|
||||||
double measurement_dt(0.01);
|
double measurement_dt(0.01);
|
||||||
Vector world_g((Vector(3) << 0.0, 0.0, 9.81));
|
|
||||||
Vector world_rho((Vector(3) << 0.0, -1.5724e-05, 0.0)); // NED system
|
|
||||||
Vector ECEF_omega_earth((Vector(3) << 0.0, 0.0, 7.292115e-5));
|
|
||||||
Vector world_omega_earth(world_R_ECEF.matrix() * ECEF_omega_earth);
|
|
||||||
|
|
||||||
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
SharedGaussian model(noiseModel::Isotropic::Sigma(9, 0.1));
|
||||||
|
|
||||||
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
Pose3 body_P_sensor(Rot3(0, 1, 0, 1, 0, 0, 0, 0, -1), Point3(1.0, -2.0, 3.0)); // IMU is in ENU orientation
|
||||||
|
|
||||||
|
Vector measurement_gyro((Vector(3) << 3.14 / 2, 3.14, +3.14)); // Measured in ENU orientation
|
||||||
Vector measurement_gyro((Vector(3) << 3.14/2, 3.14, +3.14)); // Measured in ENU orientation
|
|
||||||
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
Matrix omega__cross = skewSymmetric(measurement_gyro);
|
||||||
Vector measurement_acc = (Vector(3) << -6.763926150509185, 6.501390843381716, +2.300389940090343) + omega__cross*omega__cross*body_P_sensor.rotation().inverse().matrix()*body_P_sensor.translation().vector(); // Measured in ENU orientation
|
Vector measurement_acc =
|
||||||
|
(Vector(3) << -6.763926150509185, 6.501390843381716, +2.300389940090343)
|
||||||
|
+ omega__cross * omega__cross
|
||||||
|
* body_P_sensor.rotation().inverse().matrix()
|
||||||
|
* body_P_sensor.translation().vector(); // Measured in ENU orientation
|
||||||
|
|
||||||
|
InertialNavFactor_GlobalVelocity<Pose3, Vector3, imuBias::ConstantBias> factor(
|
||||||
|
PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc,
|
||||||
|
measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth,
|
||||||
|
model, body_P_sensor);
|
||||||
|
|
||||||
InertialNavFactor_GlobalVelocity<Pose3, LieVector, imuBias::ConstantBias> factor(PoseKey1, VelKey1, BiasKey1, PoseKey2, VelKey2, measurement_acc, measurement_gyro, measurement_dt, world_g, world_rho, world_omega_earth, model, body_P_sensor);
|
Rot3 R1(0.487316618, 0.125253866, 0.86419557, 0.580273724, 0.693095498,
|
||||||
|
-0.427669306, -0.652537293, 0.709880342, 0.265075427);
|
||||||
Rot3 R1(0.487316618, 0.125253866, 0.86419557,
|
Point3 t1(2.0, 1.0, 3.0);
|
||||||
0.580273724, 0.693095498, -0.427669306,
|
|
||||||
-0.652537293, 0.709880342, 0.265075427);
|
|
||||||
Point3 t1(2.0,1.0,3.0);
|
|
||||||
Pose3 Pose1(R1, t1);
|
Pose3 Pose1(R1, t1);
|
||||||
LieVector Vel1((Vector(3) << 0.5,-0.5,0.4));
|
Vector3 Vel1(0.5, -0.5, 0.4);
|
||||||
Rot3 R2(0.473618898, 0.119523052, 0.872582019,
|
Rot3 R2(0.473618898, 0.119523052, 0.872582019, 0.609241153, 0.67099888,
|
||||||
0.609241153, 0.67099888, -0.422594037,
|
-0.422594037, -0.636011287, 0.731761397, 0.244979388);
|
||||||
-0.636011287, 0.731761397, 0.244979388);
|
Point3 t2(2.052670960415706, 0.977252139079380, 2.942482135362800);
|
||||||
Point3 t2(2.052670960415706, 0.977252139079380, 2.942482135362800);
|
|
||||||
Pose3 Pose2(R2, t2);
|
Pose3 Pose2(R2, t2);
|
||||||
LieVector Vel2((Vector(3) << 0.510000000000000, -0.480000000000000, 0.430000000000000));
|
Vector3 Vel2(0.510000000000000, -0.480000000000000, 0.430000000000000);
|
||||||
imuBias::ConstantBias Bias1;
|
imuBias::ConstantBias Bias1;
|
||||||
|
|
||||||
Matrix H1_actual, H2_actual, H3_actual, H4_actual, H5_actual;
|
Matrix H1_actual, H2_actual, H3_actual, H4_actual, H5_actual;
|
||||||
|
|
||||||
Vector ActualErr(factor.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2, H1_actual, H2_actual, H3_actual, H4_actual, H5_actual));
|
Vector ActualErr(
|
||||||
|
factor.evaluateError(Pose1, Vel1, Bias1, Pose2, Vel2, H1_actual,
|
||||||
|
H2_actual, H3_actual, H4_actual, H5_actual));
|
||||||
|
|
||||||
// Checking for Pose part in the jacobians
|
// Checking for Pose part in the jacobians
|
||||||
// ******
|
// ******
|
||||||
Matrix H1_actualPose(H1_actual.block(0,0,6,H1_actual.cols()));
|
Matrix H1_actualPose(H1_actual.block(0, 0, 6, H1_actual.cols()));
|
||||||
Matrix H2_actualPose(H2_actual.block(0,0,6,H2_actual.cols()));
|
Matrix H2_actualPose(H2_actual.block(0, 0, 6, H2_actual.cols()));
|
||||||
Matrix H3_actualPose(H3_actual.block(0,0,6,H3_actual.cols()));
|
Matrix H3_actualPose(H3_actual.block(0, 0, 6, H3_actual.cols()));
|
||||||
Matrix H4_actualPose(H4_actual.block(0,0,6,H4_actual.cols()));
|
Matrix H4_actualPose(H4_actual.block(0, 0, 6, H4_actual.cols()));
|
||||||
Matrix H5_actualPose(H5_actual.block(0,0,6,H5_actual.cols()));
|
Matrix H5_actualPose(H5_actual.block(0, 0, 6, H5_actual.cols()));
|
||||||
|
|
||||||
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
||||||
Matrix H1_expectedPose, H2_expectedPose, H3_expectedPose, H4_expectedPose, H5_expectedPose;
|
Matrix H1_expectedPose, H2_expectedPose, H3_expectedPose, H4_expectedPose,
|
||||||
H1_expectedPose = numericalDerivative11<Pose3, Pose3>(boost::bind(&predictionErrorPose, _1, Vel1, Bias1, Pose2, Vel2, factor), Pose1);
|
H5_expectedPose;
|
||||||
H2_expectedPose = numericalDerivative11<Pose3, Vector3>(boost::bind(&predictionErrorPose, Pose1, _1, Bias1, Pose2, Vel2, factor), Vel1);
|
H1_expectedPose = numericalDerivative11<Pose3, Pose3>(
|
||||||
H3_expectedPose = numericalDerivative11<Pose3, imuBias::ConstantBias>(boost::bind(&predictionErrorPose, Pose1, Vel1, _1, Pose2, Vel2, factor), Bias1);
|
boost::bind(&predictionErrorPose, _1, Vel1, Bias1, Pose2, Vel2, factor),
|
||||||
H4_expectedPose = numericalDerivative11<Pose3, Pose3>(boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, _1, Vel2, factor), Pose2);
|
Pose1);
|
||||||
H5_expectedPose = numericalDerivative11<Pose3, Vector3>(boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, Pose2, _1, factor), Vel2);
|
H2_expectedPose = numericalDerivative11<Pose3, Vector3>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, _1, Bias1, Pose2, Vel2, factor),
|
||||||
|
Vel1);
|
||||||
|
H3_expectedPose = numericalDerivative11<Pose3, imuBias::ConstantBias>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, Vel1, _1, Pose2, Vel2, factor),
|
||||||
|
Bias1);
|
||||||
|
H4_expectedPose = numericalDerivative11<Pose3, Pose3>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, _1, Vel2, factor),
|
||||||
|
Pose2);
|
||||||
|
H5_expectedPose = numericalDerivative11<Pose3, Vector3>(
|
||||||
|
boost::bind(&predictionErrorPose, Pose1, Vel1, Bias1, Pose2, _1, factor),
|
||||||
|
Vel2);
|
||||||
|
|
||||||
// Verify they are equal for this choice of state
|
// Verify they are equal for this choice of state
|
||||||
CHECK( assert_equal(H1_expectedPose, H1_actualPose, 1e-5));
|
CHECK( assert_equal(H1_expectedPose, H1_actualPose, 1e-5));
|
||||||
|
@ -662,19 +666,30 @@ TEST (InertialNavFactor_GlobalVelocity, JacobianWithTransform ) {
|
||||||
|
|
||||||
// Checking for Vel part in the jacobians
|
// Checking for Vel part in the jacobians
|
||||||
// ******
|
// ******
|
||||||
Matrix H1_actualVel(H1_actual.block(6,0,3,H1_actual.cols()));
|
Matrix H1_actualVel(H1_actual.block(6, 0, 3, H1_actual.cols()));
|
||||||
Matrix H2_actualVel(H2_actual.block(6,0,3,H2_actual.cols()));
|
Matrix H2_actualVel(H2_actual.block(6, 0, 3, H2_actual.cols()));
|
||||||
Matrix H3_actualVel(H3_actual.block(6,0,3,H3_actual.cols()));
|
Matrix H3_actualVel(H3_actual.block(6, 0, 3, H3_actual.cols()));
|
||||||
Matrix H4_actualVel(H4_actual.block(6,0,3,H4_actual.cols()));
|
Matrix H4_actualVel(H4_actual.block(6, 0, 3, H4_actual.cols()));
|
||||||
Matrix H5_actualVel(H5_actual.block(6,0,3,H5_actual.cols()));
|
Matrix H5_actualVel(H5_actual.block(6, 0, 3, H5_actual.cols()));
|
||||||
|
|
||||||
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
// Calculate the Jacobian matrices H1 until H5 using the numerical derivative function
|
||||||
Matrix H1_expectedVel, H2_expectedVel, H3_expectedVel, H4_expectedVel, H5_expectedVel;
|
Matrix H1_expectedVel, H2_expectedVel, H3_expectedVel, H4_expectedVel,
|
||||||
H1_expectedVel = numericalDerivative11<Vector, Pose3>(boost::bind(&predictionErrorVel, _1, Vel1, Bias1, Pose2, Vel2, factor), Pose1);
|
H5_expectedVel;
|
||||||
H2_expectedVel = numericalDerivative11<Vector, Vector3>(boost::bind(&predictionErrorVel, Pose1, _1, Bias1, Pose2, Vel2, factor), Vel1);
|
H1_expectedVel = numericalDerivative11<Vector, Pose3>(
|
||||||
H3_expectedVel = numericalDerivative11<Vector, imuBias::ConstantBias>(boost::bind(&predictionErrorVel, Pose1, Vel1, _1, Pose2, Vel2, factor), Bias1);
|
boost::bind(&predictionErrorVel, _1, Vel1, Bias1, Pose2, Vel2, factor),
|
||||||
H4_expectedVel = numericalDerivative11<Vector, Pose3>(boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, _1, Vel2, factor), Pose2);
|
Pose1);
|
||||||
H5_expectedVel = numericalDerivative11<Vector, Vector3>(boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, Pose2, _1, factor), Vel2);
|
H2_expectedVel = numericalDerivative11<Vector, Vector3>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, _1, Bias1, Pose2, Vel2, factor),
|
||||||
|
Vel1);
|
||||||
|
H3_expectedVel = numericalDerivative11<Vector, imuBias::ConstantBias>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, Vel1, _1, Pose2, Vel2, factor),
|
||||||
|
Bias1);
|
||||||
|
H4_expectedVel = numericalDerivative11<Vector, Pose3>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, _1, Vel2, factor),
|
||||||
|
Pose2);
|
||||||
|
H5_expectedVel = numericalDerivative11<Vector, Vector3>(
|
||||||
|
boost::bind(&predictionErrorVel, Pose1, Vel1, Bias1, Pose2, _1, factor),
|
||||||
|
Vel2);
|
||||||
|
|
||||||
// Verify they are equal for this choice of state
|
// Verify they are equal for this choice of state
|
||||||
CHECK( assert_equal(H1_expectedVel, H1_actualVel, 1e-5));
|
CHECK( assert_equal(H1_expectedVel, H1_actualVel, 1e-5));
|
||||||
|
@ -685,5 +700,8 @@ TEST (InertialNavFactor_GlobalVelocity, JacobianWithTransform ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
|
int main() {
|
||||||
|
TestResult tr;
|
||||||
|
return TestRegistry::runAllTests(tr);
|
||||||
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -25,7 +25,7 @@ static SharedNoiseModel sigma(noiseModel::Unit::Create(2));
|
||||||
Pose3 level_pose = Pose3(Rot3::ypr(-M_PI/2, 0., -M_PI/2), gtsam::Point3(0,0,1));
|
Pose3 level_pose = Pose3(Rot3::ypr(-M_PI/2, 0., -M_PI/2), gtsam::Point3(0,0,1));
|
||||||
SimpleCamera level_camera(level_pose, *K);
|
SimpleCamera level_camera(level_pose, *K);
|
||||||
|
|
||||||
typedef InvDepthFactor3<Pose3, LieVector, LieScalar> InverseDepthFactor;
|
typedef InvDepthFactor3<Pose3, Vector5, double> InverseDepthFactor;
|
||||||
typedef NonlinearEquality<Pose3> PoseConstraint;
|
typedef NonlinearEquality<Pose3> PoseConstraint;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -38,10 +38,10 @@ TEST( InvDepthFactor, optimize) {
|
||||||
Point2 expected_uv = level_camera.project(landmark);
|
Point2 expected_uv = level_camera.project(landmark);
|
||||||
|
|
||||||
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
InvDepthCamera3<Cal3_S2> inv_camera(level_pose, K);
|
||||||
LieVector inv_landmark((Vector(5) << 0., 0., 1., 0., 0.));
|
Vector5 inv_landmark((Vector(5) << 0., 0., 1., 0., 0.));
|
||||||
// initialize inverse depth with "incorrect" depth of 1/4
|
// initialize inverse depth with "incorrect" depth of 1/4
|
||||||
// in reality this is 1/5, but initial depth is guessed
|
// in reality this is 1/5, but initial depth is guessed
|
||||||
LieScalar inv_depth(1./4);
|
double inv_depth(1./4);
|
||||||
|
|
||||||
gtsam::NonlinearFactorGraph graph;
|
gtsam::NonlinearFactorGraph graph;
|
||||||
Values initial;
|
Values initial;
|
||||||
|
@ -82,8 +82,8 @@ TEST( InvDepthFactor, optimize) {
|
||||||
Values result2 = LevenbergMarquardtOptimizer(graph, initial, lmParams).optimize();
|
Values result2 = LevenbergMarquardtOptimizer(graph, initial, lmParams).optimize();
|
||||||
|
|
||||||
Point3 result2_lmk = InvDepthCamera3<Cal3_S2>::invDepthTo3D(
|
Point3 result2_lmk = InvDepthCamera3<Cal3_S2>::invDepthTo3D(
|
||||||
result2.at<LieVector>(Symbol('l',1)),
|
result2.at<Vector5>(Symbol('l',1)),
|
||||||
result2.at<LieScalar>(Symbol('d',1)));
|
result2.at<double>(Symbol('d',1)));
|
||||||
EXPECT(assert_equal(landmark, result2_lmk, 1e-9));
|
EXPECT(assert_equal(landmark, result2_lmk, 1e-9));
|
||||||
|
|
||||||
// TODO: need to add priors to make this work with
|
// TODO: need to add priors to make this work with
|
||||||
|
|
|
@ -45,7 +45,7 @@ TEST( InvDepthFactorVariant1, optimize) {
|
||||||
double theta = atan2(ray.y(), ray.x());
|
double theta = atan2(ray.y(), ray.x());
|
||||||
double phi = atan2(ray.z(), sqrt(ray.x()*ray.x()+ray.y()*ray.y()));
|
double phi = atan2(ray.z(), sqrt(ray.x()*ray.x()+ray.y()*ray.y()));
|
||||||
double rho = 1./ray.norm();
|
double rho = 1./ray.norm();
|
||||||
LieVector expected((Vector(6) << x, y, z, theta, phi, rho));
|
Vector6 expected((Vector(6) << x, y, z, theta, phi, rho));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,12 +68,12 @@ TEST( InvDepthFactorVariant1, optimize) {
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(poseKey1, pose1.retract((Vector(6) << +0.01, -0.02, +0.03, -0.10, +0.20, -0.30)));
|
values.insert(poseKey1, pose1.retract((Vector(6) << +0.01, -0.02, +0.03, -0.10, +0.20, -0.30)));
|
||||||
values.insert(poseKey2, pose2.retract((Vector(6) << +0.01, +0.02, -0.03, -0.10, +0.20, +0.30)));
|
values.insert(poseKey2, pose2.retract((Vector(6) << +0.01, +0.02, -0.03, -0.10, +0.20, +0.30)));
|
||||||
values.insert(landmarkKey, expected.retract((Vector(6) << -0.20, +0.20, -0.35, +0.02, -0.04, +0.05)));
|
values.insert(landmarkKey, Vector6(expected + (Vector(6) << -0.20, +0.20, -0.35, +0.02, -0.04, +0.05)));
|
||||||
|
|
||||||
// Optimize the graph to recover the actual landmark position
|
// Optimize the graph to recover the actual landmark position
|
||||||
LevenbergMarquardtParams params;
|
LevenbergMarquardtParams params;
|
||||||
Values result = LevenbergMarquardtOptimizer(graph, values, params).optimize();
|
Values result = LevenbergMarquardtOptimizer(graph, values, params).optimize();
|
||||||
LieVector actual = result.at<LieVector>(landmarkKey);
|
Vector6 actual = result.at<Vector6>(landmarkKey);
|
||||||
|
|
||||||
|
|
||||||
// values.at<Pose3>(poseKey1).print("Pose1 Before:\n");
|
// values.at<Pose3>(poseKey1).print("Pose1 Before:\n");
|
||||||
|
@ -84,22 +84,22 @@ TEST( InvDepthFactorVariant1, optimize) {
|
||||||
// result.at<Pose3>(poseKey2).print("Pose2 After:\n");
|
// result.at<Pose3>(poseKey2).print("Pose2 After:\n");
|
||||||
// pose2.print("Pose2 Truth:\n");
|
// pose2.print("Pose2 Truth:\n");
|
||||||
// cout << endl << endl;
|
// cout << endl << endl;
|
||||||
// values.at<LieVector>(landmarkKey).print("Landmark Before:\n");
|
// values.at<Vector6>(landmarkKey).print("Landmark Before:\n");
|
||||||
// result.at<LieVector>(landmarkKey).print("Landmark After:\n");
|
// result.at<Vector6>(landmarkKey).print("Landmark After:\n");
|
||||||
// expected.print("Landmark Truth:\n");
|
// expected.print("Landmark Truth:\n");
|
||||||
// cout << endl << endl;
|
// cout << endl << endl;
|
||||||
|
|
||||||
// Calculate world coordinates of landmark versions
|
// Calculate world coordinates of landmark versions
|
||||||
Point3 world_landmarkBefore;
|
Point3 world_landmarkBefore;
|
||||||
{
|
{
|
||||||
LieVector landmarkBefore = values.at<LieVector>(landmarkKey);
|
Vector6 landmarkBefore = values.at<Vector6>(landmarkKey);
|
||||||
double x = landmarkBefore(0), y = landmarkBefore(1), z = landmarkBefore(2);
|
double x = landmarkBefore(0), y = landmarkBefore(1), z = landmarkBefore(2);
|
||||||
double theta = landmarkBefore(3), phi = landmarkBefore(4), rho = landmarkBefore(5);
|
double theta = landmarkBefore(3), phi = landmarkBefore(4), rho = landmarkBefore(5);
|
||||||
world_landmarkBefore = Point3(x, y, z) + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
world_landmarkBefore = Point3(x, y, z) + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
||||||
}
|
}
|
||||||
Point3 world_landmarkAfter;
|
Point3 world_landmarkAfter;
|
||||||
{
|
{
|
||||||
LieVector landmarkAfter = result.at<LieVector>(landmarkKey);
|
Vector6 landmarkAfter = result.at<Vector6>(landmarkKey);
|
||||||
double x = landmarkAfter(0), y = landmarkAfter(1), z = landmarkAfter(2);
|
double x = landmarkAfter(0), y = landmarkAfter(1), z = landmarkAfter(2);
|
||||||
double theta = landmarkAfter(3), phi = landmarkAfter(4), rho = landmarkAfter(5);
|
double theta = landmarkAfter(3), phi = landmarkAfter(4), rho = landmarkAfter(5);
|
||||||
world_landmarkAfter = Point3(x, y, z) + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
world_landmarkAfter = Point3(x, y, z) + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
||||||
|
|
|
@ -43,7 +43,7 @@ TEST( InvDepthFactorVariant2, optimize) {
|
||||||
double theta = atan2(ray.y(), ray.x());
|
double theta = atan2(ray.y(), ray.x());
|
||||||
double phi = atan2(ray.z(), sqrt(ray.x()*ray.x()+ray.y()*ray.y()));
|
double phi = atan2(ray.z(), sqrt(ray.x()*ray.x()+ray.y()*ray.y()));
|
||||||
double rho = 1./ray.norm();
|
double rho = 1./ray.norm();
|
||||||
LieVector expected((Vector(3) << theta, phi, rho));
|
Vector3 expected((Vector(3) << theta, phi, rho));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,12 +66,12 @@ TEST( InvDepthFactorVariant2, optimize) {
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(poseKey1, pose1.retract((Vector(6) << +0.01, -0.02, +0.03, -0.10, +0.20, -0.30)));
|
values.insert(poseKey1, pose1.retract((Vector(6) << +0.01, -0.02, +0.03, -0.10, +0.20, -0.30)));
|
||||||
values.insert(poseKey2, pose2.retract((Vector(6) << +0.01, +0.02, -0.03, -0.10, +0.20, +0.30)));
|
values.insert(poseKey2, pose2.retract((Vector(6) << +0.01, +0.02, -0.03, -0.10, +0.20, +0.30)));
|
||||||
values.insert(landmarkKey, expected.retract((Vector(3) << +0.02, -0.04, +0.05)));
|
values.insert(landmarkKey, Vector3(expected + (Vector(3) << +0.02, -0.04, +0.05)));
|
||||||
|
|
||||||
// Optimize the graph to recover the actual landmark position
|
// Optimize the graph to recover the actual landmark position
|
||||||
LevenbergMarquardtParams params;
|
LevenbergMarquardtParams params;
|
||||||
Values result = LevenbergMarquardtOptimizer(graph, values, params).optimize();
|
Values result = LevenbergMarquardtOptimizer(graph, values, params).optimize();
|
||||||
LieVector actual = result.at<LieVector>(landmarkKey);
|
Vector3 actual = result.at<Vector3>(landmarkKey);
|
||||||
|
|
||||||
// values.at<Pose3>(poseKey1).print("Pose1 Before:\n");
|
// values.at<Pose3>(poseKey1).print("Pose1 Before:\n");
|
||||||
// result.at<Pose3>(poseKey1).print("Pose1 After:\n");
|
// result.at<Pose3>(poseKey1).print("Pose1 After:\n");
|
||||||
|
@ -81,21 +81,21 @@ TEST( InvDepthFactorVariant2, optimize) {
|
||||||
// result.at<Pose3>(poseKey2).print("Pose2 After:\n");
|
// result.at<Pose3>(poseKey2).print("Pose2 After:\n");
|
||||||
// pose2.print("Pose2 Truth:\n");
|
// pose2.print("Pose2 Truth:\n");
|
||||||
// std::cout << std::endl << std::endl;
|
// std::cout << std::endl << std::endl;
|
||||||
// values.at<LieVector>(landmarkKey).print("Landmark Before:\n");
|
// values.at<Vector3>(landmarkKey).print("Landmark Before:\n");
|
||||||
// result.at<LieVector>(landmarkKey).print("Landmark After:\n");
|
// result.at<Vector3>(landmarkKey).print("Landmark After:\n");
|
||||||
// expected.print("Landmark Truth:\n");
|
// expected.print("Landmark Truth:\n");
|
||||||
// std::cout << std::endl << std::endl;
|
// std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
// Calculate world coordinates of landmark versions
|
// Calculate world coordinates of landmark versions
|
||||||
Point3 world_landmarkBefore;
|
Point3 world_landmarkBefore;
|
||||||
{
|
{
|
||||||
LieVector landmarkBefore = values.at<LieVector>(landmarkKey);
|
Vector3 landmarkBefore = values.at<Vector3>(landmarkKey);
|
||||||
double theta = landmarkBefore(0), phi = landmarkBefore(1), rho = landmarkBefore(2);
|
double theta = landmarkBefore(0), phi = landmarkBefore(1), rho = landmarkBefore(2);
|
||||||
world_landmarkBefore = referencePoint + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
world_landmarkBefore = referencePoint + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
||||||
}
|
}
|
||||||
Point3 world_landmarkAfter;
|
Point3 world_landmarkAfter;
|
||||||
{
|
{
|
||||||
LieVector landmarkAfter = result.at<LieVector>(landmarkKey);
|
Vector3 landmarkAfter = result.at<Vector3>(landmarkKey);
|
||||||
double theta = landmarkAfter(0), phi = landmarkAfter(1), rho = landmarkAfter(2);
|
double theta = landmarkAfter(0), phi = landmarkAfter(1), rho = landmarkAfter(2);
|
||||||
world_landmarkAfter = referencePoint + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
world_landmarkAfter = referencePoint + Point3(cos(theta)*cos(phi)/rho, sin(theta)*cos(phi)/rho, sin(phi)/rho);
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ TEST( InvDepthFactorVariant2, optimize) {
|
||||||
// std::cout << std::endl << std::endl;
|
// std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
// Test that the correct landmark parameters have been recovered
|
// Test that the correct landmark parameters have been recovered
|
||||||
EXPECT(assert_equal(expected, actual, 1e-9));
|
EXPECT(assert_equal((Vector)expected, actual, 1e-9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ TEST( InvDepthFactorVariant3, optimize) {
|
||||||
double theta = atan2(landmark_p1.x(), landmark_p1.z());
|
double theta = atan2(landmark_p1.x(), landmark_p1.z());
|
||||||
double phi = atan2(landmark_p1.y(), sqrt(landmark_p1.x()*landmark_p1.x()+landmark_p1.z()*landmark_p1.z()));
|
double phi = atan2(landmark_p1.y(), sqrt(landmark_p1.x()*landmark_p1.x()+landmark_p1.z()*landmark_p1.z()));
|
||||||
double rho = 1./landmark_p1.norm();
|
double rho = 1./landmark_p1.norm();
|
||||||
LieVector expected((Vector(3) << theta, phi, rho));
|
Vector3 expected((Vector(3) << theta, phi, rho));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,17 +66,17 @@ TEST( InvDepthFactorVariant3, optimize) {
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(poseKey1, pose1.retract((Vector(6) << +0.01, -0.02, +0.03, -0.10, +0.20, -0.30)));
|
values.insert(poseKey1, pose1.retract((Vector(6) << +0.01, -0.02, +0.03, -0.10, +0.20, -0.30)));
|
||||||
values.insert(poseKey2, pose2.retract((Vector(6) << +0.01, +0.02, -0.03, -0.10, +0.20, +0.30)));
|
values.insert(poseKey2, pose2.retract((Vector(6) << +0.01, +0.02, -0.03, -0.10, +0.20, +0.30)));
|
||||||
values.insert(landmarkKey, expected.retract((Vector(3) << +0.02, -0.04, +0.05)));
|
values.insert(landmarkKey, Vector3(expected + (Vector(3) << +0.02, -0.04, +0.05)));
|
||||||
|
|
||||||
// Optimize the graph to recover the actual landmark position
|
// Optimize the graph to recover the actual landmark position
|
||||||
LevenbergMarquardtParams params;
|
LevenbergMarquardtParams params;
|
||||||
Values result = LevenbergMarquardtOptimizer(graph, values, params).optimize();
|
Values result = LevenbergMarquardtOptimizer(graph, values, params).optimize();
|
||||||
LieVector actual = result.at<LieVector>(landmarkKey);
|
Vector3 actual = result.at<Vector3>(landmarkKey);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Test that the correct landmark parameters have been recovered
|
// Test that the correct landmark parameters have been recovered
|
||||||
EXPECT(assert_equal(expected, actual, 1e-9));
|
EXPECT(assert_equal((Vector)expected, actual, 1e-9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <gtsam_unstable/slam/TransformBtwRobotsUnaryFactor.h>
|
#include <gtsam_unstable/slam/TransformBtwRobotsUnaryFactor.h>
|
||||||
#include <gtsam/geometry/Pose2.h>
|
#include <gtsam/geometry/Pose2.h>
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
#include <gtsam/slam/BetweenFactor.h>
|
#include <gtsam/slam/BetweenFactor.h>
|
||||||
|
@ -23,26 +22,21 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
|
||||||
// Disabled this test because it is currently failing - remove the lines "#if 0" and "#endif" below
|
|
||||||
// to reenable the test.
|
|
||||||
//#if 0
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
LieVector predictionError(const Pose2& org1_T_org2, const gtsam::Key& key, const TransformBtwRobotsUnaryFactor<gtsam::Pose2>& factor){
|
Vector predictionError(const Pose2& org1_T_org2, const gtsam::Key& key, const TransformBtwRobotsUnaryFactor<gtsam::Pose2>& factor){
|
||||||
gtsam::Values values;
|
gtsam::Values values;
|
||||||
values.insert(key, org1_T_org2);
|
values.insert(key, org1_T_org2);
|
||||||
// LieVector err = factor.whitenedError(values);
|
return factor.whitenedError(values);
|
||||||
// return err;
|
|
||||||
return LieVector::Expmap(factor.whitenedError(values));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
//LieVector predictionError_standard(const Pose2& p1, const Pose2& p2, const gtsam::Key& keyA, const gtsam::Key& keyB, const BetweenFactor<gtsam::Pose2>& factor){
|
//Vector predictionError_standard(const Pose2& p1, const Pose2& p2, const gtsam::Key& keyA, const gtsam::Key& keyB, const BetweenFactor<gtsam::Pose2>& factor){
|
||||||
// gtsam::Values values;
|
// gtsam::Values values;
|
||||||
// values.insert(keyA, p1);
|
// values.insert(keyA, p1);
|
||||||
// values.insert(keyB, p2);
|
// values.insert(keyB, p2);
|
||||||
// // LieVector err = factor.whitenedError(values);
|
// // Vector err = factor.whitenedError(values);
|
||||||
// // return err;
|
// // return err;
|
||||||
// return LieVector::Expmap(factor.whitenedError(values));
|
// return Vector::Expmap(factor.whitenedError(values));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -237,7 +231,7 @@ TEST( TransformBtwRobotsUnaryFactor, Jacobian)
|
||||||
Matrix H1_actual = H_actual[0];
|
Matrix H1_actual = H_actual[0];
|
||||||
|
|
||||||
double stepsize = 1.0e-9;
|
double stepsize = 1.0e-9;
|
||||||
Matrix H1_expected = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError, _1, key, g), orgA_T_orgB, stepsize);
|
Matrix H1_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, _1, key, g), orgA_T_orgB, stepsize);
|
||||||
// CHECK( assert_equal(H1_expected, H1_actual, 1e-5));
|
// CHECK( assert_equal(H1_expected, H1_actual, 1e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,12 +285,12 @@ TEST( TransformBtwRobotsUnaryFactor, Jacobian)
|
||||||
//// CHECK( assert_equal(H2_actual_stnd, H2_actual, 1e-8));
|
//// CHECK( assert_equal(H2_actual_stnd, H2_actual, 1e-8));
|
||||||
//
|
//
|
||||||
// double stepsize = 1.0e-9;
|
// double stepsize = 1.0e-9;
|
||||||
// Matrix H1_expected = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError, _1, p2, keyA, keyB, f), p1, stepsize);
|
// Matrix H1_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, _1, p2, keyA, keyB, f), p1, stepsize);
|
||||||
// Matrix H2_expected = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError, p1, _1, keyA, keyB, f), p2, stepsize);
|
// Matrix H2_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, p1, _1, keyA, keyB, f), p2, stepsize);
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// // try to check numerical derivatives of a standard between factor
|
// // try to check numerical derivatives of a standard between factor
|
||||||
// Matrix H1_expected_stnd = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError_standard, _1, p2, keyA, keyB, h), p1, stepsize);
|
// Matrix H1_expected_stnd = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError_standard, _1, p2, keyA, keyB, h), p1, stepsize);
|
||||||
// CHECK( assert_equal(H1_expected_stnd, H1_actual_stnd, 1e-5));
|
// CHECK( assert_equal(H1_expected_stnd, H1_actual_stnd, 1e-5));
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -305,8 +299,6 @@ TEST( TransformBtwRobotsUnaryFactor, Jacobian)
|
||||||
//
|
//
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <gtsam_unstable/slam/TransformBtwRobotsUnaryFactorEM.h>
|
#include <gtsam_unstable/slam/TransformBtwRobotsUnaryFactorEM.h>
|
||||||
#include <gtsam/geometry/Pose2.h>
|
#include <gtsam/geometry/Pose2.h>
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
#include <gtsam/slam/BetweenFactor.h>
|
#include <gtsam/slam/BetweenFactor.h>
|
||||||
|
@ -23,26 +22,21 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
|
||||||
// Disabled this test because it is currently failing - remove the lines "#if 0" and "#endif" below
|
|
||||||
// to reenable the test.
|
|
||||||
//#if 0
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
LieVector predictionError(const Pose2& org1_T_org2, const gtsam::Key& key, const TransformBtwRobotsUnaryFactorEM<gtsam::Pose2>& factor){
|
Vector predictionError(const Pose2& org1_T_org2, const gtsam::Key& key, const TransformBtwRobotsUnaryFactorEM<gtsam::Pose2>& factor){
|
||||||
gtsam::Values values;
|
gtsam::Values values;
|
||||||
values.insert(key, org1_T_org2);
|
values.insert(key, org1_T_org2);
|
||||||
// LieVector err = factor.whitenedError(values);
|
return factor.whitenedError(values);
|
||||||
// return err;
|
|
||||||
return LieVector::Expmap(factor.whitenedError(values));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
//LieVector predictionError_standard(const Pose2& p1, const Pose2& p2, const gtsam::Key& keyA, const gtsam::Key& keyB, const BetweenFactor<gtsam::Pose2>& factor){
|
//Vector predictionError_standard(const Pose2& p1, const Pose2& p2, const gtsam::Key& keyA, const gtsam::Key& keyB, const BetweenFactor<gtsam::Pose2>& factor){
|
||||||
// gtsam::Values values;
|
// gtsam::Values values;
|
||||||
// values.insert(keyA, p1);
|
// values.insert(keyA, p1);
|
||||||
// values.insert(keyB, p2);
|
// values.insert(keyB, p2);
|
||||||
// // LieVector err = factor.whitenedError(values);
|
// // Vector err = factor.whitenedError(values);
|
||||||
// // return err;
|
// // return err;
|
||||||
// return LieVector::Expmap(factor.whitenedError(values));
|
// return Vector::Expmap(factor.whitenedError(values));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -266,7 +260,7 @@ TEST( TransformBtwRobotsUnaryFactorEM, Jacobian)
|
||||||
Matrix H1_actual = H_actual[0];
|
Matrix H1_actual = H_actual[0];
|
||||||
|
|
||||||
double stepsize = 1.0e-9;
|
double stepsize = 1.0e-9;
|
||||||
Matrix H1_expected = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError, _1, key, g), orgA_T_orgB, stepsize);
|
Matrix H1_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, _1, key, g), orgA_T_orgB, stepsize);
|
||||||
// CHECK( assert_equal(H1_expected, H1_actual, 1e-5));
|
// CHECK( assert_equal(H1_expected, H1_actual, 1e-5));
|
||||||
}
|
}
|
||||||
/////* ************************************************************************** */
|
/////* ************************************************************************** */
|
||||||
|
@ -316,12 +310,12 @@ TEST( TransformBtwRobotsUnaryFactorEM, Jacobian)
|
||||||
//// CHECK( assert_equal(H2_actual_stnd, H2_actual, 1e-8));
|
//// CHECK( assert_equal(H2_actual_stnd, H2_actual, 1e-8));
|
||||||
//
|
//
|
||||||
// double stepsize = 1.0e-9;
|
// double stepsize = 1.0e-9;
|
||||||
// Matrix H1_expected = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError, _1, p2, keyA, keyB, f), p1, stepsize);
|
// Matrix H1_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, _1, p2, keyA, keyB, f), p1, stepsize);
|
||||||
// Matrix H2_expected = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError, p1, _1, keyA, keyB, f), p2, stepsize);
|
// Matrix H2_expected = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError, p1, _1, keyA, keyB, f), p2, stepsize);
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// // try to check numerical derivatives of a standard between factor
|
// // try to check numerical derivatives of a standard between factor
|
||||||
// Matrix H1_expected_stnd = gtsam::numericalDerivative11<LieVector, Pose2>(boost::bind(&predictionError_standard, _1, p2, keyA, keyB, h), p1, stepsize);
|
// Matrix H1_expected_stnd = gtsam::numericalDerivative11<Vector, Pose2>(boost::bind(&predictionError_standard, _1, p2, keyA, keyB, h), p1, stepsize);
|
||||||
// CHECK( assert_equal(H1_expected_stnd, H1_actual_stnd, 1e-5));
|
// CHECK( assert_equal(H1_expected_stnd, H1_actual_stnd, 1e-5));
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -330,8 +324,6 @@ TEST( TransformBtwRobotsUnaryFactorEM, Jacobian)
|
||||||
//
|
//
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtsam/geometry/Pose3.h>
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <gtsam/inference/Key.h>
|
#include <gtsam/inference/Key.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
|
@ -6,24 +6,24 @@
|
||||||
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
|
||||||
#include <gtsam/base/debug.h>
|
#include <tests/smallExample.h>
|
||||||
#include <gtsam/base/TestableAssertions.h>
|
#include <gtsam/slam/PriorFactor.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
#include <gtsam/slam/BetweenFactor.h>
|
||||||
#include <gtsam/base/treeTraversal-inst.h>
|
#include <gtsam/slam/BearingRangeFactor.h>
|
||||||
#include <gtsam/geometry/Point2.h>
|
#include <gtsam/geometry/Point2.h>
|
||||||
#include <gtsam/geometry/Pose2.h>
|
#include <gtsam/geometry/Pose2.h>
|
||||||
#include <gtsam/inference/Ordering.h>
|
|
||||||
#include <gtsam/linear/GaussianBayesNet.h>
|
|
||||||
#include <gtsam/linear/GaussianBayesTree.h>
|
|
||||||
#include <gtsam/linear/GaussianFactorGraph.h>
|
|
||||||
#include <gtsam/nonlinear/Values.h>
|
#include <gtsam/nonlinear/Values.h>
|
||||||
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
|
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
|
||||||
#include <gtsam/nonlinear/ISAM2.h>
|
#include <gtsam/nonlinear/ISAM2.h>
|
||||||
#include <gtsam/nonlinear/Marginals.h>
|
#include <gtsam/nonlinear/Marginals.h>
|
||||||
#include <gtsam/slam/PriorFactor.h>
|
#include <gtsam/linear/GaussianBayesNet.h>
|
||||||
#include <gtsam/slam/BetweenFactor.h>
|
#include <gtsam/linear/GaussianBayesTree.h>
|
||||||
#include <gtsam/slam/BearingRangeFactor.h>
|
#include <gtsam/linear/GaussianFactorGraph.h>
|
||||||
#include <tests/smallExample.h>
|
#include <gtsam/inference/Ordering.h>
|
||||||
|
#include <gtsam/base/debug.h>
|
||||||
|
#include <gtsam/base/TestableAssertions.h>
|
||||||
|
#include <gtsam/base/treeTraversal-inst.h>
|
||||||
|
#include <gtsam/base/LieScalar.h>
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/assign/list_of.hpp>
|
#include <boost/assign/list_of.hpp>
|
||||||
|
@ -35,6 +35,9 @@ using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
|
|
||||||
|
static const SharedNoiseModel model;
|
||||||
|
static const LieScalar Zero(0);
|
||||||
|
|
||||||
// SETDEBUG("ISAM2 update", true);
|
// SETDEBUG("ISAM2 update", true);
|
||||||
// SETDEBUG("ISAM2 update verbose", true);
|
// SETDEBUG("ISAM2 update verbose", true);
|
||||||
// SETDEBUG("ISAM2 recalculate", true);
|
// SETDEBUG("ISAM2 recalculate", true);
|
||||||
|
@ -203,11 +206,11 @@ struct ConsistencyVisitor
|
||||||
consistent(true), isam(isam) {}
|
consistent(true), isam(isam) {}
|
||||||
int operator()(const ISAM2::sharedClique& node, int& parentData)
|
int operator()(const ISAM2::sharedClique& node, int& parentData)
|
||||||
{
|
{
|
||||||
if(std::find(isam.roots().begin(), isam.roots().end(), node) == isam.roots().end())
|
if(find(isam.roots().begin(), isam.roots().end(), node) == isam.roots().end())
|
||||||
{
|
{
|
||||||
if(node->parent_.expired())
|
if(node->parent_.expired())
|
||||||
consistent = false;
|
consistent = false;
|
||||||
if(std::find(node->parent()->children.begin(), node->parent()->children.end(), node) == node->parent()->children.end())
|
if(find(node->parent()->children.begin(), node->parent()->children.end(), node) == node->parent()->children.end())
|
||||||
consistent = false;
|
consistent = false;
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(Key j, node->conditional()->frontals())
|
BOOST_FOREACH(Key j, node->conditional()->frontals())
|
||||||
|
@ -223,7 +226,7 @@ struct ConsistencyVisitor
|
||||||
bool isam_check(const NonlinearFactorGraph& fullgraph, const Values& fullinit, const ISAM2& isam, Test& test, TestResult& result) {
|
bool isam_check(const NonlinearFactorGraph& fullgraph, const Values& fullinit, const ISAM2& isam, Test& test, TestResult& result) {
|
||||||
|
|
||||||
TestResult& result_ = result;
|
TestResult& result_ = result;
|
||||||
const std::string name_ = test.getName();
|
const string name_ = test.getName();
|
||||||
|
|
||||||
Values actual = isam.calculateEstimate();
|
Values actual = isam.calculateEstimate();
|
||||||
Values expected = fullinit.retract(fullgraph.linearize(fullinit)->optimize());
|
Values expected = fullinit.retract(fullgraph.linearize(fullinit)->optimize());
|
||||||
|
@ -285,19 +288,19 @@ bool isam_check(const NonlinearFactorGraph& fullgraph, const Values& fullinit, c
|
||||||
TEST(ISAM2, AddFactorsStep1)
|
TEST(ISAM2, AddFactorsStep1)
|
||||||
{
|
{
|
||||||
NonlinearFactorGraph nonlinearFactors;
|
NonlinearFactorGraph nonlinearFactors;
|
||||||
nonlinearFactors += PriorFactor<LieVector>(10, LieVector(), gtsam::SharedNoiseModel());
|
nonlinearFactors += PriorFactor<LieScalar>(10, Zero, model);
|
||||||
nonlinearFactors += NonlinearFactor::shared_ptr();
|
nonlinearFactors += NonlinearFactor::shared_ptr();
|
||||||
nonlinearFactors += PriorFactor<LieVector>(11, LieVector(), gtsam::SharedNoiseModel());
|
nonlinearFactors += PriorFactor<LieScalar>(11, Zero, model);
|
||||||
|
|
||||||
NonlinearFactorGraph newFactors;
|
NonlinearFactorGraph newFactors;
|
||||||
newFactors += PriorFactor<LieVector>(1, LieVector(), gtsam::SharedNoiseModel());
|
newFactors += PriorFactor<LieScalar>(1, Zero, model);
|
||||||
newFactors += PriorFactor<LieVector>(2, LieVector(), gtsam::SharedNoiseModel());
|
newFactors += PriorFactor<LieScalar>(2, Zero, model);
|
||||||
|
|
||||||
NonlinearFactorGraph expectedNonlinearFactors;
|
NonlinearFactorGraph expectedNonlinearFactors;
|
||||||
expectedNonlinearFactors += PriorFactor<LieVector>(10, LieVector(), gtsam::SharedNoiseModel());
|
expectedNonlinearFactors += PriorFactor<LieScalar>(10, Zero, model);
|
||||||
expectedNonlinearFactors += PriorFactor<LieVector>(1, LieVector(), gtsam::SharedNoiseModel());
|
expectedNonlinearFactors += PriorFactor<LieScalar>(1, Zero, model);
|
||||||
expectedNonlinearFactors += PriorFactor<LieVector>(11, LieVector(), gtsam::SharedNoiseModel());
|
expectedNonlinearFactors += PriorFactor<LieScalar>(11, Zero, model);
|
||||||
expectedNonlinearFactors += PriorFactor<LieVector>(2, LieVector(), gtsam::SharedNoiseModel());
|
expectedNonlinearFactors += PriorFactor<LieScalar>(2, Zero, model);
|
||||||
|
|
||||||
const FastVector<size_t> expectedNewFactorIndices = list_of(1)(3);
|
const FastVector<size_t> expectedNewFactorIndices = list_of(1)(3);
|
||||||
|
|
||||||
|
@ -694,18 +697,17 @@ namespace {
|
||||||
TEST(ISAM2, marginalizeLeaves1)
|
TEST(ISAM2, marginalizeLeaves1)
|
||||||
{
|
{
|
||||||
ISAM2 isam;
|
ISAM2 isam;
|
||||||
|
|
||||||
NonlinearFactorGraph factors;
|
NonlinearFactorGraph factors;
|
||||||
factors += PriorFactor<LieVector>(0, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += PriorFactor<LieScalar>(0, Zero, model);
|
||||||
|
|
||||||
factors += BetweenFactor<LieVector>(0, 1, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 1, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(1, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(1, 2, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(0, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 2, Zero, model);
|
||||||
|
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(0, LieVector(0.0));
|
values.insert(0, Zero);
|
||||||
values.insert(1, LieVector(0.0));
|
values.insert(1, Zero);
|
||||||
values.insert(2, LieVector(0.0));
|
values.insert(2, Zero);
|
||||||
|
|
||||||
FastMap<Key,int> constrainedKeys;
|
FastMap<Key,int> constrainedKeys;
|
||||||
constrainedKeys.insert(make_pair(0,0));
|
constrainedKeys.insert(make_pair(0,0));
|
||||||
|
@ -724,18 +726,18 @@ TEST(ISAM2, marginalizeLeaves2)
|
||||||
ISAM2 isam;
|
ISAM2 isam;
|
||||||
|
|
||||||
NonlinearFactorGraph factors;
|
NonlinearFactorGraph factors;
|
||||||
factors += PriorFactor<LieVector>(0, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += PriorFactor<LieScalar>(0, Zero, model);
|
||||||
|
|
||||||
factors += BetweenFactor<LieVector>(0, 1, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 1, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(1, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(1, 2, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(0, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 2, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(2, 3, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(2, 3, Zero, model);
|
||||||
|
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(0, LieVector(0.0));
|
values.insert(0, Zero);
|
||||||
values.insert(1, LieVector(0.0));
|
values.insert(1, Zero);
|
||||||
values.insert(2, LieVector(0.0));
|
values.insert(2, Zero);
|
||||||
values.insert(3, LieVector(0.0));
|
values.insert(3, Zero);
|
||||||
|
|
||||||
FastMap<Key,int> constrainedKeys;
|
FastMap<Key,int> constrainedKeys;
|
||||||
constrainedKeys.insert(make_pair(0,0));
|
constrainedKeys.insert(make_pair(0,0));
|
||||||
|
@ -755,25 +757,25 @@ TEST(ISAM2, marginalizeLeaves3)
|
||||||
ISAM2 isam;
|
ISAM2 isam;
|
||||||
|
|
||||||
NonlinearFactorGraph factors;
|
NonlinearFactorGraph factors;
|
||||||
factors += PriorFactor<LieVector>(0, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += PriorFactor<LieScalar>(0, Zero, model);
|
||||||
|
|
||||||
factors += BetweenFactor<LieVector>(0, 1, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 1, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(1, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(1, 2, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(0, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 2, Zero, model);
|
||||||
|
|
||||||
factors += BetweenFactor<LieVector>(2, 3, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(2, 3, Zero, model);
|
||||||
|
|
||||||
factors += BetweenFactor<LieVector>(3, 4, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(3, 4, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(4, 5, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(4, 5, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(3, 5, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(3, 5, Zero, model);
|
||||||
|
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(0, LieVector(0.0));
|
values.insert(0, Zero);
|
||||||
values.insert(1, LieVector(0.0));
|
values.insert(1, Zero);
|
||||||
values.insert(2, LieVector(0.0));
|
values.insert(2, Zero);
|
||||||
values.insert(3, LieVector(0.0));
|
values.insert(3, Zero);
|
||||||
values.insert(4, LieVector(0.0));
|
values.insert(4, Zero);
|
||||||
values.insert(5, LieVector(0.0));
|
values.insert(5, Zero);
|
||||||
|
|
||||||
FastMap<Key,int> constrainedKeys;
|
FastMap<Key,int> constrainedKeys;
|
||||||
constrainedKeys.insert(make_pair(0,0));
|
constrainedKeys.insert(make_pair(0,0));
|
||||||
|
@ -795,14 +797,14 @@ TEST(ISAM2, marginalizeLeaves4)
|
||||||
ISAM2 isam;
|
ISAM2 isam;
|
||||||
|
|
||||||
NonlinearFactorGraph factors;
|
NonlinearFactorGraph factors;
|
||||||
factors += PriorFactor<LieVector>(0, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += PriorFactor<LieScalar>(0, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(0, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(0, 2, Zero, model);
|
||||||
factors += BetweenFactor<LieVector>(1, 2, LieVector(0.0), noiseModel::Unit::Create(1));
|
factors += BetweenFactor<LieScalar>(1, 2, Zero, model);
|
||||||
|
|
||||||
Values values;
|
Values values;
|
||||||
values.insert(0, LieVector(0.0));
|
values.insert(0, Zero);
|
||||||
values.insert(1, LieVector(0.0));
|
values.insert(1, Zero);
|
||||||
values.insert(2, LieVector(0.0));
|
values.insert(2, Zero);
|
||||||
|
|
||||||
FastMap<Key,int> constrainedKeys;
|
FastMap<Key,int> constrainedKeys;
|
||||||
constrainedKeys.insert(make_pair(0,0));
|
constrainedKeys.insert(make_pair(0,0));
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
|
||||||
#include <tests/smallExample.h>
|
#include <tests/smallExample.h>
|
||||||
#include <tests/simulated2D.h>
|
#include <tests/simulated2D.h>
|
||||||
#include <gtsam/linear/GaussianFactor.h>
|
#include <gtsam/linear/GaussianFactor.h>
|
||||||
|
@ -235,13 +234,13 @@ TEST( NonlinearFactor, linearize_constraint2 )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
class TestFactor4 : public NoiseModelFactor4<LieVector, LieVector, LieVector, LieVector> {
|
class TestFactor4 : public NoiseModelFactor4<double, double, double, double> {
|
||||||
public:
|
public:
|
||||||
typedef NoiseModelFactor4<LieVector, LieVector, LieVector, LieVector> Base;
|
typedef NoiseModelFactor4<double, double, double, double> Base;
|
||||||
TestFactor4() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0)), X(1), X(2), X(3), X(4)) {}
|
TestFactor4() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0)), X(1), X(2), X(3), X(4)) {}
|
||||||
|
|
||||||
virtual Vector
|
virtual Vector
|
||||||
evaluateError(const LieVector& x1, const LieVector& x2, const LieVector& x3, const LieVector& x4,
|
evaluateError(const double& x1, const double& x2, const double& x3, const double& x4,
|
||||||
boost::optional<Matrix&> H1 = boost::none,
|
boost::optional<Matrix&> H1 = boost::none,
|
||||||
boost::optional<Matrix&> H2 = boost::none,
|
boost::optional<Matrix&> H2 = boost::none,
|
||||||
boost::optional<Matrix&> H3 = boost::none,
|
boost::optional<Matrix&> H3 = boost::none,
|
||||||
|
@ -264,10 +263,10 @@ public:
|
||||||
TEST(NonlinearFactor, NoiseModelFactor4) {
|
TEST(NonlinearFactor, NoiseModelFactor4) {
|
||||||
TestFactor4 tf;
|
TestFactor4 tf;
|
||||||
Values tv;
|
Values tv;
|
||||||
tv.insert(X(1), LieVector((Vector(1) << 1.0)));
|
tv.insert(X(1), double((1.0)));
|
||||||
tv.insert(X(2), LieVector((Vector(1) << 2.0)));
|
tv.insert(X(2), double((2.0)));
|
||||||
tv.insert(X(3), LieVector((Vector(1) << 3.0)));
|
tv.insert(X(3), double((3.0)));
|
||||||
tv.insert(X(4), LieVector((Vector(1) << 4.0)));
|
tv.insert(X(4), double((4.0)));
|
||||||
EXPECT(assert_equal((Vector(1) << 10.0), tf.unwhitenedError(tv)));
|
EXPECT(assert_equal((Vector(1) << 10.0), tf.unwhitenedError(tv)));
|
||||||
DOUBLES_EQUAL(25.0/2.0, tf.error(tv), 1e-9);
|
DOUBLES_EQUAL(25.0/2.0, tf.error(tv), 1e-9);
|
||||||
JacobianFactor jf(*boost::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv)));
|
JacobianFactor jf(*boost::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv)));
|
||||||
|
@ -283,9 +282,9 @@ TEST(NonlinearFactor, NoiseModelFactor4) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
class TestFactor5 : public NoiseModelFactor5<LieVector, LieVector, LieVector, LieVector, LieVector> {
|
class TestFactor5 : public NoiseModelFactor5<double, double, double, double, double> {
|
||||||
public:
|
public:
|
||||||
typedef NoiseModelFactor5<LieVector, LieVector, LieVector, LieVector, LieVector> Base;
|
typedef NoiseModelFactor5<double, double, double, double, double> Base;
|
||||||
TestFactor5() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0)), X(1), X(2), X(3), X(4), X(5)) {}
|
TestFactor5() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0)), X(1), X(2), X(3), X(4), X(5)) {}
|
||||||
|
|
||||||
virtual Vector
|
virtual Vector
|
||||||
|
@ -310,11 +309,11 @@ public:
|
||||||
TEST(NonlinearFactor, NoiseModelFactor5) {
|
TEST(NonlinearFactor, NoiseModelFactor5) {
|
||||||
TestFactor5 tf;
|
TestFactor5 tf;
|
||||||
Values tv;
|
Values tv;
|
||||||
tv.insert(X(1), LieVector((Vector(1) << 1.0)));
|
tv.insert(X(1), double((1.0)));
|
||||||
tv.insert(X(2), LieVector((Vector(1) << 2.0)));
|
tv.insert(X(2), double((2.0)));
|
||||||
tv.insert(X(3), LieVector((Vector(1) << 3.0)));
|
tv.insert(X(3), double((3.0)));
|
||||||
tv.insert(X(4), LieVector((Vector(1) << 4.0)));
|
tv.insert(X(4), double((4.0)));
|
||||||
tv.insert(X(5), LieVector((Vector(1) << 5.0)));
|
tv.insert(X(5), double((5.0)));
|
||||||
EXPECT(assert_equal((Vector(1) << 15.0), tf.unwhitenedError(tv)));
|
EXPECT(assert_equal((Vector(1) << 15.0), tf.unwhitenedError(tv)));
|
||||||
DOUBLES_EQUAL(56.25/2.0, tf.error(tv), 1e-9);
|
DOUBLES_EQUAL(56.25/2.0, tf.error(tv), 1e-9);
|
||||||
JacobianFactor jf(*boost::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv)));
|
JacobianFactor jf(*boost::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv)));
|
||||||
|
@ -332,9 +331,9 @@ TEST(NonlinearFactor, NoiseModelFactor5) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
class TestFactor6 : public NoiseModelFactor6<LieVector, LieVector, LieVector, LieVector, LieVector, LieVector> {
|
class TestFactor6 : public NoiseModelFactor6<double, double, double, double, double, double> {
|
||||||
public:
|
public:
|
||||||
typedef NoiseModelFactor6<LieVector, LieVector, LieVector, LieVector, LieVector, LieVector> Base;
|
typedef NoiseModelFactor6<double, double, double, double, double, double> Base;
|
||||||
TestFactor6() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0)), X(1), X(2), X(3), X(4), X(5), X(6)) {}
|
TestFactor6() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0)), X(1), X(2), X(3), X(4), X(5), X(6)) {}
|
||||||
|
|
||||||
virtual Vector
|
virtual Vector
|
||||||
|
@ -362,12 +361,12 @@ public:
|
||||||
TEST(NonlinearFactor, NoiseModelFactor6) {
|
TEST(NonlinearFactor, NoiseModelFactor6) {
|
||||||
TestFactor6 tf;
|
TestFactor6 tf;
|
||||||
Values tv;
|
Values tv;
|
||||||
tv.insert(X(1), LieVector((Vector(1) << 1.0)));
|
tv.insert(X(1), double((1.0)));
|
||||||
tv.insert(X(2), LieVector((Vector(1) << 2.0)));
|
tv.insert(X(2), double((2.0)));
|
||||||
tv.insert(X(3), LieVector((Vector(1) << 3.0)));
|
tv.insert(X(3), double((3.0)));
|
||||||
tv.insert(X(4), LieVector((Vector(1) << 4.0)));
|
tv.insert(X(4), double((4.0)));
|
||||||
tv.insert(X(5), LieVector((Vector(1) << 5.0)));
|
tv.insert(X(5), double((5.0)));
|
||||||
tv.insert(X(6), LieVector((Vector(1) << 6.0)));
|
tv.insert(X(6), double((6.0)));
|
||||||
EXPECT(assert_equal((Vector(1) << 21.0), tf.unwhitenedError(tv)));
|
EXPECT(assert_equal((Vector(1) << 21.0), tf.unwhitenedError(tv)));
|
||||||
DOUBLES_EQUAL(110.25/2.0, tf.error(tv), 1e-9);
|
DOUBLES_EQUAL(110.25/2.0, tf.error(tv), 1e-9);
|
||||||
JacobianFactor jf(*boost::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv)));
|
JacobianFactor jf(*boost::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv)));
|
||||||
|
|
Loading…
Reference in New Issue