Fixed product retract/localCoordinates and corresponding tests
							parent
							
								
									233fe13e60
								
							
						
					
					
						commit
						d1271fd9d5
					
				|  | @ -74,17 +74,21 @@ public: | ||||||
|   typedef Eigen::Matrix<double, dimension, 1> TangentVector; |   typedef Eigen::Matrix<double, dimension, 1> TangentVector; | ||||||
|   typedef OptionalJacobian<dimension, dimension> ChartJacobian; |   typedef OptionalJacobian<dimension, dimension> ChartJacobian; | ||||||
| 
 | 
 | ||||||
|   static ProductLieGroup Retract(const TangentVector& v) { |   ProductLieGroup retract(const TangentVector& v, //
 | ||||||
|     return ProductLieGroup::ChartAtOrigin::Retract(v); |       ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) const { | ||||||
|  |     if (H1||H2) throw std::runtime_error("ProductLieGroup::retract derivatives not implemented yet"); | ||||||
|  |     G g = traits<G>::Retract(this->first, v.template head<dimension1>()); | ||||||
|  |     H h = traits<H>::Retract(this->second, v.template tail<dimension2>()); | ||||||
|  |     return ProductLieGroup(g,h); | ||||||
|   } |   } | ||||||
|   static TangentVector LocalCoordinates(const ProductLieGroup& g) { |   TangentVector localCoordinates(const ProductLieGroup& g, //
 | ||||||
|     return ProductLieGroup::ChartAtOrigin::Local(g); |       ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) const { | ||||||
|   } |     if (H1||H2) throw std::runtime_error("ProductLieGroup::localCoordinates derivatives not implemented yet"); | ||||||
|   ProductLieGroup retract(const TangentVector& v) const { |     typename traits<G>::TangentVector v1 = traits<G>::Local(this->first, g.first); | ||||||
|     return compose(ProductLieGroup::ChartAtOrigin::Retract(v)); |     typename traits<H>::TangentVector v2 = traits<H>::Local(this->second, g.second); | ||||||
|   } |     TangentVector v; | ||||||
|   TangentVector localCoordinates(const ProductLieGroup& g) const { |     v << v1, v2; | ||||||
|     return ProductLieGroup::ChartAtOrigin::Local(between(g)); |     return v; | ||||||
|   } |   } | ||||||
|   /// @}
 |   /// @}
 | ||||||
| 
 | 
 | ||||||
|  | @ -147,51 +151,19 @@ public: | ||||||
|     v << v1, v2; |     v << v1, v2; | ||||||
|     return v; |     return v; | ||||||
|   } |   } | ||||||
|   struct ChartAtOrigin { |  | ||||||
|     static TangentVector Local(const ProductLieGroup& m, ChartJacobian Hm = boost::none) { |  | ||||||
|       return Logmap(m, Hm); |  | ||||||
|     } |  | ||||||
|     static ProductLieGroup Retract(const TangentVector& v, ChartJacobian Hv = boost::none) { |  | ||||||
|       return Expmap(v, Hv); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|   ProductLieGroup expmap(const TangentVector& v) const { |   ProductLieGroup expmap(const TangentVector& v) const { | ||||||
|     return compose(ProductLieGroup::Expmap(v)); |     return compose(ProductLieGroup::Expmap(v)); | ||||||
|   } |   } | ||||||
|   TangentVector logmap(const ProductLieGroup& g) const { |   TangentVector logmap(const ProductLieGroup& g) const { | ||||||
|     return ProductLieGroup::Logmap(between(g)); |     return ProductLieGroup::Logmap(between(g)); | ||||||
|   } |   } | ||||||
|   static ProductLieGroup Retract(const TangentVector& v, ChartJacobian H1) { |  | ||||||
|     return ProductLieGroup::ChartAtOrigin::Retract(v,H1); |  | ||||||
|   } |  | ||||||
|   static TangentVector LocalCoordinates(const ProductLieGroup& g, ChartJacobian H1) { |  | ||||||
|     return ProductLieGroup::ChartAtOrigin::Local(g,H1); |  | ||||||
|   } |  | ||||||
|   ProductLieGroup retract(const TangentVector& v, //
 |  | ||||||
|       ChartJacobian H1, ChartJacobian H2 = boost::none) const { |  | ||||||
|     Jacobian D_g_v; |  | ||||||
|     ProductLieGroup g = ProductLieGroup::ChartAtOrigin::Retract(v,H2 ? &D_g_v : 0); |  | ||||||
|     ProductLieGroup h = compose(g,H1,H2); |  | ||||||
|     if (H2) *H2 = (*H2) * D_g_v; |  | ||||||
|     return h; |  | ||||||
|   } |  | ||||||
|   TangentVector localCoordinates(const ProductLieGroup& g, //
 |  | ||||||
|       ChartJacobian H1, ChartJacobian H2 = boost::none) const { |  | ||||||
|     ProductLieGroup h = between(g,H1,H2); |  | ||||||
|     Jacobian D_v_h; |  | ||||||
|     TangentVector v = ProductLieGroup::ChartAtOrigin::Local(h, (H1 || H2) ? &D_v_h : 0); |  | ||||||
|     if (H1) *H1 = D_v_h * (*H1); |  | ||||||
|     if (H2) *H2 = D_v_h * (*H2); |  | ||||||
|     return v; |  | ||||||
|   } |  | ||||||
|   /// @}
 |   /// @}
 | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Define any direct product group to be a model of the multiplicative Group concept
 | // Define any direct product group to be a model of the multiplicative Group concept
 | ||||||
| template<typename G, typename H> | template<typename G, typename H> | ||||||
| struct traits<ProductLieGroup<G, H> > : internal::LieGroupTraits< | struct traits<ProductLieGroup<G, H> > : internal::LieGroupTraits<ProductLieGroup<G, H> > {}; | ||||||
|     ProductLieGroup<G, H> > { | 
 | ||||||
| }; |  | ||||||
| } // namespace gtsam
 | } // namespace gtsam
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -86,21 +86,23 @@ TEST( testPoseRTV, Lie ) { | ||||||
| 
 | 
 | ||||||
|   Vector delta(9); |   Vector delta(9); | ||||||
|   delta << 0.1, 0.1, 0.1, 0.2, 0.3, 0.4,-0.1,-0.2,-0.3; |   delta << 0.1, 0.1, 0.1, 0.2, 0.3, 0.4,-0.1,-0.2,-0.3; | ||||||
|   Rot3 rot2 = rot.retract(repeat(3, 0.1)); |   Pose3 pose2 = Pose3(rot, pt).retract(delta.head<6>()); | ||||||
|   Point3 pt2 = pt + rot * Point3(0.2, 0.3, 0.4); |   Velocity3 vel2 = vel + Velocity3(-0.1, -0.2, -0.3); | ||||||
|   Velocity3 vel2 = vel + rot * Velocity3(-0.1,-0.2,-0.3); |   PoseRTV state2(pose2.translation(), pose2.rotation(), vel2); | ||||||
|   PoseRTV state2(pt2, rot2, vel2); |   EXPECT(assert_equal(state2, (PoseRTV)state1.retract(delta), tol)); | ||||||
|   EXPECT(assert_equal(state2, (PoseRTV)state1.retract(delta), 1e-1)); |   EXPECT(assert_equal(delta, state1.localCoordinates(state2), tol)); | ||||||
|   EXPECT(assert_equal(delta, state1.localCoordinates(state2), 1e-1)); |  | ||||||
|   EXPECT(assert_equal(delta, -state2.localCoordinates(state1), 1e-1)); |  | ||||||
| 
 | 
 | ||||||
|   // roundtrip from state2 to state3 and back
 |   // roundtrip from state2 to state3 and back
 | ||||||
|   PoseRTV state3 = state2.retract(delta); |   PoseRTV state3 = state2.retract(delta); | ||||||
|   EXPECT(assert_equal(delta, state2.localCoordinates(state3), 1e-1)); |   EXPECT(assert_equal(delta, state2.localCoordinates(state3), tol)); | ||||||
| 
 | 
 | ||||||
|   // roundtrip from state3 to state4 and back, with expmap
 |   // roundtrip from state3 to state4 and back, with expmap.
 | ||||||
|   PoseRTV state4 = state3.expmap(delta); |   PoseRTV state4 = state3.expmap(delta); | ||||||
|   EXPECT(assert_equal(delta, state3.logmap(state4), 1e-1)); |   EXPECT(assert_equal(delta, state3.logmap(state4), tol)); | ||||||
|  | 
 | ||||||
|  |   // For the expmap/logmap (not necessarily retract/local) -delta goes other way
 | ||||||
|  |   EXPECT(assert_equal(state3, (PoseRTV)state4.expmap(-delta), tol)); | ||||||
|  |   EXPECT(assert_equal(delta, -state4.logmap(state3), tol)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ************************************************************************* */ | /* ************************************************************************* */ | ||||||
|  |  | ||||||
|  | @ -54,9 +54,9 @@ TEST(Lie, ProductLieGroup) { | ||||||
|   Vector5 d; |   Vector5 d; | ||||||
|   d << 1, 2, 0.1, 0.2, 0.3; |   d << 1, 2, 0.1, 0.2, 0.3; | ||||||
|   Product expected(Point2(1, 2), Pose2::Expmap(Vector3(0.1, 0.2, 0.3))); |   Product expected(Point2(1, 2), Pose2::Expmap(Vector3(0.1, 0.2, 0.3))); | ||||||
|   Product pair2 = pair1.retract(d); |   Product pair2 = pair1.expmap(d); | ||||||
|   EXPECT(assert_equal(expected, pair2, 1e-9)); |   EXPECT(assert_equal(expected, pair2, 1e-9)); | ||||||
|   EXPECT(assert_equal(d, pair1.localCoordinates(pair2), 1e-9)); |   EXPECT(assert_equal(d, pair1.logmap(pair2), 1e-9)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ************************************************************************* */ | /* ************************************************************************* */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue