规范模块目录和第三方依赖结构
This commit is contained in:
642
third_party/kdl_parser/src/joint.cpp
vendored
Normal file
642
third_party/kdl_parser/src/joint.cpp
vendored
Normal file
@@ -0,0 +1,642 @@
|
||||
/*********************************************************************
|
||||
* Software Ligcense Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: John Hsu */
|
||||
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <urdf_model/joint.h>
|
||||
//#include <console_bridge/console.h>
|
||||
#include <tinyxml.h>
|
||||
#include <urdf_parser/urdf_parser.h>
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parsePose(Pose &pose, TiXmlElement* xml);
|
||||
|
||||
bool parseJointDynamics(JointDynamics &jd, TiXmlElement* config)
|
||||
{
|
||||
jd.clear();
|
||||
|
||||
// Get joint damping
|
||||
const char* damping_str = config->Attribute("damping");
|
||||
if (damping_str == NULL){
|
||||
////CONSOLE_BRIDGE_logDebug("urdfdom.joint_dynamics: no damping, defaults to 0");
|
||||
jd.damping = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jd.damping = strToDouble(damping_str);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("damping value (%s) is not a valid float", damping_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get joint friction
|
||||
const char* friction_str = config->Attribute("friction");
|
||||
if (friction_str == NULL){
|
||||
////CONSOLE_BRIDGE_logDebug("urdfdom.joint_dynamics: no friction, defaults to 0");
|
||||
jd.friction = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jd.friction = strToDouble(friction_str);
|
||||
} catch (std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("friction value (%s) is not a valid float", friction_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (damping_str == NULL && friction_str == NULL)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("joint dynamics element specified with no damping and no friction");
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_dynamics: damping %f and friction %f", jd.damping, jd.friction);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool parseJointLimits(JointLimits &jl, TiXmlElement* config)
|
||||
{
|
||||
jl.clear();
|
||||
|
||||
// Get lower joint limit
|
||||
const char* lower_str = config->Attribute("lower");
|
||||
if (lower_str == NULL){
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_limit: no lower, defaults to 0");
|
||||
jl.lower = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jl.lower = strToDouble(lower_str);
|
||||
} catch (std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("lower value (%s) is not a valid float", lower_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get upper joint limit
|
||||
const char* upper_str = config->Attribute("upper");
|
||||
if (upper_str == NULL){
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_limit: no upper, , defaults to 0");
|
||||
jl.upper = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jl.upper = strToDouble(upper_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("upper value (%s) is not a valid float", upper_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get joint effort limit
|
||||
const char* effort_str = config->Attribute("effort");
|
||||
if (effort_str == NULL){
|
||||
////CONSOLE_BRIDGE_logError("joint limit: no effort");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jl.effort = strToDouble(effort_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("effort value (%s) is not a valid float", effort_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get joint velocity limit
|
||||
const char* velocity_str = config->Attribute("velocity");
|
||||
if (velocity_str == NULL){
|
||||
////CONSOLE_BRIDGE_logError("joint limit: no velocity");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jl.velocity = strToDouble(velocity_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("velocity value (%s) is not a valid float", velocity_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseJointSafety(JointSafety &js, TiXmlElement* config)
|
||||
{
|
||||
js.clear();
|
||||
|
||||
// Get soft_lower_limit joint limit
|
||||
const char* soft_lower_limit_str = config->Attribute("soft_lower_limit");
|
||||
if (soft_lower_limit_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_safety: no soft_lower_limit, using default value");
|
||||
js.soft_lower_limit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
js.soft_lower_limit = strToDouble(soft_lower_limit_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("soft_lower_limit value (%s) is not a valid float", soft_lower_limit_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get soft_upper_limit joint limit
|
||||
const char* soft_upper_limit_str = config->Attribute("soft_upper_limit");
|
||||
if (soft_upper_limit_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_safety: no soft_upper_limit, using default value");
|
||||
js.soft_upper_limit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
js.soft_upper_limit = strToDouble(soft_upper_limit_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("soft_upper_limit value (%s) is not a valid float", soft_upper_limit_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get k_position_ safety "position" gain - not exactly position gain
|
||||
const char* k_position_str = config->Attribute("k_position");
|
||||
if (k_position_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_safety: no k_position, using default value");
|
||||
js.k_position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
js.k_position = strToDouble(k_position_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("k_position value (%s) is not a valid float", k_position_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Get k_velocity_ safety velocity gain
|
||||
const char* k_velocity_str = config->Attribute("k_velocity");
|
||||
if (k_velocity_str == NULL)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("joint safety: no k_velocity");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
js.k_velocity = strToDouble(k_velocity_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("k_velocity value (%s) is not a valid float", k_velocity_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseJointCalibration(JointCalibration &jc, TiXmlElement* config)
|
||||
{
|
||||
jc.clear();
|
||||
|
||||
// Get rising edge position
|
||||
const char* rising_position_str = config->Attribute("rising");
|
||||
if (rising_position_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_calibration: no rising, using default value");
|
||||
jc.rising.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jc.rising.reset(new double(strToDouble(rising_position_str)));
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("rising value (%s) is not a valid float", rising_position_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get falling edge position
|
||||
const char* falling_position_str = config->Attribute("falling");
|
||||
if (falling_position_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_calibration: no falling, using default value");
|
||||
jc.falling.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jc.falling.reset(new double(strToDouble(falling_position_str)));
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("falling value (%s) is not a valid float", falling_position_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseJointMimic(JointMimic &jm, TiXmlElement* config)
|
||||
{
|
||||
jm.clear();
|
||||
|
||||
// Get name of joint to mimic
|
||||
const char* joint_name_str = config->Attribute("joint");
|
||||
|
||||
if (joint_name_str == NULL)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("joint mimic: no mimic joint specified");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
jm.joint_name = joint_name_str;
|
||||
|
||||
// Get mimic multiplier
|
||||
const char* multiplier_str = config->Attribute("multiplier");
|
||||
|
||||
if (multiplier_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_mimic: no multiplier, using default value of 1");
|
||||
jm.multiplier = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jm.multiplier = strToDouble(multiplier_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("multiplier value (%s) is not a valid float", multiplier_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get mimic offset
|
||||
const char* offset_str = config->Attribute("offset");
|
||||
if (offset_str == NULL)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom.joint_mimic: no offset, using default value of 0");
|
||||
jm.offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
jm.offset = strToDouble(offset_str);
|
||||
} catch(std::runtime_error &) {
|
||||
////CONSOLE_BRIDGE_logError("offset value (%s) is not a valid float", offset_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseJoint(Joint &joint, TiXmlElement* config)
|
||||
{
|
||||
joint.clear();
|
||||
|
||||
// Get Joint Name
|
||||
const char *name = config->Attribute("name");
|
||||
if (!name)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("unnamed joint found");
|
||||
return false;
|
||||
}
|
||||
joint.name = name;
|
||||
|
||||
// Get transform from Parent Link to Joint Frame
|
||||
TiXmlElement *origin_xml = config->FirstChildElement("origin");
|
||||
if (!origin_xml)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: Joint [%s] missing origin tag under parent describing transform from Parent Link to Joint Frame, (using Identity transform).", joint.name.c_str());
|
||||
joint.parent_to_joint_origin_transform.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parsePose(joint.parent_to_joint_origin_transform, origin_xml))
|
||||
{
|
||||
joint.parent_to_joint_origin_transform.clear();
|
||||
////CONSOLE_BRIDGE_logError("Malformed parent origin element for joint [%s]", joint.name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get Parent Link
|
||||
TiXmlElement *parent_xml = config->FirstChildElement("parent");
|
||||
if (parent_xml)
|
||||
{
|
||||
const char *pname = parent_xml->Attribute("link");
|
||||
if (!pname)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logInform("no parent link name specified for Joint link [%s]. this might be the root?", joint.name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
joint.parent_link_name = std::string(pname);
|
||||
}
|
||||
}
|
||||
|
||||
// Get Child Link
|
||||
TiXmlElement *child_xml = config->FirstChildElement("child");
|
||||
if (child_xml)
|
||||
{
|
||||
const char *pname = child_xml->Attribute("link");
|
||||
if (!pname)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logInform("no child link name specified for Joint link [%s].", joint.name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
joint.child_link_name = std::string(pname);
|
||||
}
|
||||
}
|
||||
|
||||
// Get Joint type
|
||||
const char* type_char = config->Attribute("type");
|
||||
if (!type_char)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("joint [%s] has no type, check to see if it's a reference.", joint.name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string type_str = type_char;
|
||||
if (type_str == "planar")
|
||||
joint.type = Joint::PLANAR;
|
||||
else if (type_str == "floating")
|
||||
joint.type = Joint::FLOATING;
|
||||
else if (type_str == "revolute")
|
||||
joint.type = Joint::REVOLUTE;
|
||||
else if (type_str == "continuous")
|
||||
joint.type = Joint::CONTINUOUS;
|
||||
else if (type_str == "prismatic")
|
||||
joint.type = Joint::PRISMATIC;
|
||||
else if (type_str == "fixed")
|
||||
joint.type = Joint::FIXED;
|
||||
else
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("Joint [%s] has no known type [%s]", joint.name.c_str(), type_str.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Joint Axis
|
||||
if (joint.type != Joint::FLOATING && joint.type != Joint::FIXED)
|
||||
{
|
||||
// axis
|
||||
TiXmlElement *axis_xml = config->FirstChildElement("axis");
|
||||
if (!axis_xml){
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: no axis elemement for Joint link [%s], defaulting to (1,0,0) axis", joint.name.c_str());
|
||||
joint.axis = Vector3(1.0, 0.0, 0.0);
|
||||
}
|
||||
else{
|
||||
if (axis_xml->Attribute("xyz")){
|
||||
try {
|
||||
joint.axis.init(axis_xml->Attribute("xyz"));
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
joint.axis.clear();
|
||||
////CONSOLE_BRIDGE_logError("Malformed axis element for joint [%s]: %s", joint.name.c_str(), e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get limit
|
||||
TiXmlElement *limit_xml = config->FirstChildElement("limit");
|
||||
if (limit_xml)
|
||||
{
|
||||
joint.limits.reset(new JointLimits());
|
||||
if (!parseJointLimits(*joint.limits, limit_xml))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Could not parse limit element for joint [%s]", joint.name.c_str());
|
||||
joint.limits.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (joint.type == Joint::REVOLUTE)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Joint [%s] is of type REVOLUTE but it does not specify limits", joint.name.c_str());
|
||||
return false;
|
||||
}
|
||||
else if (joint.type == Joint::PRISMATIC)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Joint [%s] is of type PRISMATIC without limits", joint.name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get safety
|
||||
TiXmlElement *safety_xml = config->FirstChildElement("safety_controller");
|
||||
if (safety_xml)
|
||||
{
|
||||
joint.safety.reset(new JointSafety());
|
||||
if (!parseJointSafety(*joint.safety, safety_xml))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Could not parse safety element for joint [%s]", joint.name.c_str());
|
||||
joint.safety.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get calibration
|
||||
TiXmlElement *calibration_xml = config->FirstChildElement("calibration");
|
||||
if (calibration_xml)
|
||||
{
|
||||
joint.calibration.reset(new JointCalibration());
|
||||
if (!parseJointCalibration(*joint.calibration, calibration_xml))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Could not parse calibration element for joint [%s]", joint.name.c_str());
|
||||
joint.calibration.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get Joint Mimic
|
||||
TiXmlElement *mimic_xml = config->FirstChildElement("mimic");
|
||||
if (mimic_xml)
|
||||
{
|
||||
joint.mimic.reset(new JointMimic());
|
||||
if (!parseJointMimic(*joint.mimic, mimic_xml))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Could not parse mimic element for joint [%s]", joint.name.c_str());
|
||||
joint.mimic.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get Dynamics
|
||||
TiXmlElement *prop_xml = config->FirstChildElement("dynamics");
|
||||
if (prop_xml)
|
||||
{
|
||||
joint.dynamics.reset(new JointDynamics());
|
||||
if (!parseJointDynamics(*joint.dynamics, prop_xml))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Could not parse joint_dynamics element for joint [%s]", joint.name.c_str());
|
||||
joint.dynamics.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* exports */
|
||||
bool exportPose(Pose &pose, TiXmlElement* xml);
|
||||
|
||||
bool exportJointDynamics(JointDynamics &jd, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement *dynamics_xml = new TiXmlElement("dynamics");
|
||||
dynamics_xml->SetAttribute("damping", urdf_export_helpers::values2str(jd.damping) );
|
||||
dynamics_xml->SetAttribute("friction", urdf_export_helpers::values2str(jd.friction) );
|
||||
xml->LinkEndChild(dynamics_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportJointLimits(JointLimits &jl, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement *limit_xml = new TiXmlElement("limit");
|
||||
limit_xml->SetAttribute("effort", urdf_export_helpers::values2str(jl.effort) );
|
||||
limit_xml->SetAttribute("velocity", urdf_export_helpers::values2str(jl.velocity) );
|
||||
limit_xml->SetAttribute("lower", urdf_export_helpers::values2str(jl.lower) );
|
||||
limit_xml->SetAttribute("upper", urdf_export_helpers::values2str(jl.upper) );
|
||||
xml->LinkEndChild(limit_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportJointSafety(JointSafety &js, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement *safety_xml = new TiXmlElement("safety_controller");
|
||||
safety_xml->SetAttribute("k_position", urdf_export_helpers::values2str(js.k_position) );
|
||||
safety_xml->SetAttribute("k_velocity", urdf_export_helpers::values2str(js.k_velocity) );
|
||||
safety_xml->SetAttribute("soft_lower_limit", urdf_export_helpers::values2str(js.soft_lower_limit) );
|
||||
safety_xml->SetAttribute("soft_upper_limit", urdf_export_helpers::values2str(js.soft_upper_limit) );
|
||||
xml->LinkEndChild(safety_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportJointCalibration(JointCalibration &jc, TiXmlElement* xml)
|
||||
{
|
||||
if (jc.falling || jc.rising)
|
||||
{
|
||||
TiXmlElement *calibration_xml = new TiXmlElement("calibration");
|
||||
if (jc.falling)
|
||||
calibration_xml->SetAttribute("falling", urdf_export_helpers::values2str(*jc.falling) );
|
||||
if (jc.rising)
|
||||
calibration_xml->SetAttribute("rising", urdf_export_helpers::values2str(*jc.rising) );
|
||||
//calibration_xml->SetAttribute("reference_position", urdf_export_helpers::values2str(jc.reference_position) );
|
||||
xml->LinkEndChild(calibration_xml);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportJointMimic(JointMimic &jm, TiXmlElement* xml)
|
||||
{
|
||||
if (!jm.joint_name.empty())
|
||||
{
|
||||
TiXmlElement *mimic_xml = new TiXmlElement("mimic");
|
||||
mimic_xml->SetAttribute("offset", urdf_export_helpers::values2str(jm.offset) );
|
||||
mimic_xml->SetAttribute("multiplier", urdf_export_helpers::values2str(jm.multiplier) );
|
||||
mimic_xml->SetAttribute("joint", jm.joint_name );
|
||||
xml->LinkEndChild(mimic_xml);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportJoint(Joint &joint, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement * joint_xml = new TiXmlElement("joint");
|
||||
joint_xml->SetAttribute("name", joint.name);
|
||||
if (joint.type == urdf::Joint::PLANAR)
|
||||
joint_xml->SetAttribute("type", "planar");
|
||||
else if (joint.type == urdf::Joint::FLOATING)
|
||||
joint_xml->SetAttribute("type", "floating");
|
||||
else if (joint.type == urdf::Joint::REVOLUTE)
|
||||
joint_xml->SetAttribute("type", "revolute");
|
||||
else if (joint.type == urdf::Joint::CONTINUOUS)
|
||||
joint_xml->SetAttribute("type", "continuous");
|
||||
else if (joint.type == urdf::Joint::PRISMATIC)
|
||||
joint_xml->SetAttribute("type", "prismatic");
|
||||
else if (joint.type == urdf::Joint::FIXED)
|
||||
joint_xml->SetAttribute("type", "fixed");
|
||||
else
|
||||
//CONSOLE_BRIDGE_logError("ERROR: Joint [%s] type [%d] is not a defined type.\n",joint.name.c_str(), joint.type);
|
||||
|
||||
// origin
|
||||
exportPose(joint.parent_to_joint_origin_transform, joint_xml);
|
||||
|
||||
// axis
|
||||
TiXmlElement * axis_xml = new TiXmlElement("axis");
|
||||
axis_xml->SetAttribute("xyz", urdf_export_helpers::values2str(joint.axis));
|
||||
joint_xml->LinkEndChild(axis_xml);
|
||||
|
||||
// parent
|
||||
TiXmlElement * parent_xml = new TiXmlElement("parent");
|
||||
parent_xml->SetAttribute("link", joint.parent_link_name);
|
||||
joint_xml->LinkEndChild(parent_xml);
|
||||
|
||||
// child
|
||||
TiXmlElement * child_xml = new TiXmlElement("child");
|
||||
child_xml->SetAttribute("link", joint.child_link_name);
|
||||
joint_xml->LinkEndChild(child_xml);
|
||||
|
||||
if (joint.dynamics)
|
||||
exportJointDynamics(*(joint.dynamics), joint_xml);
|
||||
if (joint.limits)
|
||||
exportJointLimits(*(joint.limits), joint_xml);
|
||||
if (joint.safety)
|
||||
exportJointSafety(*(joint.safety), joint_xml);
|
||||
if (joint.calibration)
|
||||
exportJointCalibration(*(joint.calibration), joint_xml);
|
||||
if (joint.mimic)
|
||||
exportJointMimic(*(joint.mimic), joint_xml);
|
||||
|
||||
xml->LinkEndChild(joint_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
261
third_party/kdl_parser/src/kdl_parser.cpp
vendored
Normal file
261
third_party/kdl_parser/src/kdl_parser.cpp
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: Wim Meeussen */
|
||||
|
||||
#include "kdl_parser/kdl_parser.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <urdf_model/model.h>
|
||||
#include <urdf_parser/urdf_parser.h>
|
||||
|
||||
#include <kdl/frames_io.hpp>
|
||||
|
||||
//#ifdef HAS_ROS
|
||||
//#include <ros/console.h>
|
||||
//#else
|
||||
// forward ROS warnings and errors to stderr
|
||||
#define ROS_DEBUG(...) fprintf(stdout, __VA_ARGS__);
|
||||
#define ROS_ERROR(...) fprintf(stderr, __VA_ARGS__);
|
||||
#define ROS_WARN(...) fprintf(stderr, __VA_ARGS__);
|
||||
//#endif
|
||||
|
||||
//#ifdef HAS_URDF
|
||||
#include <urdf_model/model.h>
|
||||
//#include <urdf_model/urdfdom_compatibility.h>
|
||||
//#endif
|
||||
|
||||
namespace kdl_parser
|
||||
{
|
||||
// construct vector
|
||||
KDL::Vector toKdl(urdf::Vector3 v)
|
||||
{
|
||||
return KDL::Vector(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
// construct rotation
|
||||
KDL::Rotation toKdl(urdf::Rotation r)
|
||||
{
|
||||
return KDL::Rotation::Quaternion(r.x, r.y, r.z, r.w);
|
||||
}
|
||||
|
||||
// construct pose
|
||||
KDL::Frame toKdl(urdf::Pose p)
|
||||
{
|
||||
return KDL::Frame(toKdl(p.rotation), toKdl(p.position));
|
||||
}
|
||||
|
||||
// construct joint
|
||||
KDL::Joint toKdl(urdf::JointSharedPtr jnt)
|
||||
{
|
||||
KDL::Frame F_parent_jnt = toKdl(jnt->parent_to_joint_origin_transform);
|
||||
|
||||
switch (jnt->type) {
|
||||
case urdf::Joint::FIXED: {
|
||||
return KDL::Joint(jnt->name, KDL::Joint::None);
|
||||
}
|
||||
case urdf::Joint::REVOLUTE: {
|
||||
KDL::Vector axis = toKdl(jnt->axis);
|
||||
return KDL::Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, KDL::Joint::RotAxis);
|
||||
}
|
||||
case urdf::Joint::CONTINUOUS: {
|
||||
KDL::Vector axis = toKdl(jnt->axis);
|
||||
return KDL::Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, KDL::Joint::RotAxis);
|
||||
}
|
||||
case urdf::Joint::PRISMATIC: {
|
||||
KDL::Vector axis = toKdl(jnt->axis);
|
||||
return KDL::Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, KDL::Joint::TransAxis);
|
||||
}
|
||||
default: {
|
||||
ROS_WARN("Converting unknown joint type of joint '%s' into a fixed joint", jnt->name.c_str());
|
||||
return KDL::Joint(jnt->name, KDL::Joint::None);
|
||||
}
|
||||
}
|
||||
return KDL::Joint();
|
||||
}
|
||||
|
||||
// construct inertia
|
||||
KDL::RigidBodyInertia toKdl(urdf::InertialSharedPtr i)
|
||||
{
|
||||
KDL::Frame origin = toKdl(i->origin);
|
||||
|
||||
// the mass is frame independent
|
||||
double kdl_mass = i->mass;
|
||||
|
||||
// kdl and urdf both specify the com position in the reference frame of the link
|
||||
KDL::Vector kdl_com = origin.p;
|
||||
|
||||
// kdl specifies the inertia matrix in the reference frame of the link,
|
||||
// while the urdf specifies the inertia matrix in the inertia reference frame
|
||||
KDL::RotationalInertia urdf_inertia =
|
||||
KDL::RotationalInertia(i->ixx, i->iyy, i->izz, i->ixy, i->ixz, i->iyz);
|
||||
|
||||
// Rotation operators are not defined for rotational inertia,
|
||||
// so we use the RigidBodyInertia operators (with com = 0) as a workaround
|
||||
KDL::RigidBodyInertia kdl_inertia_wrt_com_workaround =
|
||||
origin.M * KDL::RigidBodyInertia(0, KDL::Vector::Zero(), urdf_inertia);
|
||||
|
||||
// Note that the RigidBodyInertia constructor takes the 3d inertia wrt the com
|
||||
// while the getRotationalInertia method returns the 3d inertia wrt the frame origin
|
||||
// (but having com = Vector::Zero() in kdl_inertia_wrt_com_workaround they match)
|
||||
KDL::RotationalInertia kdl_inertia_wrt_com =
|
||||
kdl_inertia_wrt_com_workaround.getRotationalInertia();
|
||||
|
||||
return KDL::RigidBodyInertia(kdl_mass, kdl_com, kdl_inertia_wrt_com);
|
||||
}
|
||||
|
||||
|
||||
// recursive function to walk through tree
|
||||
bool addChildrenToTree(urdf::LinkConstSharedPtr root, KDL::Tree & tree)
|
||||
{
|
||||
std::vector<urdf::LinkSharedPtr> children = root->child_links;
|
||||
ROS_DEBUG("Link %s had %zu children", root->name.c_str(), children.size());
|
||||
|
||||
// constructs the optional inertia
|
||||
KDL::RigidBodyInertia inert(0);
|
||||
if (root->inertial) {
|
||||
inert = toKdl(root->inertial);
|
||||
}
|
||||
|
||||
// constructs the kdl joint
|
||||
KDL::Joint jnt = toKdl(root->parent_joint);
|
||||
|
||||
// construct the kdl segment
|
||||
KDL::Segment sgm(root->name, jnt, toKdl(
|
||||
root->parent_joint->parent_to_joint_origin_transform), inert);
|
||||
|
||||
// add segment to tree
|
||||
tree.addSegment(sgm, root->parent_joint->parent_link_name);
|
||||
|
||||
// recurslively add all children
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
if (!addChildrenToTree(children[i], tree)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool treeFromFileDocument(const std::string & file, KDL::Tree & tree)
|
||||
{
|
||||
const urdf::ModelInterfaceSharedPtr robot_model = urdf::parseURDFFileDocument(file);
|
||||
return kdl_parser::treeFromUrdfModel(*robot_model, tree);
|
||||
}
|
||||
|
||||
bool treeFromFile(const std::string& file, KDL::Tree& tree)
|
||||
{
|
||||
const urdf::ModelInterfaceSharedPtr robot_model = urdf::parseURDFFile(file);
|
||||
return kdl_parser::treeFromUrdfModel(*robot_model, tree);
|
||||
}
|
||||
|
||||
bool treeFromParam(const std::string & param, KDL::Tree & tree)
|
||||
{
|
||||
#if defined(HAS_ROS) && defined(HAS_URDF)
|
||||
urdf::Model robot_model;
|
||||
if (!robot_model.initParam(param)){
|
||||
ROS_ERROR("Could not generate robot model");
|
||||
return false;
|
||||
}
|
||||
return treeFromUrdfModel(robot_model, tree);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool treeFromString(const std::string & xml, KDL::Tree & tree)
|
||||
{
|
||||
const urdf::ModelInterfaceSharedPtr robot_model = urdf::parseURDF(xml);
|
||||
if (!robot_model) {
|
||||
ROS_ERROR("Could not generate robot model");
|
||||
return false;
|
||||
}
|
||||
return kdl_parser::treeFromUrdfModel(*robot_model, tree);
|
||||
}
|
||||
|
||||
bool treeFromXml(const tinyxml2::XMLDocument * xml_doc, KDL::Tree & tree)
|
||||
{
|
||||
if (!xml_doc) {
|
||||
ROS_ERROR("Could not parse the xml document");
|
||||
return false;
|
||||
}
|
||||
|
||||
tinyxml2::XMLPrinter printer;
|
||||
xml_doc->Print(&printer);
|
||||
|
||||
return treeFromString(printer.CStr(), tree);
|
||||
}
|
||||
|
||||
bool treeFromXml(TiXmlDocument * xml_doc, KDL::Tree & tree)
|
||||
{
|
||||
if (!xml_doc) {
|
||||
ROS_ERROR("Could not parse the xml document");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << *xml_doc;
|
||||
|
||||
return treeFromString(ss.str(), tree);
|
||||
}
|
||||
|
||||
bool treeFromUrdfModel(const urdf::ModelInterface & robot_model, KDL::Tree & tree)
|
||||
{
|
||||
if (!robot_model.getRoot()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tree = KDL::Tree(robot_model.getRoot()->name);
|
||||
|
||||
// warn if root link has inertia. KDL does not support this
|
||||
if (robot_model.getRoot()->inertial) {
|
||||
ROS_WARN("The root link %s has an inertia specified in the URDF, but KDL does not "
|
||||
"support a root link with an inertia. As a workaround, you can add an extra "
|
||||
"dummy link to your URDF.", robot_model.getRoot()->name.c_str());
|
||||
}
|
||||
|
||||
// add all children
|
||||
for (size_t i = 0; i < robot_model.getRoot()->child_links.size(); i++) {
|
||||
if (!addChildrenToTree(robot_model.getRoot()->child_links[i], tree)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace kdl_parser
|
||||
670
third_party/kdl_parser/src/link.cpp
vendored
Normal file
670
third_party/kdl_parser/src/link.cpp
vendored
Normal file
@@ -0,0 +1,670 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: Wim Meeussen */
|
||||
|
||||
|
||||
#include <urdf_parser/urdf_parser.h>
|
||||
#include <urdf_model/link.h>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <tinyxml.h>
|
||||
//#include <console_bridge/console.h>
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parsePose(Pose &pose, TiXmlElement* xml);
|
||||
|
||||
bool parseMaterial(Material &material, TiXmlElement *config, bool only_name_is_ok)
|
||||
{
|
||||
bool has_rgb = false;
|
||||
bool has_filename = false;
|
||||
|
||||
material.clear();
|
||||
|
||||
if (!config->Attribute("name"))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Material must contain a name attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
material.name = config->Attribute("name");
|
||||
|
||||
// texture
|
||||
TiXmlElement *t = config->FirstChildElement("texture");
|
||||
if (t)
|
||||
{
|
||||
if (t->Attribute("filename"))
|
||||
{
|
||||
material.texture_filename = t->Attribute("filename");
|
||||
has_filename = true;
|
||||
}
|
||||
}
|
||||
|
||||
// color
|
||||
TiXmlElement *c = config->FirstChildElement("color");
|
||||
if (c)
|
||||
{
|
||||
if (c->Attribute("rgba")) {
|
||||
|
||||
try {
|
||||
material.color.init(c->Attribute("rgba"));
|
||||
has_rgb = true;
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
material.color.clear();
|
||||
//CONSOLE_BRIDGE_logError(std::string("Material [" + material.name + "] has malformed color rgba values: " + e.what()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_rgb && !has_filename) {
|
||||
if (!only_name_is_ok) // no need for an error if only name is ok
|
||||
{
|
||||
if (!has_rgb) //CONSOLE_BRIDGE_logError(std::string("Material ["+material.name+"] color has no rgba").c_str());
|
||||
if (!has_filename){ //CONSOLE_BRIDGE_logError(std::string("Material ["+material.name+"] not defined in file").c_str());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool parseSphere(Sphere &s, TiXmlElement *c)
|
||||
{
|
||||
s.clear();
|
||||
|
||||
s.type = Geometry::SPHERE;
|
||||
if (!c->Attribute("radius"))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Sphere shape must have a radius attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
s.radius = strToDouble(c->Attribute("radius"));
|
||||
} catch(std::runtime_error &) {
|
||||
std::stringstream stm;
|
||||
stm << "radius [" << c->Attribute("radius") << "] is not a valid float";
|
||||
//CONSOLE_BRIDGE_logError(stm.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseBox(Box &b, TiXmlElement *c)
|
||||
{
|
||||
b.clear();
|
||||
|
||||
b.type = Geometry::BOX;
|
||||
if (!c->Attribute("size"))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Box shape has no size attribute");
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
b.dim.init(c->Attribute("size"));
|
||||
}
|
||||
catch (ParseError &e)
|
||||
{
|
||||
b.dim.clear();
|
||||
//CONSOLE_BRIDGE_logError(e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseCylinder(Cylinder &y, TiXmlElement *c)
|
||||
{
|
||||
y.clear();
|
||||
|
||||
y.type = Geometry::CYLINDER;
|
||||
if (!c->Attribute("length") ||
|
||||
!c->Attribute("radius"))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Cylinder shape must have both length and radius attributes");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
y.length = strToDouble(c->Attribute("length"));
|
||||
} catch(std::runtime_error &) {
|
||||
std::stringstream stm;
|
||||
stm << "length [" << c->Attribute("length") << "] is not a valid float";
|
||||
//CONSOLE_BRIDGE_logError(stm.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
y.radius = strToDouble(c->Attribute("radius"));
|
||||
} catch(std::runtime_error &) {
|
||||
std::stringstream stm;
|
||||
stm << "radius [" << c->Attribute("radius") << "] is not a valid float";
|
||||
//CONSOLE_BRIDGE_logError(stm.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool parseMesh(Mesh &m, TiXmlElement *c)
|
||||
{
|
||||
m.clear();
|
||||
|
||||
m.type = Geometry::MESH;
|
||||
if (!c->Attribute("filename")) {
|
||||
//CONSOLE_BRIDGE_logError("Mesh must contain a filename attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
m.filename = c->Attribute("filename");
|
||||
|
||||
if (c->Attribute("scale")) {
|
||||
try {
|
||||
m.scale.init(c->Attribute("scale"));
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
m.scale.clear();
|
||||
//CONSOLE_BRIDGE_logError("Mesh scale was specified, but could not be parsed: %s", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.scale.x = m.scale.y = m.scale.z = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GeometrySharedPtr parseGeometry(TiXmlElement *g)
|
||||
{
|
||||
GeometrySharedPtr geom;
|
||||
if (!g) return geom;
|
||||
|
||||
TiXmlElement *shape = g->FirstChildElement();
|
||||
if (!shape)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Geometry tag contains no child element.");
|
||||
return geom;
|
||||
}
|
||||
|
||||
std::string type_name = shape->ValueStr();
|
||||
|
||||
if (type_name == "sphere")
|
||||
{
|
||||
Sphere *s = new Sphere();
|
||||
geom.reset(s);
|
||||
if (parseSphere(*s, shape))
|
||||
return geom;
|
||||
}
|
||||
else if (type_name == "box")
|
||||
{
|
||||
Box *b = new Box();
|
||||
geom.reset(b);
|
||||
if (parseBox(*b, shape))
|
||||
return geom;
|
||||
}
|
||||
else if (type_name == "cylinder")
|
||||
{
|
||||
Cylinder *c = new Cylinder();
|
||||
geom.reset(c);
|
||||
if (parseCylinder(*c, shape))
|
||||
return geom;
|
||||
}
|
||||
else if (type_name == "mesh")
|
||||
{
|
||||
Mesh *m = new Mesh();
|
||||
geom.reset(m);
|
||||
if (parseMesh(*m, shape))
|
||||
return geom;
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Unknown geometry type '%s'", type_name.c_str());
|
||||
return geom;
|
||||
}
|
||||
|
||||
return GeometrySharedPtr();
|
||||
}
|
||||
|
||||
bool parseInertial(Inertial &i, TiXmlElement *config)
|
||||
{
|
||||
i.clear();
|
||||
|
||||
// Origin
|
||||
TiXmlElement *o = config->FirstChildElement("origin");
|
||||
if (o)
|
||||
{
|
||||
if (!parsePose(i.origin, o))
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlElement *mass_xml = config->FirstChildElement("mass");
|
||||
if (!mass_xml)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Inertial element must have a mass element");
|
||||
return false;
|
||||
}
|
||||
if (!mass_xml->Attribute("value"))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Inertial: mass element must have value attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
i.mass = strToDouble(mass_xml->Attribute("value"));
|
||||
} catch(std::runtime_error &) {
|
||||
std::stringstream stm;
|
||||
stm << "Inertial: mass [" << mass_xml->Attribute("value")
|
||||
<< "] is not a float";
|
||||
//CONSOLE_BRIDGE_logError(stm.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlElement *inertia_xml = config->FirstChildElement("inertia");
|
||||
if (!inertia_xml)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Inertial element must have inertia element");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, double>> attrs{
|
||||
std::make_pair("ixx", 0.0),
|
||||
std::make_pair("ixy", 0.0),
|
||||
std::make_pair("ixz", 0.0),
|
||||
std::make_pair("iyy", 0.0),
|
||||
std::make_pair("iyz", 0.0),
|
||||
std::make_pair("izz", 0.0)
|
||||
};
|
||||
|
||||
for (auto& attr : attrs)
|
||||
{
|
||||
if (!inertia_xml->Attribute(attr.first))
|
||||
{
|
||||
std::stringstream stm;
|
||||
stm << "Inertial: inertia element missing " << attr.first << " attribute";
|
||||
//CONSOLE_BRIDGE_logError(stm.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
attr.second = strToDouble(inertia_xml->Attribute(attr.first.c_str()));
|
||||
} catch(std::runtime_error &) {
|
||||
std::stringstream stm;
|
||||
stm << "Inertial: inertia element " << attr.first << " is not a valid double";
|
||||
//CONSOLE_BRIDGE_logError(stm.str().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
i.ixx = attrs[0].second;
|
||||
i.ixy = attrs[1].second;
|
||||
i.ixz = attrs[2].second;
|
||||
i.iyy = attrs[3].second;
|
||||
i.iyz = attrs[4].second;
|
||||
i.izz = attrs[5].second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseVisual(Visual &vis, TiXmlElement *config)
|
||||
{
|
||||
vis.clear();
|
||||
|
||||
// Origin
|
||||
TiXmlElement *o = config->FirstChildElement("origin");
|
||||
if (o) {
|
||||
if (!parsePose(vis.origin, o))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Geometry
|
||||
TiXmlElement *geom = config->FirstChildElement("geometry");
|
||||
vis.geometry = parseGeometry(geom);
|
||||
if (!vis.geometry)
|
||||
return false;
|
||||
|
||||
const char *name_char = config->Attribute("name");
|
||||
if (name_char)
|
||||
vis.name = name_char;
|
||||
|
||||
// Material
|
||||
TiXmlElement *mat = config->FirstChildElement("material");
|
||||
if (mat) {
|
||||
// get material name
|
||||
if (!mat->Attribute("name")) {
|
||||
//CONSOLE_BRIDGE_logError("Visual material must contain a name attribute");
|
||||
return false;
|
||||
}
|
||||
vis.material_name = mat->Attribute("name");
|
||||
|
||||
// try to parse material element in place
|
||||
vis.material.reset(new Material());
|
||||
if (!parseMaterial(*vis.material, mat, true))
|
||||
{
|
||||
vis.material.reset();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseCollision(Collision &col, TiXmlElement* config)
|
||||
{
|
||||
col.clear();
|
||||
|
||||
// Origin
|
||||
TiXmlElement *o = config->FirstChildElement("origin");
|
||||
if (o) {
|
||||
if (!parsePose(col.origin, o))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Geometry
|
||||
TiXmlElement *geom = config->FirstChildElement("geometry");
|
||||
col.geometry = parseGeometry(geom);
|
||||
if (!col.geometry)
|
||||
return false;
|
||||
|
||||
const char *name_char = config->Attribute("name");
|
||||
if (name_char)
|
||||
col.name = name_char;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseLink(Link &link, TiXmlElement* config)
|
||||
{
|
||||
|
||||
link.clear();
|
||||
|
||||
const char *name_char = config->Attribute("name");
|
||||
if (!name_char)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("No name given for the link.");
|
||||
return false;
|
||||
}
|
||||
link.name = std::string(name_char);
|
||||
|
||||
// Inertial (optional)
|
||||
TiXmlElement *i = config->FirstChildElement("inertial");
|
||||
if (i)
|
||||
{
|
||||
link.inertial.reset(new Inertial());
|
||||
if (!parseInertial(*link.inertial, i))
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Could not parse inertial element for Link [%s]", link.name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiple Visuals (optional)
|
||||
for (TiXmlElement* vis_xml = config->FirstChildElement("visual"); vis_xml; vis_xml = vis_xml->NextSiblingElement("visual"))
|
||||
{
|
||||
|
||||
VisualSharedPtr vis;
|
||||
vis.reset(new Visual());
|
||||
if (parseVisual(*vis, vis_xml))
|
||||
{
|
||||
link.visual_array.push_back(vis);
|
||||
}
|
||||
else
|
||||
{
|
||||
vis.reset();
|
||||
//CONSOLE_BRIDGE_logError("Could not parse visual element for Link [%s]", link.name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Visual (optional)
|
||||
// Assign the first visual to the .visual ptr, if it exists
|
||||
if (!link.visual_array.empty())
|
||||
link.visual = link.visual_array[0];
|
||||
|
||||
// Multiple Collisions (optional)
|
||||
for (TiXmlElement* col_xml = config->FirstChildElement("collision"); col_xml; col_xml = col_xml->NextSiblingElement("collision"))
|
||||
{
|
||||
CollisionSharedPtr col;
|
||||
col.reset(new Collision());
|
||||
if (parseCollision(*col, col_xml))
|
||||
{
|
||||
link.collision_array.push_back(col);
|
||||
}
|
||||
else
|
||||
{
|
||||
col.reset();
|
||||
//CONSOLE_BRIDGE_logError("Could not parse collision element for Link [%s]", link.name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Collision (optional)
|
||||
// Assign the first collision to the .collision ptr, if it exists
|
||||
if (!link.collision_array.empty())
|
||||
link.collision = link.collision_array[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* exports */
|
||||
bool exportPose(Pose &pose, TiXmlElement* xml);
|
||||
|
||||
bool exportMaterial(Material &material, TiXmlElement *xml)
|
||||
{
|
||||
TiXmlElement *material_xml = new TiXmlElement("material");
|
||||
material_xml->SetAttribute("name", material.name);
|
||||
|
||||
TiXmlElement* texture = new TiXmlElement("texture");
|
||||
if (!material.texture_filename.empty())
|
||||
texture->SetAttribute("filename", material.texture_filename);
|
||||
material_xml->LinkEndChild(texture);
|
||||
|
||||
TiXmlElement* color = new TiXmlElement("color");
|
||||
color->SetAttribute("rgba", urdf_export_helpers::values2str(material.color));
|
||||
material_xml->LinkEndChild(color);
|
||||
xml->LinkEndChild(material_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportSphere(Sphere &s, TiXmlElement *xml)
|
||||
{
|
||||
// e.g. add <sphere radius="1"/>
|
||||
TiXmlElement *sphere_xml = new TiXmlElement("sphere");
|
||||
sphere_xml->SetAttribute("radius", urdf_export_helpers::values2str(s.radius));
|
||||
xml->LinkEndChild(sphere_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportBox(Box &b, TiXmlElement *xml)
|
||||
{
|
||||
// e.g. add <box size="1 1 1"/>
|
||||
TiXmlElement *box_xml = new TiXmlElement("box");
|
||||
box_xml->SetAttribute("size", urdf_export_helpers::values2str(b.dim));
|
||||
xml->LinkEndChild(box_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportCylinder(Cylinder &y, TiXmlElement *xml)
|
||||
{
|
||||
// e.g. add <cylinder radius="1"/>
|
||||
TiXmlElement *cylinder_xml = new TiXmlElement("cylinder");
|
||||
cylinder_xml->SetAttribute("radius", urdf_export_helpers::values2str(y.radius));
|
||||
cylinder_xml->SetAttribute("length", urdf_export_helpers::values2str(y.length));
|
||||
xml->LinkEndChild(cylinder_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportMesh(Mesh &m, TiXmlElement *xml)
|
||||
{
|
||||
// e.g. add <mesh filename="my_file" scale="1 1 1"/>
|
||||
TiXmlElement *mesh_xml = new TiXmlElement("mesh");
|
||||
if (!m.filename.empty())
|
||||
mesh_xml->SetAttribute("filename", m.filename);
|
||||
mesh_xml->SetAttribute("scale", urdf_export_helpers::values2str(m.scale));
|
||||
xml->LinkEndChild(mesh_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportGeometry(GeometrySharedPtr &geom, TiXmlElement *xml)
|
||||
{
|
||||
TiXmlElement *geometry_xml = new TiXmlElement("geometry");
|
||||
if (urdf::dynamic_pointer_cast<Sphere>(geom))
|
||||
{
|
||||
exportSphere((*(urdf::dynamic_pointer_cast<Sphere>(geom).get())), geometry_xml);
|
||||
}
|
||||
else if (urdf::dynamic_pointer_cast<Box>(geom))
|
||||
{
|
||||
exportBox((*(urdf::dynamic_pointer_cast<Box>(geom).get())), geometry_xml);
|
||||
}
|
||||
else if (urdf::dynamic_pointer_cast<Cylinder>(geom))
|
||||
{
|
||||
exportCylinder((*(urdf::dynamic_pointer_cast<Cylinder>(geom).get())), geometry_xml);
|
||||
}
|
||||
else if (urdf::dynamic_pointer_cast<Mesh>(geom))
|
||||
{
|
||||
exportMesh((*(urdf::dynamic_pointer_cast<Mesh>(geom).get())), geometry_xml);
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("geometry not specified, I'll make one up for you!");
|
||||
Sphere *s = new Sphere();
|
||||
s->radius = 0.03;
|
||||
geom.reset(s);
|
||||
exportSphere((*(urdf::dynamic_pointer_cast<Sphere>(geom).get())), geometry_xml);
|
||||
}
|
||||
|
||||
xml->LinkEndChild(geometry_xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportInertial(Inertial &i, TiXmlElement *xml)
|
||||
{
|
||||
// adds <inertial>
|
||||
// <mass value="1"/>
|
||||
// <pose xyz="0 0 0" rpy="0 0 0"/>
|
||||
// <inertia ixx="1" ixy="0" />
|
||||
// </inertial>
|
||||
TiXmlElement *inertial_xml = new TiXmlElement("inertial");
|
||||
|
||||
TiXmlElement *mass_xml = new TiXmlElement("mass");
|
||||
mass_xml->SetAttribute("value", urdf_export_helpers::values2str(i.mass));
|
||||
inertial_xml->LinkEndChild(mass_xml);
|
||||
|
||||
exportPose(i.origin, inertial_xml);
|
||||
|
||||
TiXmlElement *inertia_xml = new TiXmlElement("inertia");
|
||||
inertia_xml->SetAttribute("ixx", urdf_export_helpers::values2str(i.ixx));
|
||||
inertia_xml->SetAttribute("ixy", urdf_export_helpers::values2str(i.ixy));
|
||||
inertia_xml->SetAttribute("ixz", urdf_export_helpers::values2str(i.ixz));
|
||||
inertia_xml->SetAttribute("iyy", urdf_export_helpers::values2str(i.iyy));
|
||||
inertia_xml->SetAttribute("iyz", urdf_export_helpers::values2str(i.iyz));
|
||||
inertia_xml->SetAttribute("izz", urdf_export_helpers::values2str(i.izz));
|
||||
inertial_xml->LinkEndChild(inertia_xml);
|
||||
|
||||
xml->LinkEndChild(inertial_xml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportVisual(Visual &vis, TiXmlElement *xml)
|
||||
{
|
||||
// <visual group="default">
|
||||
// <origin rpy="0 0 0" xyz="0 0 0"/>
|
||||
// <geometry>
|
||||
// <mesh filename="mesh.dae"/>
|
||||
// </geometry>
|
||||
// <material name="Grey"/>
|
||||
// </visual>
|
||||
TiXmlElement * visual_xml = new TiXmlElement("visual");
|
||||
|
||||
exportPose(vis.origin, visual_xml);
|
||||
|
||||
exportGeometry(vis.geometry, visual_xml);
|
||||
|
||||
if (vis.material)
|
||||
exportMaterial(*vis.material, visual_xml);
|
||||
|
||||
xml->LinkEndChild(visual_xml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportCollision(Collision &col, TiXmlElement* xml)
|
||||
{
|
||||
// <collision group="default">
|
||||
// <origin rpy="0 0 0" xyz="0 0 0"/>
|
||||
// <geometry>
|
||||
// <mesh filename="mesh.dae"/>
|
||||
// </geometry>
|
||||
// <material name="Grey"/>
|
||||
// </collision>
|
||||
TiXmlElement * collision_xml = new TiXmlElement("collision");
|
||||
|
||||
exportPose(col.origin, collision_xml);
|
||||
|
||||
exportGeometry(col.geometry, collision_xml);
|
||||
|
||||
xml->LinkEndChild(collision_xml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportLink(Link &link, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement * link_xml = new TiXmlElement("link");
|
||||
link_xml->SetAttribute("name", link.name);
|
||||
|
||||
if (link.inertial)
|
||||
exportInertial(*link.inertial, link_xml);
|
||||
for (std::size_t i = 0 ; i < link.visual_array.size() ; ++i)
|
||||
exportVisual(*link.visual_array[i], link_xml);
|
||||
for (std::size_t i = 0 ; i < link.collision_array.size() ; ++i)
|
||||
exportCollision(*link.collision_array[i], link_xml);
|
||||
|
||||
xml->LinkEndChild(link_xml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
326
third_party/kdl_parser/src/model.cpp
vendored
Normal file
326
third_party/kdl_parser/src/model.cpp
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: Wim Meeussen */
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "urdf_parser/urdf_parser.h"
|
||||
//#include <console_bridge/console.h>
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parseMaterial(Material &material, TiXmlElement *config, bool only_name_is_ok);
|
||||
bool parseLink(Link &link, TiXmlElement *config);
|
||||
bool parseJoint(Joint &joint, TiXmlElement *config);
|
||||
|
||||
ModelInterfaceSharedPtr parseURDFFileDocument(const std::string & xml_str)
|
||||
{
|
||||
//std::ifstream stream( path.c_str() );
|
||||
//if (!stream)
|
||||
//{
|
||||
// ////CONSOLE_BRIDGE_logError(("File " + path + " does not exist").c_str());
|
||||
// return ModelInterfaceSharedPtr();
|
||||
//}
|
||||
|
||||
//std::string xml_str((std::istreambuf_iterator<char>(stream)),
|
||||
// std::istreambuf_iterator<char>());
|
||||
return urdf::parseURDF( xml_str );
|
||||
}
|
||||
|
||||
ModelInterfaceSharedPtr parseURDFFile(const std::string& path)
|
||||
{
|
||||
std::ifstream stream( path.c_str() );
|
||||
if (!stream)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError(("File " + path + " does not exist").c_str());
|
||||
return ModelInterfaceSharedPtr();
|
||||
}
|
||||
|
||||
std::string xml_str((std::istreambuf_iterator<char>(stream)),
|
||||
std::istreambuf_iterator<char>());
|
||||
return urdf::parseURDF(xml_str);
|
||||
}
|
||||
|
||||
bool assignMaterial(const VisualSharedPtr& visual, ModelInterfaceSharedPtr& model, const char* link_name)
|
||||
{
|
||||
if (visual->material_name.empty())
|
||||
return true;
|
||||
|
||||
const MaterialSharedPtr& material = model->getMaterial(visual->material_name);
|
||||
if (material)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: setting link '%s' material to '%s'", link_name, visual->material_name.c_str());
|
||||
visual->material = material;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visual->material)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: link '%s' material '%s' defined in Visual.", link_name, visual->material_name.c_str());
|
||||
model->materials_.insert(make_pair(visual->material->name, visual->material));
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logWarn("link '%s' material '%s' undefined.", link_name,visual->material_name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ModelInterfaceSharedPtr parseURDF(const std::string &xml_string)
|
||||
{
|
||||
ModelInterfaceSharedPtr model(new ModelInterface);
|
||||
model->clear();
|
||||
|
||||
TiXmlDocument xml_doc;
|
||||
xml_doc.Parse(xml_string.c_str());
|
||||
if (xml_doc.Error())
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError(xml_doc.ErrorDesc());
|
||||
xml_doc.ClearError();
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
|
||||
TiXmlElement *robot_xml = xml_doc.FirstChildElement("robot");
|
||||
if (!robot_xml)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("Could not find the 'robot' element in the xml file");
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
|
||||
// Get robot name
|
||||
const char *name = robot_xml->Attribute("name");
|
||||
if (!name)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("No name given for the robot.");
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
model->name_ = std::string(name);
|
||||
|
||||
try
|
||||
{
|
||||
urdf_export_helpers::URDFVersion version(robot_xml->Attribute("version"));
|
||||
if (!version.equal(1, 0))
|
||||
{
|
||||
throw std::runtime_error("Invalid 'version' specified; only version 1.0 is currently supported");
|
||||
}
|
||||
}
|
||||
catch (const std::runtime_error & err)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError(err.what());
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
|
||||
// Get all Material elements
|
||||
for (TiXmlElement* material_xml = robot_xml->FirstChildElement("material"); material_xml; material_xml = material_xml->NextSiblingElement("material"))
|
||||
{
|
||||
MaterialSharedPtr material;
|
||||
material.reset(new Material);
|
||||
|
||||
try {
|
||||
parseMaterial(*material, material_xml, false); // material needs to be fully defined here
|
||||
if (model->getMaterial(material->name))
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
|
||||
material.reset();
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
else
|
||||
{
|
||||
model->materials_.insert(make_pair(material->name,material));
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: successfully added a new material '%s'", material->name.c_str());
|
||||
}
|
||||
}
|
||||
catch (ParseError &/*e*/) {
|
||||
////CONSOLE_BRIDGE_logError("material xml is not initialized correctly");
|
||||
material.reset();
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all Link elements
|
||||
for (TiXmlElement* link_xml = robot_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link"))
|
||||
{
|
||||
LinkSharedPtr link;
|
||||
link.reset(new Link);
|
||||
|
||||
try {
|
||||
parseLink(*link, link_xml);
|
||||
if (model->getLink(link->name))
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("link '%s' is not unique.", link->name.c_str());
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set link visual(s) material
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: setting link '%s' material", link->name.c_str());
|
||||
if (link->visual)
|
||||
{
|
||||
assignMaterial(link->visual, model, link->name.c_str());
|
||||
}
|
||||
for (const auto& visual : link->visual_array)
|
||||
{
|
||||
assignMaterial(visual, model, link->name.c_str());
|
||||
}
|
||||
|
||||
model->links_.insert(make_pair(link->name,link));
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: successfully added a new link '%s'", link->name.c_str());
|
||||
}
|
||||
}
|
||||
catch (ParseError &/*e*/) {
|
||||
////CONSOLE_BRIDGE_logError("link xml is not initialized correctly");
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
}
|
||||
if (model->links_.empty()){
|
||||
////CONSOLE_BRIDGE_logError("No link elements found in urdf file");
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
|
||||
// Get all Joint elements
|
||||
for (TiXmlElement* joint_xml = robot_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint"))
|
||||
{
|
||||
JointSharedPtr joint;
|
||||
joint.reset(new Joint);
|
||||
|
||||
if (parseJoint(*joint, joint_xml))
|
||||
{
|
||||
if (model->getJoint(joint->name))
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("joint '%s' is not unique.", joint->name.c_str());
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
else
|
||||
{
|
||||
model->joints_.insert(make_pair(joint->name,joint));
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: successfully added a new joint '%s'", joint->name.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("joint xml is not initialized correctly");
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// every link has children links and joints, but no parents, so we create a
|
||||
// local convenience data structure for keeping child->parent relations
|
||||
std::map<std::string, std::string> parent_link_tree;
|
||||
parent_link_tree.clear();
|
||||
|
||||
// building tree: name mapping
|
||||
try
|
||||
{
|
||||
model->initTree(parent_link_tree);
|
||||
}
|
||||
catch(ParseError &e)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("Failed to build tree: %s", e.what());
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
|
||||
// find the root link
|
||||
try
|
||||
{
|
||||
model->initRoot(parent_link_tree);
|
||||
}
|
||||
catch(ParseError &e)
|
||||
{
|
||||
////CONSOLE_BRIDGE_logError("Failed to find root link: %s", e.what());
|
||||
model.reset();
|
||||
return model;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
bool exportMaterial(Material &material, TiXmlElement *config);
|
||||
bool exportLink(Link &link, TiXmlElement *config);
|
||||
bool exportJoint(Joint &joint, TiXmlElement *config);
|
||||
TiXmlDocument* exportURDF(const ModelInterface &model)
|
||||
{
|
||||
TiXmlDocument *doc = new TiXmlDocument();
|
||||
|
||||
TiXmlElement *robot = new TiXmlElement("robot");
|
||||
robot->SetAttribute("name", model.name_);
|
||||
doc->LinkEndChild(robot);
|
||||
|
||||
|
||||
for (std::map<std::string, MaterialSharedPtr>::const_iterator m=model.materials_.begin(); m!=model.materials_.end(); m++)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: exporting material [%s]\n",m->second->name.c_str());
|
||||
exportMaterial(*(m->second), robot);
|
||||
}
|
||||
|
||||
for (std::map<std::string, LinkSharedPtr>::const_iterator l=model.links_.begin(); l!=model.links_.end(); l++)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: exporting link [%s]\n",l->second->name.c_str());
|
||||
exportLink(*(l->second), robot);
|
||||
}
|
||||
|
||||
for (std::map<std::string, JointSharedPtr>::const_iterator j=model.joints_.begin(); j!=model.joints_.end(); j++)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logDebug("urdfdom: exporting joint [%s]\n",j->second->name.c_str());
|
||||
exportJoint(*(j->second), robot);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
TiXmlDocument* exportURDF(ModelInterfaceSharedPtr &model)
|
||||
{
|
||||
return exportURDF(*model);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
135
third_party/kdl_parser/src/pose.cpp
vendored
Normal file
135
third_party/kdl_parser/src/pose.cpp
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: Wim Meeussen, John Hsu */
|
||||
|
||||
|
||||
#include <urdf_model/pose.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
//#include <console_bridge/console.h>
|
||||
#include <tinyxml.h>
|
||||
#include <urdf_parser/urdf_parser.h>
|
||||
|
||||
namespace urdf_export_helpers {
|
||||
|
||||
std::string values2str(unsigned int count, const double *values, double (*conv)(double))
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (unsigned int i = 0 ; i < count ; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ss << " ";
|
||||
ss << (conv ? conv(values[i]) : values[i]);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
std::string values2str(urdf::Vector3 vec)
|
||||
{
|
||||
double xyz[3];
|
||||
xyz[0] = vec.x;
|
||||
xyz[1] = vec.y;
|
||||
xyz[2] = vec.z;
|
||||
return values2str(3, xyz);
|
||||
}
|
||||
std::string values2str(urdf::Rotation rot)
|
||||
{
|
||||
double rpy[3];
|
||||
rot.getRPY(rpy[0], rpy[1], rpy[2]);
|
||||
return values2str(3, rpy);
|
||||
}
|
||||
std::string values2str(urdf::Color c)
|
||||
{
|
||||
double rgba[4];
|
||||
rgba[0] = c.r;
|
||||
rgba[1] = c.g;
|
||||
rgba[2] = c.b;
|
||||
rgba[3] = c.a;
|
||||
return values2str(4, rgba);
|
||||
}
|
||||
std::string values2str(double d)
|
||||
{
|
||||
return values2str(1, &d);
|
||||
}
|
||||
}
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parsePose(Pose &pose, TiXmlElement* xml)
|
||||
{
|
||||
pose.clear();
|
||||
if (xml)
|
||||
{
|
||||
const char* xyz_str = xml->Attribute("xyz");
|
||||
if (xyz_str != NULL)
|
||||
{
|
||||
try {
|
||||
pose.position.init(xyz_str);
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
////CONSOLE_BRIDGE_logError(e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* rpy_str = xml->Attribute("rpy");
|
||||
if (rpy_str != NULL)
|
||||
{
|
||||
try {
|
||||
pose.rotation.init(rpy_str);
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
////CONSOLE_BRIDGE_logError(e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportPose(Pose &pose, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement *origin = new TiXmlElement("origin");
|
||||
std::string pose_xyz_str = urdf_export_helpers::values2str(pose.position);
|
||||
std::string pose_rpy_str = urdf_export_helpers::values2str(pose.rotation);
|
||||
origin->SetAttribute("xyz", pose_xyz_str);
|
||||
origin->SetAttribute("rpy", pose_rpy_str);
|
||||
xml->LinkEndChild(origin);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
111
third_party/kdl_parser/src/tinystr.cpp
vendored
Normal file
111
third_party/kdl_parser/src/tinystr.cpp
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIXML_USE_STL
|
||||
|
||||
#include "tinystr.h"
|
||||
|
||||
// Error value for find primitive
|
||||
const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
|
||||
|
||||
|
||||
// Null rep.
|
||||
TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
|
||||
|
||||
|
||||
void TiXmlString::reserve (size_type cap)
|
||||
{
|
||||
if (cap > capacity())
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.init(length(), cap);
|
||||
memcpy(tmp.start(), data(), length());
|
||||
swap(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlString& TiXmlString::assign(const char* str, size_type len)
|
||||
{
|
||||
size_type cap = capacity();
|
||||
if (len > cap || cap > 3*(len + 8))
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.init(len);
|
||||
memcpy(tmp.start(), str, len);
|
||||
swap(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(start(), str, len);
|
||||
set_size(len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TiXmlString& TiXmlString::append(const char* str, size_type len)
|
||||
{
|
||||
size_type newsize = length() + len;
|
||||
if (newsize > capacity())
|
||||
{
|
||||
reserve (newsize + capacity());
|
||||
}
|
||||
memmove(finish(), str, len);
|
||||
set_size(newsize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.reserve(a.length() + b.length());
|
||||
tmp += a;
|
||||
tmp += b;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const char* b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
|
||||
tmp.reserve(a.length() + b_len);
|
||||
tmp += a;
|
||||
tmp.append(b, b_len);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TiXmlString operator + (const char* a, const TiXmlString & b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
|
||||
tmp.reserve(a_len + b.length());
|
||||
tmp.append(a, a_len);
|
||||
tmp += b;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
#endif // TIXML_USE_STL
|
||||
1886
third_party/kdl_parser/src/tinyxml.cpp
vendored
Normal file
1886
third_party/kdl_parser/src/tinyxml.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2951
third_party/kdl_parser/src/tinyxml2.cpp
vendored
Normal file
2951
third_party/kdl_parser/src/tinyxml2.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
third_party/kdl_parser/src/tinyxmlerror.cpp
vendored
Normal file
52
third_party/kdl_parser/src/tinyxmlerror.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#include "tinyxml.h"
|
||||
|
||||
// The goal of the seperate error file is to make the first
|
||||
// step towards localization. tinyxml (currently) only supports
|
||||
// english error messages, but the could now be translated.
|
||||
//
|
||||
// It also cleans up the code a bit.
|
||||
//
|
||||
|
||||
const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] =
|
||||
{
|
||||
"No error",
|
||||
"Error",
|
||||
"Failed to open file",
|
||||
"Error parsing Element.",
|
||||
"Failed to read Element name",
|
||||
"Error reading Element value.",
|
||||
"Error reading Attributes.",
|
||||
"Error: empty tag.",
|
||||
"Error reading end tag.",
|
||||
"Error parsing Unknown.",
|
||||
"Error parsing Comment.",
|
||||
"Error parsing Declaration.",
|
||||
"Error document empty.",
|
||||
"Error null (0) or unexpected EOF found in input stream.",
|
||||
"Error parsing CDATA.",
|
||||
"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
|
||||
};
|
||||
1638
third_party/kdl_parser/src/tinyxmlparser.cpp
vendored
Normal file
1638
third_party/kdl_parser/src/tinyxmlparser.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
84
third_party/kdl_parser/src/twist.cpp
vendored
Normal file
84
third_party/kdl_parser/src/twist.cpp
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: John Hsu */
|
||||
|
||||
|
||||
#include <urdf_model/twist.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <tinyxml.h>
|
||||
//#include <console_bridge/console.h>
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parseTwist(Twist &twist, TiXmlElement* xml)
|
||||
{
|
||||
twist.clear();
|
||||
if (xml)
|
||||
{
|
||||
const char* linear_char = xml->Attribute("linear");
|
||||
if (linear_char != NULL)
|
||||
{
|
||||
try {
|
||||
twist.linear.init(linear_char);
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
twist.linear.clear();
|
||||
//CONSOLE_BRIDGE_logError("Malformed linear string [%s]: %s", linear_char, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* angular_char = xml->Attribute("angular");
|
||||
if (angular_char != NULL)
|
||||
{
|
||||
try {
|
||||
twist.angular.init(angular_char);
|
||||
}
|
||||
catch (ParseError &e) {
|
||||
twist.angular.clear();
|
||||
//CONSOLE_BRIDGE_logError("Malformed angular [%s]: %s", angular_char, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
159
third_party/kdl_parser/src/urdf_model_state.cpp
vendored
Normal file
159
third_party/kdl_parser/src/urdf_model_state.cpp
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: John Hsu */
|
||||
|
||||
|
||||
#include <urdf_model_state/model_state.h>
|
||||
#include <urdf_model/utils.h>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <tinyxml.h>
|
||||
//#include <console_bridge/console.h>
|
||||
|
||||
namespace urdf {
|
||||
|
||||
bool parseModelState(ModelState& ms, TiXmlElement* config)
|
||||
{
|
||||
ms.clear();
|
||||
|
||||
const char* name_char = config->Attribute("name");
|
||||
if (!name_char)
|
||||
{
|
||||
/*CONSOLE_BRIDGE_logError("No name given for the model_state.");*/
|
||||
|
||||
return false;
|
||||
}
|
||||
ms.name = std::string(name_char);
|
||||
|
||||
const char* time_stamp_char = config->Attribute("time_stamp");
|
||||
if (time_stamp_char)
|
||||
{
|
||||
try {
|
||||
ms.time_stamp.set(strToDouble(time_stamp_char));
|
||||
}
|
||||
catch (std::runtime_error&) {
|
||||
//CONSOLE_BRIDGE_logError("Parsing time stamp [%s] failed", time_stamp_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TiXmlElement* joint_state_elem = config->FirstChildElement("joint_state");
|
||||
if (joint_state_elem)
|
||||
{
|
||||
JointStateSharedPtr joint_state;
|
||||
joint_state.reset(new JointState());
|
||||
|
||||
const char* joint_char = joint_state_elem->Attribute("joint");
|
||||
if (joint_char)
|
||||
joint_state->joint = std::string(joint_char);
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("No joint name given for the model_state.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*// parse position*/
|
||||
const char* position_char = joint_state_elem->Attribute("position");
|
||||
if (position_char)
|
||||
{
|
||||
|
||||
std::vector<std::string> pieces;
|
||||
urdf::split_string(pieces, position_char, " ");
|
||||
for (unsigned int i = 0; i < pieces.size(); ++i) {
|
||||
if (pieces[i] != "") {
|
||||
try {
|
||||
joint_state->position.push_back(strToDouble(pieces[i].c_str()));
|
||||
}
|
||||
catch (std::runtime_error&) {
|
||||
throw ParseError("position element (" + pieces[i] + ") is not a valid float");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* parse velocity*/
|
||||
|
||||
const char* velocity_char = joint_state_elem->Attribute("velocity");
|
||||
/**/
|
||||
int i = 0;
|
||||
|
||||
if (velocity_char)
|
||||
{
|
||||
|
||||
std::vector<std::string> pieces;
|
||||
urdf::split_string(pieces, velocity_char, " ");
|
||||
for (unsigned int i = 0; i < pieces.size(); ++i) {
|
||||
if (pieces[i] != "") {
|
||||
try {
|
||||
joint_state->velocity.push_back(strToDouble(pieces[i].c_str()));
|
||||
}
|
||||
catch (std::runtime_error&) {
|
||||
throw ParseError("velocity element (" + pieces[i] + ") is not a valid float");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse effort
|
||||
|
||||
const char* effort_char = joint_state_elem->Attribute("effort");
|
||||
/**/
|
||||
|
||||
if(effort_char)
|
||||
{
|
||||
std::vector<std::string> pieces;
|
||||
urdf::split_string(pieces, effort_char, " ");
|
||||
for (unsigned int i = 0; i < pieces.size(); ++i) {
|
||||
if (pieces[i] != "") {
|
||||
try {
|
||||
joint_state->effort.push_back(strToDouble(pieces[i].c_str()));
|
||||
}
|
||||
catch (std::runtime_error&) {
|
||||
throw ParseError("effort element (" + pieces[i] + ") is not a valid float");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*// add to vector*/
|
||||
ms.joint_states.push_back(joint_state);
|
||||
/* */
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
360
third_party/kdl_parser/src/urdf_sensor.cpp
vendored
Normal file
360
third_party/kdl_parser/src/urdf_sensor.cpp
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: John Hsu */
|
||||
|
||||
|
||||
#include <urdf_sensor/sensor.h>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <tinyxml.h>
|
||||
#include <console_bridge/console.h>
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parsePose(Pose &pose, TiXmlElement* xml);
|
||||
|
||||
bool parseCamera(Camera &camera, TiXmlElement* config)
|
||||
{
|
||||
camera.clear();
|
||||
camera.type = VisualSensor::CAMERA;
|
||||
|
||||
TiXmlElement *image = config->FirstChildElement("image");
|
||||
if (image)
|
||||
{
|
||||
const char* width_char = image->Attribute("width");
|
||||
if (width_char)
|
||||
{
|
||||
try
|
||||
{
|
||||
camera.width = std::stoul(width_char);
|
||||
}
|
||||
catch (std::invalid_argument &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera image width [%s] is not a valid int: %s", width_char, e.what());
|
||||
return false;
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera image width [%s] is out of range: %s", width_char, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor needs an image width attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* height_char = image->Attribute("height");
|
||||
if (height_char)
|
||||
{
|
||||
try
|
||||
{
|
||||
camera.height = std::stoul(height_char);
|
||||
}
|
||||
catch (std::invalid_argument &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera image height [%s] is not a valid int: %s", height_char, e.what());
|
||||
return false;
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera image height [%s] is out of range: %s", height_char, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor needs an image height attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* format_char = image->Attribute("format");
|
||||
if (format_char)
|
||||
camera.format = std::string(format_char);
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor needs an image format attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* hfov_char = image->Attribute("hfov");
|
||||
if (hfov_char)
|
||||
{
|
||||
try {
|
||||
camera.hfov = strToDouble(hfov_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Camera image hfov [%s] is not a valid float", hfov_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor needs an image hfov attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* near_char = image->Attribute("near");
|
||||
if (near_char)
|
||||
{
|
||||
try {
|
||||
camera.near = strToDouble(near_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Camera image near [%s] is not a valid float", near_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor needs an image near attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* far_char = image->Attribute("far");
|
||||
if (far_char)
|
||||
{
|
||||
try {
|
||||
camera.far = strToDouble(far_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Camera image far [%s] is not a valid float", far_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor needs an image far attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Camera sensor has no <image> element");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseRay(Ray &ray, TiXmlElement* config)
|
||||
{
|
||||
ray.clear();
|
||||
ray.type = VisualSensor::RAY;
|
||||
|
||||
TiXmlElement *horizontal = config->FirstChildElement("horizontal");
|
||||
if (horizontal)
|
||||
{
|
||||
const char* samples_char = horizontal->Attribute("samples");
|
||||
if (samples_char)
|
||||
{
|
||||
try
|
||||
{
|
||||
ray.horizontal_samples = std::stoul(samples_char);
|
||||
}
|
||||
catch (std::invalid_argument &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Ray horizontal samples [%s] is not a valid float: %s", samples_char, e.what());
|
||||
return false;
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Ray horizontal samples [%s] is out of range: %s", samples_char, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* resolution_char = horizontal->Attribute("resolution");
|
||||
if (resolution_char)
|
||||
{
|
||||
try {
|
||||
ray.horizontal_resolution = strToDouble(resolution_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Ray horizontal resolution [%s] is not a valid float", resolution_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* min_angle_char = horizontal->Attribute("min_angle");
|
||||
if (min_angle_char)
|
||||
{
|
||||
try {
|
||||
ray.horizontal_min_angle = strToDouble(min_angle_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Ray horizontal min_angle [%s] is not a valid float", min_angle_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* max_angle_char = horizontal->Attribute("max_angle");
|
||||
if (max_angle_char)
|
||||
{
|
||||
try {
|
||||
ray.horizontal_max_angle = strToDouble(max_angle_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Ray horizontal max_angle [%s] is not a valid float", max_angle_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TiXmlElement *vertical = config->FirstChildElement("vertical");
|
||||
if (vertical)
|
||||
{
|
||||
const char* samples_char = vertical->Attribute("samples");
|
||||
if (samples_char)
|
||||
{
|
||||
try
|
||||
{
|
||||
ray.vertical_samples = std::stoul(samples_char);
|
||||
}
|
||||
catch (std::invalid_argument &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Ray vertical samples [%s] is not a valid float: %s", samples_char, e.what());
|
||||
return false;
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("Ray vertical samples [%s] is out of range: %s", samples_char, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* resolution_char = vertical->Attribute("resolution");
|
||||
if (resolution_char)
|
||||
{
|
||||
try {
|
||||
ray.vertical_resolution = strToDouble(resolution_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Ray vertical resolution [%s] is not a valid float", resolution_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* min_angle_char = vertical->Attribute("min_angle");
|
||||
if (min_angle_char)
|
||||
{
|
||||
try {
|
||||
ray.vertical_min_angle = strToDouble(min_angle_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Ray vertical min_angle [%s] is not a valid float", min_angle_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* max_angle_char = vertical->Attribute("max_angle");
|
||||
if (max_angle_char)
|
||||
{
|
||||
try {
|
||||
ray.vertical_max_angle = strToDouble(max_angle_char);
|
||||
} catch(std::runtime_error &) {
|
||||
//CONSOLE_BRIDGE_logError("Ray vertical max_angle [%s] is not a valid float", max_angle_char);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VisualSensorSharedPtr parseVisualSensor(TiXmlElement *g)
|
||||
{
|
||||
VisualSensorSharedPtr visual_sensor;
|
||||
|
||||
// get sensor type
|
||||
TiXmlElement *sensor_xml;
|
||||
if (g->FirstChildElement("camera"))
|
||||
{
|
||||
Camera *camera = new Camera();
|
||||
visual_sensor.reset(camera);
|
||||
sensor_xml = g->FirstChildElement("camera");
|
||||
if (!parseCamera(*camera, sensor_xml))
|
||||
visual_sensor.reset();
|
||||
}
|
||||
else if (g->FirstChildElement("ray"))
|
||||
{
|
||||
Ray *ray = new Ray();
|
||||
visual_sensor.reset(ray);
|
||||
sensor_xml = g->FirstChildElement("ray");
|
||||
if (!parseRay(*ray, sensor_xml))
|
||||
visual_sensor.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("No know sensor types [camera|ray] defined in <sensor> block");
|
||||
}
|
||||
return visual_sensor;
|
||||
}
|
||||
|
||||
|
||||
bool parseSensor(Sensor &sensor, TiXmlElement* config)
|
||||
{
|
||||
sensor.clear();
|
||||
|
||||
const char *name_char = config->Attribute("name");
|
||||
if (!name_char)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("No name given for the sensor.");
|
||||
return false;
|
||||
}
|
||||
sensor.name = std::string(name_char);
|
||||
|
||||
// parse parent_link_name
|
||||
const char *parent_link_name_char = config->Attribute("parent_link_name");
|
||||
if (!parent_link_name_char)
|
||||
{
|
||||
//CONSOLE_BRIDGE_logError("No parent_link_name given for the sensor.");
|
||||
return false;
|
||||
}
|
||||
sensor.parent_link_name = std::string(parent_link_name_char);
|
||||
|
||||
// parse origin
|
||||
TiXmlElement *o = config->FirstChildElement("origin");
|
||||
if (o)
|
||||
{
|
||||
if (!parsePose(sensor.origin, o))
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse sensor
|
||||
sensor.sensor = parseVisualSensor(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
70
third_party/kdl_parser/src/world.cpp
vendored
Normal file
70
third_party/kdl_parser/src/world.cpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Willow Garage nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*********************************************************************/
|
||||
|
||||
/* Author: Wim Meeussen */
|
||||
|
||||
|
||||
#include <urdf_world/world.h>
|
||||
#include <urdf_model/model.h>
|
||||
#include <urdf_parser/urdf_parser.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <tinyxml.h>
|
||||
//#include <console_bridge/console.h>
|
||||
|
||||
namespace urdf{
|
||||
|
||||
bool parseWorld(World &/*world*/, TiXmlElement* /*config*/)
|
||||
{
|
||||
|
||||
// to be implemented
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportWorld(World &world, TiXmlElement* xml)
|
||||
{
|
||||
TiXmlElement * world_xml = new TiXmlElement("world");
|
||||
world_xml->SetAttribute("name", world.name);
|
||||
|
||||
// to be implemented
|
||||
// exportModels(*world.models, world_xml);
|
||||
|
||||
xml->LinkEndChild(world_xml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user