Go to the documentation of this file.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 #include "rve_render_client/mesh.h"
00031 #include "rve_render_client/mesh_instance.h"
00032 #include "rve_render_client/texture.h"
00033 #include "rve_render_client/box.h"
00034 
00035 #include <rve_common_transformers/map.h>
00036 #include <rve_transformer/transformer_manager.h>
00037 #include <rve_transformer/frame_manager.h>
00038 #include <rve_properties/property_node.h>
00039 #include <rve_properties/messages.h>
00040 
00041 #include <tf2/exceptions.h>
00042 
00043 #include <rve_msgs/make_vector3.h>
00044 #include <rve_msgs/make_quaternion.h>
00045 #include <rve_msgs/Mesh.h>
00046 #include <rve_common/eigen_conversions.h>
00047 #include <geometry_msgs/TransformStamped.h>
00048 
00049 namespace rve_common_transformers
00050 {
00051   
00052 Map::Map()
00053 {
00054 }
00055 
00056 Map::~Map()
00057 {
00058   getPropertyNode()->removeChangeCallback(this);
00059 }
00060 
00061 void Map::onInit()
00062 {
00063   
00064 
00065   ros::NodeHandle nh;
00066   map_sub_ = nh.subscribe("/map", 1, &Map::receiveOccupancyGrid, this);
00067 }
00068   
00069 void Map::makeMesh( sensor_msgs::ImagePtr &image )
00070 {
00071   ROS_INFO( "makeMesh()" );
00072   map_texture_ = rve_render_client::createTexture();
00073   map_texture_->setFromImage( image );
00074   addObject(map_texture_);
00075 
00076   rve_msgs::MeshPtr mesh(new rve_msgs::Mesh);
00077   mesh->submeshes.resize(1);
00078 
00079   rve_msgs::SubMesh& sm = mesh->submeshes[0];
00080   sm.positions.push_back(rve_msgs::makeVector3(0, map_height_meters_, 0));
00081   sm.positions.push_back(rve_msgs::makeVector3(map_width_meters_, map_height_meters_, 0));
00082   sm.positions.push_back(rve_msgs::makeVector3(0, 0, 0));
00083   sm.positions.push_back(rve_msgs::makeVector3(map_width_meters_, 0, 0));
00084   sm.indices.push_back(0);
00085   sm.indices.push_back(1);
00086   sm.indices.push_back(2);
00087   sm.indices.push_back(2);
00088   sm.indices.push_back(1);
00089   sm.indices.push_back(3);
00090 
00091   sm.normals.push_back(rve_msgs::makeVector3(0.0, 0.0, 1.0));
00092   sm.normals.push_back(rve_msgs::makeVector3(0.0, 0.0, 1.0));
00093   sm.normals.push_back(rve_msgs::makeVector3(0.0, 0.0, 1.0));
00094   sm.normals.push_back(rve_msgs::makeVector3(0.0, 0.0, 1.0));
00095 
00096   sm.tex_coords.resize(1);
00097   rve_msgs::SubMesh::_tex_coords_type& tc = sm.tex_coords;
00098   tc[0].dims = 2;
00099   tc[0].array.resize(4);
00100   tc[0].array[0].uvw[0] = 0.0;
00101   tc[0].array[0].uvw[1] = 1.0;
00102 
00103   tc[0].array[1].uvw[0] = 1.0;
00104   tc[0].array[1].uvw[1] = 1.0;
00105 
00106   tc[0].array[2].uvw[0] = 0.0;
00107   tc[0].array[2].uvw[1] = 0.0;
00108 
00109   tc[0].array[3].uvw[0] = 1.0;
00110   tc[0].array[3].uvw[1] = 0.0;
00111 
00112   sm.material_index = 0;
00113 
00114   mesh->materials.resize(1);
00115   rve_msgs::Material& mat = mesh->materials[0];
00116   mat.id = rve_common::UUID::generate();
00117   mat.opacity = 1.0;
00118   mat.has_texture = true;
00119   mat.texture = "texture://" + map_texture_->getID().toString();
00120   mat.disable_shading = true;
00121   mat.cull_mode = rve_msgs::Material::CULL_NONE;
00122 
00123   rve_render_client::MeshPtr m = rve_render_client::createMesh(mesh);
00124   mesh_instance_ = rve_render_client::createMeshInstance(m);
00125   mesh_instance_->setPosition(position_);
00126   mesh_instance_->setOrientation(orientation_);
00127   ROS_INFO("map mesh instance scene object id: %s", mesh_instance_->getID().toString().c_str());
00128   printf("map mesh instance scene object pointer: %p\n", mesh_instance_.get());
00129   addObject(mesh_instance_);
00130   addObject(m);
00131 }
00132 
00133 void Map::receiveOccupancyGrid(const nav_msgs::OccupancyGridConstPtr &msg)
00134 {
00135 #if 0
00136   if (!validateFloats(*msg))
00137   {
00138     ROS_ERROR("Message contained invalid floating point values (nans or infs)");
00139     return;
00140   }
00141 #endif
00142   if (msg->info.width * msg->info.height == 0)
00143   {
00144     ROS_ERROR("Map is zero-sized (%dx%d)", msg->info.width, msg->info.height);
00145     return;
00146   }
00147 
00148 
00149 
00150   ROS_INFO("Received a %d X %d map @ %.3f m/pix\n",
00151            msg->info.width,
00152            msg->info.height,
00153            msg->info.resolution);
00154 
00155   
00156   
00157   map_ = msg;
00158   position_.x = msg->info.origin.position.x;
00159   position_.y = msg->info.origin.position.y;
00160   position_.z = msg->info.origin.position.z;
00161   orientation_.w = msg->info.origin.orientation.w;
00162   orientation_.x = msg->info.origin.orientation.x;
00163   orientation_.y = msg->info.origin.orientation.y;
00164   orientation_.z = msg->info.origin.orientation.z;
00165   map_width_pixels_ = msg->info.width;
00166   map_height_pixels_ = msg->info.height;
00167   map_width_meters_ = map_width_pixels_ * msg->info.resolution;
00168   map_height_meters_ = map_height_pixels_ * msg->info.resolution;
00169   resolution_ = msg->info.resolution;
00170   frame_ = msg->header.frame_id;
00171   if (frame_.empty())
00172   {
00173     frame_ = "/map";
00174   }
00175 
00176   
00177   int pixels_size = map_width_pixels_ * map_height_pixels_;
00178   sensor_msgs::Image::_data_type pixels( pixels_size, 255 );
00179 
00180   for(unsigned int j=0;j<msg->info.height;j++)
00181   {
00182     for(unsigned int i=0;i<msg->info.width;i++)
00183     {
00184       unsigned char val;
00185       if(msg->data[j*msg->info.width+i] == 100)
00186       {
00187         val = 0;
00188       }
00189       else if(msg->data[j*msg->info.width+i] == 0)
00190         val = 255;
00191       else
00192         val = 127;
00193 
00194       int pidx = (j*map_width_pixels_ + i);
00195       pixels[pidx] = val;
00196     }
00197   }
00198 
00199   map_image_ = sensor_msgs::ImagePtr( new sensor_msgs::Image() );
00200   map_image_->data = pixels;
00201   map_image_->height = map_height_pixels_;
00202   map_image_->width = map_width_pixels_;
00203   map_image_->step = map_width_pixels_;
00204   map_image_->encoding = "mono8";
00205   
00206   if( !map_texture_ ) {
00207     makeMesh( map_image_ );
00208   }
00209   map_texture_->setFromImage( map_image_ );
00210 }
00211 
00212 void Map::onUpdate()
00213 {
00214   if(mesh_instance_)
00215   {
00216     try
00217     {
00218       geometry_msgs::TransformStamped transform = getManager()->getFrameManager()->lookupTransform(frame_, ros::Time());
00219       const geometry_msgs::Vector3& v = transform.transform.translation;
00220       const geometry_msgs::Quaternion& q = transform.transform.rotation;
00221       position_.x = v.x;
00222       position_.y = v.z;
00223       position_.z = v.z;
00224       orientation_.x = q.x;
00225       orientation_.y = q.y;
00226       orientation_.z = q.z;
00227       orientation_.w = q.w;
00228       mesh_instance_->setPosition(position_);
00229       mesh_instance_->setOrientation(orientation_);
00230     }
00231     catch (tf2::TransformException& e)
00232     {
00233     }
00234   }
00235 }
00236 
00237 void Map::onPropertyChanged(const rve_properties::PropertyNodePtr& node, const std::string& path, rve_properties::PropertyChangeType type)
00238 {
00239   if (type != rve_properties::PropertyChanged)
00240   {
00241     return;
00242   }
00243 }
00244 
00245 } 
00246