moved Jacobians on SO3 to Rot3
parent
87687ff887
commit
6962072301
|
|
@ -175,6 +175,39 @@ Vector Rot3::quaternion() const {
|
|||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Matrix3 Rot3::rightJacobianExpMapSO3(const Vector3& x) {
|
||||
// x is the axis-angle representation (exponential coordinates) for a rotation
|
||||
double normx = norm_2(x); // rotation angle
|
||||
Matrix3 Jr;
|
||||
if (normx < 10e-8){
|
||||
Jr = Matrix3::Identity();
|
||||
}
|
||||
else{
|
||||
const Matrix3 X = skewSymmetric(x); // element of Lie algebra so(3): X = x^
|
||||
Jr = Matrix3::Identity() - ((1-cos(normx))/(normx*normx)) * X +
|
||||
((normx-sin(normx))/(normx*normx*normx)) * X * X; // right Jacobian
|
||||
}
|
||||
return Jr;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Matrix3 Rot3::rightJacobianExpMapSO3inverse(const Vector3& x) {
|
||||
// x is the axis-angle representation (exponential coordinates) for a rotation
|
||||
double normx = norm_2(x); // rotation angle
|
||||
Matrix3 Jrinv;
|
||||
|
||||
if (normx < 10e-8){
|
||||
Jrinv = Matrix3::Identity();
|
||||
}
|
||||
else{
|
||||
const Matrix3 X = skewSymmetric(x); // element of Lie algebra so(3): X = x^
|
||||
Jrinv = Matrix3::Identity() +
|
||||
0.5 * X + (1/(normx*normx) - (1+cos(normx))/(2*normx * sin(normx)) ) * X * X;
|
||||
}
|
||||
return Jrinv;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
pair<Matrix3, Vector3> RQ(const Matrix3& A) {
|
||||
|
||||
|
|
|
|||
|
|
@ -155,6 +155,17 @@ namespace gtsam {
|
|||
return Rot3(q);
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Jacobian for Exponential map in SO(3) - equation (10.86) and following equations in
|
||||
* G.S. Chirikjian, "Stochastic Models, Information Theory, and Lie Groups", Volume 2, 2008.
|
||||
*/
|
||||
static Matrix3 rightJacobianExpMapSO3(const Vector3& x);
|
||||
|
||||
/** Right Jacobian for Log map in SO(3) - equation (10.86) and following equations in
|
||||
* G.S. Chirikjian, "Stochastic Models, Information Theory, and Lie Groups", Volume 2, 2008.
|
||||
*/
|
||||
static Matrix3 rightJacobianExpMapSO3inverse(const Vector3& x);
|
||||
|
||||
/**
|
||||
* Rodriguez' formula to compute an incremental rotation matrix
|
||||
* @param w is the rotation axis, unit length
|
||||
|
|
|
|||
|
|
@ -200,6 +200,37 @@ TEST(Rot3, log)
|
|||
CHECK_OMEGA_ZERO(x*2.*PI,y*2.*PI,z*2.*PI)
|
||||
}
|
||||
|
||||
Rot3 evaluateRotation(const Vector3 thetahat){
|
||||
return Rot3::Expmap(thetahat);
|
||||
}
|
||||
|
||||
Vector3 evaluateLogRotation(const Vector3 thetahat, const Vector3 deltatheta){
|
||||
return Rot3::Logmap( Rot3::Expmap(thetahat).compose( Rot3::Expmap(deltatheta) ) );
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( Rot3, rightJacobianExpMapSO3 )
|
||||
{
|
||||
// Linearization point
|
||||
Vector3 thetahat; thetahat << 0.1, 0, 0;
|
||||
|
||||
Matrix expectedJacobian = numericalDerivative11<Rot3, LieVector>(boost::bind(&evaluateRotation, _1), LieVector(thetahat));
|
||||
Matrix actualJacobian = Rot3::rightJacobianExpMapSO3(thetahat);
|
||||
EXPECT(assert_equal(expectedJacobian, actualJacobian));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( Rot3, rightJacobianExpMapSO3inverse )
|
||||
{
|
||||
// Linearization point
|
||||
Vector3 thetahat; thetahat << 0.1,0.1,0; ///< Current estimate of rotation rate bias
|
||||
Vector3 deltatheta; deltatheta << 0, 0, 0;
|
||||
|
||||
Matrix expectedJacobian = numericalDerivative11<LieVector>(boost::bind(&evaluateLogRotation, thetahat, _1), LieVector(deltatheta));
|
||||
Matrix actualJacobian = Rot3::rightJacobianExpMapSO3inverse(thetahat);
|
||||
EXPECT(assert_equal(expectedJacobian, actualJacobian));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(Rot3, manifold_caley)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,39 +48,6 @@ namespace gtsam {
|
|||
/** Struct to store results of preintegrating IMU measurements. Can be build
|
||||
* incrementally so as to avoid costly integration at time of factor construction. */
|
||||
|
||||
/** Right Jacobian for Exponential map in SO(3) - equation (10.86) and following equations in [1] */
|
||||
static Matrix3 rightJacobianExpMapSO3(const Vector3& x) {
|
||||
// x is the axis-angle representation (exponential coordinates) for a rotation
|
||||
double normx = norm_2(x); // rotation angle
|
||||
Matrix3 Jr;
|
||||
if (normx < 10e-8){
|
||||
Jr = Matrix3::Identity();
|
||||
}
|
||||
else{
|
||||
const Matrix3 X = skewSymmetric(x); // element of Lie algebra so(3): X = x^
|
||||
Jr = Matrix3::Identity() - ((1-cos(normx))/(normx*normx)) * X +
|
||||
((normx-sin(normx))/(normx*normx*normx)) * X * X; // right Jacobian
|
||||
}
|
||||
return Jr;
|
||||
}
|
||||
|
||||
/** Right Jacobian for Log map in SO(3) - equation (10.86) and following equations in [1] */
|
||||
static Matrix3 rightJacobianExpMapSO3inverse(const Vector3& x) {
|
||||
// x is the axis-angle representation (exponential coordinates) for a rotation
|
||||
double normx = norm_2(x); // rotation angle
|
||||
Matrix3 Jrinv;
|
||||
|
||||
if (normx < 10e-8){
|
||||
Jrinv = Matrix3::Identity();
|
||||
}
|
||||
else{
|
||||
const Matrix3 X = skewSymmetric(x); // element of Lie algebra so(3): X = x^
|
||||
Jrinv = Matrix3::Identity() +
|
||||
0.5 * X + (1/(normx*normx) - (1+cos(normx))/(2*normx * sin(normx)) ) * X * X;
|
||||
}
|
||||
return Jrinv;
|
||||
}
|
||||
|
||||
/** CombinedPreintegratedMeasurements accumulates (integrates) the IMU measurements (rotation rates and accelerations)
|
||||
* and the corresponding covariance matrix. The measurements are then used to build the Preintegrated IMU factor*/
|
||||
class CombinedPreintegratedMeasurements {
|
||||
|
|
@ -187,7 +154,7 @@ namespace gtsam {
|
|||
|
||||
const Vector3 theta_incr = correctedOmega * deltaT; // rotation vector describing rotation increment computed from the current rotation rate measurement
|
||||
const Rot3 Rincr = Rot3::Expmap(theta_incr); // rotation increment computed from the current rotation rate measurement
|
||||
const Matrix3 Jr_theta_incr = rightJacobianExpMapSO3(theta_incr); // Right jacobian computed at theta_incr
|
||||
const Matrix3 Jr_theta_incr = Rot3::rightJacobianExpMapSO3(theta_incr); // Right jacobian computed at theta_incr
|
||||
|
||||
// Update Jacobians
|
||||
/* ----------------------------------------------------------------------------------------------------------------------- */
|
||||
|
|
@ -208,11 +175,11 @@ namespace gtsam {
|
|||
Matrix3 Z_3x3 = Matrix3::Zero();
|
||||
Matrix3 I_3x3 = Matrix3::Identity();
|
||||
const Vector3 theta_i = Rot3::Logmap(deltaRij); // parametrization of so(3)
|
||||
const Matrix3 Jr_theta_i = rightJacobianExpMapSO3(theta_i);
|
||||
const Matrix3 Jr_theta_i = Rot3::rightJacobianExpMapSO3(theta_i);
|
||||
|
||||
Rot3 Rot_j = deltaRij * Rincr;
|
||||
const Vector3 theta_j = Rot3::Logmap(Rot_j); // parametrization of so(3)
|
||||
const Matrix3 Jrinv_theta_j = rightJacobianExpMapSO3inverse(theta_j);
|
||||
const Matrix3 Jrinv_theta_j = Rot3::rightJacobianExpMapSO3inverse(theta_j);
|
||||
|
||||
// Single Jacobians to propagate covariance
|
||||
Matrix3 H_pos_pos = I_3x3;
|
||||
|
|
@ -439,11 +406,11 @@ namespace gtsam {
|
|||
|
||||
const Rot3 fRhat = deltaRij_biascorrected_corioliscorrected.between(Rot_i.between(Rot_j));
|
||||
|
||||
const Matrix3 Jr_theta_bcc = rightJacobianExpMapSO3(theta_biascorrected_corioliscorrected);
|
||||
const Matrix3 Jr_theta_bcc = Rot3::rightJacobianExpMapSO3(theta_biascorrected_corioliscorrected);
|
||||
|
||||
const Matrix3 Jtheta = -Jr_theta_bcc * skewSymmetric(Rot_i.inverse().matrix() * omegaCoriolis_ * deltaTij);
|
||||
|
||||
const Matrix3 Jrinv_fRhat = rightJacobianExpMapSO3inverse(Rot3::Logmap(fRhat));
|
||||
const Matrix3 Jrinv_fRhat = Rot3::rightJacobianExpMapSO3inverse(Rot3::Logmap(fRhat));
|
||||
|
||||
if(H1) {
|
||||
H1->resize(15,6);
|
||||
|
|
@ -518,8 +485,8 @@ namespace gtsam {
|
|||
}
|
||||
|
||||
if(H5) {
|
||||
const Matrix3 Jrinv_theta_bc = rightJacobianExpMapSO3inverse(theta_biascorrected);
|
||||
const Matrix3 Jr_JbiasOmegaIncr = rightJacobianExpMapSO3(preintegratedMeasurements_.delRdelBiasOmega * biasOmegaIncr);
|
||||
const Matrix3 Jrinv_theta_bc = Rot3::rightJacobianExpMapSO3inverse(theta_biascorrected);
|
||||
const Matrix3 Jr_JbiasOmegaIncr = Rot3::rightJacobianExpMapSO3(preintegratedMeasurements_.delRdelBiasOmega * biasOmegaIncr);
|
||||
const Matrix3 JbiasOmega = Jr_theta_bcc * Jrinv_theta_bc * Jr_JbiasOmegaIncr * preintegratedMeasurements_.delRdelBiasOmega;
|
||||
|
||||
H5->resize(15,6);
|
||||
|
|
|
|||
|
|
@ -47,39 +47,6 @@ namespace gtsam {
|
|||
/** Struct to store results of preintegrating IMU measurements. Can be build
|
||||
* incrementally so as to avoid costly integration at time of factor construction. */
|
||||
|
||||
/** Right Jacobian for Exponential map in SO(3) - equation (10.86) and following equations in [1] */
|
||||
static Matrix3 rightJacobianExpMapSO3(const Vector3& x) {
|
||||
// x is the axis-angle representation (exponential coordinates) for a rotation
|
||||
double normx = norm_2(x); // rotation angle
|
||||
Matrix3 Jr;
|
||||
if (normx < 10e-8){
|
||||
Jr = Matrix3::Identity();
|
||||
}
|
||||
else{
|
||||
const Matrix3 X = skewSymmetric(x); // element of Lie algebra so(3): X = x^
|
||||
Jr = Matrix3::Identity() - ((1-cos(normx))/(normx*normx)) * X +
|
||||
((normx-sin(normx))/(normx*normx*normx)) * X * X; // right Jacobian
|
||||
}
|
||||
return Jr;
|
||||
}
|
||||
|
||||
/** Right Jacobian for Log map in SO(3) - equation (10.86) and following equations in [1] */
|
||||
static Matrix3 rightJacobianExpMapSO3inverse(const Vector3& x) {
|
||||
// x is the axis-angle representation (exponential coordinates) for a rotation
|
||||
double normx = norm_2(x); // rotation angle
|
||||
Matrix3 Jrinv;
|
||||
|
||||
if (normx < 10e-8){
|
||||
Jrinv = Matrix3::Identity();
|
||||
}
|
||||
else{
|
||||
const Matrix3 X = skewSymmetric(x); // element of Lie algebra so(3): X = x^
|
||||
Jrinv = Matrix3::Identity() +
|
||||
0.5 * X + (1/(normx*normx) - (1+cos(normx))/(2*normx * sin(normx)) ) * X * X;
|
||||
}
|
||||
return Jrinv;
|
||||
}
|
||||
|
||||
/** CombinedPreintegratedMeasurements accumulates (integrates) the IMU measurements (rotation rates and accelerations)
|
||||
* and the corresponding covariance matrix. The measurements are then used to build the Preintegrated IMU factor*/
|
||||
class PreintegratedMeasurements {
|
||||
|
|
@ -182,7 +149,7 @@ namespace gtsam {
|
|||
const Vector3 theta_incr = correctedOmega * deltaT; // rotation vector describing rotation increment computed from the current rotation rate measurement
|
||||
const Rot3 Rincr = Rot3::Expmap(theta_incr); // rotation increment computed from the current rotation rate measurement
|
||||
|
||||
const Matrix3 Jr_theta_incr = rightJacobianExpMapSO3(theta_incr); // Right jacobian computed at theta_incr
|
||||
const Matrix3 Jr_theta_incr = Rot3::rightJacobianExpMapSO3(theta_incr); // Right jacobian computed at theta_incr
|
||||
|
||||
// Update Jacobians
|
||||
/* ----------------------------------------------------------------------------------------------------------------------- */
|
||||
|
|
@ -200,11 +167,11 @@ namespace gtsam {
|
|||
Matrix3 Z_3x3 = Matrix3::Zero();
|
||||
Matrix3 I_3x3 = Matrix3::Identity();
|
||||
const Vector3 theta_i = Rot3::Logmap(deltaRij); // parametrization of so(3)
|
||||
const Matrix3 Jr_theta_i = rightJacobianExpMapSO3(theta_i);
|
||||
const Matrix3 Jr_theta_i = Rot3::rightJacobianExpMapSO3(theta_i);
|
||||
|
||||
Rot3 Rot_j = deltaRij * Rincr;
|
||||
const Vector3 theta_j = Rot3::Logmap(Rot_j); // parametrization of so(3)
|
||||
const Matrix3 Jrinv_theta_j = rightJacobianExpMapSO3inverse(theta_j);
|
||||
const Matrix3 Jrinv_theta_j = Rot3::rightJacobianExpMapSO3inverse(theta_j);
|
||||
|
||||
// Update preintegrated measurements covariance: as in [2] we consider a first order propagation that
|
||||
// can be seen as a prediction phase in an EKF framework
|
||||
|
|
@ -400,11 +367,11 @@ namespace gtsam {
|
|||
|
||||
const Rot3 fRhat = deltaRij_biascorrected_corioliscorrected.between(Rot_i.between(Rot_j));
|
||||
|
||||
const Matrix3 Jr_theta_bcc = rightJacobianExpMapSO3(theta_biascorrected_corioliscorrected);
|
||||
const Matrix3 Jr_theta_bcc = Rot3::rightJacobianExpMapSO3(theta_biascorrected_corioliscorrected);
|
||||
|
||||
const Matrix3 Jtheta = -Jr_theta_bcc * skewSymmetric(Rot_i.inverse().matrix() * omegaCoriolis_ * deltaTij);
|
||||
|
||||
const Matrix3 Jrinv_fRhat = rightJacobianExpMapSO3inverse(Rot3::Logmap(fRhat));
|
||||
const Matrix3 Jrinv_fRhat = Rot3::rightJacobianExpMapSO3inverse(Rot3::Logmap(fRhat));
|
||||
|
||||
if(H1) {
|
||||
H1->resize(9,6);
|
||||
|
|
@ -460,8 +427,8 @@ namespace gtsam {
|
|||
}
|
||||
if(H5) {
|
||||
|
||||
const Matrix3 Jrinv_theta_bc = rightJacobianExpMapSO3inverse(theta_biascorrected);
|
||||
const Matrix3 Jr_JbiasOmegaIncr = rightJacobianExpMapSO3(preintegratedMeasurements_.delRdelBiasOmega * biasOmegaIncr);
|
||||
const Matrix3 Jrinv_theta_bc = Rot3::rightJacobianExpMapSO3inverse(theta_biascorrected);
|
||||
const Matrix3 Jr_JbiasOmegaIncr = Rot3::rightJacobianExpMapSO3(preintegratedMeasurements_.delRdelBiasOmega * biasOmegaIncr);
|
||||
const Matrix3 JbiasOmega = Jr_theta_bcc * Jrinv_theta_bc * Jr_JbiasOmegaIncr * preintegratedMeasurements_.delRdelBiasOmega;
|
||||
|
||||
H5->resize(9,6);
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ TEST( ImuFactor, PartialDerivativeExpmap )
|
|||
Matrix expectedDelRdelBiasOmega = numericalDerivative11<Rot3, LieVector>(boost::bind(
|
||||
&evaluateRotation, measuredOmega, _1, deltaT), LieVector(biasOmega));
|
||||
|
||||
const Matrix3 Jr = ImuFactor::rightJacobianExpMapSO3((measuredOmega - biasOmega) * deltaT);
|
||||
const Matrix3 Jr = Rot3::rightJacobianExpMapSO3((measuredOmega - biasOmega) * deltaT);
|
||||
|
||||
Matrix3 actualdelRdelBiasOmega = - Jr * deltaT; // the delta bias appears with the minus sign
|
||||
|
||||
|
|
@ -371,7 +371,7 @@ TEST( ImuFactor, fistOrderExponential )
|
|||
Vector3 deltabiasOmega; deltabiasOmega << alpha,alpha,alpha;
|
||||
|
||||
|
||||
const Matrix3 Jr = ImuFactor::rightJacobianExpMapSO3((measuredOmega - biasOmega) * deltaT);
|
||||
const Matrix3 Jr = Rot3::rightJacobianExpMapSO3((measuredOmega - biasOmega) * deltaT);
|
||||
|
||||
Matrix3 delRdelBiasOmega = - Jr * deltaT; // the delta bias appears with the minus sign
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue