00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00062
00063
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 * 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 * 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
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
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";
00322 }
00323 else if (TAO_AXIS_Y == jdof1->getAxis()) {
00324 jaxis = "1";
00325 }
00326 else if (TAO_AXIS_Z == jdof1->getAxis()) {
00327 jaxis = "2";
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 {
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
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 & 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 *>(&joint)->getAxis() << ")";
00432 break;
00433 case TAO_JOINT_REVOLUTE:
00434 os << "revolute (axis " << dynamic_cast<taoJointDOF1 *>(&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, ¢er, &inertia);
00464 os << "m: " << mass << " COM: " << center
00465 << " I: " << jspace::inertia_matrix_to_string(inertia);
00466 return os;
00467 }
00468
00469 }