jspace/jspace/tao_util.cpp

Go to the documentation of this file.
00001 /*
00002  * Stanford Whole-Body Control Framework http://stanford-wbc.sourceforge.net/
00003  *
00004  * Copyright (C) 2009 The Board of Trustees of The Leland Stanford Junior University. All rights reserved.
00005  *
00006  * This program is free software: you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation, either version 3 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this program.  If not, see
00018  * <http://www.gnu.org/licenses/>
00019  */
00020 
00026 #include "tao_util.hpp"
00027 #include "strutil.hpp"
00028 #include <tao/dynamics/taoNode.h>
00029 #include <tao/dynamics/taoDNode.h>
00030 #include <tao/dynamics/taoJoint.h>
00031 #include <limits>
00032 
00033 
00034 namespace jspace {
00035   
00036   void mapNodesToIDs(idToNodeMap_t & idToNodeMap,
00037          taoDNode * node)
00038     throw(std::runtime_error)
00039   {
00040     deInt id = node->getID();
00041     if (idToNodeMap.find( id ) != idToNodeMap.end())
00042       throw std::runtime_error("jspace::mapNodesToIDs(): duplicate ID " + sfl::to_string(id));
00043     idToNodeMap.insert(std::make_pair(id, node));
00044     
00045     // recurse
00046     for( taoDNode* p = node->getDChild(); p != NULL; p = p->getDSibling() )
00047       mapNodesToIDs(idToNodeMap, p);
00048   }
00049   
00050   
00051   int countNumberOfLinks(taoDNode * root)
00052   {
00053     int count(0);
00054     for (taoDNode * child(root->getDChild()); child != NULL; child = child->getDSibling()) {
00055       ++count;
00056       count += countNumberOfLinks(child);
00057     }
00058     return count;
00059   }
00060   
00061   
00062   int countNumberOfJoints(taoDNode * node)
00063   {
00064     int count(0);
00065     for (taoJoint * joint(node->getJointList()); 0 != joint; joint = joint->getNext()) {
00066       ++count;
00067     }
00068     for (taoDNode * child(node->getDChild()); 0 != child; child = child->getDSibling()) {
00069       count += countNumberOfJoints(child);
00070     }
00071     return count;
00072   }
00073   
00074   
00075   int countDegreesOfFreedom(taoDNode * node)
00076   {
00077     int dof(0);
00078     for (taoJoint * joint(node->getJointList()); 0 != joint; joint = joint->getNext()) {
00079       dof += joint->getDOF();
00080     }
00081     for (taoDNode * child(node->getDChild()); 0 != child; child = child->getDSibling()) {
00082       dof += countDegreesOfFreedom(child);
00083     }
00084     return dof;
00085   }
00086   
00087   
00088   double computeTotalMass(taoDNode * node)
00089   {
00090     double mass(0);
00091     if (node->mass()) {
00092       // I guess TAO nodes always have a mass, but the interface
00093       // returns a pointer, so maybe there are cases where there is
00094       // not even a zero mass? Whatever, just be paranoid and check
00095       // for non-NULL pointers.
00096       mass = *node->mass();
00097     }
00098     for (taoDNode * child(node->getDChild()); child != NULL; child = child->getDSibling()) {
00099       mass += computeTotalMass(child);
00100     }
00101     return mass;
00102   }
00103   
00104   
00105   tao_node_info_s::
00106   tao_node_info_s()
00107     : id(-2),
00108       node(0),
00109       joint(0),
00110       link_name(""),
00111       joint_name(""),
00112       limit_lower(0),
00113       limit_upper(0)
00114   {
00115   }
00116   
00117   
00118   tao_node_info_s::
00119   tao_node_info_s(taoDNode * _node,
00120       std::string const & _link_name,
00121       std::string _joint_name,
00122       double _limit_lower,
00123       double _limit_upper)
00124     : id(_node->getID()),
00125       node(_node),
00126       joint(0),
00127       link_name(_link_name),
00128       joint_name(_joint_name),
00129       limit_lower(_limit_lower),
00130       limit_upper(_limit_upper)
00131   {
00132     if (node) {
00133       joint = node->getJointList();
00134     }
00135   }
00136   
00137   
00138   tao_node_info_s::
00139   tao_node_info_s(tao_node_info_s const & orig)
00140     : id(orig.id),
00141       node(orig.node),
00142       joint(orig.joint),
00143       link_name(orig.link_name),
00144       joint_name(orig.joint_name),
00145       limit_lower(orig.limit_lower),
00146       limit_upper(orig.limit_upper)
00147   {
00148   }
00149   
00150   
00151   tao_tree_info_s::
00152   tao_tree_info_s()
00153     : root(0)
00154   {
00155   }
00156   
00157   
00158   tao_tree_info_s::
00159   ~tao_tree_info_s()
00160   {
00161     delete root;
00162   }
00163   
00164   
00165   bool tao_tree_info_s::
00166   sort()
00167   {
00168     // swap any out-of-order entries (yes yes, this is
00169     // suboptimal... let's just assume that in most cases they will
00170     // already be correctly ordered anyway)
00171     for (ssize_t ii(0); ii < info.size(); ++ii) {
00172       if (info[ii].id != ii) {
00173   for (ssize_t jj(ii + 1); jj < info.size(); ++jj) {
00174     if (info[jj].id == ii) {
00175       std::swap(info[ii], info[jj]);
00176       break;
00177     }
00178   }
00179       }
00180     }
00181     // check if it worked
00182     for (ssize_t ii(0); ii < info.size(); ++ii) {
00183       if (info[ii].id != ii) {
00184   return false;
00185       }
00186     }
00187     return true;
00188   }
00189   
00190   
00191   static void _recurse_create_bare_tao_tree_info(tao_tree_info_s * tree_info,
00192              taoDNode * node)
00193   {
00194     tree_info->info.push_back(tao_node_info_s());
00195     tao_node_info_s & node_info(tree_info->info.back());
00196     node_info.node = node;
00197     node_info.joint = node->getJointList();
00198     node_info.id = node->getID();
00199     node_info.link_name = "link" + sfl::to_string(node_info.id);
00200     node_info.joint_name = "joint" + sfl::to_string(node_info.id);
00201     node_info.limit_lower = std::numeric_limits<double>::min();
00202     node_info.limit_upper = std::numeric_limits<double>::max();
00203     for (taoDNode * child(node->getDChild()); child != NULL; child = child->getDSibling()) {
00204       _recurse_create_bare_tao_tree_info(tree_info, child);
00205     }
00206   }
00207   
00208   
00209   tao_tree_info_s * create_bare_tao_tree_info(taoNodeRoot * root)
00210   {
00211     tao_tree_info_s * tree_info(new tao_tree_info_s());
00212     tree_info->root = root;
00213     for (taoDNode * child(root->getDChild()); child != NULL; child = child->getDSibling()) {
00214       _recurse_create_bare_tao_tree_info(tree_info, child);
00215     }
00216     return tree_info;
00217   }
00218   
00219   
00220   typedef std::map<int, int> id_counter_t;
00221   
00222   static void tao_collect_ids(taoDNode * node, id_counter_t & id_counter)
00223   {
00224     int const id(node->getID());
00225     id_counter_t::iterator idc(id_counter.find(id));
00226     if (id_counter.end() == idc) {
00227       id_counter.insert(std::make_pair(id, 1));
00228     }
00229     else {
00230       ++idc->second;
00231     }
00232     for (taoDNode * child(node->getDChild()); 0 != child; child = child->getDSibling()) {
00233       tao_collect_ids(child, id_counter);
00234     }
00235   }
00236   
00237   
00238   int tao_consistency_check(taoNodeRoot * root, std::ostream * msg)
00239   {
00240     if (root->getID() != -1) {
00241       if (msg) {
00242   *msg << "jspace::tao_consistency_check(): root has ID " << root->getID() << " instead of -1\n";
00243       }
00244       return 1;
00245     }
00246     id_counter_t id_counter;
00247     for (taoDNode * node(root->getDChild()); 0 != node; node = node->getDSibling()) {
00248       tao_collect_ids(node, id_counter);
00249     }
00250     int expected_id(0);
00251     for (id_counter_t::const_iterator idc(id_counter.begin()); idc != id_counter.end(); ++idc, ++expected_id) {
00252       if (idc->first != expected_id) {
00253   if (msg) {
00254     *msg << "jspace::tao_consistency_check(): ID gap, expected "
00255          << expected_id << " but encountered " << idc->first << "\n";
00256   }
00257   return 2;
00258       }
00259       if (1 != idc->second) {
00260   if (msg) {
00261     *msg << "jspace::tao_consistency_check(): duplicate ID " << idc->first << "\n";
00262   }
00263   return 3;
00264       }
00265     }
00266     return 0;
00267   }
00268   
00269 }

Generated on Fri Aug 26 01:31:16 2011 for Stanford Whole-Body Control Framework by  doxygen 1.5.4