applyLeftJacobianInverse
parent
6c84a2b539
commit
98697251bd
|
@ -142,14 +142,14 @@ Vector3 DexpFunctor::applyDexp(const Vector3& v, OptionalJacobian<3, 3> H1,
|
||||||
|
|
||||||
Vector3 DexpFunctor::applyInvDexp(const Vector3& v, OptionalJacobian<3, 3> H1,
|
Vector3 DexpFunctor::applyInvDexp(const Vector3& v, OptionalJacobian<3, 3> H1,
|
||||||
OptionalJacobian<3, 3> H2) const {
|
OptionalJacobian<3, 3> H2) const {
|
||||||
const Matrix3 invDexp = rightJacobian().inverse();
|
const Matrix3 invJr = rightJacobianInverse();
|
||||||
const Vector3 c = invDexp * v;
|
const Vector3 c = invJr * v;
|
||||||
if (H1) {
|
if (H1) {
|
||||||
Matrix3 D_dexpv_w;
|
Matrix3 H;
|
||||||
applyDexp(c, D_dexpv_w); // get derivative H of forward mapping
|
applyDexp(c, H); // get derivative H of forward mapping
|
||||||
*H1 = -invDexp * D_dexpv_w;
|
*H1 = -invJr * H;
|
||||||
}
|
}
|
||||||
if (H2) *H2 = invDexp;
|
if (H2) *H2 = invJr;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +164,20 @@ Vector3 DexpFunctor::applyLeftJacobian(const Vector3& v,
|
||||||
return v + BWv + CWWv;
|
return v + BWv + CWWv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector3 DexpFunctor::applyLeftJacobianInverse(const Vector3& v,
|
||||||
|
OptionalJacobian<3, 3> H1,
|
||||||
|
OptionalJacobian<3, 3> H2) const {
|
||||||
|
const Matrix3 invJl = leftJacobianInverse();
|
||||||
|
const Vector3 c = invJl * v;
|
||||||
|
if (H1) {
|
||||||
|
Matrix3 H;
|
||||||
|
applyLeftJacobian(c, H); // get derivative H of forward mapping
|
||||||
|
*H1 = -invJl * H;
|
||||||
|
}
|
||||||
|
if (H2) *H2 = invJl;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace so3
|
} // namespace so3
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
|
@ -162,7 +162,7 @@ struct GTSAM_EXPORT DexpFunctor : public ExpmapFunctor {
|
||||||
double C; // (1 - A) / theta^2 or 1/6 for theta->0
|
double C; // (1 - A) / theta^2 or 1/6 for theta->0
|
||||||
|
|
||||||
// Constant used in inverse Jacobians
|
// Constant used in inverse Jacobians
|
||||||
double D; // 1.0 - A / (2.0 * B)) / theta2 or 1/12 for theta->0
|
double D; // (1 - A/2B) / theta2 or 1/12 for theta->0
|
||||||
|
|
||||||
// Constants used in cross and doubleCross
|
// Constants used in cross and doubleCross
|
||||||
double E; // (A - 2.0 * B) / theta2 or -1/12 for theta->0
|
double E; // (A - 2.0 * B) / theta2 or -1/12 for theta->0
|
||||||
|
@ -212,6 +212,11 @@ struct GTSAM_EXPORT DexpFunctor : public ExpmapFunctor {
|
||||||
Vector3 applyLeftJacobian(const Vector3& v, OptionalJacobian<3, 3> H1 = {},
|
Vector3 applyLeftJacobian(const Vector3& v, OptionalJacobian<3, 3> H1 = {},
|
||||||
OptionalJacobian<3, 3> H2 = {}) const;
|
OptionalJacobian<3, 3> H2 = {}) const;
|
||||||
|
|
||||||
|
/// Multiplies with leftJacobianInverse(), with optional derivatives
|
||||||
|
Vector3 applyLeftJacobianInverse(const Vector3& v,
|
||||||
|
OptionalJacobian<3, 3> H1 = {},
|
||||||
|
OptionalJacobian<3, 3> H2 = {}) const;
|
||||||
|
|
||||||
static constexpr double one_sixth = 1.0 / 6.0;
|
static constexpr double one_sixth = 1.0 / 6.0;
|
||||||
static constexpr double one_twelfth = 1.0 / 12.0;
|
static constexpr double one_twelfth = 1.0 / 12.0;
|
||||||
static constexpr double one_sixtieth = 1.0 / 60.0;
|
static constexpr double one_sixtieth = 1.0 / 60.0;
|
||||||
|
|
|
@ -385,6 +385,28 @@ TEST(SO3, ApplyDexp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
TEST(SO3, ApplyInvDexp) {
|
||||||
|
Matrix aH1, aH2;
|
||||||
|
for (bool nearZero : {true, false}) {
|
||||||
|
std::function<Vector3(const Vector3&, const Vector3&)> f =
|
||||||
|
[=](const Vector3& omega, const Vector3& v) {
|
||||||
|
return so3::DexpFunctor(omega, nearZero).applyInvDexp(v);
|
||||||
|
};
|
||||||
|
for (const Vector3& omega : test_cases::omegas(nearZero)) {
|
||||||
|
so3::DexpFunctor local(omega, nearZero);
|
||||||
|
Matrix invJr = local.rightJacobianInverse();
|
||||||
|
for (const Vector3& v : test_cases::vs) {
|
||||||
|
EXPECT(
|
||||||
|
assert_equal(Vector3(invJr * v), local.applyInvDexp(v, aH1, aH2)));
|
||||||
|
EXPECT(assert_equal(numericalDerivative21(f, omega, v), aH1));
|
||||||
|
EXPECT(assert_equal(numericalDerivative22(f, omega, v), aH2));
|
||||||
|
EXPECT(assert_equal(invJr, aH2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
TEST(SO3, ApplyLeftJacobian) {
|
TEST(SO3, ApplyLeftJacobian) {
|
||||||
Matrix aH1, aH2;
|
Matrix aH1, aH2;
|
||||||
|
@ -407,22 +429,22 @@ TEST(SO3, ApplyLeftJacobian) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
TEST(SO3, ApplyInvDexp) {
|
TEST(SO3, ApplyLeftJacobianInverse) {
|
||||||
Matrix aH1, aH2;
|
Matrix aH1, aH2;
|
||||||
for (bool nearZero : {true, false}) {
|
for (bool nearZero : {true, false}) {
|
||||||
std::function<Vector3(const Vector3&, const Vector3&)> f =
|
std::function<Vector3(const Vector3&, const Vector3&)> f =
|
||||||
[=](const Vector3& omega, const Vector3& v) {
|
[=](const Vector3& omega, const Vector3& v) {
|
||||||
return so3::DexpFunctor(omega, nearZero).applyInvDexp(v);
|
return so3::DexpFunctor(omega, nearZero).applyLeftJacobianInverse(v);
|
||||||
};
|
};
|
||||||
for (const Vector3& omega : test_cases::omegas(nearZero)) {
|
for (const Vector3& omega : test_cases::omegas(nearZero)) {
|
||||||
so3::DexpFunctor local(omega, nearZero);
|
so3::DexpFunctor local(omega, nearZero);
|
||||||
Matrix invDexp = local.dexp().inverse();
|
Matrix invJl = local.leftJacobianInverse();
|
||||||
for (const Vector3& v : test_cases::vs) {
|
for (const Vector3& v : test_cases::vs) {
|
||||||
EXPECT(assert_equal(Vector3(invDexp * v),
|
EXPECT(assert_equal(Vector3(invJl * v),
|
||||||
local.applyInvDexp(v, aH1, aH2)));
|
local.applyLeftJacobianInverse(v, aH1, aH2)));
|
||||||
EXPECT(assert_equal(numericalDerivative21(f, omega, v), aH1));
|
EXPECT(assert_equal(numericalDerivative21(f, omega, v), aH1));
|
||||||
EXPECT(assert_equal(numericalDerivative22(f, omega, v), aH2));
|
EXPECT(assert_equal(numericalDerivative22(f, omega, v), aH2));
|
||||||
EXPECT(assert_equal(invDexp, aH2));
|
EXPECT(assert_equal(invJl, aH2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue