map.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
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   //getPropertyNode()->addChangeCallback(boost::bind(&Map::onPropertyChanged, this, _1, _2, _3), this, getCallbackQueue());
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 //  clear();
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   // TODO: check if resolution or position or orientation etc have
00156   // changed, and call makeMesh() again if so
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   // Convert to image.
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 } // namespace rve_common_transformers
00246 


rve_common_transformers
Author(s): Josh Faust
autogenerated on Wed Dec 11 2013 14:31:58