transform_listener.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00032 #include "tf/transform_listener.h"
00033 
00034 #include <boost/numeric/ublas/matrix.hpp>
00035 #include <boost/numeric/ublas/io.hpp>
00036 
00037 
00038 using namespace tf;
00039 std::string tf::remap(const std::string& frame_id)
00040 {
00041   ros::NodeHandle n("~");
00042   return tf::resolve(getPrefixParam(n), frame_id);
00043 };
00044 
00045 
00046 TransformListener::TransformListener(ros::Duration max_cache_time, bool spin_thread):
00047   Transformer(true, max_cache_time), tf2_listener_(Transformer::tf2_buffer_, node_, spin_thread)
00048 {
00049   //Everything is done inside tf2 init
00050 }
00051 
00052 TransformListener::TransformListener(const ros::NodeHandle& nh, ros::Duration max_cache_time, bool spin_thread):
00053   Transformer(true, max_cache_time), node_(nh), tf2_listener_(Transformer::tf2_buffer_, nh, spin_thread)
00054 {
00055   //Everything is done inside tf2 init
00056 }
00057 
00058 TransformListener::~TransformListener()
00059 {
00060   //Everything is done inside tf2 init
00061 }
00062 
00063 //Override Transformer::ok() for ticket:4882
00064 bool TransformListener::ok() const { return ros::ok(); }
00065 
00066 
00067 
00068 void TransformListener::transformQuaternion(const std::string& target_frame,
00069     const geometry_msgs::QuaternionStamped& msg_in,
00070     geometry_msgs::QuaternionStamped& msg_out) const
00071 {
00072   tf::assertQuaternionValid(msg_in.quaternion);
00073 
00074   Stamped<Quaternion> pin, pout;
00075   quaternionStampedMsgToTF(msg_in, pin);  
00076   transformQuaternion(target_frame, pin, pout);
00077   quaternionStampedTFToMsg(pout, msg_out);
00078 }
00079 
00080 void TransformListener::transformVector(const std::string& target_frame,
00081     const geometry_msgs::Vector3Stamped& msg_in,
00082     geometry_msgs::Vector3Stamped& msg_out) const
00083 {
00084   Stamped<Vector3> pin, pout;
00085   vector3StampedMsgToTF(msg_in, pin);
00086   transformVector(target_frame, pin, pout);
00087   vector3StampedTFToMsg(pout, msg_out);
00088 }
00089 
00090 void TransformListener::transformPoint(const std::string& target_frame,
00091     const geometry_msgs::PointStamped& msg_in,
00092     geometry_msgs::PointStamped& msg_out) const
00093 {
00094   Stamped<Point> pin, pout;
00095   pointStampedMsgToTF(msg_in, pin);
00096   transformPoint(target_frame, pin, pout);
00097   pointStampedTFToMsg(pout, msg_out);
00098 }
00099 
00100 void TransformListener::transformPose(const std::string& target_frame,
00101     const geometry_msgs::PoseStamped& msg_in,
00102     geometry_msgs::PoseStamped& msg_out) const
00103 {
00104   tf::assertQuaternionValid(msg_in.pose.orientation);
00105 
00106   Stamped<Pose> pin, pout;
00107   poseStampedMsgToTF(msg_in, pin);
00108   transformPose(target_frame, pin, pout);
00109   poseStampedTFToMsg(pout, msg_out);
00110 }
00111 /* http://www.ros.org/wiki/tf/Reviews/2010-03-12_API_Review
00112 void TransformListener::transformTwist(const std::string& target_frame,
00113     const geometry_msgs::TwistStamped& msg_in,
00114     geometry_msgs::TwistStamped& msg_out) const
00115 {
00116   tf::Vector3 twist_rot(msg_in.twist.angular.x,
00117                         msg_in.twist.angular.y,
00118                         msg_in.twist.angular.z);
00119   tf::Vector3 twist_vel(msg_in.twist.linear.x,
00120                         msg_in.twist.linear.y,
00121                         msg_in.twist.linear.z);
00122 
00123   tf::StampedTransform transform;
00124   lookupTransform(target_frame,msg_in.header.frame_id,  msg_in.header.stamp, transform);
00125 
00126 
00127   tf::Vector3 out_rot = transform.getBasis() * twist_rot;
00128   tf::Vector3 out_vel = transform.getBasis()* twist_vel + transform.getOrigin().cross(out_rot);
00129 
00130   geometry_msgs::TwistStamped interframe_twist;
00131   lookupVelocity(target_frame, msg_in.header.frame_id, msg_in.header.stamp, ros::Duration(0.1), interframe_twist); //\todo get rid of hard coded number
00132 
00133   msg_out.header.stamp = msg_in.header.stamp;
00134   msg_out.header.frame_id = target_frame;
00135   msg_out.twist.linear.x =  out_vel.x() + interframe_twist.twist.linear.x;
00136   msg_out.twist.linear.y =  out_vel.y() + interframe_twist.twist.linear.y;
00137   msg_out.twist.linear.z =  out_vel.z() + interframe_twist.twist.linear.z;
00138   msg_out.twist.angular.x =  out_rot.x() + interframe_twist.twist.angular.x;
00139   msg_out.twist.angular.y =  out_rot.y() + interframe_twist.twist.angular.y;
00140   msg_out.twist.angular.z =  out_rot.z() + interframe_twist.twist.angular.z;
00141 
00142   }*/
00143 
00144 void TransformListener::transformQuaternion(const std::string& target_frame, const ros::Time& target_time,
00145     const geometry_msgs::QuaternionStamped& msg_in,
00146     const std::string& fixed_frame, geometry_msgs::QuaternionStamped& msg_out) const
00147 {
00148   tf::assertQuaternionValid(msg_in.quaternion);
00149   Stamped<Quaternion> pin, pout;
00150   quaternionStampedMsgToTF(msg_in, pin);
00151   transformQuaternion(target_frame, target_time, pin, fixed_frame, pout);
00152   quaternionStampedTFToMsg(pout, msg_out);
00153 }
00154 
00155 void TransformListener::transformVector(const std::string& target_frame, const ros::Time& target_time,
00156     const geometry_msgs::Vector3Stamped& msg_in,
00157     const std::string& fixed_frame, geometry_msgs::Vector3Stamped& msg_out) const
00158 {
00159   Stamped<Vector3> pin, pout;
00160   vector3StampedMsgToTF(msg_in, pin);
00161   transformVector(target_frame, target_time, pin, fixed_frame, pout);
00162   vector3StampedTFToMsg(pout, msg_out);
00163 }
00164 
00165 void TransformListener::transformPoint(const std::string& target_frame, const ros::Time& target_time,
00166     const geometry_msgs::PointStamped& msg_in,
00167     const std::string& fixed_frame, geometry_msgs::PointStamped& msg_out) const
00168 {
00169   Stamped<Point> pin, pout;
00170   pointStampedMsgToTF(msg_in, pin);
00171   transformPoint(target_frame, target_time, pin, fixed_frame, pout);
00172   pointStampedTFToMsg(pout, msg_out);
00173 }
00174 
00175 void TransformListener::transformPose(const std::string& target_frame, const ros::Time& target_time,
00176     const geometry_msgs::PoseStamped& msg_in,
00177     const std::string& fixed_frame, geometry_msgs::PoseStamped& msg_out) const
00178 {
00179   tf::assertQuaternionValid(msg_in.pose.orientation);
00180 
00181   Stamped<Pose> pin, pout;
00182   poseStampedMsgToTF(msg_in, pin);
00183   transformPose(target_frame, target_time, pin, fixed_frame, pout);
00184   poseStampedTFToMsg(pout, msg_out);
00185 }
00186 
00187 void TransformListener::transformPointCloud(const std::string & target_frame, const sensor_msgs::PointCloud & cloudIn, sensor_msgs::PointCloud & cloudOut) const
00188 {
00189   StampedTransform transform;
00190   lookupTransform(target_frame, cloudIn.header.frame_id, cloudIn.header.stamp, transform);
00191 
00192   transformPointCloud(target_frame, transform, cloudIn.header.stamp, cloudIn, cloudOut);
00193 }
00194 void TransformListener::transformPointCloud(const std::string& target_frame, const ros::Time& target_time, 
00195     const sensor_msgs::PointCloud& cloudIn,
00196     const std::string& fixed_frame, sensor_msgs::PointCloud& cloudOut) const
00197 {
00198   StampedTransform transform;
00199   lookupTransform(target_frame, target_time,
00200       cloudIn.header.frame_id, cloudIn.header.stamp,
00201       fixed_frame,
00202       transform);
00203 
00204   transformPointCloud(target_frame, transform, target_time, cloudIn, cloudOut);
00205 
00206 
00207 }
00208 
00209 inline void transformPointMatVec(const tf::Vector3 &origin, const tf::Matrix3x3 &basis, const geometry_msgs::Point32 &in, geometry_msgs::Point32 &out)
00210 {
00211   // Use temporary variables in case &in == &out
00212   double x = basis[0].x() * in.x + basis[0].y() * in.y + basis[0].z() * in.z + origin.x();
00213   double y = basis[1].x() * in.x + basis[1].y() * in.y + basis[1].z() * in.z + origin.y();
00214   double z = basis[2].x() * in.x + basis[2].y() * in.y + basis[2].z() * in.z + origin.z();
00215   
00216   out.x = x; out.y = y; out.z = z;
00217 }
00218 
00219 
00220 void TransformListener::transformPointCloud(const std::string & target_frame, const tf::Transform& net_transform,
00221                                             const ros::Time& target_time, const sensor_msgs::PointCloud & cloudIn, 
00222                                             sensor_msgs::PointCloud & cloudOut) const
00223 {
00224   tf::Vector3 origin = net_transform.getOrigin();
00225   tf::Matrix3x3 basis  = net_transform.getBasis();
00226 
00227   unsigned int length = cloudIn.points.size();
00228 
00229   // Copy relevant data from cloudIn, if needed
00230   if (&cloudIn != &cloudOut)
00231   {
00232     cloudOut.header = cloudIn.header;
00233     cloudOut.points.resize(length);
00234     cloudOut.channels.resize(cloudIn.channels.size());
00235     for (unsigned int i = 0 ; i < cloudIn.channels.size() ; ++i)
00236       cloudOut.channels[i] = cloudIn.channels[i];
00237   }
00238 
00239   // Transform points
00240   cloudOut.header.stamp = target_time;
00241   cloudOut.header.frame_id = target_frame;
00242   for (unsigned int i = 0; i < length ; i++) {
00243     transformPointMatVec(origin, basis, cloudIn.points[i], cloudOut.points[i]);
00244   }
00245 }
00246 
00247 
00248 
00249 


tf
Author(s): Tully Foote, Eitan Marder-Eppstein, Wim Meeussen
autogenerated on Thu Aug 27 2015 13:02:09