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
00037
00038 #include "sick_laser/motor.h"
00039
00040 #include <ros/ros.h>
00041 #include <sensor_msgs/LaserScan.h>
00042 #include <sensor_msgs/PointCloud.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <pcl/point_types.h>
00045
00046 #include <vector>
00047 #include <fstream>
00048
00049 using namespace std;
00050
00051 float g_speed = 0.0;
00052 bool g_is_move = false;
00053 float g_motor_deg = 0.0;
00054 char *g_motor_dir;
00055
00056 class SickLaser
00057 {
00058 public:
00059 SickLaser ();
00060 ~SickLaser ();
00061 public:
00062 bool laserIsSaveDataAsPCD (char *c_is_save);
00063 void laserGetMotorMoveTime (double f_time);
00064 void laserGetDataCallBack (const sensor_msgs::LaserScan::ConstPtr & laser);
00065 void laserGetScanDegree (float f_degree);
00066 private:
00067 ros::NodeHandle nh_;
00068 ros::Subscriber sub_;
00069
00070 vector < double >one_frame_vec_;
00071 vector < vector < double > >data_vec_;
00072 vector < double >timestamp_vec_;
00073
00074 bool is_save_as_PCD_;
00075 ros::Time time_start_;
00076 static float f_count_;
00077 float first_scan_degree_;
00078 double motor_move_time_;
00079 };
00080
00081 float SickLaser::f_count_ = 0.0;
00082
00083 SickLaser::SickLaser ()
00084 {
00085 sub_ = nh_.subscribe ("/scan", 1000, &SickLaser::laserGetDataCallBack, this);
00086
00087 one_frame_vec_.reserve (361);
00088 data_vec_.reserve (800);
00089 timestamp_vec_.reserve (800);
00090 is_save_as_PCD_ = true;
00091 time_start_ = ros::Time::now ();
00092 first_scan_degree_ = 0.0;
00093 motor_move_time_ = 0.0;
00094 }
00095
00096 SickLaser::~SickLaser ()
00097 {
00098 }
00099
00100 bool SickLaser::laserIsSaveDataAsPCD (char *c_is_save)
00101 {
00102 if (!strcmp (c_is_save, "y"))
00103 {
00104 is_save_as_PCD_ = true;
00105 }
00106 else
00107 is_save_as_PCD_ = false;
00108
00109 return is_save_as_PCD_;
00110 }
00111
00112 void SickLaser::laserGetMotorMoveTime (double f_time)
00113 {
00114 motor_move_time_ = f_time + 0.2;
00115 }
00116
00117 void SickLaser::laserGetScanDegree (float f_degree)
00118 {
00119 first_scan_degree_ = f_degree / 180.0 * 3.1415;
00120 }
00121
00122 void SickLaser::laserGetDataCallBack (const sensor_msgs::LaserScan::ConstPtr & laser)
00123 {
00124 if (g_is_move)
00125 {
00126 double duration = ros::Time::now ().toSec () - motor_move_time_;
00127 if (duration * g_speed < g_motor_deg)
00128 {
00129 for (int i = 0; i < 361; ++i)
00130 {
00131 one_frame_vec_.push_back (laser->ranges[i]);
00132 }
00133 data_vec_.push_back (one_frame_vec_);
00134 timestamp_vec_.push_back (laser->header.stamp.toSec ());
00135 one_frame_vec_.clear ();
00136 f_count_++;
00137 ROS_INFO ("f_count_ = %f", f_count_);
00138 }
00139 else
00140 {
00141 float scandegree = duration * g_speed;
00142 ROS_INFO ("scan %f frame ", f_count_);
00143 ROS_INFO ("scan degree is: %f", scandegree);
00144 g_is_move = false;
00145
00146 float angleResolution = laser->angle_increment;
00147
00148 vector < double >vecAnglePerFrame;
00149 vecAnglePerFrame.resize (timestamp_vec_.size ());
00150 for (int i = 0; i < (int) timestamp_vec_.size (); i++)
00151 {
00152 vecAnglePerFrame[i] = (timestamp_vec_[i] - motor_move_time_) * g_speed / 180 * 3.14159;
00153 }
00154
00155 int iCloudWidth = 361;
00156 int iCloudHeight = f_count_;
00157
00158 if (is_save_as_PCD_)
00159 {
00160 ROS_INFO ("save as a PCD file ");
00161 pcl::PointCloud < pcl::PointXYZ > cloudScan;
00162 cloudScan.width = iCloudWidth;
00163 cloudScan.height = iCloudHeight;
00164 cloudScan.is_dense = false;
00165 cloudScan.points.resize (cloudScan.width * cloudScan.height);
00166
00167 if (strcmp (g_motor_dir, "0") == 0)
00168 {
00169 for (int i = 0; i < iCloudHeight; i++)
00170 for (int j = 0; j < iCloudWidth; j++)
00171 {
00172 cloudScan.points[i * iCloudWidth + j].x =
00173 data_vec_[i][j] * sin (0.0 + j * angleResolution) * cos (first_scan_degree_ - vecAnglePerFrame[i]);
00174 cloudScan.points[i * iCloudWidth + j].y =
00175 data_vec_[i][j] * sin (0.0 + j * angleResolution) * sin (first_scan_degree_ - vecAnglePerFrame[i]);
00176 cloudScan.points[i * iCloudWidth + j].z = data_vec_[i][j] * cos (0.0 + j * angleResolution);
00177 }
00178 }
00179 else if (strcmp (g_motor_dir, "1") == 0)
00180 {
00181 for (int i = 0; i < iCloudHeight; i++)
00182 for (int j = 0; j < iCloudWidth; j++)
00183 {
00184 cloudScan.points[i * iCloudWidth + j].x =
00185 data_vec_[i][j] * sin (0.0 + j * angleResolution) * cos (first_scan_degree_ + vecAnglePerFrame[i]);
00186 cloudScan.points[i * iCloudWidth + j].y =
00187 data_vec_[i][j] * sin (0.0 + j * angleResolution) * sin (first_scan_degree_ + vecAnglePerFrame[i]);
00188 cloudScan.points[i * iCloudWidth + j].z = data_vec_[i][j] * cos (0.0 + j * angleResolution);
00189 }
00190 }
00191 pcl::io::savePCDFileASCII ("laser.pcd", cloudScan);
00192
00193 ROS_INFO ("save end");
00194 }
00195 else
00196 {
00197 ros::NodeHandle nhCloud;
00198 ros::Publisher cloud_pub = nhCloud.advertise < sensor_msgs::PointCloud > ("cloud", 50);
00199
00200 int iCloudWidth = 361;
00201 int iCloudHeight = f_count_;
00202
00203 sensor_msgs::PointCloud cloud;
00204 cloud.header.stamp = ros::Time::now ();
00205 cloud.header.frame_id = "sensor_frame";
00206
00207 cloud.points.resize (iCloudWidth * iCloudHeight);
00208
00209 cloud.channels.resize (1);
00210 cloud.channels[0].name = "intensities";
00211
00212 if (strcmp (g_motor_dir, "0") == 0)
00213 {
00214 for (int i = 0; i < iCloudHeight; i++)
00215 for (int j = 0; j < iCloudWidth; j++)
00216 {
00217 cloud.points[i * iCloudWidth + j].x =
00218 data_vec_[i][j] * sin (0.0 + j * angleResolution) * cos (first_scan_degree_ - vecAnglePerFrame[i]);
00219 cloud.points[i * iCloudWidth + j].y =
00220 data_vec_[i][j] * sin (0.0 + j * angleResolution) * sin (first_scan_degree_ - vecAnglePerFrame[i]);
00221 cloud.points[i * iCloudWidth + j].z = data_vec_[i][j] * cos (0.0 + j * angleResolution);
00222 }
00223 }
00224 else if (strcmp (g_motor_dir, "1") == 0)
00225 {
00226 for (int i = 0; i < iCloudHeight; i++)
00227 for (int j = 0; j < iCloudWidth; j++)
00228 {
00229 cloud.points[i * iCloudWidth + j].x =
00230 data_vec_[i][j] * sin (0.0 + j * angleResolution) * cos (first_scan_degree_ + vecAnglePerFrame[i]);
00231 cloud.points[i * iCloudWidth + j].y =
00232 data_vec_[i][j] * sin (0.0 + j * angleResolution) * sin (first_scan_degree_ + vecAnglePerFrame[i]);
00233 cloud.points[i * iCloudWidth + j].z = data_vec_[i][j] * cos (0.0 + j * angleResolution);
00234 }
00235 }
00236 sleep (3);
00237 cloud_pub.publish (cloud);
00238 }
00239 sleep (1);
00240
00241 return;
00242 }
00243 }
00244
00245 }
00246
00247 int main (int argc, char **argv)
00248 {
00249 ros::init (argc, argv, "getdata");
00250
00251 int port = atoi (argv[1]);
00252 g_motor_dir = argv[2];
00253 int motor_fre = atoi (argv[3]);
00254 g_motor_deg = atoi (argv[4]) * 1.0;
00255 float firstdegree = atoi (argv[5]) * 1.0;
00256 char *is_save_as_pcd = argv[6];
00257
00258 ROS_INFO ("port is %d\n", port);
00259 ROS_INFO ("direction is %s\n", g_motor_dir);
00260 ROS_INFO ("frequency is %d\n", motor_fre);
00261 ROS_INFO ("degree is %f\n", g_motor_deg);
00262
00263 g_speed = motor_fre * STEP_DIS * SUBDIVISION / 180;
00264
00265 Motor myMotor (port, g_motor_dir, motor_fre, g_motor_deg);
00266 SickLaser laser;
00267
00268 laser.laserIsSaveDataAsPCD (is_save_as_pcd);
00269 laser.laserGetScanDegree (firstdegree);
00270 double ts = myMotor.motorMove ();
00271 laser.laserGetMotorMoveTime (ts);
00272 g_is_move = true;
00273
00274 ros::spin ();
00275
00276 return 0;
00277 }