update to latests design with optional root link

This commit is contained in:
wim 2009-11-24 21:04:39 +00:00
parent e72682fe0b
commit f641312f0a
3 changed files with 61 additions and 32 deletions

View File

@ -99,6 +99,11 @@ private:
/// it's time to build a tree /// it's time to build a tree
bool initTree(std::map<std::string, std::string> &parent_link_tree); bool initTree(std::map<std::string, std::string> &parent_link_tree);
/// in initXml(), onece tree is built,
/// it's time to find the root Link
bool initRoot(std::map<std::string, std::string> &parent_link_tree);
/// Model is restricted to a tree for now, which means there exists one root link /// Model is restricted to a tree for now, which means there exists one root link
/// typically, root link is the world(inertial). Where world is a special link /// typically, root link is the world(inertial). Where world is a special link
/// or is the root_link_ the link attached to the world by PLANAR/FLOATING joint? /// or is the root_link_ the link attached to the world by PLANAR/FLOATING joint?

View File

@ -238,61 +238,60 @@ bool Model::initXml(TiXmlElement *robot_xml)
return false; return false;
} }
// find the root link
if (!this->initRoot(parent_link_tree))
{
ROS_ERROR("failed to find root link");
return false;
}
return true; return true;
} }
bool Model::initTree(std::map<std::string, std::string> &parent_link_tree) bool Model::initTree(std::map<std::string, std::string> &parent_link_tree)
{ {
this->root_link_.reset();
// loop through all joints, for every link, assign children links and children joints // loop through all joints, for every link, assign children links and children joints
for (std::map<std::string,boost::shared_ptr<Joint> >::iterator joint = this->joints_.begin();joint != this->joints_.end(); joint++) for (std::map<std::string,boost::shared_ptr<Joint> >::iterator joint = this->joints_.begin();joint != this->joints_.end(); joint++)
{ {
std::string parent_link_name = joint->second->parent_link_name; std::string parent_link_name = joint->second->parent_link_name;
std::string child_link_name = joint->second->child_link_name; std::string child_link_name = joint->second->child_link_name;
ROS_DEBUG(" Build tree: joint: '%s' has parent link '%s' and child link '%s'", joint->first.c_str(), parent_link_name.c_str(),child_link_name.c_str()); ROS_DEBUG("build tree: joint: '%s' has parent link '%s' and child link '%s'", joint->first.c_str(), parent_link_name.c_str(),child_link_name.c_str());
// case where joint is not connected to any link
if (parent_link_name.empty() && !child_link_name.empty()) if (parent_link_name.empty() && !child_link_name.empty())
{ {
ROS_ERROR(" Joint %s specifies only parent link but not child link",(joint->second)->name.c_str()); ROS_ERROR(" Joint %s specifies child link but not parent link.",(joint->second)->name.c_str());
return false; return false;
} }
else if (!parent_link_name.empty() && child_link_name.empty()) else if (!parent_link_name.empty() && child_link_name.empty())
{ {
ROS_ERROR(" Joint %s specifies only child link but not parent link",(joint->second)->name.c_str()); ROS_ERROR(" Joint %s specifies parent link but not child link.",(joint->second)->name.c_str());
return false; return false;
} }
else if (parent_link_name.empty() && child_link_name.empty()) else if (parent_link_name.empty() && child_link_name.empty())
{ {
ROS_DEBUG(" Joint %s has not parent or child link, it is an abstract joint.",(joint->second)->name.c_str()); ROS_DEBUG(" Joint %s specifies no parent link and no child link. This is an abstract joint.",(joint->second)->name.c_str());
} }
// normal joint case
else else
{ {
// find child and parent link of joint // find child and parent links
boost::shared_ptr<Link> child_link, parent_link; boost::shared_ptr<Link> child_link, parent_link;
this->getLink(child_link_name, child_link); this->getLink(child_link_name, child_link);
this->getLink(parent_link_name, parent_link);
if (!child_link) if (!child_link)
{ {
ROS_ERROR(" Child link '%s' of joint: %s not found",child_link_name.c_str(),joint->first.c_str()); ROS_ERROR(" child link '%s' of joint '%s' not found", child_link_name.c_str(), joint->first.c_str() );
return false; return false;
} }
this->getLink(parent_link_name, parent_link);
if (!parent_link) if (!parent_link)
{ {
if (root_link_) ROS_DEBUG(" parent link '%s' of joint '%s' not found. Automatically adding it. This must be the root link",
{ parent_link_name.c_str(), joint->first.c_str() );
ROS_ERROR("This tree contains two root links");
return false;
}
ROS_DEBUG(" Parent link '%s' of joint '%s' not found. This should be the root link.", parent_link_name.c_str(), joint->first.c_str() );
parent_link.reset(new Link); parent_link.reset(new Link);
parent_link->name = parent_link_name; parent_link->name = parent_link_name;
root_link_ = parent_link; this->links_.insert(make_pair(parent_link->name, parent_link));
this->links_.insert(make_pair(parent_link_name, parent_link)); ROS_DEBUG(" successfully added new link '%s'", parent_link->name.c_str());
} }
//set parent link for child link //set parent link for child link
@ -314,17 +313,42 @@ bool Model::initTree(std::map<std::string, std::string> &parent_link_tree)
} }
} }
// we should have found root
if (!root_link_){
ROS_ERROR("The tree does not contain a root link");
return false;
}
return true; return true;
} }
bool Model::initRoot(std::map<std::string, std::string> &parent_link_tree)
{
this->root_link_.reset();
for (std::map<std::string, std::string>::iterator p=parent_link_tree.begin(); p!=parent_link_tree.end(); p++)
{
if (parent_link_tree.find(p->second) == parent_link_tree.end())
{
if (this->root_link_)
{
ROS_DEBUG("child '%s', parent '%s', root '%s'", p->first.c_str(), p->second.c_str(), this->root_link_->name.c_str());
if (this->root_link_->name != p->second)
{
ROS_ERROR("Two root links found: '%s' and '%s'", this->root_link_->name.c_str(), p->second.c_str());
return false;
}
}
else
getLink(p->second,this->root_link_);
}
}
if (!this->root_link_)
{
ROS_ERROR("No root link found. The robot xml is not a valid tree.");
return false;
}
ROS_DEBUG("Link '%s' is the root link", this->root_link_->name.c_str());
return true;
}
boost::shared_ptr<Material> Model::getMaterial(const std::string& name) const boost::shared_ptr<Material> Model::getMaterial(const std::string& name) const
{ {

View File

@ -76,7 +76,7 @@ TEST_F(TestParser, test)
robot_model_xml.LoadFile(g_argv[i]); robot_model_xml.LoadFile(g_argv[i]);
TiXmlElement *robot_xml = robot_model_xml.FirstChildElement("robot"); TiXmlElement *robot_xml = robot_model_xml.FirstChildElement("robot");
ASSERT_TRUE(robot_xml != NULL); ASSERT_TRUE(robot_xml != NULL);
if (i == g_argc-1) if (i >= g_argc-2)
ASSERT_TRUE(robot.initXml(robot_xml)); ASSERT_TRUE(robot.initXml(robot_xml));
else else
ASSERT_FALSE(robot.initXml(robot_xml)); ASSERT_FALSE(robot.initXml(robot_xml));