void srdf::Model::loadPassiveJoints(const urdf::ModelInterface &urdf_model, TiXmlElement *robot_xml) { for (TiXmlElement* c_xml = robot_xml->FirstChildElement("passive_joint"); c_xml; c_xml = c_xml->NextSiblingElement("passive_joint")) { const char *name = c_xml->Attribute("name"); if (!name) { logError("No name specified for passive joint. Ignoring."); continue; } PassiveJoint pj; pj.name_ = boost::trim_copy(std::string(name)); // see if a virtual joint was marked as passive bool vjoint = false; for (std::size_t i = 0 ; !vjoint && i < virtual_joints_.size() ; ++i) if (virtual_joints_[i].name_ == pj.name_) vjoint = true; if (!vjoint && !urdf_model.getJoint(pj.name_)) { logError("Joint '%s' marked as passive is not known to the URDF. Ignoring.", name); continue; } passive_joints_.push_back(pj); } }
bool treeToUrdfModel(const KDL::Tree& tree, const std::string & robot_name, urdf::ModelInterface& robot_model) { robot_model.clear(); robot_model.name_ = robot_name; //Add all links KDL::SegmentMap::iterator seg; KDL::SegmentMap segs; KDL::SegmentMap::const_iterator root_seg; root_seg = tree.getRootSegment(); segs = tree.getSegments(); for( seg = segs.begin(); seg != segs.end(); seg++ ) { if (robot_model.getLink(seg->first)) { std::cerr << "[ERR] link " << seg->first << " is not unique." << std::endl; robot_model.clear(); return false; } else { urdf::LinkPtr link; resetPtr(link, new urdf::Link); //add name link->name = seg->first; //insert link robot_model.links_.insert(make_pair(seg->first,link)); std::cerr << "[DEBUG] successfully added a new link " << link->name << std::endl; } //inserting joint //The fake root segment has no joint to add if( seg->first != root_seg->first ) { KDL::Joint jnt; jnt = GetTreeElementSegment(seg->second).getJoint(); if (robot_model.getJoint(jnt.getName())) { std::cerr << "[ERR] joint " << jnt.getName() << " is not unique." << std::endl; robot_model.clear(); return false; } else { urdf::JointPtr joint; urdf::LinkPtr link = robot_model.links_[seg->first]; //This variable will be set by toUrdf KDL::Frame H_new_old_successor; KDL::Frame H_new_old_predecessor = getH_new_old(GetTreeElementSegment(GetTreeElementParent(seg->second)->second)); urdf::resetPtr(joint, new urdf::Joint()); //convert joint *joint = toUrdf(jnt, GetTreeElementSegment(seg->second).getFrameToTip(),H_new_old_predecessor,H_new_old_successor); //insert parent joint->parent_link_name = GetTreeElementParent(seg->second)->first; //insert child joint->child_link_name = seg->first; //insert joint robot_model.joints_.insert(make_pair(seg->first,joint)); std::cerr << "[DEBUG] successfully added a new joint" << jnt.getName() << std::endl; //add inertial, taking in account an eventual change in the link frame resetPtr(link->inertial, new urdf::Inertial()); *(link->inertial) = toUrdf(H_new_old_successor * GetTreeElementSegment(seg->second).getInertia()); } } } // 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 //{ robot_model.initTree(parent_link_tree); //} /* catch(ParseError &e) { logError("Failed to build tree: %s", e.what()); robot_model.clear(); return false; }*/ // find the root link //try //{ robot_model.initRoot(parent_link_tree); //} /* catch(ParseError &e) { logError("Failed to find root link: %s", e.what()); robot_model.reset(); return false; } */ return true; }
void srdf::Model::loadGroups(const urdf::ModelInterface &urdf_model, TiXmlElement *robot_xml) { for (TiXmlElement* group_xml = robot_xml->FirstChildElement("group"); group_xml; group_xml = group_xml->NextSiblingElement("group")) { const char *gname = group_xml->Attribute("name"); if (!gname) { logError("Group name not specified"); continue; } Group g; g.name_ = std::string(gname); boost::trim(g.name_); // get the links in the groups for (TiXmlElement* link_xml = group_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link")) { const char *lname = link_xml->Attribute("name"); if (!lname) { logError("Link name not specified"); continue; } std::string lname_str = boost::trim_copy(std::string(lname)); if (!urdf_model.getLink(lname_str)) { logError("Link '%s' declared as part of group '%s' is not known to the URDF", lname, gname); continue; } g.links_.push_back(lname_str); } // get the joints in the groups for (TiXmlElement* joint_xml = group_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint")) { const char *jname = joint_xml->Attribute("name"); if (!jname) { logError("Joint name not specified"); continue; } std::string jname_str = boost::trim_copy(std::string(jname)); if (!urdf_model.getJoint(jname_str)) { bool missing = true; for (std::size_t k = 0 ; k < virtual_joints_.size() ; ++k) if (virtual_joints_[k].name_ == jname_str) { missing = false; break; } if (missing) { logError("Joint '%s' declared as part of group '%s' is not known to the URDF", jname, gname); continue; } } g.joints_.push_back(jname_str); } // get the chains in the groups for (TiXmlElement* chain_xml = group_xml->FirstChildElement("chain"); chain_xml; chain_xml = chain_xml->NextSiblingElement("chain")) { const char *base = chain_xml->Attribute("base_link"); const char *tip = chain_xml->Attribute("tip_link"); if (!base) { logError("Base link name not specified for chain"); continue; } if (!tip) { logError("Tip link name not specified for chain"); continue; } std::string base_str = boost::trim_copy(std::string(base)); std::string tip_str = boost::trim_copy(std::string(tip)); if (!urdf_model.getLink(base_str)) { logError("Link '%s' declared as part of a chain in group '%s' is not known to the URDF", base, gname); continue; } if (!urdf_model.getLink(tip_str)) { logError("Link '%s' declared as part of a chain in group '%s' is not known to the URDF", tip, gname); continue; } bool found = false; boost::shared_ptr<const urdf::Link> l = urdf_model.getLink(tip_str); std::set<std::string> seen; while (!found && l) { seen.insert(l->name); if (l->name == base_str) found = true; else l = l->getParent(); } if (!found) { l = urdf_model.getLink(base_str); while (!found && l) { if (seen.find(l->name) != seen.end()) found = true; else l = l->getParent(); } } if (found) g.chains_.push_back(std::make_pair(base_str, tip_str)); else logError("Links '%s' and '%s' do not form a chain. Not included in group '%s'", base, tip, gname); } // get the subgroups in the groups for (TiXmlElement* subg_xml = group_xml->FirstChildElement("group"); subg_xml; subg_xml = subg_xml->NextSiblingElement("group")) { const char *sub = subg_xml->Attribute("name"); if (!sub) { logError("Group name not specified when included as subgroup"); continue; } g.subgroups_.push_back(boost::trim_copy(std::string(sub))); } if (g.links_.empty() && g.joints_.empty() && g.chains_.empty() && g.subgroups_.empty()) logWarn("Group '%s' is empty.", gname); groups_.push_back(g); } // check the subgroups std::set<std::string> known_groups; bool update = true; while (update) { update = false; for (std::size_t i = 0 ; i < groups_.size() ; ++i) { if (known_groups.find(groups_[i].name_) != known_groups.end()) continue; if (groups_[i].subgroups_.empty()) { known_groups.insert(groups_[i].name_); update = true; } else { bool ok = true; for (std::size_t j = 0 ; ok && j < groups_[i].subgroups_.size() ; ++j) if (known_groups.find(groups_[i].subgroups_[j]) == known_groups.end()) ok = false; if (ok) { known_groups.insert(groups_[i].name_); update = true; } } } } // if there are erroneous groups, keep only the valid ones if (known_groups.size() != groups_.size()) { std::vector<Group> correct; for (std::size_t i = 0 ; i < groups_.size() ; ++i) if (known_groups.find(groups_[i].name_) != known_groups.end()) correct.push_back(groups_[i]); else logError("Group '%s' has unsatisfied subgroups", groups_[i].name_.c_str()); groups_.swap(correct); } }
void srdf::Model::loadGroupStates(const urdf::ModelInterface &urdf_model, TiXmlElement *robot_xml) { for (TiXmlElement* gstate_xml = robot_xml->FirstChildElement("group_state"); gstate_xml; gstate_xml = gstate_xml->NextSiblingElement("group_state")) { const char *sname = gstate_xml->Attribute("name"); const char *gname = gstate_xml->Attribute("group"); if (!sname) { logError("Name of group state is not specified"); continue; } if (!gname) { logError("Name of group for state '%s' is not specified", sname); continue; } GroupState gs; gs.name_ = boost::trim_copy(std::string(sname)); gs.group_ = boost::trim_copy(std::string(gname)); bool found = false; for (std::size_t k = 0 ; k < groups_.size() ; ++k) if (groups_[k].name_ == gs.group_) { found = true; break; } if (!found) { logError("Group state '%s' specified for group '%s', but that group is not known", sname, gname); continue; } // get the joint values in the group state for (TiXmlElement* joint_xml = gstate_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint")) { const char *jname = joint_xml->Attribute("name"); const char *jval = joint_xml->Attribute("value"); if (!jname) { logError("Joint name not specified in group state '%s'", sname); continue; } if (!jval) { logError("Joint name not specified for joint '%s' in group state '%s'", jname, sname); continue; } std::string jname_str = boost::trim_copy(std::string(jname)); if (!urdf_model.getJoint(jname_str)) { bool missing = true; for (std::size_t k = 0 ; k < virtual_joints_.size() ; ++k) if (virtual_joints_[k].name_ == jname_str) { missing = false; break; } if (missing) { logError("Joint '%s' declared as part of group state '%s' is not known to the URDF", jname, sname); continue; } } try { std::string jval_str = std::string(jval); std::stringstream ss(jval_str); while (ss.good() && !ss.eof()) { std::string val; ss >> val >> std::ws; gs.joint_values_[jname_str].push_back(boost::lexical_cast<double>(val)); } } catch (boost::bad_lexical_cast &e) { logError("Unable to parse joint value '%s'", jval); } if (gs.joint_values_.empty()) logError("Unable to parse joint value ('%s') for joint '%s' in group state '%s'", jval, jname, sname); } group_states_.push_back(gs); } }