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, | ||||
|                                   OptionalJacobian<3, 3> H2) const { | ||||
|   const Matrix3 invDexp = rightJacobian().inverse(); | ||||
|   const Vector3 c = invDexp * v; | ||||
|   const Matrix3 invJr = rightJacobianInverse(); | ||||
|   const Vector3 c = invJr * v; | ||||
|   if (H1) { | ||||
|     Matrix3 D_dexpv_w; | ||||
|     applyDexp(c, D_dexpv_w);  // get derivative H of forward mapping
 | ||||
|     *H1 = -invDexp * D_dexpv_w; | ||||
|     Matrix3 H; | ||||
|     applyDexp(c, H);  // get derivative H of forward mapping
 | ||||
|     *H1 = -invJr * H; | ||||
|   } | ||||
|   if (H2) *H2 = invDexp; | ||||
|   if (H2) *H2 = invJr; | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
|  | @ -164,6 +164,20 @@ Vector3 DexpFunctor::applyLeftJacobian(const Vector3& v, | |||
|   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
 | ||||
| 
 | ||||
| //******************************************************************************
 | ||||
|  |  | |||
|  | @ -162,7 +162,7 @@ struct GTSAM_EXPORT DexpFunctor : public ExpmapFunctor { | |||
|   double C;  // (1 - A) / theta^2 or 1/6 for theta->0
 | ||||
| 
 | ||||
|   // 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
 | ||||
|   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 = {}, | ||||
|                             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_twelfth = 1.0 / 12.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) { | ||||
|   Matrix aH1, aH2; | ||||
|  | @ -407,22 +429,22 @@ TEST(SO3, ApplyLeftJacobian) { | |||
| } | ||||
| 
 | ||||
| //******************************************************************************
 | ||||
| TEST(SO3, ApplyInvDexp) { | ||||
| TEST(SO3, ApplyLeftJacobianInverse) { | ||||
|   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); | ||||
|           return so3::DexpFunctor(omega, nearZero).applyLeftJacobianInverse(v); | ||||
|         }; | ||||
|     for (const Vector3& omega : test_cases::omegas(nearZero)) { | ||||
|       so3::DexpFunctor local(omega, nearZero); | ||||
|       Matrix invDexp = local.dexp().inverse(); | ||||
|       Matrix invJl = local.leftJacobianInverse(); | ||||
|       for (const Vector3& v : test_cases::vs) { | ||||
|         EXPECT(assert_equal(Vector3(invDexp * v), | ||||
|                             local.applyInvDexp(v, aH1, aH2))); | ||||
|         EXPECT(assert_equal(Vector3(invJl * v), | ||||
|                             local.applyLeftJacobianInverse(v, aH1, aH2))); | ||||
|         EXPECT(assert_equal(numericalDerivative21(f, omega, v), aH1)); | ||||
|         EXPECT(assert_equal(numericalDerivative22(f, omega, v), aH2)); | ||||
|         EXPECT(assert_equal(invDexp, aH2)); | ||||
|         EXPECT(assert_equal(invJl, aH2)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue