visualization_manager.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, 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 <QApplication>
00031 
00032 #include "visualization_manager.h"
00033 #include "selection/selection_manager.h"
00034 #include "render_panel.h"
00035 #include "displays_panel.h"
00036 #include "viewport_mouse_event.h"
00037 #include "frame_manager.h"
00038 
00039 #include "view_controller.h"
00040 #include "view_controllers/xy_orbit_view_controller.h"
00041 #include "view_controllers/orbit_view_controller.h"
00042 #include "view_controllers/fps_view_controller.h"
00043 #include "view_controllers/fixed_orientation_ortho_view_controller.h"
00044 
00045 #include "display.h"
00046 #include "display_wrapper.h"
00047 #include "properties/property_manager.h"
00048 #include "properties/property.h"
00049 #include "properties/forwards.h"
00051 
00052 #include "tools/tool.h"
00053 #include "tools/move_tool.h"
00054 #include "tools/goal_tool.h"
00055 #include "tools/initial_pose_tool.h"
00056 #include "tools/selection_tool.h"
00057 #include "tools/interaction_tool.h"
00058 
00059 #include <ogre_helpers/qt_ogre_render_window.h>
00060 
00061 #include <tf/transform_listener.h>
00062 
00063 #include <ros/package.h>
00064 
00065 #include "config.h"
00066 
00067 #include <boost/bind.hpp>
00068 
00069 #include <OGRE/OgreRoot.h>
00070 #include <OGRE/OgreSceneManager.h>
00071 #include <OGRE/OgreSceneNode.h>
00072 #include <OGRE/OgreLight.h>
00073 #include <OGRE/OgreViewport.h>
00074 #include <OGRE/OgreMaterialManager.h>
00075 #include <OGRE/OgreMaterial.h>
00076 #include <OGRE/OgreRenderWindow.h>
00077 
00078 #include <algorithm>
00079 
00080 #define CAMERA_TYPE "Camera Type"
00081 #define CAMERA_CONFIG "Camera Config"
00082 
00083 namespace rviz
00084 {
00085 
00086 VisualizationManager::VisualizationManager( RenderPanel* render_panel, WindowManagerInterface* wm )
00087 : ogre_root_( Ogre::Root::getSingletonPtr() )
00088 , update_timer_(0)
00089 , shutting_down_(false)
00090 , current_tool_( NULL )
00091 , render_panel_( render_panel )
00092 , time_update_timer_(0.0f)
00093 , frame_update_timer_(0.0f)
00094 , view_controller_(0)
00095 , render_requested_(1)
00096 , frame_count_(0)
00097 , window_manager_(wm)
00098 , disable_update_(false)
00099 , target_frame_is_fixed_frame_(false)
00100 {
00101   frame_manager_ = FrameManager::instance();
00102 
00103   render_panel->setAutoRender(false);
00104 
00105   threaded_nh_.setCallbackQueue(&threaded_queue_);
00106 
00107   scene_manager_ = ogre_root_->createSceneManager( Ogre::ST_GENERIC );
00108 
00109   target_scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00110 
00111   Ogre::Light* directional_light = scene_manager_->createLight( "MainDirectional" );
00112   directional_light->setType( Ogre::Light::LT_DIRECTIONAL );
00113   directional_light->setDirection( Ogre::Vector3( -1, 0, -1 ) );
00114   directional_light->setDiffuseColour( Ogre::ColourValue( 1.0f, 1.0f, 1.0f ) );
00115 
00116   property_manager_ = new PropertyManager();
00117   tool_property_manager_ = new PropertyManager();
00118 
00119   connect( property_manager_, SIGNAL( configChanged() ), this, SIGNAL( configChanged() ));
00120   connect( tool_property_manager_, SIGNAL( configChanged() ), this, SIGNAL( configChanged() ));
00121 
00122   CategoryPropertyWPtr options_category = property_manager_->createCategory( ".Global Options", "", CategoryPropertyWPtr(), this );
00123   target_frame_property_ = property_manager_->createProperty<TFFrameProperty>( "Target Frame", "", boost::bind( &VisualizationManager::getTargetFrame, this ),
00124                                                                               boost::bind( &VisualizationManager::setTargetFrame, this, _1 ), options_category, this );
00125   setPropertyHelpText(target_frame_property_, "Reference frame for the 3D camera view.");
00126   fixed_frame_property_ = property_manager_->createProperty<EditEnumProperty>( "Fixed Frame", "", boost::bind( &VisualizationManager::getFixedFrame, this ),
00127                                                                              boost::bind( &VisualizationManager::setFixedFrame, this, _1 ), options_category, this );
00128   setPropertyHelpText(fixed_frame_property_, "Frame into which all data is transformed before being displayed.");
00129   background_color_property_ = property_manager_->createProperty<ColorProperty>( "Background Color", "", boost::bind( &VisualizationManager::getBackgroundColor, this ),
00130                                                                              boost::bind( &VisualizationManager::setBackgroundColor, this, _1 ), options_category, this );
00131   setPropertyHelpText(background_color_property_, "Background color for the 3D view.");
00132   status_property_ = property_manager_->createStatus(".Global Status", "", CategoryPropertyWPtr(), this);
00133 
00134   CategoryPropertyPtr cat_prop = options_category.lock();
00135   cat_prop->collapse();
00136 
00137   setBackgroundColor(Color(0.0f, 0.0f, 0.0f));
00138 
00139   createColorMaterials();
00140 
00141   selection_manager_ = new SelectionManager(this);
00142 
00143   threaded_queue_threads_.create_thread(boost::bind(&VisualizationManager::threadedQueueThreadFunc, this));
00144 
00145   display_class_loader_ = new pluginlib::ClassLoader<Display>( "rviz", "rviz::Display" );
00146 }
00147 
00148 VisualizationManager::~VisualizationManager()
00149 {
00150   delete update_timer_;
00151   delete idle_timer_;
00152 
00153   shutting_down_ = true;
00154   threaded_queue_threads_.join_all();
00155 
00156   if(selection_manager_)
00157   {
00158     selection_manager_->setSelection(M_Picked());
00159   }
00160 
00161   V_DisplayWrapper::iterator it = displays_.begin();
00162   V_DisplayWrapper::iterator end = displays_.end();
00163   for (; it != end; ++it)
00164   {
00165     delete *it;
00166   }
00167   displays_.clear();
00168 
00169   V_Tool::iterator tool_it = tools_.begin();
00170   V_Tool::iterator tool_end = tools_.end();
00171   for ( ; tool_it != tool_end; ++tool_it )
00172   {
00173     delete *tool_it;
00174   }
00175   tools_.clear();
00176 
00177   delete display_class_loader_;
00178   delete property_manager_;
00179   delete tool_property_manager_;
00180 
00181   delete selection_manager_;
00182 
00183   scene_manager_->destroySceneNode( target_scene_node_ );
00184 
00185   if(ogre_root_)
00186   {
00187     ogre_root_->destroySceneManager( scene_manager_ );
00188   }
00189 }
00190 
00191 void VisualizationManager::initialize(const StatusCallback& cb, bool verbose)
00192 {
00193   if(cb)
00194   {
00195     cb("Initializing TF");
00196   }
00197 
00198   setFixedFrame("/map");
00199   setTargetFrame(FIXED_FRAME_STRING);
00200 
00201   render_panel_->getCamera()->setPosition(0, 10, 15);
00202   render_panel_->getCamera()->setNearClipDistance(0.01f);
00203   render_panel_->getCamera()->lookAt(0, 0, 0);
00204 
00205   addViewController(XYOrbitViewController::getClassNameStatic(), "XYOrbit");
00206   addViewController(OrbitViewController::getClassNameStatic(), "Orbit");
00207   addViewController(FPSViewController::getClassNameStatic(), "FPS");
00208   addViewController(FixedOrientationOrthoViewController::getClassNameStatic(), "TopDownOrtho");
00209   setCurrentViewControllerType(OrbitViewController::getClassNameStatic());
00210 
00211   MoveTool *move_tool = createTool< MoveTool >( "Move Camera", 'm' );
00212   setCurrentTool( move_tool );
00213   setDefaultTool( move_tool );
00214 
00215   createTool< InteractionTool >( "Interact", 'i' );
00216   createTool< SelectionTool >( "Select", 's' );
00217   createTool< GoalTool >( "2D Nav Goal", 'g' );
00218   createTool< InitialPoseTool >( "2D Pose Estimate", 'p' );
00219 
00220   selection_manager_->initialize( verbose );
00221 
00222   last_update_ros_time_ = ros::Time::now();
00223   last_update_wall_time_ = ros::WallTime::now();
00224 }
00225 
00226 void VisualizationManager::startUpdate()
00227 {
00228   update_timer_ = new QTimer;
00229   connect( update_timer_, SIGNAL( timeout() ), this, SLOT( onUpdate() ));
00230   update_timer_->start( 33 );
00231 
00232   idle_timer_ = new QTimer;
00233   connect( idle_timer_, SIGNAL( timeout() ), this, SLOT( onIdle() ));
00234   idle_timer_->start( 33 );
00235 }
00236 
00237 void createColorMaterial(const std::string& name, const Ogre::ColourValue& color)
00238 {
00239   Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create( name, ROS_PACKAGE_NAME );
00240   mat->setAmbient(color * 0.5f);
00241   mat->setDiffuse(color);
00242   mat->setSelfIllumination(color);
00243   mat->setLightingEnabled(true);
00244   mat->setReceiveShadows(false);
00245 }
00246 
00247 void VisualizationManager::createColorMaterials()
00248 {
00249   createColorMaterial("RVIZ/Red", Ogre::ColourValue(1.0f, 0.0f, 0.0f, 1.0f));
00250   createColorMaterial("RVIZ/Green", Ogre::ColourValue(0.0f, 1.0f, 0.0f, 1.0f));
00251   createColorMaterial("RVIZ/Blue", Ogre::ColourValue(0.0f, 0.0f, 1.0f, 1.0f));
00252   createColorMaterial("RVIZ/Cyan", Ogre::ColourValue(0.0f, 1.0f, 1.0f, 1.0f));
00253 }
00254 
00255 void VisualizationManager::getDisplayNames(S_string& displays)
00256 {
00257   V_DisplayWrapper::iterator vis_it = displays_.begin();
00258   V_DisplayWrapper::iterator vis_end = displays_.end();
00259   for ( ; vis_it != vis_end; ++vis_it )
00260   {
00261     displays.insert((*vis_it)->getName());
00262   }
00263 }
00264 
00265 std::string VisualizationManager::getTargetFrame()
00266 {
00267   if(target_frame_is_fixed_frame_)
00268   {
00269     return FIXED_FRAME_STRING;
00270   }
00271 
00272   return target_frame_;
00273 }
00274 
00275 void VisualizationManager::queueRender()
00276 {
00277 // I believe the QTimer with zero duration (idle_timer_) makes this unnecessary.  The timer is always "awake".
00278 //  if(!render_requested_)
00279 //  {
00280 //    w xWakeUpIdle();
00281 //  }
00282   render_requested_ = 1;
00283 }
00284 
00285 void VisualizationManager::onUpdate()
00286 {
00287   if(disable_update_)
00288   {
00289     return;
00290   }
00291 
00292   disable_update_ = true;
00293 
00294   //process pending mouse events
00295 
00296   std::deque<ViewportMouseEvent> event_queue;
00297   {
00298     boost::mutex::scoped_lock lock(vme_queue_mutex_);
00299     event_queue.swap( vme_queue_ );
00300   }
00301 
00302   std::deque<ViewportMouseEvent>::iterator event_it;
00303 
00304   for ( event_it= event_queue.begin(); event_it!=event_queue.end(); event_it++ )
00305   {
00306     ViewportMouseEvent &vme = *event_it;
00307     int flags = getCurrentTool()->processMouseEvent(vme);
00308 
00309     if( flags & Tool::Render )
00310     {
00311       queueRender();
00312     }
00313 
00314     if( flags & Tool::Finished )
00315     {
00316       setCurrentTool( getDefaultTool() );
00317     }
00318   }
00319 
00320 
00321   ros::WallTime update_start = ros::WallTime::now();
00322 
00323   ros::WallDuration wall_diff = ros::WallTime::now() - last_update_wall_time_;
00324   ros::Duration ros_diff = ros::Time::now() - last_update_ros_time_;
00325   float wall_dt = wall_diff.toSec();
00326   float ros_dt = ros_diff.toSec();
00327 
00328   if(ros_dt < 0.0)
00329   {
00330     resetTime();
00331   }
00332 
00333   frame_manager_->update();
00334 
00335   ros::spinOnce();
00336 
00337   last_update_ros_time_ = ros::Time::now();
00338   last_update_wall_time_ = ros::WallTime::now();
00339 
00340   V_DisplayWrapper::iterator vis_it = displays_.begin();
00341   V_DisplayWrapper::iterator vis_end = displays_.end();
00342   for ( ; vis_it != vis_end; ++vis_it )
00343   {
00344     Display* display = (*vis_it)->getDisplay();
00345 
00346     if( display && display->isEnabled() )
00347     {
00348       display->update( wall_dt, ros_dt );
00349     }
00350   }
00351 
00352   view_controller_->update(wall_dt, ros_dt);
00353 
00354   time_update_timer_ += wall_dt;
00355 
00356   if( time_update_timer_ > 0.1f )
00357   {
00358     time_update_timer_ = 0.0f;
00359 
00360     updateTime();
00361   }
00362 
00363   frame_update_timer_ += wall_dt;
00364 
00365   if(frame_update_timer_ > 1.0f)
00366   {
00367     frame_update_timer_ = 0.0f;
00368 
00369     updateFrames();
00370   }
00371 
00372   selection_manager_->update();
00373 
00374   if(frame_count_ % 6 == 0)
00375   {
00376     property_manager_->update();
00377     tool_property_manager_->update();
00378   }
00379 
00380   current_tool_->update(wall_dt, ros_dt);
00381 
00382   disable_update_ = false;
00383 
00384 // I believe the QTimer with zero duration (idle_timer_) makes this unnecessary.  The timer is always "awake".
00385 //  w xWakeUpIdle();
00386 }
00387 
00388 void VisualizationManager::onIdle()
00389 {
00390   ros::WallTime cur = ros::WallTime::now();
00391   double dt = (cur - last_render_).toSec();
00392 
00393   if(dt > 0.1f)
00394   {
00395     render_requested_ = 1;
00396   }
00397 
00398   // Cap at 60fps
00399   if(render_requested_ && dt > 0.016f)
00400   {
00401     render_requested_ = 0;
00402     last_render_ = cur;
00403     frame_count_++;
00404 
00405     boost::mutex::scoped_lock lock(render_mutex_);
00406 
00407 //    ros::WallTime start = ros::WallTime::now();
00408     ogre_root_->renderOneFrame();
00409 //    ros::WallTime end = ros::WallTime::now();
00410 //    ros::WallDuration d = end - start;
00411 //    ROS_INFO("Render took [%f] msec", d.toSec() * 1000.0f);
00412   }
00413 }
00414 
00415 void VisualizationManager::updateTime()
00416 {
00417   if( ros_time_begin_.isZero() )
00418   {
00419     ros_time_begin_ = ros::Time::now();
00420   }
00421 
00422   ros_time_elapsed_ = ros::Time::now() - ros_time_begin_;
00423 
00424   if( wall_clock_begin_.isZero() )
00425   {
00426     wall_clock_begin_ = ros::WallTime::now();
00427   }
00428 
00429   wall_clock_elapsed_ = ros::WallTime::now() - wall_clock_begin_;
00430 
00431   Q_EMIT timeChanged();
00432 }
00433 
00434 void VisualizationManager::updateFrames()
00435 {
00436   typedef std::vector<std::string> V_string;
00437   V_string frames;
00438   frame_manager_->getTFClient()->getFrameStrings( frames );
00439   std::sort(frames.begin(), frames.end());
00440 
00441   EditEnumPropertyPtr target_prop = target_frame_property_.lock();
00442   EditEnumPropertyPtr fixed_prop = fixed_frame_property_.lock();
00443   StatusPropertyPtr status_prop = status_property_.lock();
00444   ROS_ASSERT(target_prop);
00445   ROS_ASSERT(fixed_prop);
00446   ROS_ASSERT(status_prop);
00447 
00448   if(frames != available_frames_)
00449   {
00450     fixed_prop->clear();
00451 
00452     V_string::iterator it = frames.begin();
00453     V_string::iterator end = frames.end();
00454     for (; it != end; ++it)
00455     {
00456       const std::string& frame = *it;
00457 
00458       if(frame.empty())
00459       {
00460         continue;
00461       }
00462 
00463       fixed_prop->addOption(frame);
00464     }
00465 
00466     available_frames_ = frames;
00467   }
00468 
00469   // Check the fixed frame to see if it's ok
00470   std::string error;
00471   if(frame_manager_->frameHasProblems(fixed_frame_, ros::Time(), error))
00472   {
00473     if(frames.empty())
00474     {
00475       fixed_prop->setToWarn();
00476       std::stringstream ss;
00477       ss << "No tf data.  Actual error: " << error;
00478       status_prop->setStatus(status_levels::Warn, "Fixed Frame", ss.str());
00479     }
00480     else
00481     {
00482       fixed_prop->setToError();
00483       status_prop->setStatus(status_levels::Error, "Fixed Frame", error);
00484     }
00485   }
00486   else
00487   {
00488     fixed_prop->setToOK();
00489     status_prop->setStatus(status_levels::Ok, "Fixed Frame", "OK");
00490   }
00491 
00492   if(frame_manager_->transformHasProblems(target_frame_, ros::Time(), error))
00493   {
00494     target_prop->setToError();
00495     status_prop->setStatus(status_levels::Error, "Target Frame", error);
00496   }
00497   else
00498   {
00499     target_prop->setToOK();
00500     status_prop->setStatus(status_levels::Ok, "Target Frame", "OK");
00501   }
00502 }
00503 
00504 tf::TransformListener* VisualizationManager::getTFClient()
00505 {
00506   return frame_manager_->getTFClient();
00507 }
00508 
00509 void VisualizationManager::resetTime()
00510 {
00511   resetDisplays();
00512   frame_manager_->getTFClient()->clear();
00513 
00514   ros_time_begin_ = ros::Time();
00515   wall_clock_begin_ = ros::WallTime();
00516 
00517   queueRender();
00518 }
00519 
00520 void VisualizationManager::onDisplayCreated(DisplayWrapper* wrapper)
00521 {
00522   Display* display = wrapper->getDisplay();
00523   display->setRenderCallback( boost::bind( &VisualizationManager::queueRender, this ) );
00524   display->setLockRenderCallback( boost::bind( &VisualizationManager::lockRender, this ) );
00525   display->setUnlockRenderCallback( boost::bind( &VisualizationManager::unlockRender, this ) );
00526 
00527   display->setFixedFrame( fixed_frame_ );
00528 }
00529 
00530 bool VisualizationManager::addDisplay(DisplayWrapper* wrapper, bool enabled)
00531 {
00532   if(getDisplayWrapper(wrapper->getName()))
00533   {
00534     ROS_ERROR("Display of name [%s] already exists", wrapper->getName().c_str());
00535     return false;
00536   }
00537 
00538   Q_EMIT displayAdding( wrapper );
00539   displays_.push_back(wrapper);
00540 
00541   connect( wrapper, SIGNAL( displayCreated( DisplayWrapper* )), this, SLOT( onDisplayCreated( DisplayWrapper* )));
00542   wrapper->setPropertyManager( property_manager_, CategoryPropertyWPtr() );
00543   wrapper->createDisplay();
00544 
00545   Q_EMIT displayAdded( wrapper );
00546 
00547   wrapper->setEnabled(enabled);
00548 
00549   return true;
00550 }
00551 
00552 void VisualizationManager::removeDisplay( DisplayWrapper* display )
00553 {
00554   V_DisplayWrapper::iterator it = std::find(displays_.begin(), displays_.end(), display);
00555   ROS_ASSERT( it != displays_.end() );
00556 
00557   Q_EMIT displayRemoving( display );
00558 
00559   displays_.erase( it );
00560 
00561   Q_EMIT displayRemoved( display );
00562 
00563   delete display;
00564 
00565   queueRender();
00566 }
00567 
00568 void VisualizationManager::removeAllDisplays()
00569 {
00570   Q_EMIT displaysRemoving( displays_ );
00571 
00572   while (!displays_.empty())
00573   {
00574     removeDisplay(displays_.back());
00575   }
00576 
00577   Q_EMIT displaysRemoved( V_DisplayWrapper() );
00578 }
00579 
00580 void VisualizationManager::removeDisplay( const std::string& name )
00581 {
00582   DisplayWrapper* display = getDisplayWrapper( name );
00583 
00584   if( !display )
00585   {
00586     return;
00587   }
00588 
00589   removeDisplay( display );
00590 }
00591 
00592 void VisualizationManager::resetDisplays()
00593 {
00594   V_DisplayWrapper::iterator vis_it = displays_.begin();
00595   V_DisplayWrapper::iterator vis_end = displays_.end();
00596   for ( ; vis_it != vis_end; ++vis_it )
00597   {
00598     Display* display = (*vis_it)->getDisplay();
00599 
00600     if(display)
00601     {
00602       display->reset();
00603     }
00604   }
00605 }
00606 
00607 void VisualizationManager::addTool( Tool* tool )
00608 {
00609   tools_.push_back( tool );
00610 
00611   Q_EMIT toolAdded( tool );
00612 }
00613 
00614 void VisualizationManager::setCurrentTool( Tool* tool )
00615 {
00616   if( current_tool_ )
00617   {
00618     current_tool_->deactivate();
00619   }
00620 
00621   current_tool_ = tool;
00622   current_tool_->activate();
00623 
00624   Q_EMIT toolChanged( tool );
00625 }
00626 
00627 void VisualizationManager::setDefaultTool( Tool* tool )
00628 {
00629   default_tool_ = tool;
00630 }
00631 
00632 Tool* VisualizationManager::getTool( int index )
00633 {
00634   ROS_ASSERT( index >= 0 );
00635   ROS_ASSERT( index < (int)tools_.size() );
00636 
00637   return tools_[ index ];
00638 }
00639 
00640 DisplayWrapper* VisualizationManager::getDisplayWrapper( const std::string& name )
00641 {
00642   V_DisplayWrapper::iterator vis_it = displays_.begin();
00643   V_DisplayWrapper::iterator vis_end = displays_.end();
00644   for ( ; vis_it != vis_end; ++vis_it )
00645   {
00646     DisplayWrapper* wrapper = *vis_it;
00647     if( wrapper->getName() == name )
00648     {
00649       return wrapper;
00650     }
00651   }
00652 
00653   return 0;
00654 }
00655 
00656 DisplayWrapper* VisualizationManager::getDisplayWrapper( Display* display )
00657 {
00658   V_DisplayWrapper::iterator vis_it = displays_.begin();
00659   V_DisplayWrapper::iterator vis_end = displays_.end();
00660   for ( ; vis_it != vis_end; ++vis_it )
00661   {
00662     DisplayWrapper* wrapper = *vis_it;
00663     if( wrapper->getDisplay() == display )
00664     {
00665       return wrapper;
00666     }
00667   }
00668 
00669   return 0;
00670 }
00671 
00672 // Make a map from class name (like "rviz::GridDisplay") to lookup
00673 // name (like "rviz/Grid").  This is here because of a mismatch
00674 // between the old rviz plugin system and pluginlib (the new one).
00675 void makeClassNameToLookupNameMap( pluginlib::ClassLoader<Display>* class_loader,
00676                                    std::map<std::string, std::string>* map )
00677 {
00678   std::vector<std::string> lookup_names = class_loader->getDeclaredClasses();
00679 
00680   std::vector<std::string>::const_iterator ni;
00681   for( ni = lookup_names.begin(); ni != lookup_names.end(); ni++ )
00682   {
00683     std::string class_name = class_loader->getClassType( (*ni) );
00684     (*map)[ class_name ] = (*ni);
00685   }
00686 }
00687 
00688 void VisualizationManager::loadDisplayConfig( const boost::shared_ptr<Config>& config, const StatusCallback& cb )
00689 {
00690   disable_update_ = true;
00691 
00692   if(cb)
00693   {
00694     cb("Creating displays");
00695   }
00696 
00697   std::map<std::string, std::string> class_name_to_lookup_name;
00698   makeClassNameToLookupNameMap( display_class_loader_, &class_name_to_lookup_name );
00699 
00700   int i = 0;
00701   while (1)
00702   {
00703     std::string error = "";
00704 
00705     std::stringstream name, class_name, type;
00706     name << "Display" << i << "/Name";
00707     class_name << "Display" << i << "/ClassName";
00708     type << "Display" << i << "/Type";
00709 
00710     std::string vis_name, vis_class, vis_type, lookup_name;
00711     if(!config->get(name.str(), &vis_name))
00712     {
00713       break;
00714     }
00715 
00716     if(!config->get(class_name.str(), &vis_class))
00717     {
00718       if( config->get( type.str(), &vis_type ))
00719       {
00720         error = "This config file uses an old format with 'Type=" + vis_type +
00721           "'.  The new format uses the C++ class name, for example 'ClassName=rviz::GridDisplay' for a Grid display.";
00722         lookup_name = vis_type;
00723       }
00724       else
00725       {
00726         error = "This display has no 'ClassName' entry, so it cannot be created.";
00727       }
00728     }
00729 
00730     if( error == "" )
00731     {
00732       // TODO: should just read class-lookup-name from config file, but
00733       // that would not be consistent with the old (v1.6) config file format.
00734       lookup_name = class_name_to_lookup_name[ vis_class ];
00735       if( lookup_name == "" )
00736       {
00737         lookup_name = vis_class;
00738         error = "The class named '" + vis_class + "' was not found in rviz or any other plugin.";
00739       }
00740     }
00741 
00742     // Call createDisplay() even if there was an error so we can show
00743     // the name and the error in the Displays panel.
00744     DisplayWrapper* wrapper = createDisplay( lookup_name, vis_name, false);
00745     if( wrapper && error != "")
00746     {
00747       CategoryPropertyWPtr cat = wrapper->getCategory();
00748       setPropertyHelpText( cat, error );
00749     }
00750 
00751     ++i;
00752   }
00753 
00754   property_manager_->load( config, cb );
00755   tool_property_manager_->load( config, cb );
00756 
00757   std::string camera_type;
00758   if(config->get(CAMERA_TYPE, &camera_type))
00759   {
00760     if(setCurrentViewControllerType(camera_type))
00761     {
00762       std::string camera_config;
00763       if(config->get(CAMERA_CONFIG, &camera_config))
00764       {
00765         view_controller_->fromString(camera_config);
00766       }
00767     }
00768   }
00769 
00770   Q_EMIT displaysConfigLoaded( config );
00771 
00772   disable_update_ = false;
00773 }
00774 
00775 void VisualizationManager::saveDisplayConfig( const boost::shared_ptr<Config>& config )
00776 {
00777   int i = 0;
00778   V_DisplayWrapper::iterator vis_it = displays_.begin();
00779   V_DisplayWrapper::iterator vis_end = displays_.end();
00780   for ( ; vis_it != vis_end; ++vis_it, ++i )
00781   {
00782     DisplayWrapper* wrapper = *vis_it;
00783 
00784     std::stringstream name, class_name_key;
00785     name << "Display" << i << "/Name";
00786     class_name_key << "Display" << i << "/ClassName";
00787     config->set( name.str(), wrapper->getName() );
00788     std::string lookup_name = wrapper->getClassLookupName();
00789     // TODO: should just write class-lookup-name to config file, but
00790     // that would not be consistent with the old (v1.6) config file format.
00791     std::string class_name = display_class_loader_->getClassType( lookup_name );
00792     config->set( class_name_key.str(), class_name );
00793   }
00794 
00795   property_manager_->save( config );
00796   tool_property_manager_->save( config );
00797 
00798   if(view_controller_)
00799   {
00800     config->set(CAMERA_TYPE, view_controller_->getClassName());
00801     config->set(CAMERA_CONFIG, view_controller_->toString());
00802   }
00803 
00804   Q_EMIT displaysConfigSaved( config );
00805 }
00806 
00807 DisplayWrapper* VisualizationManager::createDisplay( const std::string& class_lookup_name,
00808                                                      const std::string& name,
00809                                                      bool enabled )
00810 {
00811 //  PluginPtr plugin = plugin_manager_->getPluginByPackage(package);
00812 //  if(!plugin)
00813 //  {
00814 //    ROS_ERROR("Package [%s] does not have any plugins loaded available, for display of type [%s], and name [%s]", package.c_str(), class_name.c_str(), name.c_str());
00815 //  }
00816 
00817   DisplayWrapper* wrapper = new DisplayWrapper( class_lookup_name, display_class_loader_, name, this);
00818   if(addDisplay(wrapper, enabled))
00819   {
00820     return wrapper;
00821   }
00822   else
00823   {
00824     delete wrapper;
00825     return 0;
00826   }
00827 }
00828 
00829 void VisualizationManager::setTargetFrame( const std::string& _frame )
00830 {
00831   target_frame_is_fixed_frame_ = false;
00832   std::string frame = _frame;
00833   if(frame == FIXED_FRAME_STRING)
00834   {
00835     frame = fixed_frame_;
00836     target_frame_is_fixed_frame_ = true;
00837   }
00838 
00839   std::string remapped_name = frame_manager_->getTFClient()->resolve(frame);
00840 
00841   if(target_frame_ == remapped_name)
00842   {
00843     return;
00844   }
00845 
00846   target_frame_ = remapped_name;
00847 
00848   propertyChanged(target_frame_property_);
00849 
00850   if(view_controller_)
00851   {
00852     view_controller_->setTargetFrame(target_frame_);
00853   }
00854 }
00855 
00856 void VisualizationManager::setFixedFrame( const std::string& frame )
00857 {
00858   std::string remapped_name = frame_manager_->getTFClient()->resolve(frame);
00859 
00860   if(fixed_frame_ == remapped_name)
00861   {
00862     return;
00863   }
00864 
00865   fixed_frame_ = remapped_name;
00866 
00867   frame_manager_->setFixedFrame(fixed_frame_);
00868 
00869   V_DisplayWrapper::iterator it = displays_.begin();
00870   V_DisplayWrapper::iterator end = displays_.end();
00871   for ( ; it != end; ++it )
00872   {
00873     Display* display = (*it)->getDisplay();
00874 
00875     if(display)
00876     {
00877       display->setFixedFrame(fixed_frame_);
00878     }
00879   }
00880 
00881   propertyChanged(fixed_frame_property_);
00882 
00883   if(target_frame_is_fixed_frame_)
00884   {
00885     setTargetFrame(FIXED_FRAME_STRING);
00886   }
00887 }
00888 
00889 bool VisualizationManager::isValidDisplay(const DisplayWrapper* display)
00890 {
00891   V_DisplayWrapper::iterator it = displays_.begin();
00892   V_DisplayWrapper::iterator end = displays_.end();
00893   for ( ; it != end; ++it )
00894   {
00895     if(display == (*it))
00896     {
00897       return true;
00898     }
00899   }
00900 
00901   return false;
00902 }
00903 
00904 double VisualizationManager::getWallClock()
00905 {
00906   return ros::WallTime::now().toSec();
00907 }
00908 
00909 double VisualizationManager::getROSTime()
00910 {
00911   return (ros_time_begin_ + ros_time_elapsed_).toSec();
00912 }
00913 
00914 double VisualizationManager::getWallClockElapsed()
00915 {
00916   return wall_clock_elapsed_.toSec();
00917 }
00918 
00919 double VisualizationManager::getROSTimeElapsed()
00920 {
00921   return ros_time_elapsed_.toSec();
00922 }
00923 
00924 void VisualizationManager::setBackgroundColor(const Color& c)
00925 {
00926   background_color_ = c;
00927 
00928   render_panel_->setBackgroundColor(Ogre::ColourValue(c.r_, c.g_, c.b_, 1.0f));
00929 
00930   propertyChanged(background_color_property_);
00931 
00932   queueRender();
00933 }
00934 
00935 const Color& VisualizationManager::getBackgroundColor()
00936 {
00937   return background_color_;
00938 }
00939 
00940 void VisualizationManager::handleChar( QKeyEvent* event, RenderPanel* panel )
00941 {
00942   if( event->key() == Qt::Key_Escape )
00943   {
00944     setCurrentTool( getDefaultTool() );
00945 
00946     return;
00947   }
00948   getCurrentTool()->processKeyEvent( event, panel );
00949 }
00950 
00951 void VisualizationManager::addViewController(const std::string& class_name, const std::string& name)
00952 {
00953   Q_EMIT viewControllerTypeAdded( class_name, name );
00954 }
00955 
00956 bool VisualizationManager::setCurrentViewControllerType(const std::string& type)
00957 {
00958   if(view_controller_ && (view_controller_->getClassName() == type || view_controller_->getName() == type))
00959   {
00960     return true;
00961   }
00962 
00963   bool found = true;
00964   // hack hack hack hack until this becomes truly plugin based
00965   if(type == "rviz::OrbitViewController" || type == "Orbit")
00966   {
00967     view_controller_ = new OrbitViewController(this, "Orbit",target_scene_node_);
00968   }
00969   else if(type == "rviz::XYOrbitViewController" || type == "XYOrbit" ||
00970            type == "rviz::SimpleOrbitViewController" || type == "SimpleOrbit" /* the old class name */) 
00971   {
00972     view_controller_ = new XYOrbitViewController(this, "XYOrbit",target_scene_node_);
00973   }
00974   else if(type == "rviz::FPSViewController" || type == "FPS")
00975   {
00976     view_controller_ = new FPSViewController(this, "FPS",target_scene_node_);
00977   }
00978   else if(type == "rviz::FixedOrientationOrthoViewController" || type == "TopDownOrtho" || type == "Top-down Orthographic")
00979   {
00980     view_controller_ = new FixedOrientationOrthoViewController(this, "TopDownOrtho",target_scene_node_);
00981   }
00982   else if(!view_controller_)
00983   {
00984     view_controller_ = new OrbitViewController(this, "Orbit",target_scene_node_);
00985   }
00986   else
00987   {
00988     found = false;
00989   }
00990 
00991   if(found)
00992   {
00993     // RenderPanel::setViewController() deletes the old
00994     // ViewController, so don't do it here or it will crash!
00995     render_panel_->setViewController(view_controller_);
00996     view_controller_->setTargetFrame( target_frame_ );
00997     connect( view_controller_, SIGNAL( configChanged() ), this, SIGNAL( configChanged() ));
00998     Q_EMIT viewControllerChanged( view_controller_ );
00999     Q_EMIT configChanged();
01000   }
01001 
01002   return found;
01003 }
01004 
01005 std::string VisualizationManager::getCurrentViewControllerType()
01006 {
01007   return view_controller_->getClassName();
01008 }
01009 
01010 void VisualizationManager::handleMouseEvent(ViewportMouseEvent& vme)
01011 {
01012   boost::mutex::scoped_lock lock( vme_queue_mutex_ );
01013   vme_queue_.push_back(vme);
01014 }
01015 
01016 void VisualizationManager::threadedQueueThreadFunc()
01017 {
01018   while (!shutting_down_)
01019   {
01020     threaded_queue_.callOne(ros::WallDuration(0.1));
01021   }
01022 }
01023 
01024 void VisualizationManager::onPluginUnloading(const PluginStatus& status)
01025 {
01026   // We need to force an update of the property manager here, because the memory allocated for properties is done inside their shared objects.
01027   // If a plugin is unloaded and then later the update is called, the weak pointers can cause crashes, because the objects they point to are
01028   // no longer valid.
01029   property_manager_->update();
01030 }
01031 
01032 void VisualizationManager::notifyConfigChanged()
01033 {
01034   Q_EMIT configChanged();
01035 }
01036 
01037 } // namespace rviz


rviz
Author(s): Dave Hershberger, Josh Faust
autogenerated on Mon Jan 6 2014 11:54:33