jspace/jspace/tao_dump.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_dump.hpp"
00027 #include "tao_util.hpp"
00028 
00029 #include <tao/dynamics/taoNode.h>
00030 #include <tao/dynamics/taoJoint.h>
00031 #include <tao/dynamics/taoDynamics.h>
00032 #include <tao/dynamics/taoVar.h>
00033 #include <tao/utility/TaoDeMassProp.h>
00034 #include <iostream>
00035 #include <sstream>
00036 
00037 
00038 static void dump_deFloat(std::ostream & os, deFloat const * arr, size_t len)
00039 {
00040   if (0 == arr)
00041     os << "<NULL>";
00042   else {
00043     os << "{ ";
00044     for (size_t ii(0); ii < len; ++ii) {
00045       if (ii > 0)
00046   os << "  ";
00047       os << arr[ii];
00048     }
00049     os << " }";
00050   }
00051 }
00052 
00053 namespace jspace {
00054 
00055 std::string inertia_matrix_to_string(deMatrix3 const & mx)
00056 {
00057   if (0 == &mx) {
00058     return "<NULL>";
00059   }
00060   
00061   // WARNING: do not just directly access the underlying array of
00062   // deFloat... because deMatrix3 actually implements a 4x4 matrix for
00063   // whatever reason they had back when.
00064   std::ostringstream os;
00065   os << "{ XX: " << mx.elementAt(0, 0)
00066      << "  xy: " << mx.elementAt(0, 1)
00067      << "  xz: " << mx.elementAt(0, 2)
00068      << "  YY: " << mx.elementAt(1, 1)
00069      << "  yz: " << mx.elementAt(1, 2)
00070      << "  ZZ: " << mx.elementAt(2, 2)
00071      << " }";
00072   std::string result(os.str());
00073   return result;
00074 }
00075 
00076   
00077   void dump_tao_tree(std::ostream & os, taoDNode * root, std::string prefix,
00078          bool detailed,
00079          std::vector<std::string> * id_to_link_name,
00080          std::vector<std::string> * id_to_joint_name)
00081   {
00082     if ((0 <= root->getID()) && id_to_link_name && (id_to_link_name->size() > static_cast<size_t>(root->getID()))) {
00083       os << prefix << "* " << (*id_to_link_name)[root->getID()]
00084    << " (ID " << root->getID() << " at "<< (void*) root << ")\n";
00085     }
00086     else {
00087       os << prefix << "* ID " << root->getID() << " at "<< (void*) root << "\n";
00088     }
00089     
00090     os << prefix << "    home:         " << *root->frameHome() << "\n"
00091        << prefix << "    center:       " << *root->center() << "\n"
00092        << prefix << "    mass:         " << *root->mass() << "\n"
00093        << prefix << "    inertia:      " << inertia_matrix_to_string(*root->inertia()) << "\n";
00094     if (id_to_joint_name && (id_to_joint_name->size() > static_cast<size_t>(root->getID()))) {
00095       os << prefix << "    joint name:   " << (*id_to_joint_name)[root->getID()] << "\n";
00096     }
00097     for (taoJoint /*const*/ * jlist(root->getJointList()); jlist != 0; jlist = jlist->getNext()) {
00098       os << prefix << "    joint:        " << *jlist << "\n";
00099     }
00100     
00101     if (detailed) {
00102       os << prefix << "    velocity:     " << *root->velocity() << "\n"
00103    << prefix << "    acceleration: " << *root->acceleration() << "\n"
00104    << prefix << "    force:        " << *root->force() << "\n"
00105    << prefix << "    local:        " << *root->frameLocal() << "\n"
00106    << prefix << "    global:       " << *root->frameGlobal() << "\n";
00107     }
00108     
00109     prefix += "  ";
00110     for (taoDNode * child(root->getDChild()); child != 0; child = child->getDSibling())
00111       dump_tao_tree(os, child, prefix, detailed, id_to_link_name, id_to_joint_name);
00112   }
00113   
00114   
00115   static void _dump_tao_tree_info(std::ostream & os, taoDNode * root, tao_tree_info_s::node_info_t const & info,
00116           std::string prefix, bool detailed)
00117   {
00118     int const id(root->getID());
00119     if ((0 <= id) && (info.size() > static_cast<size_t>(id))) {
00120       os << prefix << "* " << info[id].link_name
00121    << " (ID " << id << " at "<< (void*) root << ")\n";
00122     }
00123     else {
00124       os << prefix << "* ID " << id << " at "<< (void*) root << "\n";
00125     }
00126     
00127     os << prefix << "    home:         " << *root->frameHome() << "\n"
00128        << prefix << "    center:       " << *root->center() << "\n"
00129        << prefix << "    mass:         " << *root->mass() << "\n"
00130        << prefix << "    inertia:      " << inertia_matrix_to_string(*root->inertia()) << "\n";
00131     if (info.size() > static_cast<size_t>(id)) {
00132       os << prefix << "    joint name:   " << info[id].joint_name << "\n"
00133    << prefix << "    lower limit:  " << info[id].limit_lower << "\n"
00134    << prefix << "    upper limit:  " << info[id].limit_upper << "\n";
00135     }
00136     for (taoJoint /*const*/ * jlist(root->getJointList()); jlist != 0; jlist = jlist->getNext()) {
00137       os << prefix << "    joint:        " << *jlist << "\n";
00138     }
00139     
00140     if (detailed) {
00141       os << prefix << "    velocity:     " << *root->velocity() << "\n"
00142    << prefix << "    acceleration: " << *root->acceleration() << "\n"
00143    << prefix << "    force:        " << *root->force() << "\n"
00144    << prefix << "    local:        " << *root->frameLocal() << "\n"
00145    << prefix << "    global:       " << *root->frameGlobal() << "\n";
00146     }
00147     
00148     prefix += "  ";
00149     for (taoDNode * child(root->getDChild()); child != 0; child = child->getDSibling())
00150       _dump_tao_tree_info(os, child, info, prefix, detailed);
00151   }
00152   
00153   
00154   void dump_tao_tree_info(std::ostream & os, tao_tree_info_s * tree, std::string prefix, bool detailed)
00155   {
00156     _dump_tao_tree_info(os, tree->root, tree->info, prefix, detailed);
00157   }
00158   
00159   
00160   static void _dump_tao_tree_info_saixml(std::ostream & os, taoDNode * root, tao_tree_info_s::node_info_t const & info,
00161            std::string prefix) throw(std::runtime_error)
00162   {
00163     deFrame * const home(root->frameHome());
00164     if ( ! home) {
00165   throw std::runtime_error("_dump_tao_tree_info_saixml(): no home frame");
00166     }
00167     deVector3 const & pos(home->translation());
00168     deVector3 raxis;
00169     deFloat rangle;
00170     home->rotation().get(raxis, rangle);
00171     
00172     int const id(root->getID());
00173     std::string closing;
00174     if (0 > id) {
00175       os << prefix << "<baseNode>\n"
00176    << prefix << "  <gravity>0, 0, -9.81</gravity>\n"
00177    << prefix << "  <pos>" << pos[0] << ", " << pos[1] << ", " << pos[2] << "</pos>\n"
00178    << prefix << "  <rot>" << raxis[0] << ", " << raxis[1] << ", " << raxis[2] <<  ", " << rangle << "</rot>\n";
00179       closing = prefix + "</baseNode>\n";
00180     }
00181     else {
00182       deVector3 const & com(*root->center());
00183       deMatrix3 const * inertia(root->inertia());
00184       taoJoint const * joint(root->getJointList());
00185       if ( ! joint) {
00186   throw std::runtime_error("_dump_tao_tree_info_saixml(): no joint");
00187       }
00188       std::string jtype;
00189       double mixx(0);
00190       double miyy(0);
00191       double mizz(0);
00192       if (0 != dynamic_cast<taoJointPrismatic const *>(joint)) {
00193   jtype = "P";
00194       }
00195       else if (0 != dynamic_cast<taoJointRevolute const *>(joint)) {
00196   jtype = "R";
00197   mixx = (pow(com[1], 2) + pow(com[2], 2)) * *(root->mass());
00198   miyy = (pow(com[0], 2) + pow(com[2], 2)) * *(root->mass());
00199   mizz = (pow(com[0], 2) + pow(com[1], 2)) * *(root->mass());
00200       }
00201       else {
00202   throw std::runtime_error("_dump_tao_tree_info_saixml(): invalid joint type");
00203       }
00204       std::string jaxis;
00205       taoJointDOF1 const * jdof1(dynamic_cast<taoJointDOF1 const *>(joint));
00206       if (TAO_AXIS_X == jdof1->getAxis()) {
00207   jaxis = "X";
00208       }
00209       else if (TAO_AXIS_Y == jdof1->getAxis()) {
00210   jaxis = "Y";
00211       }
00212       else if (TAO_AXIS_Z == jdof1->getAxis()) {
00213   jaxis = "Z";
00214       }
00215       else {
00216   throw std::runtime_error("_dump_tao_tree_info_saixml(): invalid joint axis");
00217       }
00218       
00219       os << prefix << "<jointNode>\n"
00220    << prefix << "  <ID>" << id << "</ID>\n"
00221    << prefix << "  <linkName>" << info[id].link_name << "</linkName>\n"
00222    << prefix << "  <jointName>" << info[id].joint_name << "</jointName>\n"
00223    << prefix << "  <type>" << jtype << "</type>\n"
00224    << prefix << "  <axis>" << jaxis << "</axis>\n"
00225    << prefix << "  <lowerJointLimit>" << info[id].limit_lower << "</lowerJointLimit>\n"
00226    << prefix << "  <upperJointLimit>" << info[id].limit_upper << "</upperJointLimit>\n"
00227    << prefix << "  <mass>" << *(root->mass()) << "</mass>\n"
00228    << prefix << "  <inertia>" << inertia->elementAt(0, 0) - mixx
00229    << ", " << inertia->elementAt(1, 1) - miyy
00230    << ", " << inertia->elementAt(2, 2) - mizz << "</inertia>\n"
00231    << prefix << "  <com>" << com[0] << ", " << com[1] << ", " << com[2] << "</com>\n"
00232    << prefix << "  <pos>" << pos[0] << ", " << pos[1] << ", " << pos[2] << "</pos>\n"
00233    << prefix << "  <rot>" << raxis[0] << ", " << raxis[1] << ", " << raxis[2] <<  ", " << rangle << "</rot>\n";
00234       closing = prefix + "</jointNode>\n";
00235     }
00236     
00237     prefix += "  ";
00238     for (taoDNode * child(root->getDChild()); child != 0; child = child->getDSibling())
00239       _dump_tao_tree_info_saixml(os, child, info, prefix);
00240     
00241     os << closing;
00242   }
00243   
00244   
00245   void dump_tao_tree_info_saixml(std::ostream & os, tao_tree_info_s * tree) throw(std::runtime_error)
00246   {
00247     os << "<?xml version=\"1.0\" ?>\n"
00248        << "<dynworld>\n";
00249     std::string prefix("  ");
00250     _dump_tao_tree_info_saixml(os, tree->root, tree->info, prefix);
00251     os << "</dynworld>\n";
00252   }
00253   
00254   
00255   void dump_tao_tree_info_lotusxml(std::ostream & os,
00256            std::string const & robot_name,
00257            std::string const & root_link_name,
00258            tao_tree_info_s * tree) throw(std::runtime_error)
00259   {
00260     os << "<?xml version=\"1.0\" ?>\n"
00261        << "<lotus_world>\n"
00262        << "  <globals>\n"
00263        << "    <gravity> 0.000 0.000 -9.81 </gravity>\n"
00264        << "  </globals>\n"
00265        << "  <robot name=\"" << robot_name << "\">\n";
00266     
00268     // root
00269     
00270     deFrame * home(tree->root->frameHome());
00271     if ( ! home) {
00272       throw std::runtime_error("dump_tao_tree_info_lotusxml(): no root home frame");
00273     }
00274     deVector3 & pos(home->translation());
00275     deQuaternion & rot(home->rotation());
00276     
00277     os << "    <root_link>\n"
00278        << "      <link_name>" << root_link_name << "</link_name>\n"
00279        << "      <position_in_parent>" << pos[0] << "  " << pos[1] << "  " << pos[2] << "</position_in_parent>\n"
00280        << "      <orientation_in_parent>"
00281        << rot[0] << "  " << rot[1] << "  " << rot[2] <<  "  " << rot[3] << "</orientation_in_parent>\n"
00282        << "    </root_link>\n";
00283 
00285     // links
00286     
00287     for (tao_tree_info_s::node_info_t::const_iterator inode(tree->info.begin());
00288    inode != tree->info.end(); ++inode) {
00289       home = inode->node->frameHome();
00290       if ( ! home) {
00291   throw std::runtime_error("dump_tao_tree_info_lotusxml(): no home frame in link `" + inode->link_name + "'");
00292       }
00293       pos = home->translation();
00294       rot = home->rotation();
00295       deVector3 const & com(*inode->node->center());
00296       deMatrix3 const * inertia(inode->node->inertia());
00297       taoJoint const * joint(inode->node->getJointList());
00298       if ( ! joint) {
00299   throw std::runtime_error("dump_tao_tree_info_lotusxml(): no joint in link `" + inode->link_name + "'");
00300       }
00301       std::string jtype;
00302       double mixx(0);
00303       double miyy(0);
00304       double mizz(0);
00305       if (0 != dynamic_cast<taoJointPrismatic const *>(joint)) {
00306   jtype = "p";
00307       }
00308       else if (0 != dynamic_cast<taoJointRevolute const *>(joint)) {
00309   jtype = "r";
00310   mixx = (pow(com[1], 2) + pow(com[2], 2)) * *(inode->node->mass());
00311   miyy = (pow(com[0], 2) + pow(com[2], 2)) * *(inode->node->mass());
00312   mizz = (pow(com[0], 2) + pow(com[1], 2)) * *(inode->node->mass());
00313       }
00314       else {
00315   throw std::runtime_error("dump_tao_tree_info_lotusxml(): invalid joint type in link `"
00316          + inode->link_name + "'");
00317       }
00318       std::string jaxis;
00319       taoJointDOF1 const * jdof1(dynamic_cast<taoJointDOF1 const *>(joint));
00320       if (TAO_AXIS_X == jdof1->getAxis()) {
00321   jaxis = "0";//XXXX really soon: "x";
00322       }
00323       else if (TAO_AXIS_Y == jdof1->getAxis()) {
00324   jaxis = "1";//XXXX really soon: "y";
00325       }
00326       else if (TAO_AXIS_Z == jdof1->getAxis()) {
00327   jaxis = "2";//XXXX really soon: "z";
00328       }
00329       else {
00330   throw std::runtime_error("dump_tao_tree_info_lotusxml(): invalid joint axis in link `"
00331          + inode->link_name + "'");
00332       }
00333       
00334       std::string parent_link_name;
00335       { // Yes, this way of finding the parent link name is braindead, please look away...
00336   taoDNode * parent(inode->node->getDParent());
00337   if (parent == tree->root) {
00338     parent_link_name = root_link_name;
00339   }
00340   else {
00341     for (tao_tree_info_s::node_info_t::const_iterator jj(tree->info.begin());
00342          jj != tree->info.end(); ++jj) {
00343       if (jj->node == parent) {
00344         parent_link_name = jj->link_name;
00345         break;
00346       }
00347     }
00348     if (parent_link_name.empty()) {
00349       throw std::runtime_error("dump_tao_tree_info_lotusxml(): invalid parent for link `"
00350              + inode->link_name + "'");
00351     }
00352   }
00353       }
00354       
00355       os << "    <link>\n"
00356    << "      <link_name>" << inode->link_name << "</link_name>\n"
00357    << "      <mass>" << *(inode->node->mass()) << "</mass>\n"
00358    << "      <inertia>" << inertia->elementAt(0, 0) - mixx
00359    << "  " << inertia->elementAt(1, 1) - miyy
00360    << "  " << inertia->elementAt(2, 2) - mizz << "</inertia>\n"
00361    << "      <center_of_mass>" << com[0] << "  " << com[1] << "  " << com[2] << "</center_of_mass>\n"
00362    << "      <position_in_parent>" << pos[0] << "  " << pos[1] << "  " << pos[2] << "</position_in_parent>\n"
00363    << "      <orientation_in_parent>"
00364    << rot[0] << "  " << rot[1] << "  " << rot[2] <<  "  " << rot[3] << "</orientation_in_parent>\n"
00365    << "      <joint_name>" << inode->joint_name << "</joint_name>\n"
00366    << "      <parent_link_name>" << parent_link_name << "</parent_link_name>\n"
00367    << "      <lower_joint_limit>" << inode->limit_lower << "</lower_joint_limit>\n"
00368    << "      <upper_joint_limit>" << inode->limit_upper << "</upper_joint_limit>\n"
00369    << "      <default_joint_position>" << 0 << "</default_joint_position>\n"
00370    << "      <axis>" << jaxis << "</axis>\n"
00371    << "      <joint_type>" << jtype << "</joint_type>\n"
00372    << "    </link>\n";
00373     }
00374     
00376     // done
00377     
00378     os << "  </robot>\n"
00379        << "</lotus_world>";
00380   }
00381   
00382 }
00383 
00384 namespace std {
00385   
00386 
00387   ostream & operator << (ostream & os, deVector6 const & vec) {
00388     if (0 == &vec)
00389       os << "<NULL>";
00390     else
00391       dump_deFloat(os, &vec.elementAt(0), 6);
00392     return os;
00393   }
00394   
00395 
00396   ostream & operator << (ostream & os, deVector3 const & vec) {
00397     if (0 == &vec)
00398       os << "<NULL>";
00399     else
00400       dump_deFloat(os, &vec.elementAt(0), 3);
00401     return os;
00402   }
00403   
00404 
00405   ostream & operator << (ostream & os, deQuaternion const & vec) {
00406     if (0 == &vec)
00407       os << "<NULL>";
00408     else
00409       dump_deFloat(os, &vec[0], 4);
00410     return os;
00411   }
00412   
00413 
00414   ostream & operator << (ostream & os, deFrame const & frame) {
00415     if (0 == &frame)
00416       os << "<NULL>";
00417     else
00418       os << "r: " << frame.rotation() << "  t: " << frame.translation();
00419     return os;
00420   }
00421 
00422 
00423   ostream & operator << (ostream & os, taoJoint /*const*/ & joint) {
00424     if (0 == &joint) {
00425       os << "<NULL>";
00426       return os;
00427     }
00428     taoJointType const jtype(joint.getType());
00429     switch (jtype) {
00430     case TAO_JOINT_PRISMATIC:
00431       os << "prismatic (axis " << dynamic_cast<taoJointDOF1 /*const*/ *>(&joint)->getAxis() << ")";
00432       break;
00433     case TAO_JOINT_REVOLUTE:
00434       os << "revolute (axis " << dynamic_cast<taoJointDOF1 /*const*/ *>(&joint)->getAxis() << ")";
00435       break;
00436     case TAO_JOINT_SPHERICAL: os << "spherical "; break;
00437     case TAO_JOINT_USER:      os << "user "; break;
00438     default:                  os << "<invalid type: " << jtype << "> ";
00439     }
00440     os << "  " << joint.getDOF() << " DOF";
00441     std::vector<deFloat> foo(joint.getDOF());
00442     joint.getQ(&foo[0]);
00443     os << "  q: ";
00444     dump_deFloat(os, &foo[0], joint.getDOF());
00445     joint.getDQ(&foo[0]);
00446     os << "  dq: ";
00447     dump_deFloat(os, &foo[0], joint.getDOF());
00448     joint.getDDQ(&foo[0]);
00449     os << "  ddq: ";
00450     dump_deFloat(os, &foo[0], joint.getDOF());
00451     joint.getTau(&foo[0]);
00452     os << "  tau: ";
00453     dump_deFloat(os, &foo[0], joint.getDOF());
00454     return os;
00455   }
00456   
00457 
00458   ostream & operator << (ostream & os, deMassProp const & rhs)
00459   {
00460     deFloat mass;
00461     deVector3 center;
00462     deMatrix3 inertia;
00463     rhs.get(&mass, &center, &inertia);
00464     os << "m: " << mass << "  COM: " << center
00465        << "  I: " << jspace::inertia_matrix_to_string(inertia);
00466     return os;
00467   }
00468   
00469 }

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