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