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 #include <string>
00020 #include <map>
00021 #include <tinyxml.h>
00022 #include <boost/algorithm/string.hpp>
00023 #include <boost/lexical_cast.hpp>
00024 #include <robot_calibration/calibration_offset_parser.h>
00025 #include <robot_calibration/models/chain.h>
00026
00027 namespace robot_calibration
00028 {
00029
00030 CalibrationOffsetParser::CalibrationOffsetParser()
00031 {
00032
00033 }
00034
00035 bool CalibrationOffsetParser::add(const std::string name)
00036 {
00037 parameter_names_.push_back(name);
00038 parameter_offsets_.push_back(0.0);
00039 return true;
00040 }
00041
00042 bool CalibrationOffsetParser::addFrame(
00043 const std::string name,
00044 bool calibrate_x, bool calibrate_y, bool calibrate_z,
00045 bool calibrate_roll, bool calibrate_pitch, bool calibrate_yaw)
00046 {
00047 frame_names_.push_back(name);
00048 if (calibrate_x)
00049 add(std::string(name).append("_x"));
00050 if (calibrate_y)
00051 add(std::string(name).append("_y"));
00052 if (calibrate_z)
00053 add(std::string(name).append("_z"));
00054
00055
00056
00057 if (calibrate_roll)
00058 add(std::string(name).append("_a"));
00059 if (calibrate_pitch)
00060 add(std::string(name).append("_b"));
00061 if (calibrate_yaw)
00062 add(std::string(name).append("_c"));
00063
00064 return true;
00065 }
00066
00067 bool CalibrationOffsetParser::update(const double* const free_params)
00068 {
00069 for (size_t i = 0; i < parameter_offsets_.size(); ++i)
00070 parameter_offsets_[i] = free_params[i];
00071 return true;
00072 }
00073
00074 double CalibrationOffsetParser::get(const std::string name) const
00075 {
00076 for (size_t i = 0; i < parameter_names_.size(); ++i)
00077 {
00078 if (parameter_names_[i] == name)
00079 return parameter_offsets_[i];
00080 }
00081
00082 return 0.0;
00083 }
00084
00085 bool CalibrationOffsetParser::getFrame(const std::string name, KDL::Frame& offset) const
00086 {
00087
00088 bool has_offset = false;
00089 for (size_t i = 0; i < frame_names_.size(); ++i)
00090 {
00091 if (frame_names_[i] == name)
00092 {
00093 has_offset = true;
00094 break;
00095 }
00096 }
00097
00098 if (!has_offset)
00099 return false;
00100
00101 offset.p.x(get(std::string(name).append("_x")));
00102 offset.p.y(get(std::string(name).append("_y")));
00103 offset.p.z(get(std::string(name).append("_z")));
00104
00105 offset.M = rotation_from_axis_magnitude(
00106 get(std::string(name).append("_a")),
00107 get(std::string(name).append("_b")),
00108 get(std::string(name).append("_c")));
00109
00110 return true;
00111 }
00112
00113 int CalibrationOffsetParser::size()
00114 {
00115 return parameter_names_.size();
00116 }
00117
00118 std::string CalibrationOffsetParser::getOffsetYAML()
00119 {
00120 std::stringstream ss;
00121 for (size_t i = 0; i < parameter_names_.size(); ++i)
00122 {
00123 ss << parameter_names_[i] << ": " << parameter_offsets_[i] << std::endl;
00124 }
00125 return ss.str();
00126 }
00127
00128 std::string CalibrationOffsetParser::updateURDF(const std::string &urdf)
00129 {
00130 const double precision = 8;
00131
00132 TiXmlDocument xml_doc;
00133 xml_doc.Parse(urdf.c_str());
00134
00135 TiXmlElement *robot_xml = xml_doc.FirstChildElement("robot");
00136 if (!robot_xml)
00137 {
00138
00139
00140 return urdf;
00141 }
00142
00143
00144 for (TiXmlElement* joint_xml = robot_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint"))
00145 {
00146 const char * name = joint_xml->Attribute("name");
00147
00148
00149 double offset = get(std::string(name));
00150 if (offset != 0.0)
00151 {
00152 TiXmlElement *calibration_xml = joint_xml->FirstChildElement("calibration");
00153 if (calibration_xml)
00154 {
00155
00156 const char * rising_position_str = calibration_xml->Attribute("rising");
00157 if (rising_position_str != NULL)
00158 {
00159 try
00160 {
00161 offset += double(boost::lexical_cast<double>(rising_position_str));
00162 calibration_xml->SetDoubleAttribute("rising", offset);
00163 }
00164 catch (boost::bad_lexical_cast &e)
00165 {
00166
00167 }
00168 }
00169 else
00170 {
00171
00172 }
00173 }
00174 else
00175 {
00176
00177 calibration_xml = new TiXmlElement("calibration");
00178 calibration_xml->SetDoubleAttribute("rising", offset);
00179 TiXmlNode * calibration = calibration_xml->Clone();
00180 joint_xml->InsertEndChild(*calibration);
00181 }
00182 }
00183
00184 KDL::Frame frame_offset;
00185 bool has_update = getFrame(name, frame_offset);
00186 if (has_update)
00187 {
00188 std::vector<double> xyz(3, 0.0);
00189 std::vector<double> rpy(3, 0.0);
00190
00191 xyz[0] = frame_offset.p.x();
00192 xyz[1] = frame_offset.p.y();
00193 xyz[2] = frame_offset.p.z();
00194
00195
00196 frame_offset.M.GetRPY(rpy[0], rpy[1], rpy[2]);
00197
00198
00199 std::stringstream xyz_ss, rpy_ss;
00200
00201 TiXmlElement *origin_xml = joint_xml->FirstChildElement("origin");
00202 if (origin_xml)
00203 {
00204
00205 const char * xyz_str = origin_xml->Attribute("xyz");
00206 const char * rpy_str = origin_xml->Attribute("rpy");
00207
00208
00209 std::vector<std::string> xyz_pieces;
00210 boost::split(xyz_pieces, xyz_str, boost::is_any_of(" "));
00211
00212 if (xyz_pieces.size() == 3)
00213 {
00214
00215 for (int i = 0; i < 3; ++i)
00216 {
00217 double x = double(boost::lexical_cast<double>(xyz_pieces[i]) + xyz[i]);
00218 if (i > 0)
00219 xyz_ss << " ";
00220 xyz_ss << std::fixed << std::setprecision(precision) << x;
00221 }
00222 }
00223 else
00224 {
00225
00226 for (int i = 0; i < 3; ++i)
00227 {
00228 if (i > 0)
00229 xyz_ss << " ";
00230 xyz_ss << std::fixed << std::setprecision(precision) << xyz[i];
00231 }
00232 }
00233
00234
00235 std::vector<std::string> rpy_pieces;
00236 boost::split(rpy_pieces, rpy_str, boost::is_any_of(" "));
00237
00238 if (rpy_pieces.size() == 3)
00239 {
00240
00241 for (int i = 0; i < 3; ++i)
00242 {
00243 double x = double(boost::lexical_cast<double>(rpy_pieces[i]) + rpy[i]);
00244 if (i > 0)
00245 rpy_ss << " ";
00246 rpy_ss << std::fixed << std::setprecision(precision) << x;
00247 }
00248 }
00249 else
00250 {
00251
00252 for (int i = 0; i < 3; ++i)
00253 {
00254 if (i > 0)
00255 rpy_ss << " ";
00256 rpy_ss << std::fixed << std::setprecision(precision) << rpy[i];
00257 }
00258 }
00259
00260
00261 origin_xml->SetAttribute("xyz", xyz_ss.str());
00262 origin_xml->SetAttribute("rpy", rpy_ss.str());
00263 }
00264 else
00265 {
00266
00267 origin_xml = new TiXmlElement("origin");
00268
00269
00270 for (int i = 0; i < 3; ++i)
00271 {
00272 if (i > 0)
00273 xyz_ss << " ";
00274 xyz_ss << std::fixed << std::setprecision(precision) << xyz[i];
00275 }
00276 origin_xml->SetAttribute("xyz", xyz_ss.str());
00277
00278
00279 for (int i = 0; i < 3; ++i)
00280 {
00281 if (i > 0)
00282 rpy_ss << " ";
00283 rpy_ss << std::fixed << std::setprecision(precision) << rpy[i];
00284 }
00285 origin_xml->SetAttribute("rpy", rpy_ss.str());
00286
00287 TiXmlNode * origin = origin_xml->Clone();
00288 joint_xml->InsertEndChild(*origin);
00289 }
00290 }
00291 }
00292
00293
00294 TiXmlPrinter printer;
00295 printer.SetIndent(" ");
00296 xml_doc.Accept(&printer);
00297 std::string new_urdf = printer.CStr();
00298
00299 return new_urdf;
00300 }
00301
00302 }