Go to the documentation of this file.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
00031
00032
00033
00034
00035
00036 #include <ros/ros.h>
00037
00038
00039 #include "laser_assembler/AssembleScans2.h"
00040
00041
00042 #include "sensor_msgs/PointCloud2.h"
00043 #include "sensor_msgs/JointState.h"
00044
00045 #include <tf_conversions/tf_eigen.h>
00046 #include <tf/transform_listener.h>
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 namespace spin_laser_snapshotter
00058 {
00059
00060 class SpinLaserSnapshotter
00061 {
00062
00063 public:
00064 ros::NodeHandle n_;
00065 ros::NodeHandle private_ns_;
00066 ros::Publisher pub_;
00067 ros::Subscriber sub_;
00068
00069 ros::Time prev_signal_;
00070 double prev_angle_;
00071
00072 bool first_time_;
00073 bool negative_direction_;
00074 int num_skips_;
00075 int num_skips_left_;
00076 double rate_;
00077 std::string fixed_frame_;
00078 std::string spindle_frame_;
00079 std::string motor_frame_;
00080 tf::TransformListener* listener_;
00081 ros::Timer timer_;
00082 SpinLaserSnapshotter() : private_ns_("~")
00083 {
00084 prev_signal_.fromNSec(0);
00085
00086 pub_ = n_.advertise<sensor_msgs::PointCloud2> ("full_cloud2", 1);
00087
00088 private_ns_.param("num_skips", num_skips_, 0);
00089 num_skips_left_=num_skips_;
00090
00091 prev_angle_ = -1;
00092 first_time_ = true;
00093 private_ns_.param("negative_direction", negative_direction_, false);
00094 ROS_INFO_STREAM("negative_direction: " << negative_direction_);
00095 bool use_tf;
00096 private_ns_.param("use_tf", use_tf, false);
00097 if (!use_tf) {
00098 sub_ = n_.subscribe("joint_states", 40, &SpinLaserSnapshotter::scannerSignalCallback, this);
00099 }
00100 else {
00101 listener_ = new tf::TransformListener();
00102 private_ns_.param("tf_polling_rate", rate_, 30.0);
00103 private_ns_.param("spindle_frame", spindle_frame_, std::string("multisense/spindle"));
00104 private_ns_.param("motor_frame", motor_frame_, std::string("multisense/motor"));
00105 timer_ = private_ns_.createTimer(
00106 ros::Duration(1.0 / rate_), boost::bind(
00107 &SpinLaserSnapshotter::timerCallback, this, _1));
00108 }
00109 }
00110
00111 ~SpinLaserSnapshotter()
00112 {
00113
00114 }
00115
00116 void timerCallback(const ros::TimerEvent& event)
00117 {
00118
00119 if (listener_->waitForTransform(motor_frame_, spindle_frame_, event.current_real,
00120 ros::Duration(1 / rate_))) {
00121 tf::StampedTransform transform;
00122 listener_->lookupTransform(spindle_frame_, motor_frame_, event.current_real, transform);
00123
00124 Eigen::Affine3d t;
00125 tf::transformTFToEigen(transform, t);
00126 double yaw = atan2(t(1,0), t(0,0));
00127 sensor_msgs::JointState js;
00128 js.header.stamp = transform.stamp_;
00129 js.position.push_back(yaw);
00130 const sensor_msgs::JointState js_const (js);
00131 scannerSignalCallback(boost::make_shared<sensor_msgs::JointState>(js_const));
00132 }
00133 }
00134
00135 void scannerSignalCallback(const sensor_msgs::JointStateConstPtr& js)
00136 {
00137 double theta = js->position[0];
00138 if (negative_direction_) {
00139 theta = - theta;
00140 }
00141 double ang = fmod(theta, 2 * M_PI);
00142
00143
00144
00145 if ( prev_angle_ < 0 ) {
00146 prev_angle_ = ang;
00147 return;
00148 }
00149 if ((ang - prev_angle_) >= - M_PI) {
00150 prev_angle_ = ang;
00151 return;
00152 }
00153
00154 if (prev_signal_.toSec() == 0.0) {
00155 first_time_ = true;
00156 }
00157
00158 ros::Time stmp = js->header.stamp;
00159 if (first_time_)
00160 {
00161 prev_signal_ = stmp;
00162 first_time_ = false;
00163 }
00164 else
00165 {
00166 if (num_skips_ > 0)
00167 {
00168 if (num_skips_left_ > 0)
00169 {
00170 num_skips_left_ -= 1;
00171 return;
00172 }
00173 else
00174 {
00175 num_skips_left_ = num_skips_;
00176 }
00177 }
00178
00179 laser_assembler::AssembleScans2::Request req;
00180 laser_assembler::AssembleScans2::Response res;
00181
00182 req.begin = prev_signal_;
00183 req.end = stmp;
00184 if (!ros::service::call("assemble_scans2", req, res))
00185 ROS_ERROR("Failed to call service on point cloud assembler or laser scan assembler.");
00186
00187 pub_.publish(res.cloud);
00188 ROS_DEBUG("Snapshotter::Published Cloud size=%u", res.cloud.width * res.cloud.height);
00189
00190 prev_signal_ = stmp;
00191 prev_angle_ = -1;
00192 }
00193 }
00194 };
00195 }
00196
00197 using namespace spin_laser_snapshotter;
00198
00199 int main(int argc, char **argv)
00200 {
00201 ros::init(argc, argv, "spin_laser_snapshotter");
00202 SpinLaserSnapshotter snapshotter ;
00203 ros::spin();
00204 return 0;
00205 }