tf_filter.cpp
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 #include <ros/ros.h>
00030 #include <tf/transform_listener.h>
00031 #include <tf/transform_broadcaster.h>
00032 #include <string>
00033 #include <iostream>
00034 
00035 std::ostream& operator<<(std::ostream& os, const tf::Transform& transform)
00036 {
00037   using std::setw;
00038   tf::Vector3 origin = transform.getOrigin();
00039   tf::Quaternion quat = transform.getRotation();
00040   os << setw(10) << origin.x() << " " << setw(10) << origin.y() << " " << setw(10) << origin.z() << " ";
00041   os << setw(10) << quat.x() << " " << setw(10) << quat.y() << " " << setw(10) << quat.z() << " " << setw(10) << quat.w();
00042   return os;
00043 }
00044 
00045 void printHeader(std::ostream& os, const std::string& frame_id)
00046 {
00047   os << frame_id << ".x " << frame_id << ".y " << frame_id << ".z "
00048      << frame_id << ".qx " << frame_id << ".qy " << frame_id << ".qz " << frame_id << ".qw ";
00049 }
00050 
00051 int main(int argc, char** argv)
00052 {
00053   ros::init(argc, argv, "tf_filter");
00054 
00055   ros::NodeHandle nh;
00056   ros::NodeHandle nhp("~");
00057 
00058   std::string reference_frame_id;
00059   std::string child_frame_id;
00060   double frequency, ramp_wwf;
00061   int num_samples_wwf, wwf_index;
00062   bool full_arrays = false;
00063 
00064   nhp.param("reference_frame_id", reference_frame_id, std::string("/base_link"));
00065   nhp.param("child_frame_id", child_frame_id, std::string("/camera"));
00066   nhp.param("frequency", frequency, 100.0);
00067 
00068   // Use Weighted Window Filter
00069   nhp.param("ramp_wwf", ramp_wwf, 0.5);
00070   nhp.param("num_samples_wwf", num_samples_wwf, 10);
00071  
00072   ROS_INFO("TF Filter initiated.\n\tPARAMETERS: \
00073             \n\t * Reference frame ID: %s \
00074             \n\t * Child frame ID:     %s \
00075             \n\t * Frequency:          %f \
00076             \n\t * Ramp WWF:           %f \
00077             \n\t * Num samples WWF:    %d", 
00078             reference_frame_id.c_str(),
00079             child_frame_id.c_str(),
00080             frequency,
00081             ramp_wwf, 
00082             num_samples_wwf);
00083 
00084   double * x_array, * y_array, * z_array;
00085   double * sR_array, * cR_array, * sP_array, * cP_array, * sY_array, * cY_array;
00086   double * t_array, * w_array;
00087 
00088   //fill circular arrays with zeros
00089   wwf_index = 0;
00090   x_array  = new double[num_samples_wwf];
00091   y_array  = new double[num_samples_wwf];
00092   z_array  = new double[num_samples_wwf];
00093   sR_array = new double[num_samples_wwf]; // sin(roll) array
00094   cR_array = new double[num_samples_wwf]; // cos(roll) array
00095   sP_array = new double[num_samples_wwf]; // sin(pitch) array
00096   cP_array = new double[num_samples_wwf]; // cos(pitch) array
00097   sY_array = new double[num_samples_wwf]; // sin(yaw) array
00098   cY_array = new double[num_samples_wwf]; // cos(yaw) array
00099   t_array  = new double[num_samples_wwf]; //times used for the ramp
00100   w_array  = new double[num_samples_wwf]; //weights
00101   for(int i = 0; i< num_samples_wwf; i++){
00102     x_array[i] = 0.0;
00103     y_array[i] = 0.0;
00104     z_array[i] = 0.0;
00105     sR_array[i] = 0.0;
00106     cR_array[i] = 0.0;
00107     sP_array[i] = 0.0;
00108     cP_array[i] = 0.0;
00109     sY_array[i] = 0.0;
00110     cY_array[i] = 0.0;
00111     t_array[i] = 0.0; 
00112     w_array[i] = 0.0; 
00113   }
00114 
00115   tf::TransformListener listener;
00116   tf::TransformBroadcaster broadcaster;
00117   
00118   ros::Rate rate(frequency);
00119   while (ros::ok())
00120   {
00121     rate.sleep(); //TODO: here or at the end?
00122 
00123     // Wait for clock
00124     if (!ros::Time::isValid()) continue; 
00125     ros::Time requested_time = ros::Time(0); //(ros::Time::now() - ros::Duration(2 / frequency));
00126     tf::StampedTransform transform;
00127     try
00128     {
00129       // first look up transform, this could throw exceptions
00130       ros::Duration timeout(2 / frequency);
00131       ros::Duration polling_sleep_duration(0.5 / frequency);
00132       listener.waitForTransform(
00133           reference_frame_id, 
00134           child_frame_id, 
00135           requested_time,
00136           timeout, 
00137           polling_sleep_duration);
00138       listener.lookupTransform(
00139           reference_frame_id, 
00140           child_frame_id, 
00141           requested_time, 
00142           transform);
00143 
00144       ROS_DEBUG_STREAM("Received transform: " << transform);
00145       ROS_DEBUG_STREAM("With frame_id: " << transform.frame_id_ << " and child_id " << transform.child_frame_id_);
00146 
00147       // get position and orientation
00148       double roll, pitch, yaw;
00149       tf::Matrix3x3 rotm(transform.getRotation());
00150       rotm.getRPY(roll, pitch, yaw);
00151 
00152       x_array[wwf_index] = transform.getOrigin().x();
00153       y_array[wwf_index] = transform.getOrigin().y();
00154       z_array[wwf_index] = transform.getOrigin().z();
00155       sR_array[wwf_index] = sin(roll);
00156       cR_array[wwf_index] = cos(roll);
00157       sP_array[wwf_index] = sin(pitch);
00158       cP_array[wwf_index] = cos(pitch);
00159       sY_array[wwf_index] = sin(yaw);
00160       cY_array[wwf_index] = cos(yaw);
00161 
00162       // save ros time into circular array
00163       ros::Time now = transform.stamp_;
00164       t_array[wwf_index] = now.toSec();
00165 
00166       // compute weights for every element of the arrays
00167       // and leave weights of empty cells to zero
00168       int num_elem = num_samples_wwf;
00169       if(!full_arrays){
00170         num_elem = wwf_index + 1; 
00171       }
00172       double w_total = 0.0;
00173       for(int i = 0; i < num_elem; i++){
00174         double t_aux = t_array[i] - t_array[wwf_index]; //<=0
00175         w_array[i] = std::max(0.0,ramp_wwf*t_aux + 1);
00176         w_total += w_array[i];
00177       }
00178 
00179       
00180       double w_aux;
00181       double x, y, z, sinR, cosR, sinP, cosP, sinY, cosY;
00182       x = y = z = sinR = cosR = sinP = cosP = sinY = cosY = 0.0;
00183 
00184       // Compute final tf
00185       for(int i = 0; i < num_elem; i++){
00186         w_aux = w_array[i]/w_total;
00187         x += w_aux * x_array[i];
00188         y += w_aux * y_array[i];
00189         z += w_aux * z_array[i];
00190         sinR += w_aux * sR_array[i];
00191         cosR += w_aux * cR_array[i];
00192         sinP += w_aux * sP_array[i];
00193         cosP += w_aux * cP_array[i];
00194         sinY += w_aux * sY_array[i];
00195         cosY += w_aux * cY_array[i];
00196       }
00197 
00198       tf::Vector3 orig(x,y,z);
00199 
00200       roll = atan2(sinR, cosR);
00201       pitch = atan2(sinP, cosP);
00202       yaw = atan2(sinY, cosY);
00203 
00204       tf::Quaternion quat;
00205       quat.setRPY(roll, pitch, yaw);
00206 
00207       transform.setOrigin(orig);
00208       transform.setRotation(quat);
00209 
00210       // Set the output stamped transform and send it
00211       transform.child_frame_id_ = transform.child_frame_id_ + "_filtered";
00212       broadcaster.sendTransform(transform);
00213 
00214       // Increment the counter
00215       wwf_index++;
00216       if (wwf_index==num_samples_wwf){
00217         full_arrays = true;
00218         wwf_index = 0;
00219       }
00220     }
00221     catch (const tf::TransformException& e)
00222     {
00223       std::cerr << "TransformException caught: " << e.what() << std::endl;
00224     }
00225   }
00226   return 0;
00227 }
00228 


tf_tools
Author(s): Stephan Wirth , Miquel Massot
autogenerated on Fri Aug 28 2015 13:15:19