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 "image_display.h"
00031 #include "rviz/visualization_manager.h"
00032 #include "rviz/render_panel.h"
00033 #include "rviz/properties/property.h"
00034 #include "rviz/properties/property_manager.h"
00035 #include "rviz/window_manager_interface.h"
00036 #include "rviz/frame_manager.h"
00037 #include "rviz/validate_floats.h"
00038
00039 #include <tf/transform_listener.h>
00040
00041 #include <boost/bind.hpp>
00042
00043 #include <ogre_tools/axes.h>
00044
00045 #include <OGRE/OgreSceneNode.h>
00046 #include <OGRE/OgreSceneManager.h>
00047 #include <OGRE/OgreRectangle2D.h>
00048 #include <OGRE/OgreMaterialManager.h>
00049 #include <OGRE/OgreTextureManager.h>
00050 #include <OGRE/OgreViewport.h>
00051 #include <OGRE/OgreRenderWindow.h>
00052 #include <OGRE/OgreManualObject.h>
00053 #include <OGRE/OgreRoot.h>
00054 #include <OGRE/OgreRenderSystem.h>
00055
00056 #include <wx/frame.h>
00057
00058 namespace rviz
00059 {
00060
00061 ImageDisplay::ImageDisplay( const std::string& name, VisualizationManager* manager )
00062 : Display( name, manager )
00063 , transport_("raw")
00064 , texture_(update_nh_)
00065 , frame_(0)
00066 {
00067 {
00068 static uint32_t count = 0;
00069 std::stringstream ss;
00070 ss << "ImageDisplay" << count++;
00071 scene_manager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, ss.str());
00072 }
00073
00074 scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00075
00076 {
00077 static int count = 0;
00078 std::stringstream ss;
00079 ss << "ImageDisplayObject" << count++;
00080
00081 screen_rect_ = new Ogre::Rectangle2D(true);
00082 screen_rect_->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - 1);
00083 screen_rect_->setCorners(-1.0f, 1.0f, 1.0f, -1.0f);
00084
00085 ss << "Material";
00086 material_ = Ogre::MaterialManager::getSingleton().create( ss.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
00087 material_->setSceneBlending( Ogre::SBT_REPLACE );
00088 material_->setDepthWriteEnabled(false);
00089 material_->setReceiveShadows(false);
00090 material_->setDepthCheckEnabled(false);
00091
00092 material_->getTechnique(0)->setLightingEnabled(false);
00093 Ogre::TextureUnitState* tu = material_->getTechnique(0)->getPass(0)->createTextureUnitState();
00094 tu->setTextureName(texture_.getTexture()->getName());
00095 tu->setTextureFiltering( Ogre::TFO_NONE );
00096
00097 material_->setCullingMode(Ogre::CULL_NONE);
00098 Ogre::AxisAlignedBox aabInf;
00099 aabInf.setInfinite();
00100 screen_rect_->setBoundingBox(aabInf);
00101 screen_rect_->setMaterial(material_->getName());
00102 scene_node_->attachObject(screen_rect_);
00103
00104 }
00105
00106 wxWindow* parent = 0;
00107
00108 WindowManagerInterface* wm = vis_manager_->getWindowManager();
00109 if (wm)
00110 {
00111 parent = wm->getParentWindow();
00112 }
00113 else
00114 {
00115 frame_ = new wxFrame(0, wxID_ANY, wxString::FromAscii(name.c_str()), wxDefaultPosition, wxDefaultSize, wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER | wxCAPTION | wxCLIP_CHILDREN);
00116 parent = frame_;
00117 }
00118
00119 render_panel_ = new RenderPanel(parent, false, this);
00120 render_panel_->SetSize(wxSize(640, 480));
00121 if (wm)
00122 {
00123 wm->addPane(name, render_panel_);
00124 }
00125
00126 render_panel_->createRenderWindow();
00127
00128 render_panel_->initialize(scene_manager_, vis_manager_);
00129
00130 render_panel_->setAutoRender(false);
00131 render_panel_->getViewport()->setOverlaysEnabled(false);
00132 render_panel_->getViewport()->setClearEveryFrame(true);
00133 render_panel_->getRenderWindow()->setActive(false);
00134 render_panel_->getRenderWindow()->setAutoUpdated(false);
00135 render_panel_->getCamera()->setNearClipDistance( 0.01f );
00136 }
00137
00138 ImageDisplay::~ImageDisplay()
00139 {
00140 unsubscribe();
00141
00142 if (frame_)
00143 {
00144 frame_->Destroy();
00145 }
00146 else
00147 {
00148 WindowManagerInterface* wm = vis_manager_->getWindowManager();
00149 wm->removePane(render_panel_);
00150 render_panel_->Destroy();
00151 }
00152
00153 delete screen_rect_;
00154
00155 scene_node_->getParentSceneNode()->removeAndDestroyChild(scene_node_->getName());
00156 }
00157
00158 void ImageDisplay::onEnable()
00159 {
00160 subscribe();
00161
00162 if (frame_)
00163 {
00164 frame_->Show(true);
00165 }
00166 else
00167 {
00168 WindowManagerInterface* wm = vis_manager_->getWindowManager();
00169 wm->showPane(render_panel_);
00170 }
00171
00172 render_panel_->getRenderWindow()->setActive(true);
00173 }
00174
00175 void ImageDisplay::onDisable()
00176 {
00177 render_panel_->getRenderWindow()->setActive(false);
00178
00179 if (frame_)
00180 {
00181 frame_->Show(false);
00182 }
00183 else
00184 {
00185 WindowManagerInterface* wm = vis_manager_->getWindowManager();
00186 wm->closePane(render_panel_);
00187 }
00188
00189 unsubscribe();
00190
00191 clear();
00192 }
00193
00194 void ImageDisplay::subscribe()
00195 {
00196 if ( !isEnabled() )
00197 {
00198 return;
00199 }
00200
00201 texture_.setTopic(topic_);
00202 }
00203
00204 void ImageDisplay::unsubscribe()
00205 {
00206 texture_.setTopic("");
00207 }
00208
00209 void ImageDisplay::setTopic( const std::string& topic )
00210 {
00211 unsubscribe();
00212
00213 topic_ = topic;
00214 clear();
00215
00216 subscribe();
00217
00218 propertyChanged(topic_property_);
00219 }
00220
00221 void ImageDisplay::setTransport(const std::string& transport)
00222 {
00223 transport_ = transport;
00224
00225 texture_.setTransportType(transport);
00226
00227 propertyChanged(transport_property_);
00228 }
00229
00230 void ImageDisplay::clear()
00231 {
00232 texture_.clear();
00233
00234 setStatus(status_levels::Warn, "Image", "No Image received");
00235
00236 render_panel_->getCamera()->setPosition(Ogre::Vector3(999999, 999999, 999999));
00237 }
00238
00239 void ImageDisplay::updateStatus()
00240 {
00241 if (texture_.getImageCount() == 0)
00242 {
00243 setStatus(status_levels::Warn, "Image", "No image received");
00244 }
00245 else
00246 {
00247 std::stringstream ss;
00248 ss << texture_.getImageCount() << " images received";
00249 setStatus(status_levels::Ok, "Image", ss.str());
00250 }
00251 }
00252
00253 void ImageDisplay::update(float wall_dt, float ros_dt)
00254 {
00255 updateStatus();
00256
00257 try
00258 {
00259 texture_.update();
00260
00261
00262 float win_width = render_panel_->getViewport()->getActualWidth();
00263 float win_height = render_panel_->getViewport()->getActualHeight();
00264
00265 float img_width = texture_.getWidth();
00266 float img_height = texture_.getHeight();
00267
00268 if ( img_width != 0 && img_height != 0 && win_width !=0 && win_height != 0 )
00269 {
00270 float img_aspect = img_width / img_height;
00271 float win_aspect = win_width / win_height;
00272
00273 if ( img_aspect > win_aspect )
00274 {
00275 screen_rect_->setCorners(-1.0f, 1.0f * win_aspect/img_aspect, 1.0f, -1.0f * win_aspect/img_aspect, false);
00276 }
00277 else
00278 {
00279 screen_rect_->setCorners(-1.0f * img_aspect/win_aspect, 1.0f, 1.0f * img_aspect/win_aspect, -1.0f, false);
00280 }
00281 }
00282
00283 render_panel_->getRenderWindow()->update();
00284 }
00285 catch (UnsupportedImageEncoding& e)
00286 {
00287 setStatus(status_levels::Error, "Image", e.what());
00288 }
00289 }
00290
00291 void ImageDisplay::onTransportEnumOptions(V_string& choices)
00292 {
00293 texture_.getAvailableTransportTypes(choices);
00294 }
00295
00296 void ImageDisplay::createProperties()
00297 {
00298 topic_property_ = property_manager_->createProperty<ROSTopicStringProperty>( "Image Topic", property_prefix_, boost::bind( &ImageDisplay::getTopic, this ),
00299 boost::bind( &ImageDisplay::setTopic, this, _1 ), parent_category_, this );
00300 setPropertyHelpText(topic_property_, "sensor_msgs::Image topic to subscribe to.");
00301 ROSTopicStringPropertyPtr topic_prop = topic_property_.lock();
00302 topic_prop->setMessageType(ros::message_traits::datatype<sensor_msgs::Image>());
00303
00304 transport_property_ = property_manager_->createProperty<EditEnumProperty>("Transport Hint", property_prefix_, boost::bind(&ImageDisplay::getTransport, this),
00305 boost::bind(&ImageDisplay::setTransport, this, _1), parent_category_, this);
00306 EditEnumPropertyPtr ee_prop = transport_property_.lock();
00307 ee_prop->setOptionCallback(boost::bind(&ImageDisplay::onTransportEnumOptions, this, _1));
00308 }
00309
00310 void ImageDisplay::fixedFrameChanged()
00311 {
00312 }
00313
00314 void ImageDisplay::targetFrameChanged()
00315 {
00316
00317 }
00318
00319 void ImageDisplay::reset()
00320 {
00321 Display::reset();
00322
00323 clear();
00324 }
00325
00326 }