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 "laser_scan_display.h"
00031 #include "rviz/visualization_manager.h"
00032 #include "rviz/properties/property.h"
00033 #include "rviz/properties/property_manager.h"
00034 #include "rviz/frame_manager.h"
00035
00036 #include "ogre_tools/point_cloud.h"
00037
00038 #include <tf/transform_listener.h>
00039 #include <sensor_msgs/PointCloud.h>
00040 #include <laser_geometry/laser_geometry.h>
00041
00042 #include <OGRE/OgreSceneNode.h>
00043 #include <OGRE/OgreSceneManager.h>
00044
00045 namespace rviz
00046 {
00047
00048 LaserScanDisplay::LaserScanDisplay( const std::string& name, VisualizationManager* manager )
00049 : PointCloudBase( name, manager )
00050 , tf_filter_(*manager->getTFClient(), "", 10, threaded_nh_)
00051 {
00052 projector_ = new laser_geometry::LaserProjection();
00053
00054 tf_filter_.connectInput(sub_);
00055 tf_filter_.registerCallback(boost::bind(&LaserScanDisplay::incomingScanCallback, this, _1));
00056 vis_manager_->getFrameManager()->registerFilterForTransformStatusCheck(tf_filter_, this);
00057 }
00058
00059 LaserScanDisplay::~LaserScanDisplay()
00060 {
00061 unsubscribe();
00062 tf_filter_.clear();
00063 delete projector_;
00064 }
00065
00066 void LaserScanDisplay::setTopic( const std::string& topic )
00067 {
00068 unsubscribe();
00069
00070 topic_ = topic;
00071 reset();
00072
00073 subscribe();
00074
00075 propertyChanged(topic_property_);
00076
00077 causeRender();
00078 }
00079
00080
00081 void LaserScanDisplay::onEnable()
00082 {
00083 PointCloudBase::onEnable();
00084
00085 subscribe();
00086 }
00087
00088 void LaserScanDisplay::onDisable()
00089 {
00090 unsubscribe();
00091
00092 PointCloudBase::onDisable();
00093 }
00094
00095 void LaserScanDisplay::subscribe()
00096 {
00097 if ( !isEnabled() )
00098 {
00099 return;
00100 }
00101
00102 sub_.subscribe(threaded_nh_, topic_, 2);
00103 }
00104
00105 void LaserScanDisplay::unsubscribe()
00106 {
00107 sub_.unsubscribe();
00108 tf_filter_.clear();
00109 }
00110
00111
00112 void LaserScanDisplay::incomingScanCallback(const sensor_msgs::LaserScan::ConstPtr& scan)
00113 {
00114 sensor_msgs::PointCloudPtr cloud(new sensor_msgs::PointCloud);
00115
00116 std::string frame_id = scan->header.frame_id;
00117
00118
00119 ros::Duration tolerance(scan->time_increment * scan->ranges.size());
00120 if (tolerance > filter_tolerance_)
00121 {
00122 filter_tolerance_ = tolerance;
00123 tf_filter_.setTolerance(filter_tolerance_);
00124 }
00125
00126 try
00127 {
00128 projector_->transformLaserScanToPointCloud(fixed_frame_, *scan, *cloud , *vis_manager_->getTFClient(), laser_geometry::channel_option::Intensity);
00129 }
00130 catch (tf::TransformException& e)
00131 {
00132 ROS_DEBUG("LaserScan [%s]: failed to transform scan: %s. This message should not repeat (tolerance should now be set on our tf::MessageFilter).", name_.c_str(), e.what());
00133 return;
00134 }
00135 addMessage(cloud);
00136 }
00137
00138 void LaserScanDisplay::targetFrameChanged()
00139 {
00140 }
00141
00142 void LaserScanDisplay::fixedFrameChanged()
00143 {
00144 tf_filter_.setTargetFrame(fixed_frame_);
00145
00146 PointCloudBase::fixedFrameChanged();
00147 }
00148
00149 void LaserScanDisplay::createProperties()
00150 {
00151 topic_property_ = property_manager_->createProperty<ROSTopicStringProperty>( "Topic", property_prefix_, boost::bind( &LaserScanDisplay::getTopic, this ),
00152 boost::bind( &LaserScanDisplay::setTopic, this, _1 ), parent_category_, this );
00153 setPropertyHelpText(topic_property_, "sensor_msgs::LaserScan topic to subscribe to.");
00154 ROSTopicStringPropertyPtr str_prop = topic_property_.lock();
00155 str_prop->addLegacyName("Scan Topic");
00156 str_prop->setMessageType(ros::message_traits::datatype<sensor_msgs::LaserScan>());
00157
00158 PointCloudBase::createProperties();
00159 }
00160
00161 }