Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <nav_msgs/Path.h>
00003 #include <geometry_msgs/Transform.h>
00004 #include <Eigen/Core>
00005 #include <eigen_conversions/eigen_msg.h>
00006
00007
00008 namespace moveit_controller_multidof {
00009
00015 class TransformPathConverter {
00016 private:
00017 typedef Eigen::Transform<double,3,Eigen::Affine> EigenTransform;
00018 public:
00019 TransformPathConverter(){}
00020 ~TransformPathConverter();
00021
00032 static void convert(const std::vector<geometry_msgs::Transform>& transforms, nav_msgs::Path& path,
00033 const std::string& frame_id,
00034 bool transforms_are_relative,
00035 const geometry_msgs::Pose& start_pose=geometry_msgs::Pose(),
00036 const ros::Time& time=ros::Time::now(),
00037 const std::vector<ros::Duration>& path_times=std::vector<ros::Duration>()) {
00038
00039 path.poses.clear();
00040 path.header.frame_id=frame_id;
00041 path.header.stamp=time;
00042
00043
00044 Eigen::Vector3d pose;
00045 Eigen::Quaterniond orientation;
00046
00047 EigenTransform currTransform;
00048 currTransform.setIdentity();
00049
00050 geometry_msgs::PoseStamped curr;
00051 curr.header.frame_id=frame_id;
00052 curr.header.stamp=time;
00053
00054 if (transforms_are_relative) {
00055
00056 curr.pose=start_pose;
00057 path.poses.push_back(curr);
00058 }
00059
00060 int i=0;
00061 for (std::vector<geometry_msgs::Transform>::const_iterator it=transforms.begin(); it!=transforms.end(); ++it) {
00062 if (transforms_are_relative) {
00063
00064 Eigen::Vector3d trans;
00065 Eigen::Quaterniond rot;
00066 tf::quaternionMsgToEigen (it->rotation, rot);
00067 tf::vectorMsgToEigen (it->translation, trans);
00068
00069 currTransform.translate(trans);
00070 currTransform.rotate(rot);
00071
00072 Eigen::Vector3d nextPos=currTransform.translation();
00073 Eigen::Quaterniond nextOri=Eigen::Quaterniond(currTransform.rotation());
00074
00075 geometry_msgs::Point nextPoint;
00076 nextPoint.x=nextPos.x();
00077 nextPoint.y=nextPos.y();
00078 nextPoint.z=nextPos.z();
00079 curr.pose.position=nextPoint;
00080
00081 tf::quaternionEigenToMsg (nextOri,curr.pose.orientation);
00082 } else {
00083 curr.pose.position.x=it->translation.x;
00084 curr.pose.position.y=it->translation.y;
00085 curr.pose.position.z=it->translation.z;
00086 curr.pose.orientation.x=it->rotation.x;
00087 curr.pose.orientation.y=it->rotation.y;
00088 curr.pose.orientation.z=it->rotation.z;
00089 curr.pose.orientation.w=it->rotation.w;
00090 }
00091
00092 if (!path_times.empty()) curr.header.stamp=time+path_times[i];
00093 path.poses.push_back(curr);
00094 ++i;
00095 }
00096
00097 }
00098
00099 static void convert(const nav_msgs::Path& path, std::vector<geometry_msgs::Transform>& transforms,
00100 bool make_relative_transforms)
00101 {
00102 ROS_ERROR("This is an untested implementation, check it!");
00103
00104 if (path.poses.empty()) return;
00105
00106
00107
00108 if (!make_relative_transforms) {
00109 geometry_msgs::Transform t;
00110 const geometry_msgs::PoseStamped& p=path.poses.front();
00111 t.translation.x=p.pose.position.x;
00112 t.translation.y=p.pose.position.y;
00113 t.translation.z=p.pose.position.z;
00114 t.rotation.x=p.pose.orientation.x;
00115 t.rotation.y=p.pose.orientation.y;
00116 t.rotation.z=p.pose.orientation.z;
00117 t.rotation.w=p.pose.orientation.w;
00118 transforms.push_back(t);
00119 }
00120
00121
00122 if (make_relative_transforms && (path.poses.size()==1)) {
00123 transforms.push_back(geometry_msgs::Transform());
00124 return;
00125 }
00126
00127 geometry_msgs::PoseStamped lastPose=path.poses.front();
00128
00129 for (int i=1; i<path.poses.size(); ++i) {
00130 const geometry_msgs::PoseStamped& p=path.poses[i];
00131 geometry_msgs::Transform t;
00132 if (make_relative_transforms) {
00133 t.translation.x=p.pose.position.x;
00134 t.translation.y=p.pose.position.y;
00135 t.translation.z=p.pose.position.z;
00136 t.rotation.x=p.pose.orientation.x;
00137 t.rotation.y=p.pose.orientation.y;
00138 t.rotation.z=p.pose.orientation.z;
00139 t.rotation.w=p.pose.orientation.w;
00140 }else{
00141 t.translation.x=p.pose.position.x - lastPose.pose.position.x;
00142 t.translation.y=p.pose.position.y - lastPose.pose.position.y;
00143 t.translation.z=p.pose.position.z - lastPose.pose.position.z;
00144 Eigen::Quaterniond currOri,lastOri, diff;
00145 tf::quaternionMsgToEigen (lastPose.pose.orientation, lastOri);
00146 tf::quaternionMsgToEigen (p.pose.orientation, currOri);
00147 diff=getRotationFromTo(lastOri,currOri);
00148 tf::quaternionEigenToMsg(diff,t.rotation);
00149 }
00150 transforms.push_back(t);
00151 lastPose=p;
00152 }
00153 }
00154
00155
00156
00157 template<typename T>
00158 static Eigen::Quaternion<T> getRotationFromTo(const Eigen::Quaternion<T>& q1, const Eigen::Quaternion<T>& q2) {
00159 Eigen::Quaternion<T> ret= q2*q1.inverse();
00160 ret.normalize();
00161 return ret;
00162 }
00163
00164
00165
00166
00167 };
00168
00169 }