JoinFixedLinks.cpp
Go to the documentation of this file.
00001 
00031 #include <ros/ros.h>
00032 #include <urdf_traverser/UrdfTraverser.h>
00033 #include <urdf_traverser/Functions.h>
00034 #include <urdf_traverser/ActiveJoints.h>
00035 #include <urdf_transform/JoinFixedLinks.h>
00036 
00037 using urdf_traverser::UrdfTraverser;
00038 using urdf_traverser::RecursionParams;
00039 using urdf_traverser::LinkRecursionParams;
00040 
00048 int joinFixedLinksOnThis(urdf_traverser::RecursionParamsPtr& params)
00049 {
00050     LinkRecursionParams::Ptr lparam =
00051       baselib_binding_ns::dynamic_pointer_cast<LinkRecursionParams>(params);
00052     if (!lparam)
00053     {
00054         ROS_ERROR("Wrong recursion parameter type");
00055         return -1;
00056     }
00057 
00058     urdf_traverser::LinkPtr link = lparam->getLink();
00059 
00060     if (!link)
00061     {
00062         lparam->resultLink = link;
00063         return 1;
00064     }
00065 
00066     // ROS_INFO("--joinFixedLinksOnThis: Traverse %s",link->name.c_str());
00067     urdf_traverser::JointPtr jointToParent = link->parent_joint;
00068     if (!jointToParent)
00069     {
00070         // ROS_WARN("End of chain at %s, because of no parent joint", link->name.c_str());
00071         lparam->resultLink = link;
00072         return 1;
00073     }
00074 
00075     urdf_traverser::LinkPtr parentLink;
00076     lparam->model->getLink(jointToParent->parent_link_name, parentLink);
00077     if (!parentLink)
00078     {
00079         // ROS_WARN("End of chain at %s, because of no parent link", link->name.c_str());
00080         lparam->resultLink = link;
00081         return 1;
00082     }
00083 
00084     /*if (link->child_joints.empty()) {
00085         ROS_WARN("INFO: end effector %s",link->name.c_str());
00086         return link;
00087     }*/
00088 
00089 
00090     if (urdf_traverser::isActive(jointToParent))
00091     {
00092         // ROS_INFO("Parent of %s (%s) is active so won't delete",link->name.c_str(), jointToParent->name.c_str());
00093         // We won't delete this joint, as it is active.
00094         /*ROS_INFO("No joining of %s and %s (return latter)",
00095                  parentLink->name.c_str(),link->name.c_str());*/
00096         lparam->resultLink = link;
00097         return 1;
00098     }
00099 
00100     // this joint is fixed, so we will delete it
00101     ROS_INFO("Joining fixed joint (%s) between %s and %s",jointToParent->name.c_str(), parentLink->name.c_str(),link->name.c_str());
00102 
00103     // remove this link from the parent
00104     for (std::vector<urdf_traverser::LinkPtr>::iterator pc = parentLink->child_links.begin();
00105             pc != parentLink->child_links.end(); pc++)
00106     {
00107         urdf_traverser::LinkPtr child = (*pc);
00108         if (child->name == link->name)
00109         {
00110             // ROS_WARN("Remove link %s",link->name.c_str());
00111             parentLink->child_links.erase(pc);
00112             break;
00113         }
00114     }
00115     for (std::vector<urdf_traverser::JointPtr>::iterator pj = parentLink->child_joints.begin();
00116             pj != parentLink->child_joints.end(); pj++)
00117     {
00118         urdf_traverser::JointPtr child = (*pj);
00119         // this child joint is the current one that we just now removed
00120         if (child->name == jointToParent->name)
00121         {
00122             // ROS_WARN("Remove joint %s",child->name.c_str());
00123             parentLink->child_joints.erase(pj);
00124             break;
00125         }
00126     }
00127 
00128     // the local transfrom of the parent joint
00129     urdf_traverser::EigenTransform localTrans = urdf_traverser::getTransform(link);
00130     // ROS_INFO_STREAM("Transform between "<<parentLink->name<<" and "<<link->name<<": "<<localTrans);
00131     // all this link's child joints now must receive the extra transform from this joint which we removed.
00132     // then, the joints should be added to the parent link
00133     for (std::vector<urdf_traverser::JointPtr>::iterator j = link->child_joints.begin(); j != link->child_joints.end(); j++)
00134     {
00135         urdf_traverser::JointPtr child = (*j);
00136         if (!urdf_traverser::isActive(child))
00137         {
00138             ROS_ERROR("consistency: At this stage, we should only have active joints, found joint %s!",
00139                       child->name.c_str());
00140         }
00141         urdf_traverser::EigenTransform jTrans = urdf_traverser::getTransform(child);
00142 
00143         jTrans = localTrans * jTrans;
00144         urdf_traverser::setTransform(jTrans, child);
00145 #if 0
00146         EigenTransform rotAxTrans = jTrans.inverse();
00147         // ROS_INFO_STREAM("Transforming rotation axis by "<<rotAxTrans);
00148         // ROS_INFO_STREAM("Old child axis of "<<child->name<<": "<<child->axis);
00149         urdf_traverser::applyTransform(rotAxTrans, child->axis);
00150         /*Eigen::Vector3d childAxis(child->axis.x, child->axis.y, child->axis.z);
00151         childAxis.normalize();
00152         child->axis.x=childAxis.x();
00153         child->axis.y=childAxis.y();
00154         child->axis.z=childAxis.z();*/
00155         // ROS_INFO_STREAM("New child axis of "<<child->name<<": "<<child->axis);
00156 #endif
00157         // add this child joint to the parent
00158         child->parent_link_name = parentLink->name;
00159         parentLink->child_joints.push_back(child);
00160 
00161         // this link's child link has to be added to parents as well
00162         urdf_traverser::LinkPtr childChildLink;
00163         lparam->model->getLink(child->child_link_name, childChildLink);
00164         if (!childChildLink)
00165         {
00166             ROS_ERROR("consistency: found null child link for joint %s", child->name.c_str());
00167         }
00168         parentLink->child_links.push_back(childChildLink);
00169         childChildLink->setParent(parentLink);
00170     }
00171 
00172     for (std::vector<urdf_traverser::VisualPtr>::iterator vit = link->visual_array.begin();
00173             vit != link->visual_array.end(); ++vit)
00174     {
00175         urdf_traverser::VisualPtr visual = *vit;
00176         // apply the transform to the visual before adding it to the parent
00177         urdf_traverser::EigenTransform jTrans = urdf_traverser::getTransform(visual->origin);
00178         jTrans = localTrans * jTrans;
00179         urdf_traverser::setTransform(jTrans, visual->origin);
00180         parentLink->visual_array.push_back(visual);
00181     }
00182 
00183 
00184     for (std::vector<urdf_traverser::CollisionPtr>::iterator cit = link->collision_array.begin();
00185             cit != link->collision_array.end(); ++cit)
00186     {
00187         urdf_traverser::CollisionPtr coll = *cit;
00188         // apply the transform to the visual before adding it to the parent
00189         urdf_traverser::EigenTransform jTrans = urdf_traverser::getTransform(coll->origin);
00190         jTrans = localTrans * jTrans;
00191         urdf_traverser::setTransform(jTrans, coll->origin);
00192         parentLink->collision_array.push_back(coll);
00193     }
00194 
00195 
00196     if (parentLink->visual) parentLink->visual.reset();
00197     if (parentLink->collision) parentLink->collision.reset();
00198 
00199 
00200     // combine inertials
00201     // parent->inertial=XXX TODO;
00202         
00203     // ROS_INFO("Resulting link: %s",parentLink->name.c_str());
00204 
00205     lparam->resultLink = parentLink;
00206     return 1;
00207 }
00208 
00209 
00210 bool urdf_transform::joinFixedLinks(UrdfTraverser& traverser, const std::string& fromLink)
00211 {
00212     std::string rootLinkName = traverser.getRootLinkName();
00213     std::string startLink = fromLink;
00214     if (startLink.empty())
00215     {
00216         startLink = rootLinkName;
00217     }
00218     urdf_traverser::LinkPtr link = traverser.getLink(startLink);
00219     if (!link)
00220     {
00221         ROS_ERROR_STREAM("No link named '" << startLink << "'");
00222         return false;
00223     }
00224 
00225     // ROS_INFO_STREAM("### Joining fixed links starting from "<<startLink);
00226 
00227     bool includeRoot = false;
00228     LinkRecursionParams * lp = new LinkRecursionParams(traverser.getModel());
00229     urdf_traverser::RecursionParamsPtr p(lp);
00230     int travResult = traverser.traverseTreeBottomUp(startLink,
00231                                                     boost::bind(&joinFixedLinksOnThis, _1),
00232                                                     p, includeRoot);
00233     if (travResult < 0)
00234     {
00235         ROS_ERROR("Could not join fixed links");
00236         return false;
00237     }
00238 
00239     urdf_traverser::LinkPtr newLink = lp->resultLink;
00240     if (includeRoot && (newLink->name != startLink))
00241     {
00242         ROS_INFO_STREAM("Starting link " << startLink << " re-assigned to be " << newLink->name << ".");
00243         if (startLink == rootLinkName)
00244         {
00245             ROS_INFO("Re-assigning root link of the model");
00246             traverser.getModel()->root_link_ = newLink;
00247         }
00248     }
00249 
00250     // consistency check: All joints in the tree must be active now!
00251     if (urdf_traverser::hasFixedJoints(traverser, startLink))
00252     {
00253         ROS_ERROR("consistency: We should now only have active joints in the tree!");
00254         return false;
00255     }
00256     return true;
00257 }
00258 
00259 


urdf_transform
Author(s): Jennifer Buehler
autogenerated on Fri Mar 1 2019 03:38:10