Go to the documentation of this file.00001
00014 #include <iostream>
00015 #include <fstream>
00016 #include <string>
00017 #include <cmath>
00018 #include <limits>
00019 #include <yaml-cpp/yaml.h>
00020
00021 #ifdef HAVE_NEW_YAMLCPP
00022 namespace YAML {
00023
00024
00025
00026 template<typename T>
00027 void operator >> (const YAML::Node& node, T& i) {
00028 i = node.as<T>();
00029 }
00030 }
00031 #endif // HAVE_NEW_YAMLCPP
00032
00033 #include <ros/ros.h>
00034 #include <velodyne_pointcloud/calibration.h>
00035
00036 namespace velodyne_pointcloud
00037 {
00038
00039 const std::string NUM_LASERS = "num_lasers";
00040 const std::string LASERS = "lasers";
00041 const std::string LASER_ID = "laser_id";
00042 const std::string ROT_CORRECTION = "rot_correction";
00043 const std::string VERT_CORRECTION = "vert_correction";
00044 const std::string DIST_CORRECTION = "dist_correction";
00045 const std::string TWO_PT_CORRECTION_AVAILABLE =
00046 "two_pt_correction_available";
00047 const std::string DIST_CORRECTION_X = "dist_correction_x";
00048 const std::string DIST_CORRECTION_Y = "dist_correction_y";
00049 const std::string VERT_OFFSET_CORRECTION = "vert_offset_correction";
00050 const std::string HORIZ_OFFSET_CORRECTION = "horiz_offset_correction";
00051 const std::string MAX_INTENSITY = "max_intensity";
00052 const std::string MIN_INTENSITY = "min_intensity";
00053 const std::string FOCAL_DISTANCE = "focal_distance";
00054 const std::string FOCAL_SLOPE = "focal_slope";
00055
00056 void operator >> (const YAML::Node& node,
00057 std::pair<int, LaserCorrection>& correction)
00058 {
00059 node[LASER_ID] >> correction.first;
00060 node[ROT_CORRECTION] >> correction.second.rot_correction;
00061 node[VERT_CORRECTION] >> correction.second.vert_correction;
00062 node[DIST_CORRECTION] >> correction.second.dist_correction;
00063 #ifdef HAVE_NEW_YAMLCPP
00064 if (node[TWO_PT_CORRECTION_AVAILABLE])
00065 node[TWO_PT_CORRECTION_AVAILABLE] >>
00066 correction.second.two_pt_correction_available;
00067 #else
00068 if (const YAML::Node *pName = node.FindValue(TWO_PT_CORRECTION_AVAILABLE))
00069 *pName >> correction.second.two_pt_correction_available;
00070 #endif
00071 else
00072 correction.second.two_pt_correction_available = false;
00073 node[DIST_CORRECTION_X] >> correction.second.dist_correction_x;
00074 node[DIST_CORRECTION_Y] >> correction.second.dist_correction_y;
00075 node[VERT_OFFSET_CORRECTION] >> correction.second.vert_offset_correction;
00076 node[HORIZ_OFFSET_CORRECTION] >> correction.second.horiz_offset_correction;
00077 #ifdef HAVE_NEW_YAMLCPP
00078 if (node[MAX_INTENSITY])
00079 node[MAX_INTENSITY] >> correction.second.max_intensity;
00080 #else
00081 if (const YAML::Node *pName = node.FindValue(MAX_INTENSITY))
00082 *pName >> correction.second.max_intensity;
00083 #endif
00084 else
00085 correction.second.max_intensity = 255;
00086 #ifdef HAVE_NEW_YAMLCPP
00087 if (node[MIN_INTENSITY])
00088 node[MIN_INTENSITY] >> correction.second.min_intensity;
00089 #else
00090 if (const YAML::Node *pName = node.FindValue(MIN_INTENSITY))
00091 *pName >> correction.second.min_intensity;
00092 #endif
00093 else
00094 correction.second.min_intensity = 0;
00095 node[FOCAL_DISTANCE] >> correction.second.focal_distance;
00096 node[FOCAL_SLOPE] >> correction.second.focal_slope;
00097
00098
00099 correction.second.cos_rot_correction =
00100 cosf(correction.second.rot_correction);
00101 correction.second.sin_rot_correction =
00102 sinf(correction.second.rot_correction);
00103 correction.second.cos_vert_correction =
00104 cosf(correction.second.vert_correction);
00105 correction.second.sin_vert_correction =
00106 sinf(correction.second.vert_correction);
00107
00108 correction.second.laser_ring = 0;
00109 }
00110
00111 void operator >> (const YAML::Node& node, Calibration& calibration)
00112 {
00113 int num_lasers;
00114 node[NUM_LASERS] >> num_lasers;
00115 const YAML::Node& lasers = node[LASERS];
00116 calibration.laser_corrections.clear();
00117 calibration.num_lasers = num_lasers;
00118 for (int i = 0; i < num_lasers; i++) {
00119 std::pair<int, LaserCorrection> correction;
00120 lasers[i] >> correction;
00121 calibration.laser_corrections.insert(correction);
00122 }
00123
00124
00125
00126
00127
00128 double next_angle = -std::numeric_limits<double>::infinity();
00129 for (int ring = 0; ring < num_lasers; ++ring) {
00130
00131
00132 double min_seen = std::numeric_limits<double>::infinity();
00133 int next_index = num_lasers;
00134 for (int j = 0; j < num_lasers; ++j) {
00135
00136 double angle = calibration.laser_corrections[j].vert_correction;
00137 if (next_angle < angle && angle < min_seen) {
00138 min_seen = angle;
00139 next_index = j;
00140 }
00141 }
00142
00143 if (next_index < num_lasers) {
00144
00145
00146 calibration.laser_corrections[next_index].laser_ring = ring;
00147 next_angle = min_seen;
00148 ROS_INFO_STREAM("laser_ring[" << next_index << "] = " << ring
00149 << ", angle = " << next_angle);
00150 }
00151 }
00152 }
00153
00154 YAML::Emitter& operator << (YAML::Emitter& out,
00155 const std::pair<int, LaserCorrection> correction)
00156 {
00157 out << YAML::BeginMap;
00158 out << YAML::Key << LASER_ID << YAML::Value << correction.first;
00159 out << YAML::Key << ROT_CORRECTION <<
00160 YAML::Value << correction.second.rot_correction;
00161 out << YAML::Key << VERT_CORRECTION <<
00162 YAML::Value << correction.second.vert_correction;
00163 out << YAML::Key << DIST_CORRECTION <<
00164 YAML::Value << correction.second.dist_correction;
00165 out << YAML::Key << TWO_PT_CORRECTION_AVAILABLE <<
00166 YAML::Value << correction.second.two_pt_correction_available;
00167 out << YAML::Key << DIST_CORRECTION_X <<
00168 YAML::Value << correction.second.dist_correction_x;
00169 out << YAML::Key << DIST_CORRECTION_Y <<
00170 YAML::Value << correction.second.dist_correction_y;
00171 out << YAML::Key << VERT_OFFSET_CORRECTION <<
00172 YAML::Value << correction.second.vert_offset_correction;
00173 out << YAML::Key << HORIZ_OFFSET_CORRECTION <<
00174 YAML::Value << correction.second.horiz_offset_correction;
00175 out << YAML::Key << MAX_INTENSITY <<
00176 YAML::Value << correction.second.max_intensity;
00177 out << YAML::Key << MIN_INTENSITY <<
00178 YAML::Value << correction.second.min_intensity;
00179 out << YAML::Key << FOCAL_DISTANCE <<
00180 YAML::Value << correction.second.focal_distance;
00181 out << YAML::Key << FOCAL_SLOPE <<
00182 YAML::Value << correction.second.focal_slope;
00183 out << YAML::EndMap;
00184 return out;
00185 }
00186
00187 YAML::Emitter& operator <<
00188 (YAML::Emitter& out, const Calibration& calibration)
00189 {
00190 out << YAML::BeginMap;
00191 out << YAML::Key << NUM_LASERS <<
00192 YAML::Value << calibration.laser_corrections.size();
00193 out << YAML::Key << LASERS << YAML::Value << YAML::BeginSeq;
00194 for (std::map<int, LaserCorrection>::const_iterator
00195 it = calibration.laser_corrections.begin();
00196 it != calibration.laser_corrections.end(); it++)
00197 {
00198 out << *it;
00199 }
00200 out << YAML::EndSeq;
00201 out << YAML::EndMap;
00202 return out;
00203 }
00204
00205 void Calibration::read(const std::string& calibration_file) {
00206 std::ifstream fin(calibration_file.c_str());
00207 if (!fin.is_open()) {
00208 initialized = false;
00209 return;
00210 }
00211 initialized = true;
00212 try {
00213 YAML::Node doc;
00214 #ifdef HAVE_NEW_YAMLCPP
00215 fin.close();
00216 doc = YAML::LoadFile(calibration_file);
00217 #else
00218 YAML::Parser parser(fin);
00219 parser.GetNextDocument(doc);
00220 #endif
00221 doc >> *this;
00222 } catch (YAML::Exception &e) {
00223 std::cerr << "YAML Exception: " << e.what() << std::endl;
00224 initialized = false;
00225 }
00226 fin.close();
00227 }
00228
00229 void Calibration::write(const std::string& calibration_file) {
00230 std::ofstream fout(calibration_file.c_str());
00231 YAML::Emitter out;
00232 out << *this;
00233 fout << out.c_str();
00234 fout.close();
00235 }
00236
00237 }