Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00040 #include <pose_graph/transforms.h>
00041 #include <tf/transform_datatypes.h>
00042 #include <boost/random/mersenne_twister.hpp>
00043 #include <boost/random/uniform_real.hpp>
00044 #include <boost/random/variate_generator.hpp>
00045 #include <boost/lexical_cast.hpp>
00046
00047
00048
00049 #include <ros/ros.h>
00050
00051 namespace pose_graph
00052 {
00053
00054 namespace nm=nav_msgs;
00055 namespace gm=geometry_msgs;
00056
00057 using Eigen3::Translation3d;
00058 using Eigen3::Quaterniond;
00059 using std::string;
00060 using nav_msgs::OccupancyGrid;
00061
00062
00063 Affine3d poseToWorldTransform (const Pose& p)
00064 {
00065 return
00066 Translation3d(p.position.x, p.position.y, p.position.z) *
00067 Quaterniond(p.orientation.w, p.orientation.x, p.orientation.y, p.orientation.z);
00068 }
00069
00070
00071
00072 Affine3d relativeTransform (const Pose& pose1, const Pose& pose2)
00073 {
00074 const Affine3d inv2(poseToWorldTransform(pose2).inverse());
00075 const Affine3d result=inv2*poseToWorldTransform(pose1);
00076 return result;
00077 }
00078
00079
00080 Affine3d transformBetween (const Pose& pose1, const Pose& pose2)
00081 {
00082 const Affine3d inv1(poseToWorldTransform(pose1).inverse());
00083 return poseToWorldTransform(pose2) * inv1;
00084 }
00085
00086
00087
00088 Pose applyTransform (const Affine3d& trans, const Pose& pose)
00089 {
00090 const Affine3d pose_to_world = poseToWorldTransform(pose);
00091 const Affine3d new_pose_to_world = trans*pose_to_world;
00092 Pose new_pose;
00093 new_pose.position.x = new_pose_to_world.translation().x();
00094 new_pose.position.y = new_pose_to_world.translation().y();
00095 new_pose.position.z = new_pose_to_world.translation().z();
00096 const Quaterniond rotation(new_pose_to_world.rotation());
00097 new_pose.orientation.x = rotation.x();
00098 new_pose.orientation.y = rotation.y();
00099 new_pose.orientation.z = rotation.z();
00100 new_pose.orientation.w = rotation.w();
00101
00102 return new_pose;
00103 }
00104
00105
00106 Point32 transformPoint (const Affine3d& trans, const Point32& point)
00107 {
00108 Point32 ret;
00109 Vector3d result = trans*Vector3d(point.x, point.y, point.z);
00110 ret.x = result.x();
00111 ret.y = result.y();
00112 ret.z = result.z();
00113
00114 return ret;
00115 }
00116
00117
00118 Point transformPoint (const Affine3d& trans, const Point& point)
00119 {
00120 Point ret;
00121 Vector3d result = trans*Vector3d(point.x, point.y, point.z);
00122 ret.x = result.x();
00123 ret.y = result.y();
00124 ret.z = result.z();
00125
00126 return ret;
00127 }
00128
00129
00130 Pose perturbPose (const Pose& pose, double r)
00131 {
00132 boost::mt19937 rng(ros::Time::now().toNSec());
00133 boost::uniform_real<float> u(-r, r);
00134 boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > gen(rng, u);
00135
00136 Pose perturbed;
00137 perturbed.orientation = pose.orientation;
00138 perturbed.position.x = pose.position.x + gen();
00139 perturbed.position.y = pose.position.y + gen();
00140 perturbed.position.z = pose.position.z;
00141
00142 return perturbed;
00143 }
00144
00145 Point pointInReferenceFrame (const Point& p, const Pose& pose)
00146 {
00147 return transformPoint(poseToWorldTransform(pose), p);
00148 }
00149
00150
00151
00152 Eigen3::Vector4d quaternionMsgToVector4d (const geometry_msgs::Quaternion& m)
00153 {
00154 return Eigen3::Vector4d(m.x, m.y, m.z, m.w);
00155 }
00156
00157 Eigen3::Vector4d translationToVector4d(const geometry_msgs::Point& p)
00158 {
00159 return Eigen3::Vector4d(p.x, p.y, p.z, 1.0);
00160 }
00161
00162
00163
00164 Pose2D projectToPose2D (const Pose& pose)
00165 {
00166 Pose2D pose2d;
00167 pose2d.x = pose.position.x;
00168 pose2d.y = pose.position.y;
00169 pose2d.theta = tf::getYaw(pose.orientation);
00170 return pose2d;
00171 }
00172
00173
00174
00175 Affine3d relativeTransform (const Pose2D& pose1, const Pose2D& pose2)
00176 {
00177 return relativeTransform(convertToPose(pose1), convertToPose(pose2));
00178 }
00179
00182 Pose relativePose (const Pose& pose1, const Pose& pose2)
00183 {
00184 const Affine3d toPose2Coords(poseToWorldTransform(pose2).inverse());
00185 return applyTransform(toPose2Coords, pose1);
00186 }
00187
00188
00189 Pose convertToPose (const Pose2D& pose2d)
00190 {
00191 Pose p;
00192 p.position.x = pose2d.x;
00193 p.position.y = pose2d.y;
00194 p.position.z = 0.0;
00195 p.orientation = tf::createQuaternionMsgFromYaw(pose2d.theta);
00196 return p;
00197 }
00198
00199 Pose convertToPose (const Affine3d trans)
00200 {
00201 Pose id;
00202 id.orientation.w = 1.0;
00203 return applyTransform(trans, id);
00204 }
00205
00206 OccupancyGrid transformGrid (const Affine3d& trans, const OccupancyGrid& g)
00207 {
00208 OccupancyGrid g2(g);
00209 g2.info.origin = applyTransform(trans, g.info.origin);
00210 return g2;
00211 }
00212
00214 Pose2D makePose2D (double x, double y, double theta)
00215 {
00216 Pose2D p;
00217 p.x = x;
00218 p.y = y;
00219 p.theta = theta;
00220 return p;
00221 }
00222
00223
00225 nm::MapMetaData getMapInfo (const gm::Pose& pose, const double size, const double resolution)
00226 {
00227 const Eigen3::Affine3d node_ref_transform = poseToWorldTransform(pose);
00228
00229 gm::Pose local_origin;
00230 local_origin.position.x = -size/2;
00231 local_origin.position.y = -size/2;
00232 local_origin.orientation.w = 1.0;
00233
00234 nm::MapMetaData info;
00235 info.resolution = resolution;
00236 info.width = size/resolution;
00237 info.height = size/resolution;
00238 info.origin = applyTransform(node_ref_transform, local_origin);
00239
00240 return info;
00241 }
00242
00243
00244 }