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