Go to the documentation of this file.00001
00033 #include <ros/ros.h>
00034 #include <ros/topic.h>
00035 #include <rosbag/bag.h>
00036 #include <multisense_ros/DeviceInfo.h>
00037 #include <multisense_ros/RawCamConfig.h>
00038 #include <multisense_ros/RawCamCal.h>
00039 #include <multisense_ros/RawCamData.h>
00040 #include <multisense_ros/RawLidarData.h>
00041 #include <multisense_ros/RawLidarCal.h>
00042 #include <multisense_lib/MultiSenseTypes.hh>
00043 #include <stdio.h>
00044 #include <ros/callback_queue.h>
00045
00046 #include <dynamic_reconfigure/DoubleParameter.h>
00047 #include <dynamic_reconfigure/StrParameter.h>
00048 #include <dynamic_reconfigure/Reconfigure.h>
00049 #include <dynamic_reconfigure/Config.h>
00050
00051 namespace {
00052
00053 #define TOPIC_DEVICE_INFO "/multisense/calibration/device_info"
00054 #define TOPIC_RAW_CAM_CAL "/multisense/calibration/raw_cam_cal"
00055 #define TOPIC_RAW_CAM_CONFIG "/multisense/calibration/raw_cam_config"
00056 #define TOPIC_RAW_CAM_DATA "/multisense/calibration/raw_cam_data"
00057 #define TOPIC_RAW_LIDAR "/multisense/calibration/raw_lidar_data"
00058 #define TOPIC_RAW_LIDAR_CAL "/multisense/calibration/raw_lidar_cal"
00059
00060
00061
00062
00063 class LaserHelper {
00064 public:
00065
00066 LaserHelper() : motion_started_(false) {}
00067
00068 void callback(const multisense_ros::RawLidarData::ConstPtr& msg)
00069 {
00070
00071
00072
00073
00074 if (motion_started_ || 0 == scans_.size())
00075 scans_.push_back(msg);
00076
00077 if (!motion_started_) {
00078 std::list<multisense_ros::RawLidarData::ConstPtr>::const_iterator it = scans_.begin();
00079
00080 if (msg->angle_start != (*it)->angle_start) {
00081 motion_started_ = true;
00082 scans_.clear();
00083 scans_.push_back(msg);
00084 }
00085 }
00086 }
00087
00088
00089
00090
00091
00092 bool done() const
00093 {
00094 std::list<multisense_ros::RawLidarData::ConstPtr>::const_iterator it;
00095
00096
00097
00098
00099 it = scans_.begin();
00100 if (scans_.end() == it)
00101 return false;
00102
00103
00104
00105
00106 double previous_start = (*it)->angle_start / 1000000.0;
00107 double total_swept = 0.0;
00108
00109 for (it = scans_.begin(); it != scans_.end(); it++) {
00110
00111 double current_start = (*it)->angle_start / 1000000.0;
00112 double current_swept = current_start - previous_start;
00113
00114
00115
00116
00117 while(current_swept > M_PI)
00118 current_swept -= 2*M_PI;
00119 while(current_swept < -M_PI)
00120 current_swept += 2*M_PI;
00121
00122
00123
00124
00125 total_swept += current_swept;
00126
00127
00128
00129
00130 previous_start = current_start;
00131 }
00132
00133 return ( fabs(total_swept) > 2.0 * M_PI);
00134 }
00135
00136
00137
00138
00139
00140
00141 bool getRotation(std::list<multisense_ros::RawLidarData::ConstPtr>& scan_collection)
00142 {
00143 scans_.clear();
00144 ros::NodeHandle nh;
00145 nh.setCallbackQueue(&queue_);
00146
00147 ros::Subscriber sub_ = nh.subscribe<multisense_ros::RawLidarData>(TOPIC_RAW_LIDAR, 5,
00148 boost::bind(&LaserHelper::callback, this, _1));
00149
00150 ros::Time start = ros::Time::now();
00151
00152
00153
00154
00155 while(1) {
00156
00157 queue_.callOne(ros::WallDuration(1.0));
00158
00159 if (done()) {
00160 scan_collection = scans_;
00161 return true;
00162 }
00163
00164 if ((ros::Time::now().toSec() - start.toSec()) >= SCAN_COLLECT_TIMEOUT)
00165 return false;
00166 }
00167 }
00168
00169 private:
00170
00171 #if __cplusplus >= 201103
00172 static constexpr double SCAN_COLLECT_TIMEOUT = 20.0;
00173 #else
00174 static const double SCAN_COLLECT_TIMEOUT = 20.0;
00175 #endif
00176
00177 bool motion_started_;
00178 ros::CallbackQueue queue_;
00179 std::list<multisense_ros::RawLidarData::ConstPtr> scans_;
00180 };
00181
00182 void setConf(const dynamic_reconfigure::Config& conf)
00183 {
00184 dynamic_reconfigure::ReconfigureRequest srv_req;
00185 dynamic_reconfigure::ReconfigureResponse srv_resp;
00186
00187 srv_req.config = conf;
00188
00189 ros::service::call("/multisense/set_parameters", srv_req, srv_resp);
00190 }
00191
00192 void setMotorSpeed(double radPerSec)
00193 {
00194 dynamic_reconfigure::DoubleParameter double_param;
00195 dynamic_reconfigure::Config conf;
00196
00197 double_param.name = "motor_speed";
00198 double_param.value = radPerSec;
00199 conf.doubles.push_back(double_param);
00200
00201 setConf(conf);
00202 }
00203
00204 void setResolution(const std::string& res)
00205 {
00206 dynamic_reconfigure::StrParameter str_param;
00207 dynamic_reconfigure::Config conf;
00208
00209 str_param.name = "resolution";
00210 str_param.value = res;
00211 conf.strs.push_back(str_param);
00212
00213 setConf(conf);
00214 }
00215
00216 };
00217
00218 int main(int argc,
00219 char** argvPP)
00220 {
00221 ros::init(argc, argvPP, "raw_snapshot");
00222 ros::NodeHandle nh;
00223
00224 if (argc != 2 ||
00225 std::string(argvPP[1]) == "--help" ||
00226 std::string(argvPP[1]) == "-h") {
00227
00228 printf("Usage: %s <out_bag_filename>\n", argvPP[0]);
00229 return -1;
00230 }
00231
00232 std::string outfile(argvPP[1]);
00233
00234 printf("Capturing device information... "); fflush(stdout);
00235 multisense_ros::DeviceInfo::ConstPtr device_info = ros::topic::waitForMessage<multisense_ros::DeviceInfo>(TOPIC_DEVICE_INFO, nh);
00236 if (!device_info) {
00237 printf(" Error capturing DeviceInfo. Exiting\n");
00238 return -1;
00239 }
00240 printf(" Success\n");
00241
00242 switch(device_info->imagerType) {
00243 case crl::multisense::system::DeviceInfo::IMAGER_TYPE_CMV2000_GREY:
00244 case crl::multisense::system::DeviceInfo::IMAGER_TYPE_CMV2000_COLOR:
00245 printf("Imager type is CMV2000; setting resolution to 1024x544x128... ");
00246 setResolution("1024x544x128");
00247 break;
00248 case crl::multisense::system::DeviceInfo::IMAGER_TYPE_CMV4000_GREY:
00249 case crl::multisense::system::DeviceInfo::IMAGER_TYPE_CMV4000_COLOR:
00250 printf("Imager type is CMV4000; setting resolution to 1024x1024x128... ");
00251 setResolution("1024x1024x128");
00252 break;
00253 default:
00254 printf("Imager type is not recognized; not setting resolution... ");
00255 printf(" Error setting imager resolution. Exiting\n");
00256 return -1;
00257 break;
00258 }
00259 ros::Duration(1.0).sleep();
00260
00261 printf("Capturing lidar calibration... ");
00262 multisense_ros::RawLidarCal::ConstPtr lidar_cal = ros::topic::waitForMessage<multisense_ros::RawLidarCal>(TOPIC_RAW_LIDAR_CAL, nh);
00263 if (!lidar_cal) {
00264 printf(" Error capturing RawLidarCal. Exiting\n");
00265 return -1;
00266 }
00267 printf(" Success\n");
00268
00269 printf("Capturing camera calibration... "); fflush(stdout);
00270 multisense_ros::RawCamCal::ConstPtr cam_cal = ros::topic::waitForMessage<multisense_ros::RawCamCal>(TOPIC_RAW_CAM_CAL, nh);
00271 if (!cam_cal) {
00272 printf(" Error capturing RawCamCal. Exiting\n");
00273 return -1;
00274 }
00275 printf(" Success\n");
00276
00277 printf("Capturing camera config... "); fflush(stdout);
00278 multisense_ros::RawCamConfig::ConstPtr cam_config = ros::topic::waitForMessage<multisense_ros::RawCamConfig>(TOPIC_RAW_CAM_CONFIG, nh);
00279 if (!cam_config) {
00280 printf(" Error capturing RawCamConfig. Exiting\n");
00281 return -1;
00282 }
00283 printf(" Success\n");
00284
00285 printf("Capturing a single left-rectified/disparity image pair... "); fflush(stdout);
00286 multisense_ros::RawCamData::ConstPtr cam_data = ros::topic::waitForMessage<multisense_ros::RawCamData>(TOPIC_RAW_CAM_DATA, nh);
00287 if (!cam_data) {
00288 printf(" Error capturing RawCamData. Exiting\n");
00289 return -1;
00290 }
00291 printf(" Success\n");
00292
00293 printf("Capturing a full rotation of lidar scans... "); fflush(stdout);
00294
00295 setMotorSpeed(0.785);
00296
00297 LaserHelper laser_helper;
00298 std::list<multisense_ros::RawLidarData::ConstPtr> raw_lidar_data;
00299
00300 if (false == laser_helper.getRotation(raw_lidar_data)) {
00301 printf(" Error capturing RawLidarData...\n");
00302 return -1;
00303 }
00304 printf(" Captured %zu lidar scans\n", raw_lidar_data.size());
00305
00306 setMotorSpeed(0.0);
00307
00308
00309
00310
00311 printf("Saving data to file [%s]\n", outfile.c_str());
00312 rosbag::Bag bag;
00313 bag.open(outfile, rosbag::bagmode::Write);
00314
00315 bag.write(TOPIC_DEVICE_INFO, ros::TIME_MIN, *device_info);
00316 bag.write(TOPIC_RAW_LIDAR_CAL, ros::TIME_MIN, *lidar_cal);
00317 bag.write(TOPIC_RAW_CAM_CAL, ros::TIME_MIN, *cam_cal);
00318 bag.write(TOPIC_RAW_CAM_CONFIG, ros::TIME_MIN, *cam_config);
00319 bag.write(TOPIC_RAW_CAM_DATA, ros::TIME_MIN, *cam_data);
00320
00321 std::list<multisense_ros::RawLidarData::ConstPtr>::const_iterator it;
00322 for (it = raw_lidar_data.begin(); it != raw_lidar_data.end(); it++)
00323 bag.write(TOPIC_RAW_LIDAR, ros::TIME_MIN, **it);
00324
00325 bag.close();
00326 printf(" Success\n");
00327
00328 return 0;
00329 }
00330