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
00067 urdf_traverser::JointPtr jointToParent = link->parent_joint;
00068 if (!jointToParent)
00069 {
00070
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
00080 lparam->resultLink = link;
00081 return 1;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 if (urdf_traverser::isActive(jointToParent))
00091 {
00092
00093
00094
00095
00096 lparam->resultLink = link;
00097 return 1;
00098 }
00099
00100
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
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
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
00120 if (child->name == jointToParent->name)
00121 {
00122
00123 parentLink->child_joints.erase(pj);
00124 break;
00125 }
00126 }
00127
00128
00129 urdf_traverser::EigenTransform localTrans = urdf_traverser::getTransform(link);
00130
00131
00132
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
00148
00149 urdf_traverser::applyTransform(rotAxTrans, child->axis);
00150
00151
00152
00153
00154
00155
00156 #endif
00157
00158 child->parent_link_name = parentLink->name;
00159 parentLink->child_joints.push_back(child);
00160
00161
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
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
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
00201
00202
00203
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
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
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