patches_tf.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2011, Robert Bosch LLC.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the Robert Bosch nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *********************************************************************/
00036 
00037 //\Author Adrian Funk, Bosch LLC
00038 
00039 
00040 #include <ros/ros.h>
00041 #include <tf/transform_broadcaster.h>
00042 #include <vector>
00043 #include <string>
00044 #include <boost/lexical_cast.hpp>
00045 
00046 using namespace std;
00047 
00048 // Struct for keeping position vector and orientation quaternion internally
00049 typedef struct
00050 {
00051   tf::Vector3 position;
00052   tf::Quaternion orientation;
00053   string parent_frame;
00054 } patch_position;
00055 
00056 template <class T>
00057 inline void readParam( const ros::NodeHandle &nh, const std::string &str_name, T &rhs )
00058 {
00059   if( !nh.getParam(str_name, rhs) )
00060   {
00061     ROS_ERROR("Could not find parameter %s", str_name.c_str());
00062     exit(1);
00063   }
00064   return;
00065 }
00066 
00067 
00068 int main( int argc, char **argv )
00069 {
00070   ros::init( argc, argv, "patches_tf" );
00071   ros::NodeHandle nh;
00072   ros::NodeHandle nh_private("~");
00073 
00074   int patches = 0;
00075   vector<patch_position> patch_array;
00076   readParam( nh, "/prox_sensor_driver/sensor_count", patches );
00077 
00078   // Fill up data structure for each patch
00079   patch_position tmp;
00080   for( int current_patch = 0; current_patch < patches; current_patch++ )
00081   {
00082     // Read the parameters
00083     double x_pos, y_pos, z_pos;
00084     double x_ori, y_ori, z_ori;
00085 
00086     string patch_domain( "patch_" + boost::lexical_cast<string>( current_patch ) );
00087 
00088     readParam( nh_private, patch_domain + "/x_pos", x_pos );
00089     readParam( nh_private, patch_domain + "/y_pos", y_pos );
00090     readParam( nh_private, patch_domain + "/z_pos", z_pos );
00091 
00092     readParam( nh_private, patch_domain + "/x_ori", x_ori );
00093     readParam( nh_private, patch_domain + "/y_ori", y_ori );
00094     readParam( nh_private, patch_domain + "/z_ori", z_ori );
00095 
00096     readParam( nh_private, patch_domain + "/string_parent_frame", tmp.parent_frame );
00097 
00098 
00099     tf::Vector3 patch_center( x_pos, y_pos, z_pos);
00100     tf::Vector3 patch_normal( x_ori, y_ori, z_ori);
00101 
00102     if( patch_normal.isZero() )
00103     {
00104       ROS_ERROR("Normal of patch %d is zero vector!", current_patch);
00105       exit(1);
00106     }
00107 
00108     // Create the quaternion out of the normal
00109     //
00110     // For this we have to find out how to turn the x-axis on the normal of the patch
00111     // This is done by computing the cross-product of x-axis and normal of the patch
00112     // This vector serves as rotation axis, then we only have to turn the x-axis around this
00113     // vector by the amount of angle between normal of the patch and x-axis
00114 
00115     patch_normal.normalize();
00116     tf::Vector3 x_axis(1.0, 0.0, 0.0);
00117     tf::Vector3 rot_axis = x_axis.cross( patch_normal );
00118     double angle;
00119 
00120     if( rot_axis.isZero() ) // This happens when the normal of the patch is exactly the x-axis
00121     {
00122       rot_axis = x_axis;
00123       angle = 0.0;
00124     }
00125     else // Compute angle between normal and x-axis
00126     {
00127       angle = acos( patch_normal.dot(x_axis) );
00128     }
00129 
00130     tf::Quaternion patch_orientation( rot_axis, angle);
00131     patch_orientation.normalize(); // Normalize quaternion! Otherwise transform might not work correctly
00132 
00133 
00134     // Save data results for that we don't have to compute them before every transform
00135     tmp.position = patch_center;
00136     tmp.orientation = patch_orientation;
00137     patch_array.push_back( tmp );
00138 
00139 
00140     ROS_INFO("---------");
00141     ROS_INFO("Added patch %d", current_patch);
00142     ROS_INFO("Position: X:%lf Y:%lf Z:%lf", x_pos, y_pos, z_pos);
00143     ROS_INFO("Orientation: X:%lf Y:%lf Z:%lf", x_ori, y_ori, z_ori);
00144     ROS_INFO("Parent frame: %s", tmp.parent_frame.c_str());
00145   }
00146   // Now we have all the data we need stored in the vector patches
00147 
00148   tf::TransformBroadcaster br;
00149   tf::Transform transform;
00150 
00151   ros::Rate r( 20 );
00152 
00153   while( nh.ok() )
00154   {
00155     // Publish a transform for each patch
00156     for( int current_patch = 0; current_patch < patches; current_patch++ )
00157     {
00158       patch_position patch = patch_array.at( current_patch );
00159 
00160       transform.setOrigin( patch.position );
00161       transform.setRotation( patch.orientation );
00162       br.sendTransform( tf::StampedTransform( transform,
00163                                               ros::Time::now(),
00164                                               patch.parent_frame,
00165                                               "/patch_" + boost::lexical_cast<string>( current_patch )) );
00166     }
00167     r.sleep();
00168   }
00169 
00170   return(0);
00171 }
00172 


proximity_sensor_tf
Author(s): Adrian Funk (Maintained by Philip Roan)
autogenerated on Fri Jan 3 2014 11:08:55