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 "object_recognition_gui/object_recognition_rviz_ui.h"
00031
00032 #include "rviz_interaction_tools/image_tools.h"
00033
00034 #include "rviz_interaction_tools/mesh_object_switcher.h"
00035 #include "rviz_interaction_tools/mesh_object.h"
00036 #include "rviz_interaction_tools/camera_tools.h"
00037
00038 #include <OGRE/OgreManualObject.h>
00039 #include <OGRE/OgreMaterialManager.h>
00040 #include <OGRE/OgreRenderWindow.h>
00041 #include <OGRE/OgreSceneNode.h>
00042 #include <OGRE/OgreSceneManager.h>
00043 #include <OGRE/OgreRoot.h>
00044
00045 #include <rviz/render_panel.h>
00046 #include <rviz/window_manager_interface.h>
00047 #include "rviz/display_context.h"
00048
00049 #include "rviz_interaction_tools/image_overlay.h"
00050 #include "rviz_interaction_tools/camera_tools.h"
00051 #include "rviz_interaction_tools/unique_string_manager.h"
00052
00053 #include "ui_object_recognition_frame.h"
00054
00055 using namespace rviz_interaction_tools;
00056
00057 namespace object_recognition_gui
00058 {
00059
00060
00061 static const std::string VALID_MAT_NAME = "object_recognition_valid";
00062 static const std::string VALID_SEL_MAT_NAME = "object_recognition_valid_selected";
00063 static const std::string INVALID_MAT_NAME = "object_recognition_invalid";
00064 static const std::string INVALID_SEL_MAT_NAME = "object_recognition_invalid_selected";
00065
00066
00067 ObjectRecognitionRvizUI::ObjectRecognitionRvizUI(rviz::DisplayContext* context) :
00068 QWidget(),
00069 object_recognition_server_(0),
00070 ui_( new Ui::ObjectRecognitionFrame )
00071 {
00072 ui_->setupUi( this );
00073 render_panel_ = ui_->render_panel_;
00074 connect( render_panel_, SIGNAL( mouseEvent( QMouseEvent* )),
00075 this, SLOT( onRenderWindowMouseEvent( QMouseEvent* )));
00076 connect( ui_->cancel, SIGNAL( clicked() ), this, SLOT( cancelButtonClicked() ));
00077 connect( ui_->ok, SIGNAL( clicked() ), this, SLOT( acceptButtonClicked() ));
00078
00079 UniqueStringManager usm;
00080
00081
00082 scene_manager_ = Ogre::Root::getSingleton().createSceneManager( Ogre::ST_GENERIC, usm.unique("ObjectRecognitionRvizUI") );
00083
00084 scene_root_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00085
00086 image_overlay_ = new rviz_interaction_tools::ImageOverlay( scene_root_, Ogre::RENDER_QUEUE_BACKGROUND );
00087
00088 setupRenderPanel( context );
00089
00090 createMaterials();
00091
00092 ray_scene_query_ = scene_manager_->createRayQuery(Ogre::Ray());
00093 }
00094
00095 ObjectRecognitionRvizUI::~ObjectRecognitionRvizUI()
00096 {
00097 if ( object_recognition_server_ )
00098 {
00099 stopActionServer();
00100 }
00101
00102 cleanupAndHide();
00103
00104 scene_manager_->destroyQuery( ray_scene_query_ );
00105
00106 render_panel_->getRenderWindow()->setActive(false);
00107
00108 delete render_panel_;
00109 delete image_overlay_;
00110 delete ui_;
00111
00112 Ogre::Root::getSingleton().destroySceneManager( scene_manager_ );
00113 }
00114
00115
00116 void ObjectRecognitionRvizUI::showBoundingBoxes( bool show )
00117 {
00118 scene_manager_->showBoundingBoxes(show);
00119 }
00120
00121 bool ObjectRecognitionRvizUI::getShowBoundingBoxes()
00122 {
00123 return scene_manager_->getShowBoundingBoxes();
00124 }
00125
00126 void ObjectRecognitionRvizUI::updateBoundingBoxes()
00127 {
00128 bool show = getShowBoundingBoxes();
00129 showBoundingBoxes (show);
00130 }
00131
00132
00133 void ObjectRecognitionRvizUI::cleanupAndHide()
00134 {
00135 for ( size_t m=0; m<mesh_switchers_.size(); ++m )
00136 {
00137 delete mesh_switchers_[m];
00138 }
00139 mesh_switchers_.clear();
00140 hide();
00141 }
00142
00143
00144 void ObjectRecognitionRvizUI::setupRenderPanel( rviz::DisplayContext* context )
00145 {
00146 render_panel_->initialize( scene_manager_, context );
00147
00148 render_panel_->setAutoRender(false);
00149 render_panel_->getViewport()->setOverlaysEnabled(false);
00150 render_panel_->getViewport()->setClearEveryFrame(true);
00151 render_panel_->getRenderWindow()->setAutoUpdated(false);
00152 render_panel_->getRenderWindow()->setActive(true);
00153
00154
00155 render_panel_->getCamera()->setPosition(0.0, 0.0, 0.0);
00156 render_panel_->getCamera()->lookAt(Ogre::Vector3(0, 0, 1));
00157 render_panel_->getCamera()->roll(Ogre::Radian(3.141592653));
00158 render_panel_->getCamera()->setFOVy(Ogre::Radian(0.518));
00159 render_panel_->getCamera()->setAspectRatio(640.0 / 480.0);
00160 render_panel_->getCamera()->setNearClipDistance( 0.01f );
00161 }
00162
00163
00164 void ObjectRecognitionRvizUI::createMaterials()
00165 {
00166 Ogre::MaterialPtr white = Ogre::MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
00167
00168 Ogre::Pass *pass;
00169
00170
00171
00172
00173 Ogre::MaterialPtr valid_mat = white->clone( VALID_MAT_NAME );
00174
00175 pass = valid_mat->getTechnique(0)->getPass(0);
00176
00177 pass->setPolygonMode( Ogre::PM_WIREFRAME );
00178 pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
00179 pass->setDepthWriteEnabled(false);
00180 pass->setDepthCheckEnabled(false);
00181 pass->setLightingEnabled(true);
00182 pass->setCullingMode( Ogre::CULL_NONE );
00183 pass->setAmbient(0.0, 0.0, 0.0);
00184 pass->setDiffuse(0.0, 0.0, 0.0, 0.3);
00185 pass->setSpecular(0.0, 0.0, 0.0, 0.3);
00186
00187 pass->setSelfIllumination( 0.0, 0.9, 0.0 );
00188
00189
00190 pass = valid_mat->clone( VALID_SEL_MAT_NAME )->getTechnique(0)->getPass(0);
00191 pass->setSelfIllumination( 0.4, 1.0, 0.4 );
00192
00193
00194 pass = valid_mat->clone( INVALID_MAT_NAME )->getTechnique(0)->getPass(0);
00195 pass->setSelfIllumination( 0.9, 0.0, 0.0 );
00196
00197
00198 pass = valid_mat->clone( INVALID_SEL_MAT_NAME )->getTechnique(0)->getPass(0);
00199 pass->setSelfIllumination( 1.0, 0.4, 0.4 );
00200
00201 pass->_dirtyHash();
00202 }
00203
00204
00205 void ObjectRecognitionRvizUI::parseMeshes(const std::vector<interactive_perception_msgs::ModelHypothesisList> &model_hyp_list)
00206 {
00207 ROS_ASSERT( mesh_switchers_.size() == 0 );
00208
00209
00210 int num_models = model_hyp_list.size();
00211 mesh_switchers_.resize(num_models);
00212 for ( int m=0; m<num_models; ++m )
00213 {
00214 const std::vector<interactive_perception_msgs::ModelHypothesis> &hyp_list =
00215 model_hyp_list[m].hypotheses;
00216
00217 int num_hyp = hyp_list.size();
00218 mesh_switchers_[m] = new MeshObjectSwitcher( VALID_MAT_NAME, VALID_SEL_MAT_NAME, INVALID_MAT_NAME, INVALID_SEL_MAT_NAME );
00219
00220 if ( hyp_list.size() == 0 || hyp_list[0].mesh.triangles.size() == 0 )
00221 {
00222 continue;
00223 }
00224
00225 for ( int h=0; h<num_hyp; ++h )
00226 {
00227 const shape_msgs::Mesh& mesh = hyp_list[h].mesh;
00228 const geometry_msgs::Pose pose = hyp_list[h].pose.pose;
00229 #if 0
00230 ROS_INFO_STREAM( "Model " << m << ", hypothesis " << h
00231 << ") has " << mesh.triangles.size() << " triangles and "
00232 << mesh.vertices.size() << " vertices." );
00233 ROS_INFO_STREAM( " Position:" << pose.position.x << " "
00234 << pose.position.y << " " << pose.position.z <<
00235 ". Orientation: " << pose.orientation.w << " " << pose.orientation.x
00236 << " " << pose.orientation.y << " " << pose.orientation.z );
00237 #endif
00238 MeshObject* mesh_object = new MeshObject( scene_manager_, scene_root_ );
00239
00240 std::ostringstream s;
00241 s << "obj_rec model " << m << " hypothesis " << h;
00242 std::string name = s.str();
00243
00244 mesh_object->loadMesh( name, mesh );
00245 mesh_object->setPose( pose );
00246
00247 Ogre::Entity* entity = mesh_object->getEntity();
00248 entity->getUserObjectBindings().setUserAny( "model", Ogre::Any(m) );
00249 entity->setRenderQueueGroup(Ogre::RENDER_QUEUE_MAIN);
00250
00251 mesh_switchers_[m]->addObject( mesh_object );
00252 }
00253
00254 mesh_switchers_[m]->setValid( model_hyp_list[m].accept );
00255 mesh_switchers_[m]->setVisible( 0 );
00256 }
00257 }
00258
00259
00260 void ObjectRecognitionRvizUI::update(float wall_dt, float ros_dt)
00261 {
00262 render_panel_->getRenderWindow()->update();
00263 }
00264
00265
00266 void ObjectRecognitionRvizUI::onRenderWindowMouseEvent( QMouseEvent* event )
00267 {
00268 ROS_ASSERT( object_recognition_server_->isActive() );
00269
00270 int x = event->x();
00271 int y = event->y();
00272
00273 QSize size = render_panel_->size();
00274
00275
00276 Ogre::Ray mouse_ray = render_panel_->getCamera()->getCameraToViewportRay(x/float(size.width()), y/float(size.height()));
00277 ray_scene_query_->setRay( mouse_ray );
00278
00279 for ( size_t m=0; m<mesh_switchers_.size(); ++m )
00280 {
00281 mesh_switchers_[m]->setSelected(false);
00282 }
00283
00284
00285 ray_scene_query_->setSortByDistance(true);
00286 Ogre::RaySceneQueryResult& result = ray_scene_query_->execute();
00287 Ogre::RaySceneQueryResult::iterator iter = result.begin();
00288
00289 int i=0;
00290 while( iter != result.end() )
00291 {
00292 Ogre::MovableObject* movable_object = iter->movable;
00293 if ( movable_object )
00294 {
00295 Ogre::Any model_any = movable_object->getUserObjectBindings().getUserAny( "model" );
00296
00297 if ( !model_any.isEmpty() )
00298 {
00299 int model = Ogre::any_cast<int>(model_any);
00300
00301
00302 if ( model >=0 && model < (int)mesh_switchers_.size() )
00303 {
00304 mesh_switchers_[model]->setSelected(true);
00305
00306 if ( mesh_switchers_[model]->isValid() )
00307 {
00308 if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton)
00309 {
00310 mesh_switchers_[model]->next();
00311 }
00312 else if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::RightButton)
00313 {
00314 mesh_switchers_[model]->setValid( false );
00315 }
00316 }
00317 else
00318 {
00319 if ( event->type() == QEvent::MouseButtonPress )
00320 {
00321 mesh_switchers_[model]->setValid( true );
00322 }
00323 }
00324 }
00325 break;
00326 }
00327 }
00328
00329 i++;
00330 iter++;
00331 }
00332 }
00333
00334
00335 void ObjectRecognitionRvizUI::acceptButtonClicked()
00336 {
00337 interactive_perception_msgs::ObjectRecognitionGuiResult result;
00338
00339 result.selected_hypothesis_indices.resize( mesh_switchers_.size() );
00340 for ( unsigned i=0; i<mesh_switchers_.size(); ++i )
00341 {
00342 result.selected_hypothesis_indices[i] =
00343 mesh_switchers_[i]->isValid() ? mesh_switchers_[i]->getVisible() : -1;
00344 }
00345
00346 object_recognition_server_->setSucceeded(result);
00347 cleanupAndHide();
00348 }
00349
00350
00351 void ObjectRecognitionRvizUI::cancelButtonClicked()
00352 {
00353 object_recognition_server_->setAborted();
00354 cleanupAndHide();
00355 }
00356
00357
00358 void ObjectRecognitionRvizUI::startActionServer( ros::NodeHandle &node_handle )
00359 {
00360 if ( object_recognition_server_ )
00361 {
00362 ROS_ERROR( "ObjectRecognitionGuiAction server already started!" );
00363 return;
00364 }
00365
00366
00367 object_recognition_server_ =
00368 new actionlib::SimpleActionServer<interactive_perception_msgs::ObjectRecognitionGuiAction>( node_handle, "object_recognition_popup", false );
00369
00370 object_recognition_server_->registerGoalCallback( boost::bind(&ObjectRecognitionRvizUI::acceptNewGoal, this) );
00371 object_recognition_server_->registerPreemptCallback( boost::bind(&ObjectRecognitionRvizUI::preempt, this) );
00372
00373 object_recognition_server_->start();
00374 }
00375
00376
00377 void ObjectRecognitionRvizUI::stopActionServer()
00378 {
00379 if ( !object_recognition_server_ )
00380 {
00381 ROS_ERROR("ObjectRecognitionGuiAction server cannot be stopped because it is not running.");
00382 return;
00383 }
00384
00385
00386 if ( object_recognition_server_->isActive() )
00387 {
00388 ROS_WARN("Aborting ObjectRecognitionGuiAction goal.");
00389 object_recognition_server_->setAborted();
00390 cleanupAndHide();
00391 }
00392
00393 delete object_recognition_server_;
00394 object_recognition_server_ = 0;
00395 }
00396
00397 void ObjectRecognitionRvizUI::acceptNewGoal()
00398 {
00399 const interactive_perception_msgs::ObjectRecognitionGuiGoal::ConstPtr &goal = object_recognition_server_->acceptNewGoal();
00400
00401 try {
00402 image_overlay_->setImage( goal->image );
00403 image_overlay_->update();
00404 } catch ( ... )
00405 {
00406 ROS_ERROR("Could not set the overlay image!");
00407 object_recognition_server_->setAborted();
00408 return;
00409 }
00410
00411 rviz_interaction_tools::updateCamera( render_panel_->getCamera(), goal->camera_info );
00412
00413 parseMeshes( goal->model_hypotheses );
00414
00415 show();
00416 }
00417
00418 void ObjectRecognitionRvizUI::preempt()
00419 {
00420 object_recognition_server_->setPreempted();
00421 cleanupAndHide();
00422 }
00423
00424
00425
00426
00427 }