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
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
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
00117
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
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
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 }