Go to the documentation of this file.00001
00031 #include <Eigen/Core>
00032 #include <Eigen/Geometry>
00033
00034 #include <ros/ros.h>
00035 #include <urdf_traverser/Functions.h>
00036 #include <urdf_traverser/Helpers.h>
00037 #include <urdf_traverser/UrdfTraverser.h>
00038 #include <urdf_transform/AlignRotationAxis.h>
00039
00040 using urdf_traverser::UrdfTraverser;
00041 using urdf_traverser::RecursionParams;
00042
00043
00048 class Vector3RecursionParams: public RecursionParams
00049 {
00050 public:
00051 typedef baselib_binding::shared_ptr<Vector3RecursionParams>::type Ptr;
00052 Vector3RecursionParams(): RecursionParams() {}
00053 Vector3RecursionParams(const Eigen::Vector3d& _vec):
00054 RecursionParams(),
00055 vec(_vec) {}
00056 Vector3RecursionParams(const Vector3RecursionParams& o):
00057 RecursionParams(o),
00058 vec(o.vec) {}
00059 virtual ~Vector3RecursionParams() {}
00060
00061
00062 Eigen::Vector3d vec;
00063 };
00064
00073 int allRotationsToAxisCB(urdf_traverser::RecursionParamsPtr& p)
00074 {
00075 urdf_traverser::LinkPtr link = p->getLink();
00076 if (!link)
00077 {
00078 ROS_ERROR("allRotationsToAxis: NULL link passed");
00079 return -1;
00080 }
00081
00082 Vector3RecursionParams::Ptr param = baselib_binding_ns::dynamic_pointer_cast<Vector3RecursionParams>(p);
00083 if (!param)
00084 {
00085 ROS_ERROR("Wrong recursion parameter type");
00086 return -1;
00087 }
00088
00089 urdf_traverser::JointPtr joint = link->parent_joint;
00090 if (!joint)
00091 {
00092 ROS_INFO_STREAM("allRotationsToAxis: Joint for link " << link->name << " is NULL, so this must be the root joint");
00093 return 1;
00094 }
00095
00096 Eigen::Vector3d axis = param->vec;
00097
00098 Eigen::Quaterniond alignAxis;
00099 if (urdf_traverser::jointTransformForAxis(joint, axis, alignAxis))
00100 {
00101 Eigen::Vector3d rotAxis(joint->axis.x, joint->axis.y, joint->axis.z);
00102
00103
00104 urdf_traverser::applyTransform(joint, urdf_traverser::EigenTransform(alignAxis), false);
00105
00106
00107 Eigen::Quaterniond alignAxisInv = alignAxis.inverse();
00108 urdf_traverser::applyTransform(link, urdf_traverser::EigenTransform(alignAxisInv), true);
00109
00110
00111
00112 for (std::vector<urdf_traverser::JointPtr>::iterator pj = link->child_joints.begin();
00113 pj != link->child_joints.end(); pj++)
00114 {
00115 urdf_traverser::applyTransform(*pj, urdf_traverser::EigenTransform(alignAxisInv), true);
00116 }
00117
00118
00119 joint->axis.x = axis.x();
00120 joint->axis.y = axis.y();
00121 joint->axis.z = axis.z();
00122 }
00123
00124
00125 return 1;
00126 }
00127
00128
00129 bool urdf_transform::allRotationsToAxis(UrdfTraverser& traverser, const std::string& fromLink, const Eigen::Vector3d& axis)
00130 {
00131
00132 std::string startLink = fromLink;
00133 if (startLink.empty())
00134 {
00135 startLink = traverser.getRootLinkName();
00136 }
00137 urdf_traverser::LinkPtr startLink_ = traverser.getLink(startLink);
00138 if (!startLink_)
00139 {
00140 ROS_ERROR("Link %s does not exist", startLink.c_str());
00141 return false;
00142 }
00143
00144 Vector3RecursionParams * vp = new Vector3RecursionParams(axis);
00145 urdf_traverser::RecursionParamsPtr p(vp);
00146
00147
00148
00149 int travRet = traverser.traverseTreeTopDown(startLink,
00150 boost::bind(&allRotationsToAxisCB, _1), p, false);
00151 if (travRet <= 0)
00152 {
00153 ROS_ERROR("Recursion to align all rotation axes failed");
00154 return false;
00155 }
00156 return true;
00157 }
00158
00159
00160