pose_labeler.cpp
Go to the documentation of this file.
00001 
00027 #include <topological_tools/pose_labeler.h>
00028 
00029 
00030 
00031 using namespace topological_tools;
00032 
00033 
00034 
00035 PoseLabeler::PoseLabeler ( const std::string& label_map_filename ) :
00036     label_map_ ( IMG_Load ( label_map_filename.c_str() ) ),
00037     map_loaded_ ( false )
00038 {
00039     if ( label_map_ == 0 )
00040     {
00041         ROS_ERROR_STREAM ( "Unable to open label map file " << label_map_filename );
00042         abort();
00043     }
00044 }
00045 
00046 
00047 
00048 uint32_t PoseLabeler::getPixelValue ( boost::shared_ptr<SDL_Surface> surface, int x, int y )
00049 {
00050     //NOTE: From SDL Wiki (http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access as of 13/12/12)
00051     int bpp = surface->format->BytesPerPixel;
00052     Uint8* p = ( Uint8* ) surface->pixels + y * surface->pitch + x * bpp;
00053 
00054     switch ( bpp )
00055     {
00056     case 1:
00057         return *p;
00058         break;
00059 
00060     case 2:
00061         return * ( Uint16* ) p;
00062         break;
00063 
00064     case 3:
00065         if ( SDL_BYTEORDER == SDL_BIG_ENDIAN )
00066         {
00067             return p[0] << 16 | p[1] << 8 | p[2];
00068         }
00069         else
00070         {
00071             return p[0] | p[1] << 8 | p[2] << 16;
00072         }
00073         break;
00074 
00075     case 4:
00076         return * ( Uint32* ) p;
00077         break;
00078 
00079     default:
00080         return 0;
00081     }
00082 }
00083 
00084 
00085 
00086 PoseLabeler::~PoseLabeler()
00087 {
00088     //SDL_FreeSurface (label_map_.get());
00089 }
00090 
00091 
00092 
00093 void PoseLabeler::setMapMetaData ( const nav_msgs::MapMetaDataConstPtr& mdata )
00094 {
00095     setMapMetaData ( *mdata );
00096 }
00097 
00098 
00099 
00100 void PoseLabeler::setMapMetaData ( nav_msgs::MapMetaData mdata )
00101 {
00102     map_metadata_ = mdata;
00103     map_loaded_ = true;
00104 }
00105 
00106 
00107 PoseLabel PoseLabeler::getPoseLabel ( geometry_msgs::PoseWithCovarianceStamped msg )
00108 {
00109     if ( !map_loaded_ )
00110     {
00111         ROS_WARN ( "Label not calculated - Metadata not available" );
00112         return PoseLabel();
00113     }
00114 
00115     ROS_DEBUG_STREAM_NAMED ( "pose_label", "received_position (x,y) = " << msg.pose.pose.position.x << " , " << msg.pose.pose.position.y );
00116     //This is simply a coordinate transform from the world frame to map pixel coordinates.
00117     //TF isn't used as the output coordinate frame is adimensional and shouldn't be accessed by anything else.
00118     float x0 = map_metadata_.origin.position.x;
00119     float y0 = map_metadata_.origin.position.y;
00120     uint32_t px, py;
00121     if ( map_metadata_.origin.orientation.z != 0 )
00122     {
00123         double theta = acos ( map_metadata_.origin.orientation.w );
00124         px = floor ( ( -x0 + cos ( theta ) * msg.pose.pose.position.x - sin ( theta ) * msg.pose.pose.position.y ) / map_metadata_.resolution );
00125         py = label_map_->h - floor ( ( -y0 + sin ( theta ) * msg.pose.pose.position.x + cos ( theta ) * msg.pose.pose.position.y ) / map_metadata_.resolution );
00126     }
00127     else
00128     {
00129         //This is the most common case. It saves a little time on the cos and sin calculations.
00130         px = floor ( ( msg.pose.pose.position.x - x0 ) / map_metadata_.resolution );
00131         ROS_DEBUG_STREAM_NAMED ( "pose_label", "label_map_.h: " << label_map_->h << ", y: " << msg.pose.pose.position.y << ", y0: " << y0 << ", res:" << map_metadata_.resolution << ", Map HxW: " << map_metadata_.height << " , " << map_metadata_.width );
00132         py = label_map_->h - floor ( ( msg.pose.pose.position.y - y0 ) / map_metadata_.resolution );
00133     }
00134     //   ROS_DEBUG_STREAM_NAMED ("pose_label", "(x,y) = " << px << " , " << py << ", Map HxW: " << map_metadata_.height << " , " <<map_metadata_.width);
00135 
00136     if ( px <= map_metadata_.width &&
00137             py <= map_metadata_.height )
00138     {
00139         PoseLabel pl;
00140         uint32_t label = getPixelValue ( label_map_, px, py );
00141         pl.label = label;
00142         ROS_DEBUG_STREAM_NAMED ( "pose_label", "(x,y) = " << px << " , " << py << ". Label: " << label );
00143         return pl;
00144     }
00145     else
00146     {
00147         ROS_WARN_STREAM ( "Label not calculated - Position out of bounds. Check the map metadata origin/resolution" );
00148         return PoseLabel();
00149     }
00150 }


topological_tools
Author(s): Joao Messias
autogenerated on Wed Aug 26 2015 12:28:47