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
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
00087 double length (const Vector3d& v)
00088 {
00089 return sqrt(v.dot(v));
00090 }
00091
00092
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
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
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 }