AlignRotationAxis.cpp
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     // Result set
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         // ROS_INFO_STREAM("Transforming axis "<<rotAxis<<" for joint "<<joint->name<<" with transform "<<urdf_traverser::EigenTransform(alignAxis));
00103 
00104         urdf_traverser::applyTransform(joint, urdf_traverser::EigenTransform(alignAxis), false);
00105 
00106         // the link has to receive the inverse transform, so it stays at the original position
00107         Eigen::Quaterniond alignAxisInv = alignAxis.inverse();
00108         urdf_traverser::applyTransform(link, urdf_traverser::EigenTransform(alignAxisInv), true);
00109 
00110         // we also have to fix the child joint's (1st order child joints) transform
00111         // to correct for this transformation.
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         // finally, set the rotation axis to the target
00119         joint->axis.x = axis.x();
00120         joint->axis.y = axis.y();
00121         joint->axis.z = axis.z();
00122     }
00123 
00124     // all good, indicate that recursion can continue
00125     return 1;
00126 }
00127 
00128 
00129 bool urdf_transform::allRotationsToAxis(UrdfTraverser& traverser, const std::string& fromLink, const Eigen::Vector3d& axis)
00130 {
00131     // ROS_INFO_STREAM("### Transforming all rotations starting from "<<fromLinkName<<" to axis "<<axis);
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     // traverse top-down, but don't include the link itself, as the method allRotationsToAxis()
00148     // operates on the links parent joints.
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 


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