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 
00032 
00033 
00034 
00035 
00036 
00037 
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 
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   
00079   patch_position tmp;
00080   for( int current_patch = 0; current_patch < patches; current_patch++ )
00081   {
00082     
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     
00109     
00110     
00111     
00112     
00113     
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() ) 
00121     {
00122       rot_axis = x_axis;
00123       angle = 0.0;
00124     }
00125     else 
00126     {
00127       angle = acos( patch_normal.dot(x_axis) );
00128     }
00129 
00130     tf::Quaternion patch_orientation( rot_axis, angle);
00131     patch_orientation.normalize(); 
00132 
00133 
00134     
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   
00147 
00148   tf::TransformBroadcaster br;
00149   tf::Transform transform;
00150 
00151   ros::Rate r( 20 );
00152 
00153   while( nh.ok() )
00154   {
00155     
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