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