visualize_patches.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, Philip Roan, Bosch LLC
00038 
00039 #include <ros/ros.h>
00040 #include <visualization_msgs/Marker.h>
00041 #include <visualization_msgs/MarkerArray.h>
00042 #include <vector>
00043 #include <math.h>
00044 #include <proximity_sensor_driver/prox_sensor_measurement.h>
00045 
00046 using namespace std;
00047 
00048 // Global variables to be used in the callback
00049 int sensor_count = 0;
00050 vector<int> sensor_measurements;
00051 
00052 // Reads the data of the proximity sensor and saves it in sensor_measurements
00053 void proxSensorDataCallback( const boost::shared_ptr<proximity_sensor_driver::prox_sensor_measurement const> &msg )
00054 {
00055   for( int int_current_patch = 0; int_current_patch < sensor_count; int_current_patch++ )
00056   {
00057     sensor_measurements[int_current_patch] = abs( msg->value[int_current_patch] - msg->offset[int_current_patch] );
00058   }
00059   return;
00060 }
00061 
00062 // Function for reading critical parameters
00063 template <class T>
00064 inline void readParam( const ros::NodeHandle &nh, const std::string &str_name, T &rhs )
00065 {
00066   if( !nh.getParam(str_name, rhs) )
00067   {
00068     ROS_ERROR("Could not find parameter %s", str_name.c_str());
00069     exit(1);
00070   }
00071   return;
00072 }
00073 
00074 
00075 int main( int argc, char** argv )
00076 {
00077   ros::init( argc, argv, "visualize_patches" );
00078   ros::NodeHandle nh;
00079 
00080   // Read parameters
00081   int int_noise;
00082   int int_min_intensity;
00083   readParam( nh, "/prox_sensor_driver/sensor_count", sensor_count );
00084   readParam( nh, "/prox_sensor_driver/noise_threshold", int_noise );
00085   readParam( nh, "/prox_sensor_driver/static_threshold", int_min_intensity );
00086   sensor_measurements.resize( sensor_count );
00087 
00088   // Subscribe and advertise
00089   ros::Subscriber prox_sensor_sub = nh.subscribe( "/prox_sensor_data", 100, proxSensorDataCallback );
00090   ros::Publisher marker_pub = nh.advertise<visualization_msgs::MarkerArray>( "proximity_sensor_marker_array", 20 );
00091   ros::Publisher fake_pub = nh.advertise<visualization_msgs::Marker>( "proximity_sensor_marker", 20 ); // This makes the marker array visible in rviz
00092 
00093   visualization_msgs::Marker patch;
00094   visualization_msgs::Marker arrow;
00095 
00096   // Set up the patch marker
00097   patch.ns = "patches";
00098   patch.type = visualization_msgs::Marker::CYLINDER;
00099   patch.action = visualization_msgs::Marker::ADD;
00100   patch.pose.position.x = 0;
00101   patch.pose.position.y = 0;
00102   patch.pose.position.z = 0;
00103   patch.pose.orientation.x = 0;
00104   patch.pose.orientation.y = sqrt(0.5);
00105   patch.pose.orientation.z = 0;
00106   patch.pose.orientation.w = sqrt(0.5);
00107   patch.scale.x = 0.06;
00108   patch.scale.y = 0.06;
00109   patch.scale.z = 0.005;
00110   patch.color.b = 0.0;
00111   patch.color.a = 0.6;
00112   patch.lifetime = ros::Duration();
00113 
00114   // Set up the arrow marker
00115   arrow.ns = "arrows";
00116   //arrow.type = visualization_msgs::Marker::ARROW;
00117   arrow.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00118   arrow.action = visualization_msgs::Marker::ADD;
00119   arrow.pose.position.x = 0.01;
00120   arrow.pose.position.y = 0;
00121   arrow.pose.position.z = 0;
00122   arrow.pose.orientation.x = 0;
00123   arrow.pose.orientation.y = 0;
00124   arrow.pose.orientation.z = 0;
00125   arrow.pose.orientation.w = 1;
00126   arrow.scale.x = 0.075;
00127   arrow.scale.y = 0.075;
00128   arrow.scale.z = 0.025;
00129   arrow.color.g = 1.0;
00130   arrow.color.b = 1.0;
00131   arrow.color.a = 0.6;
00132   arrow.lifetime = ros::Duration();
00133 
00134   // Reserve space for an arrow and a patch marker for each patch
00135         
00136 
00137   ros::Rate r(5);
00138 
00139   while( ros::ok() )
00140   {
00141     visualization_msgs::MarkerArray marker_array;
00142     ros::spinOnce(); // Get current proximity sensor readings
00143 
00144     // Add patch and arrow marker for each sensor patch to a marker array
00145     for( int int_current_patch = 0; int_current_patch < sensor_count; int_current_patch++ )
00146     {
00147       // Patch
00148       patch.header.frame_id = "/patch_" + boost::lexical_cast<string>( int_current_patch );
00149       patch.header.stamp = ros::Time(0);
00150       patch.id = int_current_patch;
00151 
00152       // Determine whether the patch is "active" (red) or "inactive" (green)
00153       if( sensor_measurements[int_current_patch] >= int_min_intensity + int_noise )
00154       {
00155         patch.color.r = 1.0;
00156         patch.color.g = 0.0;
00157       }
00158       else
00159       {
00160         patch.color.r = 0.0;
00161         patch.color.g = 1.0;
00162       }
00163 
00164       marker_array.markers.push_back( patch );
00165 
00166 
00167       // Arrow
00168       arrow.header.frame_id = "/patch_" + boost::lexical_cast<string>( int_current_patch );
00169       arrow.header.stamp = ros::Time(0);
00170       arrow.id = int_current_patch;
00171 
00172       // When the patch is active the arrow is white
00173       if( sensor_measurements[int_current_patch] >= int_min_intensity + int_noise )
00174       {
00175         arrow.color.r = 1.0;
00176         arrow.text = boost::lexical_cast<string>( int_current_patch );
00177       }
00178       else // If it's not 100% active it becomes whiter and whiter, the stronger the reading gets
00179       {
00180         arrow.color.r = (double)(sensor_measurements[int_current_patch] - int_noise) / (double)int_min_intensity;
00181         arrow.text = boost::lexical_cast<string>( int_current_patch );
00182       }
00183 
00184       marker_array.markers.push_back( arrow );
00185     }
00186     marker_pub.publish( marker_array );
00187     r.sleep();
00188   }
00189 
00190   return 0;
00191 }
00192 


proximity_sensor_visualize
Author(s): Adrian Funk (Maintained by Philip Roan)
autogenerated on Fri Jan 3 2014 11:09:01