geometry.cpp
Go to the documentation of this file.
00001 
00038 #include <pose_graph/geometry.h>
00039 #include <tf/transform_datatypes.h>
00040 #include <boost/foreach.hpp>
00041 
00042 namespace pose_graph 
00043 {
00044 
00045 namespace sm=sensor_msgs;
00046 namespace gm=geometry_msgs;
00047 
00048 using Eigen3::Quaterniond;
00049 using Eigen3::Vector3d;
00050 using Eigen3::Affine3d;
00051 using geometry_msgs::Pose;
00052 using geometry_msgs::Point;
00053 using geometry_msgs::Point32;
00054 using std::min;
00055 
00056 PoseConstraint::PoseConstraint () : translation(Vector3d(0,0,0)), rotation(Quaterniond(0,0,0,1))
00057 {
00058   precision = Eigen3::MatrixXd::Identity(6, 6);  
00059 }
00060 
00061 PoseConstraint::PoseConstraint (const Vector3d& translation, const Quaterniond& rotation)
00062   : translation(translation), rotation(rotation)
00063 {
00064   precision = Eigen3::MatrixXd::Identity(6, 6);
00065 }
00066 
00067 PoseConstraint::PoseConstraint (const Eigen3::Vector3d& translation, const Eigen3::Quaterniond& rotation, 
00068                                 const Eigen3::Matrix<double, 6, 6>& precision) :
00069   translation(translation), rotation(rotation), precision(precision)
00070 {
00071 }
00072 
00073 
00074 
00075 // Print a constraint
00076 ostream& operator<< (ostream& str, const PoseConstraint& constraint)
00077 {
00078   tf::Quaternion q(constraint.rotation.x(), constraint.rotation.y(),
00079                    constraint.rotation.z(), constraint.rotation.w());
00080   str << "[" << constraint.translation.x() << ", " << constraint.translation.y() 
00081       << ", " << tf::getYaw(q) << "]";
00082   return str;
00083 }
00084 
00085 
00086 // Length of a vector
00087 double length (const Vector3d& v)
00088 {
00089   return sqrt(v.dot(v));
00090 }
00091 
00092 // Length of translation part of pose constraint
00093 double length (const PoseConstraint& constraint)
00094 {
00095   return length(constraint.translation);
00096 }
00097 
00098 double length (const gm::Point& p)
00099 {
00100   return sqrt(p.x*p.x + p.y+p.y + p.z+p.z);
00101 }
00102 
00103 // Given a pose constraint, return the expected relative pose
00104 Pose getPose (const PoseConstraint& c)
00105 {
00106   Pose p;
00107   p.position.x = c.translation.x();
00108   p.position.y = c.translation.y();
00109   p.position.z = c.translation.z();
00110   p.orientation.x = c.rotation.x();
00111   p.orientation.y = c.rotation.y();
00112   p.orientation.z = c.rotation.z();
00113   p.orientation.w = c.rotation.w();
00114   return p;
00115 }
00116 
00117 
00118 
00119 
00120 // Given a transform between two frames, get a PoseConstraint.  
00121 PoseConstraint makeConstraint (const Affine3d& trans, const Eigen3::Matrix<double, 6, 6>& prec)
00122 {
00123   return PoseConstraint(trans.translation(), Quaterniond(trans.rotation()), prec);
00124 }
00125 
00126 
00127 double euclideanDistance (const Point& p1, const Point& p2)
00128 {
00129   return length(Vector3d(p1.x-p2.x, p1.y-p2.y, p1.z-p2.z));
00130 }
00131 
00132 
00133 Point convertToPoint (const Point32& p)
00134 {
00135   Point p2;
00136   p2.x = p.x;
00137   p2.y = p.y;
00138   p2.z = p.z;
00139   return p2;
00140 }
00141 
00142 
00143 gm::Point computeBarycenter (const sm::LaserScan& scan)
00144 {
00145   gm::Point sum;
00146   double angle=scan.angle_min;
00147   unsigned num_hits=0;
00148 
00150   BOOST_FOREACH (const double range, scan.ranges) {
00151     ROS_ASSERT (angle>=scan.angle_min && angle<=scan.angle_max+scan.angle_increment/2);
00152     if (range <= scan.range_max) {
00153       sum.x += range*cos(angle);
00154       sum.y += range*sin(angle);
00155       num_hits++;
00156     }
00157     angle += scan.angle_increment;
00158   }
00159   ROS_ASSERT_MSG (num_hits>0, "Can't find barycenter of scan: no in-range hits out of %zu", scan.ranges.size());
00160 
00161   gm::Point result;
00162   result.x = sum.x/num_hits;
00163   result.y = sum.y/num_hits;
00164   return result;
00165 }
00166   
00167 
00168 double euclideanDistance (const gm::Pose2D& p1, const gm::Pose2D& p2, const double mult)
00169 {
00170   const double dx = p1.x - p2.x;
00171   const double dy = p1.y - p2.y;
00172   const double dtheta1 = fabs(p1.theta - p2.theta);
00173   const double dtheta2 = p1.theta + 2*M_PI-p2.theta;
00174   const double dtheta3 = p2.theta + 2*M_PI-p1.theta;
00175   const double dtheta = min(dtheta1, min(dtheta2, dtheta3));
00176 
00177   return sqrt(dx*dx + dy*dy) + mult*dtheta;
00178 }
00179 
00180 PrecisionMatrix makePrecisionMatrix (const double x_prec, const double y_prec, const double theta_prec)
00181 {
00182   PrecisionMatrix prec = Eigen3::MatrixXd::Identity(6,6);
00183   prec(0,0) = x_prec;
00184   prec(1,1) = y_prec;
00185   prec(5,5) = theta_prec/4;
00186   return prec;
00187 }
00188 
00189 PrecisionMatrix makePrecisionMatrix (const double x_prec, const double y_prec, const double xy_prec,
00190                                      const double theta_prec)
00191 {
00192   PrecisionMatrix prec = Eigen3::MatrixXd::Identity(6,6);
00193   prec(0,0) = x_prec;
00194   prec(1,1) = y_prec;
00195   prec(0,1) = xy_prec;
00196   prec(1,0) = xy_prec;
00197   prec(5,5) = theta_prec/4;
00198   return prec;
00199 }
00200 
00201 } // namespace


pose_graph
Author(s): Bhaskara Marthi
autogenerated on Tue Jan 7 2014 11:17:15