规范模块目录和第三方依赖结构

This commit is contained in:
zhangshun
2026-06-01 16:57:39 +08:00
parent e8e485b115
commit c2ce29d874
1758 changed files with 187 additions and 102 deletions

642
third_party/kdl_parser/src/joint.cpp vendored Normal file
View 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;
}
}

View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

2951
third_party/kdl_parser/src/tinyxml2.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

View 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.",
};

File diff suppressed because it is too large Load Diff

84
third_party/kdl_parser/src/twist.cpp vendored Normal file
View 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;
}
}

View 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;
}
}

View 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
View 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;
}
}