00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "kdl_parser/kdl_parser.hpp"
00038 #include <urdf/model.h>
00039 #include <urdf/urdfdom_compatibility.h>
00040 #include <kdl/frames_io.hpp>
00041 #include <ros/console.h>
00042
00043 using namespace std;
00044 using namespace KDL;
00045
00046 namespace kdl_parser{
00047
00048
00049
00050 Vector toKdl(urdf::Vector3 v)
00051 {
00052 return Vector(v.x, v.y, v.z);
00053 }
00054
00055
00056 Rotation toKdl(urdf::Rotation r)
00057 {
00058 return Rotation::Quaternion(r.x, r.y, r.z, r.w);
00059 }
00060
00061
00062 Frame toKdl(urdf::Pose p)
00063 {
00064 return Frame(toKdl(p.rotation), toKdl(p.position));
00065 }
00066
00067
00068 Joint toKdl(urdf::JointSharedPtr jnt)
00069 {
00070 Frame F_parent_jnt = toKdl(jnt->parent_to_joint_origin_transform);
00071
00072 switch (jnt->type){
00073 case urdf::Joint::FIXED:{
00074 return Joint(jnt->name, Joint::None);
00075 }
00076 case urdf::Joint::REVOLUTE:{
00077 Vector axis = toKdl(jnt->axis);
00078 return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::RotAxis);
00079 }
00080 case urdf::Joint::CONTINUOUS:{
00081 Vector axis = toKdl(jnt->axis);
00082 return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::RotAxis);
00083 }
00084 case urdf::Joint::PRISMATIC:{
00085 Vector axis = toKdl(jnt->axis);
00086 return Joint(jnt->name, F_parent_jnt.p, F_parent_jnt.M * axis, Joint::TransAxis);
00087 }
00088 default:{
00089 ROS_WARN("Converting unknown joint type of joint '%s' into a fixed joint", jnt->name.c_str());
00090 return Joint(jnt->name, Joint::None);
00091 }
00092 }
00093 return Joint();
00094 }
00095
00096
00097 RigidBodyInertia toKdl(urdf::InertialSharedPtr i)
00098 {
00099 Frame origin = toKdl(i->origin);
00100
00101
00102 double kdl_mass = i->mass;
00103
00104
00105 Vector kdl_com = origin.p;
00106
00107
00108
00109 RotationalInertia urdf_inertia =
00110 RotationalInertia(i->ixx, i->iyy, i->izz, i->ixy, i->ixz, i->iyz);
00111
00112
00113
00114 RigidBodyInertia kdl_inertia_wrt_com_workaround =
00115 origin.M *RigidBodyInertia(0, Vector::Zero(), urdf_inertia);
00116
00117
00118
00119
00120 RotationalInertia kdl_inertia_wrt_com =
00121 kdl_inertia_wrt_com_workaround.getRotationalInertia();
00122
00123 return RigidBodyInertia(kdl_mass,kdl_com,kdl_inertia_wrt_com);
00124 }
00125
00126
00127
00128 bool addChildrenToTree(urdf::LinkConstSharedPtr root, Tree& tree)
00129 {
00130 std::vector<urdf::LinkSharedPtr > children = root->child_links;
00131 ROS_DEBUG("Link %s had %i children", root->name.c_str(), (int)children.size());
00132
00133
00134 RigidBodyInertia inert(0);
00135 if (root->inertial)
00136 inert = toKdl(root->inertial);
00137
00138
00139 Joint jnt = toKdl(root->parent_joint);
00140
00141
00142 Segment sgm(root->name, jnt, toKdl(root->parent_joint->parent_to_joint_origin_transform), inert);
00143
00144
00145 tree.addSegment(sgm, root->parent_joint->parent_link_name);
00146
00147
00148 for (size_t i=0; i<children.size(); i++){
00149 if (!addChildrenToTree(children[i], tree))
00150 return false;
00151 }
00152 return true;
00153 }
00154
00155
00156 bool treeFromFile(const string& file, Tree& tree)
00157 {
00158 TiXmlDocument urdf_xml;
00159 urdf_xml.LoadFile(file);
00160 return treeFromXml(&urdf_xml, tree);
00161 }
00162
00163 bool treeFromParam(const string& param, Tree& tree)
00164 {
00165 urdf::Model robot_model;
00166 if (!robot_model.initParam(param)){
00167 ROS_ERROR("Could not generate robot model");
00168 return false;
00169 }
00170 return treeFromUrdfModel(robot_model, tree);
00171 }
00172
00173 bool treeFromString(const string& xml, Tree& tree)
00174 {
00175 TiXmlDocument urdf_xml;
00176 urdf_xml.Parse(xml.c_str());
00177 return treeFromXml(&urdf_xml, tree);
00178 }
00179
00180 bool treeFromXml(TiXmlDocument *xml_doc, Tree& tree)
00181 {
00182 urdf::Model robot_model;
00183 if (!robot_model.initXml(xml_doc)){
00184 ROS_ERROR("Could not generate robot model");
00185 return false;
00186 }
00187 return treeFromUrdfModel(robot_model, tree);
00188 }
00189
00190
00191 bool treeFromUrdfModel(const urdf::ModelInterface& robot_model, Tree& tree)
00192 {
00193 tree = Tree(robot_model.getRoot()->name);
00194
00195
00196 if (robot_model.getRoot()->inertial)
00197 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());
00198
00199
00200 for (size_t i=0; i<robot_model.getRoot()->child_links.size(); i++)
00201 if (!addChildrenToTree(robot_model.getRoot()->child_links[i], tree))
00202 return false;
00203
00204 return true;
00205 }
00206
00207 }
00208