00001 #include "nxt_ultrasonic_display.h"
00002 #include "rviz/visualization_manager.h"
00003 #include "rviz/properties/property.h"
00004 #include "rviz/properties/property_manager.h"
00005 #include "rviz/common.h"
00006 #include "rviz/frame_manager.h"
00007 #include "rviz/validate_floats.h"
00008
00009 #include <tf/transform_listener.h>
00010
00011 #include <ogre_tools/shape.h>
00012
00013 #include <OGRE/OgreSceneNode.h>
00014 #include <OGRE/OgreSceneManager.h>
00015
00016 namespace nxt_rviz_plugin
00017 {
00018 NXTUltrasonicDisplay::NXTUltrasonicDisplay( const std::string& name, rviz::VisualizationManager* manager )
00019 : Display( name, manager )
00020 , color_( 0.1f, 1.0f, 0.0f )
00021 , messages_received_(0)
00022 , tf_filter_(*manager->getTFClient(), "", 10, update_nh_)
00023 {
00024 scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00025
00026 cone_ = new ogre_tools::Shape(ogre_tools::Shape::Cone, vis_manager_->getSceneManager(), scene_node_);
00027
00028 scene_node_->setVisible( false );
00029
00030 setAlpha( 0.5f );
00031 Ogre::Vector3 scale( 0, 0, 0);
00032 rviz::scaleRobotToOgre( scale );
00033 cone_->setScale(scale);
00034 cone_->setColor(color_.r_, color_.g_, color_.b_, alpha_);
00035
00036 tf_filter_.connectInput(sub_);
00037 tf_filter_.registerCallback(boost::bind(&NXTUltrasonicDisplay::incomingMessage, this, _1));
00038 vis_manager_->getFrameManager()->registerFilterForTransformStatusCheck(tf_filter_, this);
00039 }
00040
00041 NXTUltrasonicDisplay::~NXTUltrasonicDisplay()
00042 {
00043 unsubscribe();
00044 clear();
00045 delete cone_;
00046 }
00047
00048 void NXTUltrasonicDisplay::clear()
00049 {
00050
00051 messages_received_ = 0;
00052 setStatus(rviz::status_levels::Warn, "Topic", "No messages received");
00053 }
00054
00055 void NXTUltrasonicDisplay::setTopic( const std::string& topic )
00056 {
00057 unsubscribe();
00058
00059 topic_ = topic;
00060
00061 subscribe();
00062
00063 propertyChanged(topic_property_);
00064
00065 causeRender();
00066 }
00067
00068 void NXTUltrasonicDisplay::setColor( const rviz::Color& color )
00069 {
00070 color_ = color;
00071
00072 propertyChanged(color_property_);
00073
00074 processMessage(current_message_);
00075 causeRender();
00076 }
00077
00078 void NXTUltrasonicDisplay::setAlpha( float alpha )
00079 {
00080 alpha_ = alpha;
00081
00082 propertyChanged(alpha_property_);
00083
00084 processMessage(current_message_);
00085 causeRender();
00086 }
00087
00088 void NXTUltrasonicDisplay::subscribe()
00089 {
00090 if ( !isEnabled() )
00091 {
00092 return;
00093 }
00094
00095 sub_.subscribe(update_nh_, topic_, 10);
00096 }
00097
00098 void NXTUltrasonicDisplay::unsubscribe()
00099 {
00100 sub_.unsubscribe();
00101 }
00102
00103 void NXTUltrasonicDisplay::onEnable()
00104 {
00105 scene_node_->setVisible( true );
00106 subscribe();
00107 }
00108
00109 void NXTUltrasonicDisplay::onDisable()
00110 {
00111 unsubscribe();
00112 clear();
00113 scene_node_->setVisible( false );
00114 }
00115
00116 void NXTUltrasonicDisplay::fixedFrameChanged()
00117 {
00118 clear();
00119
00120 tf_filter_.setTargetFrame( fixed_frame_ );
00121 }
00122
00123 void NXTUltrasonicDisplay::update(float wall_dt, float ros_dt)
00124 {
00125 }
00126
00127
00128 void NXTUltrasonicDisplay::processMessage(const nxt_msgs::Range::ConstPtr& msg)
00129 {
00130 if (!msg)
00131 {
00132 return;
00133 }
00134
00135 ++messages_received_;
00136
00137 {
00138 std::stringstream ss;
00139 ss << messages_received_ << " messages received";
00140 setStatus(rviz::status_levels::Ok, "Topic", ss.str());
00141 }
00142
00143 Ogre::Vector3 position;
00144 Ogre::Quaternion orientation;
00145 geometry_msgs::Pose pose;
00146 pose.position.z = pose.position.y = 0;
00147 pose.position.x = msg->range/2;
00148 pose.orientation.x = 0.707;
00149 pose.orientation.z = -0.707;
00150 if (!vis_manager_->getFrameManager()->transform(msg->header.frame_id,msg->header.stamp,pose, position, orientation, true))
00151 {
00152 ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'", msg->header.frame_id.c_str(), fixed_frame_.c_str() );
00153 }
00154
00155 cone_->setPosition(position);
00156 cone_->setOrientation(orientation);
00157 Ogre::Vector3 scale( sin(msg->spread_angle) * msg->range, sin(msg->spread_angle) * msg->range , msg->range);
00158 rviz::scaleRobotToOgre( scale );
00159 cone_->setScale(scale);
00160 cone_->setColor(color_.r_, color_.g_, color_.b_, alpha_);
00161
00162 }
00163
00164 void NXTUltrasonicDisplay::incomingMessage(const nxt_msgs::Range::ConstPtr& msg)
00165 {
00166 processMessage(msg);
00167 }
00168
00169 void NXTUltrasonicDisplay::reset()
00170 {
00171 Display::reset();
00172 clear();
00173 }
00174
00175 void NXTUltrasonicDisplay::createProperties()
00176 {
00177 topic_property_ = property_manager_->createProperty<rviz::ROSTopicStringProperty>( "Topic", property_prefix_, boost::bind( &NXTUltrasonicDisplay::getTopic, this ),
00178 boost::bind( &NXTUltrasonicDisplay::setTopic, this, _1 ), parent_category_, this );
00179 setPropertyHelpText(topic_property_, "nxt_msgs::Range topic to subscribe to.");
00180 rviz::ROSTopicStringPropertyPtr topic_prop = topic_property_.lock();
00181 topic_prop->setMessageType(ros::message_traits::datatype<nxt_msgs::Range>());
00182 color_property_ = property_manager_->createProperty<rviz::ColorProperty>( "Color", property_prefix_, boost::bind( &NXTUltrasonicDisplay::getColor, this ),
00183 boost::bind( &NXTUltrasonicDisplay::setColor, this, _1 ), parent_category_, this );
00184 setPropertyHelpText(color_property_, "Color to draw the range.");
00185 alpha_property_ = property_manager_->createProperty<rviz::FloatProperty>( "Alpha", property_prefix_, boost::bind( &NXTUltrasonicDisplay::getAlpha, this ),
00186 boost::bind( &NXTUltrasonicDisplay::setAlpha, this, _1 ), parent_category_, this );
00187 setPropertyHelpText(alpha_property_, "Amount of transparency to apply to the range.");
00188 }
00189
00190 const char* NXTUltrasonicDisplay::getDescription()
00191 {
00192 return "Displays data from a nxt_msgs::Range message as a cone.";
00193 }
00194 }