00001
00031 #include <ros/ros.h>
00032 #include <urdf_traverser/Functions.h>
00033 #include <urdf_traverser/Helpers.h>
00034
00035
00036 bool urdf_traverser::isActive(const JointPtr& joint)
00037 {
00038 if (!joint) return false;
00039 return (joint->type == urdf::Joint::REVOLUTE) ||
00040 (joint->type == urdf::Joint::CONTINUOUS) ||
00041 (joint->type == urdf::Joint::PRISMATIC);
00042 }
00043
00044 Eigen::Vector3d urdf_traverser::getRotationAxis(const JointConstPtr& j)
00045 {
00046 return Eigen::Vector3d(j->axis.x, j->axis.y, j->axis.z);
00047 }
00048
00049 bool urdf_traverser::scaleTranslation(JointPtr& joint, double scale_factor)
00050 {
00051 EigenTransform vTrans = getTransform(joint);
00052 scaleTranslation(vTrans, scale_factor);
00053 setTransform(vTrans, joint);
00054 }
00055
00056 void urdf_traverser::scaleTranslation(LinkPtr& link, double scale_factor)
00057 {
00058 for (std::vector<VisualPtr >::iterator vit = link->visual_array.begin();
00059 vit != link->visual_array.end(); ++vit)
00060 {
00061 VisualPtr visual = *vit;
00062 EigenTransform vTrans = getTransform(visual->origin);
00063 scaleTranslation(vTrans, scale_factor);
00064 setTransform(vTrans, visual->origin);
00065 }
00066
00067
00068 for (std::vector<CollisionPtr >::iterator cit = link->collision_array.begin();
00069 cit != link->collision_array.end(); ++cit)
00070 {
00071 CollisionPtr coll = *cit;
00072 EigenTransform vTrans = getTransform(coll->origin);
00073 scaleTranslation(vTrans, scale_factor);
00074 setTransform(vTrans, coll->origin);
00075 }
00076 if (!link->inertial)
00077 {
00078
00079 return;
00080 }
00081
00082 EigenTransform vTrans = getTransform(link->inertial->origin);
00083 scaleTranslation(vTrans, scale_factor);
00084 setTransform(vTrans, link->inertial->origin);
00085 }
00086
00087 void urdf_traverser::scaleTranslation(EigenTransform& t, double scale_factor)
00088 {
00089 Eigen::Vector3d trans = t.translation();
00090 trans *= scale_factor;
00091 Eigen::Matrix3d rot = t.rotation();
00092 t.setIdentity();
00093 t.translate(trans);
00094 t.rotate(rot);
00095 }
00096
00097 void urdf_traverser::setTransform(const EigenTransform& t, urdf::Pose& p)
00098 {
00099 Eigen::Vector3d trans(t.translation());
00100 Eigen::Quaterniond rot(t.rotation());
00101
00102 p.position.x = trans.x();
00103 p.position.y = trans.y();
00104 p.position.z = trans.z();
00105 p.rotation.x = rot.x();
00106 p.rotation.y = rot.y();
00107 p.rotation.z = rot.z();
00108 p.rotation.w = rot.w();
00109 }
00110
00111 void urdf_traverser::applyTransform(const EigenTransform& t, urdf::Vector3& v)
00112 {
00113 Eigen::Vector3d _v(v.x, v.y, v.z);
00114 Eigen::Quaterniond rot(t.rotation());
00115
00116 _v = rot * _v;
00117 v.x = _v.x();
00118 v.y = _v.y();
00119 v.z = _v.z();
00120 }
00121
00122 void urdf_traverser::setTransform(const EigenTransform& t, JointPtr& joint)
00123 {
00124 setTransform(t, joint->parent_to_joint_origin_transform);
00125 }
00126
00127
00128 urdf_traverser::EigenTransform urdf_traverser::getTransform(const JointConstPtr& joint)
00129 {
00130 assert(joint);
00131 return getTransform(joint->parent_to_joint_origin_transform);
00132 }
00133
00134 urdf_traverser::EigenTransform urdf_traverser::getTransform(const LinkConstPtr& link)
00135 {
00136 assert(link);
00137 return getTransform(link->parent_joint);
00138 }
00139
00140 urdf_traverser::EigenTransform urdf_traverser::getTransform(const LinkConstPtr& from_link, const LinkConstPtr& to_link)
00141 {
00142 return EigenTransform(getTransformMatrix(from_link, to_link));
00143 }
00144
00145 urdf_traverser::EigenTransform urdf_traverser::getTransform(const urdf::Pose& p)
00146 {
00147 urdf::Vector3 _jtr = p.position;
00148 Eigen::Vector3d jtr(_jtr.x, _jtr.y, _jtr.z);
00149 urdf::Rotation _jrot = p.rotation;
00150 Eigen::Quaterniond jrot(_jrot.w, _jrot.x, _jrot.y, _jrot.z);
00151 jrot.normalize();
00152 EigenTransform tr;
00153 tr.setIdentity();
00154 tr = tr.translate(jtr);
00155 tr = tr.rotate(jrot);
00156 return tr;
00157 }
00158
00159
00160
00161 Eigen::Matrix4d urdf_traverser::getTransformMatrix(const LinkConstPtr& from_link, const LinkConstPtr& to_link)
00162 {
00163 assert(from_link);
00164 assert(to_link);
00165 if (from_link->name == to_link->name) return Eigen::Matrix4d::Identity();
00166
00167 std::vector<JointPtr> pjoints = getChain(from_link, to_link);
00168
00169 if (pjoints.empty())
00170 {
00171 ROS_ERROR("could not get chain from %s to %s", from_link->name.c_str(), to_link->name.c_str());
00172 return Eigen::Matrix4d::Identity();
00173 }
00174
00175
00176
00177 Eigen::Matrix4d ret = Eigen::Matrix4d::Identity();
00178
00179 for (std::vector<JointPtr>::iterator it = pjoints.begin(); it != pjoints.end(); ++it)
00180 {
00181
00182 Eigen::Matrix4d mat = getTransform(*it).matrix();
00183 ret *= mat;
00184 }
00185 return ret;
00186 }
00187
00188 bool urdf_traverser::applyTransform(JointPtr& joint, const EigenTransform& trans, bool preMult)
00189 {
00190 EigenTransform vTrans = getTransform(joint);
00191 if (preMult) vTrans = trans * vTrans;
00192 else vTrans = vTrans * trans;
00193 setTransform(vTrans, joint);
00194 }
00195
00196 void urdf_traverser::applyTransform(LinkPtr& link, const EigenTransform& trans, bool preMult)
00197 {
00198
00199 assert(link);
00200
00201 for (std::vector<VisualPtr >::iterator vit = link->visual_array.begin();
00202 vit != link->visual_array.end(); ++vit)
00203 {
00204 VisualPtr visual = *vit;
00205 if (visual)
00206 {
00207 EigenTransform vTrans = getTransform(visual->origin);
00208
00209 if (preMult) vTrans = trans * vTrans;
00210 else vTrans = vTrans * trans;
00211 setTransform(vTrans, visual->origin);
00212 }
00213 }
00214
00215
00216 for (std::vector<CollisionPtr >::iterator cit = link->collision_array.begin();
00217 cit != link->collision_array.end(); ++cit)
00218 {
00219 CollisionPtr coll = *cit;
00220 if (coll)
00221 {
00222 EigenTransform vTrans = getTransform(coll->origin);
00223 if (preMult) vTrans = trans * vTrans;
00224 else vTrans = vTrans * trans;
00225 setTransform(vTrans, coll->origin);
00226 }
00227 }
00228
00229 if (link->inertial)
00230 {
00231 EigenTransform vTrans = getTransform(link->inertial->origin);
00232 if (preMult) vTrans = trans * vTrans;
00233 else vTrans = vTrans * trans;
00234 setTransform(vTrans, link->inertial->origin);
00235 }
00236 }
00237
00238 std::vector<urdf_traverser::JointPtr>
00239 urdf_traverser::getChain(const LinkConstPtr& from_link, const LinkConstPtr& to_link)
00240 {
00241 assert(from_link);
00242 assert(to_link);
00243 std::vector<JointPtr> chain;
00244
00245 if (to_link->name == from_link->name) return chain;
00246
00247 LinkConstPtr curr = to_link;
00248 LinkConstPtr pl = to_link->getParent();
00249
00250 while (curr && (curr->name != from_link->name))
00251 {
00252
00253 JointPtr pj = curr->parent_joint;
00254 if (!pj)
00255 {
00256 ROS_ERROR("UrdfTraverser: End of chain at link '%s'", curr->name.c_str());
00257 return std::vector<JointPtr>();
00258 }
00259 chain.push_back(pj);
00260 curr = pl;
00261 pl = curr->getParent();
00262
00263 }
00264 if (curr->name != from_link->name)
00265 {
00266 ROS_ERROR_STREAM("UrdfTraverser: could not find link " <<
00267 from_link->name << " while traversing up the chain starting from " <<
00268 to_link->name << ". Failed to find parent chain!");
00269 return std::vector<JointPtr>();
00270 }
00271
00272 std::reverse(chain.begin(), chain.end());
00273
00274 return chain;
00275 }
00276
00277
00278 bool urdf_traverser::isChildOf(const LinkConstPtr& parent, const LinkConstPtr& child)
00279 {
00280 for (unsigned int i = 0; i < parent->child_links.size(); ++i)
00281 {
00282 LinkPtr childLink = parent->child_links[i];
00283 if (childLink->name == child->name) return true;
00284 }
00285 return false;
00286 }
00287
00288 bool urdf_traverser::isChildJointOf(const LinkConstPtr& parent, const JointConstPtr& joint)
00289 {
00290 for (unsigned int i = 0; i < parent->child_joints.size(); ++i)
00291 {
00292 JointPtr childJnt = parent->child_joints[i];
00293 if (childJnt->name == joint->name) return true;
00294 }
00295 return false;
00296 }
00297
00298 bool equalAxes(const Eigen::Vector3d& z1, const Eigen::Vector3d& z2, double tolerance)
00299 {
00300 Eigen::Vector3d _z1 = z1;
00301 Eigen::Vector3d _z2 = z2;
00302 _z1.normalize();
00303 _z2.normalize();
00304 double dot = _z1.dot(_z2);
00305 return (std::fabs(dot - 1.0)) < tolerance;
00306 }
00307
00308
00309 bool urdf_traverser::jointTransformForAxis(const JointConstPtr& joint,
00310 const Eigen::Vector3d& axis, Eigen::Quaterniond& rotation)
00311 {
00312 Eigen::Vector3d rotAxis(joint->axis.x, joint->axis.y, joint->axis.z);
00313 if (rotAxis.norm() < 1e-06) return false;
00314 rotAxis.normalize();
00315
00316 if (equalAxes(rotAxis, axis, 1e-06)) return false;
00317
00318
00319
00320 rotation = Eigen::Quaterniond::FromTwoVectors(axis, rotAxis);
00321
00322 return true;
00323 }
00324
00325
00326