219 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
| /* ----------------------------------------------------------------------------
 | |
| 
 | |
|  * GTSAM Copyright 2010, Georgia Tech Research Corporation, 
 | |
|  * Atlanta, Georgia 30332-0415
 | |
|  * All Rights Reserved
 | |
|  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
 | |
| 
 | |
|  * See LICENSE for the license information
 | |
| 
 | |
|  * -------------------------------------------------------------------------- */
 | |
| 
 | |
| /**
 | |
|  * @file    simulated2DConstraints.h
 | |
|  * @brief   measurement functions and constraint definitions for simulated 2D robot
 | |
|  * @author  Alex Cunningham
 | |
|  */
 | |
| 
 | |
| // \callgraph
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <gtsam/base/numericalDerivative.h>
 | |
| 
 | |
| #include <gtsam/nonlinear/NonlinearEquality.h>
 | |
| #include <gtsam/slam/BetweenFactor.h>
 | |
| #include <gtsam/slam/BoundingConstraint.h>
 | |
| #include <tests/simulated2D.h>
 | |
| 
 | |
| // \namespace
 | |
| 
 | |
| namespace simulated2D {
 | |
| 
 | |
|   namespace equality_constraints {
 | |
| 
 | |
|     /** Typedefs for regular use */
 | |
|     typedef NonlinearEquality1<Point2> UnaryEqualityConstraint;
 | |
|     typedef NonlinearEquality1<Point2> UnaryEqualityPointConstraint;
 | |
|     typedef BetweenConstraint<Point2> OdoEqualityConstraint;
 | |
| 
 | |
|     /** Equality between variables */
 | |
|     typedef NonlinearEquality2<Point2> PoseEqualityConstraint;
 | |
|     typedef NonlinearEquality2<Point2> PointEqualityConstraint;
 | |
| 
 | |
|   } // \namespace equality_constraints
 | |
| 
 | |
|   namespace inequality_constraints {
 | |
| 
 | |
|     /**
 | |
|      * Unary inequality constraint forcing a coordinate to be greater/less than a fixed value (c)
 | |
|      * @tparam VALUE is the value type for the variable constrained, e.g. Pose2, Point3, etc.
 | |
|      * @tparam IDX is an index in tangent space to constrain, must be less than KEY::VALUE::Dim()
 | |
|      */
 | |
|     template<class VALUE, unsigned int IDX>
 | |
|     struct ScalarCoordConstraint1: public BoundingConstraint1<VALUE> {
 | |
|       typedef BoundingConstraint1<VALUE> Base;  ///< Base class convenience typedef
 | |
|       typedef ScalarCoordConstraint1<VALUE, IDX> This; ///< This class convenience typedef
 | |
|       typedef boost::shared_ptr<ScalarCoordConstraint1<VALUE, IDX> > shared_ptr; ///< boost::shared_ptr convenience typedef
 | |
|       typedef VALUE Point; ///< Constrained variable type
 | |
| 
 | |
|       virtual ~ScalarCoordConstraint1() {}
 | |
| 
 | |
|       /// @return a deep copy of this factor
 | |
|       virtual gtsam::NonlinearFactor::shared_ptr clone() const {
 | |
|         return boost::static_pointer_cast<gtsam::NonlinearFactor>(
 | |
|             gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
 | |
| 
 | |
|       /**
 | |
|        * Constructor for constraint
 | |
|        * @param key is the label for the constrained variable
 | |
|        * @param c is the measured value for the fixed coordinate
 | |
|        * @param isGreaterThan is a flag to set inequality as greater than or less than
 | |
|        * @param mu is the penalty function gain
 | |
|        */
 | |
|       ScalarCoordConstraint1(Key key, double c,
 | |
|           bool isGreaterThan, double mu = 1000.0) :
 | |
|             Base(key, c, isGreaterThan, mu) {
 | |
|       }
 | |
| 
 | |
|       /**
 | |
|        * Access function for the constrained index
 | |
|        * @return the index for the constrained coordinate
 | |
|        */
 | |
|       inline unsigned int index() const { return IDX; }
 | |
| 
 | |
|       /**
 | |
|        * extracts a single value from the point to compute error
 | |
|        * @param x is the estimate of the constrained variable being evaluated
 | |
|        * @param H is an optional Jacobian, linearized at x
 | |
|        */
 | |
|       virtual double value(const Point& x, boost::optional<Matrix&> H =
 | |
|           boost::none) const {
 | |
|         if (H) {
 | |
|           Matrix D = Matrix::Zero(1, traits<Point>::GetDimension(x));
 | |
|           D(0, IDX) = 1.0;
 | |
|           *H = D;
 | |
|         }
 | |
|         return traits<Point>::Logmap(x)(IDX);
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     /** typedefs for use with simulated2D systems */
 | |
|     typedef ScalarCoordConstraint1<Point2, 0> PoseXInequality; ///< Simulated2D domain example factor constraining X
 | |
|     typedef ScalarCoordConstraint1<Point2, 1> PoseYInequality; ///< Simulated2D domain example factor constraining Y
 | |
| 
 | |
|     /**
 | |
|      * Trait for distance constraints to provide distance
 | |
|      * @tparam T1 is a Lie value for which distance functions exist
 | |
|      * @tparam T2 is a Lie value for which distance functions exist
 | |
|      * @param a is the first Lie element
 | |
|      * @param b is the second Lie element
 | |
|      * @return a scalar distance between values
 | |
|      */
 | |
|     template<class T1, class T2>
 | |
|     double range_trait(const T1& a, const T2& b) { return distance2(a, b); }
 | |
| 
 | |
|     /**
 | |
|      * Binary inequality constraint forcing the range between points
 | |
|      * to be less than or equal to a bound
 | |
|      * @tparam VALUES is the variable set for the graph
 | |
|      * @tparam KEY is the type of the keys for the variables constrained
 | |
|      */
 | |
|     template<class VALUE>
 | |
|     struct MaxDistanceConstraint : public BoundingConstraint2<VALUE, VALUE> {
 | |
|       typedef BoundingConstraint2<VALUE, VALUE> Base;  ///< Base class for factor
 | |
|       typedef MaxDistanceConstraint<VALUE> This;  ///< This class for factor
 | |
|       typedef VALUE Point; ///< Type of variable constrained
 | |
| 
 | |
|       virtual ~MaxDistanceConstraint() {}
 | |
| 
 | |
|       /// @return a deep copy of this factor
 | |
|       virtual gtsam::NonlinearFactor::shared_ptr clone() const {
 | |
|         return boost::static_pointer_cast<gtsam::NonlinearFactor>(
 | |
|             gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
 | |
| 
 | |
|       /**
 | |
|        * Primary constructor for factor
 | |
|        * @param key1 is the first variable key
 | |
|        * @param key2 is the second variable key
 | |
|        * @param range_bound is the maximum range allowed between the variables
 | |
|        * @param mu is the gain for the penalty function
 | |
|        */
 | |
|       MaxDistanceConstraint(Key key1, Key key2, double range_bound, double mu = 1000.0) :
 | |
|         Base(key1, key2, range_bound, false, mu) {}
 | |
| 
 | |
|       /**
 | |
|        * computes the range with derivatives
 | |
|        * @param x1 is the first variable value
 | |
|        * @param x2 is the second variable value
 | |
|        * @param H1 is an optional Jacobian in x1
 | |
|        * @param H2 is an optional Jacobian in x2
 | |
|        * @return the distance between the variables
 | |
|        */
 | |
|       virtual double value(const Point& x1, const Point& x2,
 | |
|           boost::optional<Matrix&> H1 = boost::none,
 | |
|           boost::optional<Matrix&> H2 = boost::none) const {
 | |
|         if (H1) *H1 = numericalDerivative21(range_trait<Point,Point>, x1, x2, 1e-5);
 | |
|         if (H1) *H2 = numericalDerivative22(range_trait<Point,Point>, x1, x2, 1e-5);
 | |
|         return range_trait(x1, x2);
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     typedef MaxDistanceConstraint<Point2> PoseMaxDistConstraint; ///< Simulated2D domain example factor
 | |
| 
 | |
|     /**
 | |
|      * Binary inequality constraint forcing a minimum range
 | |
|      * NOTE: this is not a convex function!  Be careful with initialization.
 | |
|      * @tparam POSE is the type of the pose value constrained
 | |
|      * @tparam POINT is the type of the point value constrained
 | |
|      */
 | |
|     template<class POSE, class POINT>
 | |
|     struct MinDistanceConstraint : public BoundingConstraint2<POSE, POINT> {
 | |
|       typedef BoundingConstraint2<POSE, POINT> Base; ///< Base class for factor
 | |
|       typedef MinDistanceConstraint<POSE, POINT> This; ///< This class for factor
 | |
|       typedef POSE Pose; ///< Type of pose variable constrained
 | |
|       typedef POINT Point; ///< Type of point variable constrained
 | |
| 
 | |
|       virtual ~MinDistanceConstraint() {}
 | |
| 
 | |
|       /// @return a deep copy of this factor
 | |
|       virtual gtsam::NonlinearFactor::shared_ptr clone() const {
 | |
|         return boost::static_pointer_cast<gtsam::NonlinearFactor>(
 | |
|             gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
 | |
| 
 | |
|       /**
 | |
|        * Primary constructor for factor
 | |
|        * @param key1 is the first variable key
 | |
|        * @param key2 is the second variable key
 | |
|        * @param range_bound is the minimum range allowed between the variables
 | |
|        * @param mu is the gain for the penalty function
 | |
|        */
 | |
|       MinDistanceConstraint(Key key1, Key key2,
 | |
|           double range_bound, double mu = 1000.0)
 | |
|       : Base(key1, key2, range_bound, true, mu) {}
 | |
| 
 | |
|       /**
 | |
|        * computes the range with derivatives
 | |
|        * @param x1 is the first variable value
 | |
|        * @param x2 is the second variable value
 | |
|        * @param H1 is an optional Jacobian in x1
 | |
|        * @param H2 is an optional Jacobian in x2
 | |
|        * @return the distance between the variables
 | |
|        */
 | |
|       virtual double value(const Pose& x1, const Point& x2,
 | |
|           boost::optional<Matrix&> H1 = boost::none,
 | |
|           boost::optional<Matrix&> H2 = boost::none) const {
 | |
|         if (H1) *H1 = numericalDerivative21(range_trait<Pose,Point>, x1, x2, 1e-5);
 | |
|         if (H1) *H2 = numericalDerivative22(range_trait<Pose,Point>, x1, x2, 1e-5);
 | |
|         return range_trait(x1, x2);
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     typedef MinDistanceConstraint<Point2, Point2> LandmarkAvoid; ///< Simulated2D domain example factor
 | |
| 
 | |
| 
 | |
|   } // \namespace inequality_constraints
 | |
| 
 | |
| } // \namespace simulated2D
 | |
| 
 |