Go to the documentation of this file.00001
00031 #include <ros/ros.h>
00032 #include <urdf_traverser/UrdfTraverser.h>
00033 #include <urdf_traverser/DependencyOrderedJoints.h>
00034 #include <urdf_traverser/Functions.h>
00035
00036 using urdf_traverser::UrdfTraverser;
00037 using urdf_traverser::RecursionParams;
00038
00044 class OrderedJointsRecursionParams: public urdf_traverser::RecursionParams
00045 {
00046 public:
00047 typedef baselib_binding::shared_ptr<OrderedJointsRecursionParams>::type Ptr;
00048 OrderedJointsRecursionParams(): RecursionParams() {}
00049 OrderedJointsRecursionParams(bool _allowSplits, bool _onlyActive):
00050 allowSplits(_allowSplits),
00051 onlyActive(_onlyActive) {}
00052 OrderedJointsRecursionParams(const OrderedJointsRecursionParams& o):
00053 RecursionParams(o),
00054 allowSplits(o.allowSplits),
00055 onlyActive(o.onlyActive),
00056 dependencyOrderedJoints(o.dependencyOrderedJoints) {}
00057 virtual ~OrderedJointsRecursionParams() {}
00058
00059
00060 std::vector<urdf_traverser::JointPtr> dependencyOrderedJoints;
00061
00062
00063
00064 bool allowSplits;
00065
00066
00067 bool onlyActive;
00068 };
00069
00070
00071 int addJointLink(urdf_traverser::RecursionParamsPtr& p)
00072 {
00073 OrderedJointsRecursionParams::Ptr param = baselib_binding_ns::dynamic_pointer_cast<OrderedJointsRecursionParams>(p);
00074 if (!param || !param->getLink())
00075 {
00076 ROS_ERROR("Wrong recursion parameter type, or NULL link");
00077 return -1;
00078 }
00079
00080
00081 urdf_traverser::LinkPtr link = param->getLink();
00082 assert(link);
00083
00084 urdf_traverser::LinkPtr parent = link->getParent();
00085 if (parent->child_joints.empty())
00086 {
00087 ROS_ERROR("If links are connected, there must be at least one joint");
00088 return -1;
00089 }
00090 if (!link->parent_joint)
00091 {
00092 ROS_ERROR("NULL parent joint");
00093 return -1;
00094 }
00095 if (parent->child_joints.size() > 1)
00096 {
00097 if (!param->allowSplits)
00098 {
00099 ROS_ERROR("Splitting point at %s!", parent->name.c_str());
00100 return -1;
00101 }
00102
00103 }
00104
00105 if (param->onlyActive && !urdf_traverser::isActive(link->parent_joint))
00106 {
00107
00108 return 1;
00109 }
00110
00111
00112 param->dependencyOrderedJoints.push_back(link->parent_joint);
00113 return 1;
00114 }
00115
00116
00117
00118 bool urdf_traverser::getDependencyOrderedJoints(UrdfTraverser& traverser,
00119 std::vector<urdf_traverser::JointPtr>& result,
00120 const urdf_traverser::JointPtr& fromJoint,
00121 bool allowSplits, bool onlyActive)
00122 {
00123 urdf_traverser::LinkPtr childLink = traverser.getChildLink(fromJoint);
00124 if (!childLink)
00125 {
00126 ROS_ERROR("Child link %s not found", fromJoint->child_link_name.c_str());
00127 return false;
00128 }
00129 if (!urdf_traverser::getDependencyOrderedJoints(traverser, result, childLink->name, allowSplits, onlyActive))
00130 {
00131 ROS_ERROR("Could not get ordered joints for %s", fromJoint->child_link_name.c_str());
00132 return false;
00133 }
00134 if (!onlyActive || urdf_traverser::isActive(fromJoint))
00135 {
00136 result.insert(result.begin(), fromJoint);
00137 }
00138 return true;
00139 }
00140
00141
00142 bool urdf_traverser::getDependencyOrderedJoints(UrdfTraverser& traverser,
00143 std::vector<JointPtr>& result, const std::string& fromLink,
00144 bool allowSplits, bool onlyActive)
00145 {
00146 urdf_traverser::LinkPtr _fromLink = traverser.getLink(fromLink);
00147 if (!_fromLink)
00148 {
00149 ROS_ERROR_STREAM("No link named " << fromLink << " in URDF.");
00150 return false;
00151 }
00152 if (!allowSplits && (_fromLink->child_joints.size() > 1))
00153 {
00154 ROS_ERROR("Splitting point at %s!", fromLink.c_str());
00155 return false;
00156 }
00157 OrderedJointsRecursionParams * p = new OrderedJointsRecursionParams(allowSplits, onlyActive);
00158 RecursionParamsPtr rp(p);
00159 int travRet = traverser.traverseTreeTopDown(fromLink, boost::bind(&addJointLink, _1), rp, false);
00160 if (travRet < 0)
00161 {
00162 ROS_ERROR("Could not add depenency order");
00163 p->dependencyOrderedJoints.clear();
00164 return false;
00165 }
00166
00167 result = p->dependencyOrderedJoints;
00168 return true;
00169 }