Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

robot/sim/SimulatedBasicEnvironment.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2003 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: SimulatedBasicEnvironment.cpp 1033 2004-02-11 20:47:52Z jungd $
00019   $Revision: 1.14 $
00020   $Date: 2004-02-11 15:47:52 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <robot/sim/SimulatedBasicEnvironment>
00026 
00027 // OSG
00028 #include <osg/Vec4>
00029 #include <osg/Group>
00030 #include <osg/Notify>
00031 #include <osg/Fog>
00032 #include <osg/Node>
00033 #include <osg/NodeVisitor>
00034 #include <osg/Material>
00035 
00036 #include <base/Externalizer>
00037 #include <base/externalization_error>
00038 #include <base/Application>
00039 #include <base/VFile>
00040 #include <physics/Shape>
00041 #include <physics/Box>
00042 #include <physics/Sphere>
00043 #include <physics/Material>
00044 #include <physics/Solid>
00045 #include <physics/ODESolidSystem>
00046 #include <physics/ConstraintGroup>
00047 #include <physics/FixedConstraint>
00048 
00049 
00050 using robot::sim::SimulatedBasicEnvironment;
00051 
00052 using base::Externalizer;
00053 using base::externalization_error;
00054 using base::Orient;
00055 using base::Dimension3;
00056 using base::Application;
00057 using base::VFile;
00058 using base::PathName;
00059 using base::dom::DOMNode;
00060 using base::dom::DOMElement;
00061 using physics::Shape;
00062 using physics::Box;
00063 using physics::Sphere;
00064 using physics::Material;
00065 using physics::Solid;
00066 using physics::SolidSystem;
00067 using physics::ODESolidSystem;
00068 using physics::ConstraintGroup;
00069 using physics::FixedConstraint;
00070 using physics::Collidable;
00071 using physics::CollisionCuller;
00072 using robot::sim::BasicEnvironment;
00073 using robot::sim::SimulatedRobot;
00074 
00075 
00076 
00077 SimulatedBasicEnvironment::SimulatedBasicEnvironment(ref<base::VFileSystem> fs, ref<base::Cache> cache, const String& name, bool dynamic)
00078   : BasicEnvironment(fs, cache, name), OSGWorld(fs, cache, name), dynamic(dynamic)
00079 {
00080   construct();
00081 }
00082 
00083 
00084 /// \todo clone anchored state of robot platform
00085 SimulatedBasicEnvironment::SimulatedBasicEnvironment(const SimulatedBasicEnvironment& e)
00086   : BasicEnvironment(e), OSGWorld(e), dynamic(e.dynamic)
00087 {
00088   construct();
00089   
00090   // duplicate robots
00091   RobotList::const_iterator r = e.robots.begin();
00092   RobotAnchoredList::const_iterator ra = robotsAnchored.begin();
00093   RobotList::const_iterator rend = e.robots.end();
00094   while (r != rend) {
00095     ref<SimulatedRobot> robot(*r);
00096     addRobot(robot->getRobotDescription(), 
00097              robot->getPosition(), robot->getOrientation(), 
00098              *ra); 
00099     ++r;
00100     ++ra;
00101   }
00102 
00103   // duplicate tools
00104   ToolList::const_iterator t = e.tools.begin();
00105   ToolList::const_iterator tend = e.tools.end();
00106   while (t != tend) {
00107     ref<const SolidTool> solidTool(narrow_ref<const SolidTool>(*t));
00108     addTool(solidTool->getToolDescription(), solidTool->getPosition(), solidTool->getOrientation());
00109     ++t;
00110   }
00111 
00112   
00113   // duplicate obstacles
00114   //  (should be an easier way sometime...)
00115   ObstacleList::const_iterator o = e.obstacles.begin();
00116   ObstacleList::const_iterator oend = e.obstacles.end();
00117   while (o != oend) {
00118     ref<SolidObstacle> obst(*o);
00119     ref<const Solid> solid(obst->solid);
00120     ref<const Shape> shape(solid->getShape());
00121     
00122     if (instanceof(*shape, const Box)) {
00123       ref<const Box> box(narrow_ref<const Box>(shape));
00124       addBoxObstacle(box->dimensions(), solid->getPosition(), solid->getOrientation(),
00125                      solid->getMaterial(), solid->getName());
00126     }
00127     else if (instanceof(*shape, const Sphere)) {
00128       ref<const Sphere> sphere(narrow_ref<const Sphere>(shape));
00129       addSphereObstacle(sphere->radius(), solid->getPosition(), solid->getOrientation(),
00130                         solid->getMaterial(), solid->getName());
00131     }
00132     else
00133       throw std::runtime_error(Exception("unhandled obstacle shape"));
00134     
00135     ++o;
00136   }
00137   
00138 }
00139 
00140 
00141 void SimulatedBasicEnvironment::setDynamic(bool enabled)
00142 {
00143   dynamic = enabled;
00144   RobotList::const_iterator r = robots.begin();
00145   RobotList::const_iterator rend = robots.end();
00146   while (r != rend) {
00147     (*r)->setDynamic(enabled);
00148     ++r;
00149   }
00150 
00151   ToolList::const_iterator t = tools.begin();
00152   ToolList::const_iterator tend = tools.end();
00153   while (t != tend) {
00154     ref<const SolidTool> solidTool(narrow_ref<const SolidTool>(*t));
00155     solidTool->simTool->setDynamic(enabled);
00156     ++t;
00157   }
00158 
00159 }
00160 
00161 
00162 
00163 ref<robot::Robot> SimulatedBasicEnvironment::addRobot(ref<const robot::RobotDescription> robotDescription,
00164                                                       const base::Point3& position, 
00165                                                       const base::Orient& orientation,
00166                                                       bool anchored)
00167 {
00168   ref<SimulatedRobot> robot(NewObj SimulatedRobot(robotDescription,
00169                                                   position, orientation,
00170                                                   system, dynamic));
00171   Assert(collidables);                                               
00172   ref<Collidable> robotCollidable( robot->createCollidable() );
00173   collidables->addCollidable( robotCollidable );
00174 
00175   if (anchored) {
00176     ref<Solid> platformSolid(robot->getPlatformSolid()); // get robot's platform Solid
00177     ref<FixedConstraint> fixed(system->createFixedConstraint()); // create a fixed constraint
00178     cgroup->addConstraint(fixed); 
00179     fixed->attach(ground, platformSolid); // attach platform to ground
00180 
00181     // tell collision detector not to collide them 
00182     ref<Collidable> platformBase( robotCollidable->findNamed("body") );
00183     if (platformBase)
00184       collisionCuller->collisionEnable(false,groundCollidable,platformBase);
00185   }
00186 
00187   robots.push_back(robot);
00188   robotsAnchored.push_back(anchored);
00189   return robot;
00190 }
00191 
00192 /// \todo remove solid & collidable
00193 void SimulatedBasicEnvironment::removeRobot(ref<robot::Robot> robot)
00194 {
00195   if (instanceof(*robot, SimulatedRobot)) {
00196     ref<SimulatedRobot> simRobot( narrow_ref<SimulatedRobot>(robot));
00197     robots.remove(simRobot);
00198   }
00199   else
00200     throw std::invalid_argument(Exception("unknown robot"));
00201 }
00202 
00203 
00204 ref<BasicEnvironment::Tool> SimulatedBasicEnvironment::addTool(ref<const robot::ToolDescription> toolDescription,
00205                                                                const base::Point3& position, 
00206                                                                const base::Orient& orientation)
00207 {
00208   ref<SimulatedTool> simTool(NewObj SimulatedTool(toolDescription,
00209                                                   position, orientation,
00210                                                   system, dynamic));
00211   Assert(simTool);                                               
00212   Assert(collidables);
00213 
00214   ref<Collidable> toolCollidable( simTool->createCollidable() );
00215   collidables->addCollidable( toolCollidable );
00216                                                   
00217                                                   
00218   ref<SolidTool> tool(NewObj SolidTool(toolDescription->getName(),toolDescription,
00219                                        position, orientation, simTool));
00220   tools.push_back(tool);
00221   return tool;
00222 }
00223 
00224 /// \todo remove solid
00225 void SimulatedBasicEnvironment::removeTool(ref<BasicEnvironment::Tool> tool)
00226 {
00227   tools.remove(tool);
00228 }
00229 
00230 
00231 void SimulatedBasicEnvironment::placeToolInProximity(ref<Tool> tool, ref<Robot> robot, Int manipulatorIndex)
00232 {
00233    if (instanceof(*robot, SimulatedRobot)) {
00234      if (instanceof(*tool, SolidTool)) {
00235        ref<SimulatedRobot> simRobot( narrow_ref<SimulatedRobot>(robot));
00236        ref<SolidTool> solidTool( narrow_ref<SolidTool>(tool) );
00237        ref<SimulatedTool> simTool( solidTool->simTool );
00238 
00239        simRobot->placeToolInProximity(simTool, manipulatorIndex);
00240      }
00241      else
00242        throw std::invalid_argument(Exception("unknown tool"));
00243   }
00244   else
00245     throw std::invalid_argument(Exception("unknown robot"));
00246 }
00247 
00248 
00249 
00250 
00251 ref<BasicEnvironment::Obstacle> SimulatedBasicEnvironment::addBoxObstacle(base::Dimension3 dim, 
00252                                                                           const base::Point3& position, 
00253                                                                           const base::Orient& orientation,
00254                                                                           const String& name)
00255 {
00256   ref<Material> material(NewObj physics::Material());
00257   material->setBaseColor(gfx::Color3(0.7,0.4,0.8)); // default
00258   material->setDensity(1.0); // default
00259 
00260   return addBoxObstacle(dim,position,orientation,material,name);
00261 }
00262 
00263 
00264 ref<BasicEnvironment::Obstacle> SimulatedBasicEnvironment::addSphereObstacle(Real radius,
00265                                                                              const base::Point3& position, 
00266                                                                              const base::Orient& orientation,
00267                                                                              const String& name)
00268 {
00269   ref<Material> material(NewObj physics::Material());
00270   material->setBaseColor(gfx::Color3(0.7,0.4,0.8)); // default
00271   material->setDensity(1.0); // default
00272 
00273   return addSphereObstacle(radius,position,orientation,material,name);
00274 }
00275 
00276 
00277 ref<BasicEnvironment::Obstacle> SimulatedBasicEnvironment::addBoxObstacle(base::Dimension3 dim, 
00278                                                                           const base::Point3& position, 
00279                                                                           const base::Orient& orientation,
00280                                                                           ref<const physics::Material> material,
00281                                                                           const String& name)
00282 {
00283   ref<Box> box(NewObj Box(dim.x,dim.y,dim.z));
00284   ref<Solid> solid(system->createSolid(box, material));
00285   solid->setName( (name=="")?String("box obstacle"):name);
00286   system->addSolid(solid);
00287   solid->setEnabled(dynamic);
00288   solid->setPosition(position);
00289   solid->setOrientation(orientation.getQuat4());
00290   
00291   ref<Collidable> obstCollidable( solid->createCollidable() );
00292   collidables->addCollidable( obstCollidable );
00293 
00294   ref<SolidObstacle> obstacle(NewObj SolidObstacle(dim,position,orientation,solid));
00295   obstacles.push_back(obstacle);
00296   return obstacle;
00297 }
00298 
00299 
00300 ref<BasicEnvironment::Obstacle> SimulatedBasicEnvironment::addSphereObstacle(Real radius,
00301                                                                              const base::Point3& position, 
00302                                                                              const base::Orient& orientation,
00303                                                                              ref<const physics::Material> material,
00304                                                                              const String& name)
00305 {
00306   ref<Sphere> sphere(NewObj Sphere(radius));
00307   ref<Solid> solid(system->createSolid(sphere, material));
00308   solid->setName( (name=="")?String("sphere obstacle"):name);
00309   system->addSolid(solid);
00310   solid->setEnabled(dynamic);
00311   solid->setPosition(position);
00312   solid->setOrientation(orientation.getQuat4());
00313 
00314   ref<Collidable> obstCollidable( solid->createCollidable() );
00315   collidables->addCollidable( obstCollidable );
00316 
00317   ref<SolidObstacle> obstacle(NewObj SolidObstacle(radius,position,orientation,solid));
00318   obstacles.push_back(obstacle);
00319   return obstacle;
00320 }
00321 
00322 
00323 
00324 void SimulatedBasicEnvironment::removeObstacle(ref<BasicEnvironment::Obstacle> obstacle)
00325 {
00326   if (instanceof(*obstacle, SolidObstacle)) 
00327     obstacles.remove( narrow_ref<SolidObstacle>(obstacle) );
00328   else
00329     throw std::invalid_argument(Exception("unknown Obstacle"));
00330 }
00331 
00332 /// \TODO shouldn't this remove the old Solid from the system an 
00333 ///  add the new one (and also create a new Collidable from the new Solid)???
00334 void SimulatedBasicEnvironment::setObstacleColor(ref<BasicEnvironment::Obstacle> obstacle, const gfx::Color3& color)
00335 {
00336   if (instanceof(*obstacle, SolidObstacle)) {
00337 
00338     ref<SolidObstacle> solidobst( narrow_ref<SolidObstacle>(obstacle) );
00339     ref<Solid> s( solidobst->solid );
00340     // create a Solid identical to the old but with a different material color
00341     //  and substitute one for the other
00342     ref<Material> newmat(NewObj Material(*s->getMaterial()));
00343     newmat->setBaseColor(color);
00344     ref<Solid> newsolid(system->createSolid(s->getShape(), newmat));
00345     newsolid->setName( s->getName() );
00346     solidobst->solid = newsolid;
00347   }
00348   else
00349     throw std::invalid_argument(Exception("unknown Obstacle"));
00350 }
00351 
00352 
00353 void SimulatedBasicEnvironment::setObstacleDensity(ref<BasicEnvironment::Obstacle> obstacle, Real density)
00354 {
00355   if (instanceof(*obstacle, SolidObstacle)) {
00356 
00357     ref<SolidObstacle> solidobst( narrow_ref<SolidObstacle>(obstacle) );
00358     ref<Solid> s( solidobst->solid );
00359     // create a Solid identical to the old but with a different material density
00360     //  and substitute one for the other
00361     ref<Material> newmat(NewObj Material(*s->getMaterial()));
00362     newmat->setDensity(density);
00363     ref<Solid> newsolid(system->createSolid(s->getShape(), newmat));
00364     newsolid->setName( s->getName() );
00365     solidobst->solid = newsolid;
00366   }
00367   else
00368     throw std::invalid_argument(Exception("unknown Obstacle"));
00369 }
00370 
00371 
00372 ref<physics::Solid> SimulatedBasicEnvironment::findObstacle(ref<BasicEnvironment::Obstacle> obstacle)
00373 {
00374   if (instanceof(*obstacle, SolidObstacle)) {
00375     ref<SolidObstacle> so( narrow_ref<SolidObstacle>(obstacle) );
00376     return so->solid;
00377   }
00378   else
00379     return ref<physics::Solid>(0);
00380 }
00381 
00382 
00383 void SimulatedBasicEnvironment::construct()
00384 {
00385   // Rigid-body physics simulation system
00386   system = ref<SolidSystem>(NewNamedObj("BasicEnvironmentSolidSystem") ODESolidSystem());
00387   system->setGravity(base::Vector3(0,0,-9.8));
00388   //system->setGravity(base::Vector3(0,0,0));//!!!
00389   system->setParameter("ERP",0.2);
00390   system->setParameter("CFM",1e-7);
00391 
00392   collisionCuller = system->getCollisionCuller();
00393   collidables = collisionCuller->createCollidableGroup();
00394   
00395   // create a constraint group for environment wide constraints (e.g. fixed constraints for fixing robots to the ground)
00396   cgroup = ref<ConstraintGroup>(system->createConstraintGroup());
00397 
00398   // make a big flat 'plane' for the 'ground'
00399   const Real t = 1.0; // thickness
00400   ref<Box> groundBox(NewObj Box(150,150,t));
00401   ref<physics::Material> groundMaterial(NewObj physics::Material());
00402   groundMaterial->setDensity(0.01); 
00403   //groundMaterial->setBaseColor(gfx::Color3(244.0/256.0,164.0/256.0,96.0/256.0)); // 'brown'
00404   groundMaterial->setBaseColor(gfx::Color3(1.0,1.0,1.0)); // 'white'
00405   //!!!groundMaterial->setSurfaceAppearance(PathName("images/LlanoTex.jpg"));
00406   ground = system->createSolid(groundBox, groundMaterial);
00407   ground->setName("ground");
00408   system->setGround(ground, Point3(0,0,-(t/2.0))); // system treats the ground Solid as special - it's anchored to the world frame.
00409 
00410   groundCollidable = ground->createCollidable();
00411   collidables->addCollidable( groundCollidable );
00412   
00413   system->setCollidable(collidables);
00414 }
00415 
00416 
00417 
00418 void SimulatedBasicEnvironment::checkTools()
00419 {
00420   // check each tool for proximity with each robot
00421   RobotList::const_iterator r = robots.begin();
00422   RobotList::const_iterator rend = robots.end();
00423   while (r != rend) {
00424     ref<SimulatedRobot> robot(*r);
00425     
00426     ToolList::const_iterator t = tools.begin();
00427     ToolList::const_iterator tend = tools.end();
00428     while (t != tend) {
00429       ref<SimulatedTool> simTool( narrow_ref<SolidTool>(*t)->simTool );
00430       
00431       robot->checkProximity(simTool);
00432       
00433       ++t;
00434     }
00435 
00436     ++r;
00437   }
00438         
00439 }
00440 
00441 
00442 
00443 void SimulatedBasicEnvironment::preSimulate()
00444 {
00445   system->preSimulate();
00446   checkTools();
00447 }
00448 
00449 
00450 void SimulatedBasicEnvironment::simulateForSimTime(const base::Time& dt)
00451 {
00452   if (dynamic) 
00453     system->simulateForSimTime(dt);
00454   else
00455     system->simulateForSimTime(0); // just do collisions and update Visual (if any)
00456   checkTools();
00457 }
00458 
00459 
00460 
00461 osg::Node* SimulatedBasicEnvironment::createOSGVisual(Visual::Attributes visualAttributes) const
00462 {
00463   if ((rootnode!=0) && (attributes==visualAttributes))
00464     return &(*rootnode);
00465 
00466   rootnode = NewObj osg::Group;
00467   rootnode->setName("root");
00468   
00469   // create physics system graphics
00470   osg::Node* g = system->createOSGVisual( visualAttributes 
00471 #ifdef DEBUG
00472 //                                       | gfx::Visual::ShowAxes 
00473                                          //| gfx::Visual::ShowCollisionModel
00474                                          //| gfx::Visual::ShowNormals
00475 #endif
00476                                         );
00477   
00478   rootnode->addChild(g);
00479 
00480   
00481   // Set state of rootnode (fog etc.)
00482   osg::StateSet* pState = NewObj osg::StateSet;
00483   //    pState->setMode(GL_LIGHTING,osg::StateAttribute::ON); 
00484   osg::Vec4 fogColor(0.65f,0.65f,0.65f,1.0f);
00485   osg::Fog* fog = NewObj osg::Fog;
00486   fog->setMode(osg::Fog::LINEAR);
00487   fog->setDensity(0.1f);
00488   fog->setStart(100.0f);
00489   fog->setEnd(10000.0f - 100.0f); // (max view dist)
00490   fog->setColor(fogColor);
00491   pState->setAttributeAndModes(fog,osg::StateAttribute::ON);
00492   rootnode->setStateSet(pState);
00493   
00494   return &(*rootnode);
00495 } 
00496 
00497 
00498 
00499 
00500 bool SimulatedBasicEnvironment::formatSupported(const String format, Real version, ExternalizationType type) const
00501 {
00502   return ( (format=="xml") && (version==1.0) ); 
00503 }
00504 
00505 
00506 void SimulatedBasicEnvironment::externalize(base::Externalizer& e, String format, Real version)
00507 {
00508   if (format=="") format="xml";
00509 
00510   if (!formatSupported(format,version,e.ioType()))
00511     throw std::invalid_argument(Exception(String("format ")+format+" v"+base::realToString(version)+" unsupported"));
00512   
00513   if (format == "xml") {
00514 
00515     if (e.isOutput()) {
00516 
00517       DOMElement* envElem = e.createElement("environment");
00518       e.setElementAttribute(envElem,"type","basic");
00519 
00520       e.pushContext(envElem);
00521 
00522       e.appendBreak(envElem);
00523 
00524       // externalize the robots
00525       RobotList::const_iterator r = robots.begin();
00526       RobotAnchoredList::const_iterator ra = robotsAnchored.begin();
00527       RobotList::const_iterator rend = robots.end();
00528       if (r != rend) 
00529         e.appendComment(envElem,"robots   (description, position, and orientation (Quat) )");
00530         while (r != rend) {
00531           ref<SimulatedRobot> robot(*r);
00532           
00533           if (robot->isDescriptionProvided()) 
00534             robot->getRobotDescription()->externalize(e, format, version);
00535           else
00536             throw externalization_error(Exception("can't externalize a Robot with no description"));
00537           
00538           DOMElement* robotElem = e.lastAppendedElement();
00539           Point3 position(robot->getPosition());
00540           DOMElement* posElem = e.createElement("position",false);
00541           e.appendText(posElem, e.toString(position) );
00542           e.appendNode(robotElem, posElem);
00543           e.appendBreak(robotElem);
00544           
00545           Orient orientation(robot->getOrientation());
00546           DOMElement* orientElem = e.createElement("orientation",false);
00547           Vector v( orientation.getVector(Orient::Quat) );
00548           e.appendText(orientElem, e.toString(v,true));
00549           e.appendNode(robotElem, orientElem);
00550           e.appendBreak(robotElem);
00551           
00552           if (*ra)
00553             e.setElementAttribute(robotElem, "anchored", "true");
00554           
00555           ++r;
00556           ++ra;
00557           e.appendBreak(envElem);
00558       }
00559       e.appendBreak(envElem);
00560 
00561 
00562       // externalize tools
00563       ToolList::const_iterator t = tools.begin();
00564       ToolList::const_iterator tend = tools.end();
00565       if (t != tend)
00566         e.appendComment(envElem,"tools   (position, orientation (Quat) and description)");
00567         while (t != tend) {
00568           ref<Tool> tool(*t);
00569           tool->getToolDescription()->externalize(e, format, version);
00570           
00571           DOMElement* toolElem = e.lastAppendedElement();
00572           
00573           Point3 position(tool->getPosition()); 
00574           DOMElement* posElem = e.createElement("position",false);
00575           e.appendText(posElem, e.toString(position) );
00576           e.appendNode(toolElem, posElem);
00577           e.appendBreak(toolElem);
00578           
00579           Orient orientation(tool->getOrientation()); 
00580           DOMElement* orientElem = e.createElement("orientation",false);
00581           Vector v( orientation.getVector(Orient::Quat) );
00582           e.appendText(orientElem, e.toString(v,true));
00583           e.appendNode(toolElem, orientElem);
00584           e.appendBreak(toolElem);
00585           
00586           ++t;
00587           e.appendBreak(envElem);
00588       }
00589       e.appendBreak(envElem);
00590 
00591 
00592       // externalize obstacles
00593       ObstacleList::const_iterator o = obstacles.begin();
00594       ObstacleList::const_iterator oend = obstacles.end();
00595       if (o != oend)
00596         e.appendComment(envElem,"obstacles (position, orientation (Quat) and description)");
00597       while (o != oend) {
00598         ref<SolidObstacle> obstacle(*o);
00599         
00600         DOMElement* obstElem = e.createElement("obstacle");
00601         e.setElementAttribute(obstElem,"name",obstacle->solid->getName());
00602         
00603         Point3& position(obstacle->position); 
00604         DOMElement* posElem = e.createElement("position",false);
00605         e.appendText(posElem, e.toString(position) );
00606         e.appendNode(obstElem, posElem);
00607         e.appendBreak(obstElem);
00608         
00609         Orient& orientation(obstacle->orientation); 
00610         DOMElement* orientElem = e.createElement("orientation",false);
00611         Vector v( orientation.getVector(Orient::Quat) );
00612         e.appendText(orientElem, e.toString(v,true));
00613         e.appendNode(obstElem, orientElem);
00614         e.appendBreak(obstElem);
00615         
00616         if (obstacle->type == Obstacle::BoxObstacle) {
00617           e.setElementAttribute(obstElem,"type","box");
00618           DOMElement* dElem = e.createElement("dimensions",false);
00619           e.appendText( dElem, e.toString(obstacle->dims) );
00620           e.appendNode(obstElem,dElem);
00621         }
00622         else if (obstacle->type == Obstacle::SphereObstacle) {
00623           e.setElementAttribute(obstElem,"type","sphere");
00624           DOMElement* rElem = e.createElement("radius",false);
00625           e.appendText(rElem, base::realToString(obstacle->radius));
00626           e.appendNode(obstElem,rElem);
00627         }
00628         else
00629           throw externalization_error(Exception("unsupported obstacle type"));
00630         
00631         e.pushContext(obstElem);
00632         ref<Material> mat(NewObj Material(*obstacle->solid->getMaterial()));
00633         mat->externalize(e, format, version);
00634         e.popContext();
00635         
00636         
00637         e.appendNode(envElem, obstElem);
00638         
00639         ++o;
00640         e.appendBreak(envElem);
00641       }
00642       
00643       
00644       e.popContext();
00645       
00646       e.appendElement(envElem);
00647       
00648     }
00649     else { // input
00650 
00651       // first clear the current environment
00652       while (!robots.empty()) removeRobot( robots.front() );
00653       while (!tools.empty()) removeTool( tools.front() );
00654       while (!obstacles.empty()) removeObstacle( obstacles.front() );
00655       construct();
00656 
00657       // now load the new one
00658       DOMNode* context = e.context();
00659     
00660       DOMElement* envElem = e.getFirstElement(context, "environment");
00661       // handle link
00662       String link = e.getElementAttribute(envElem,"link",false);
00663       if (link != "") {
00664         
00665         ref<VFile> linkFile = Application::getInstance()->universe()->cache()->findFile(link,e.getArchivePath());
00666         load(linkFile,format,version);
00667       }
00668       else {
00669         
00670         if ( e.getElementAttribute(envElem, "type") != "basic" )
00671           throw externalization_error(Exception("unsupported environment type"));
00672         
00673         e.pushContext(envElem);
00674         
00675         // read in robots
00676         DOMElement* robotElem = e.getFirstChildElement(envElem, "robot",false);
00677         while (robotElem) {
00678           // get position & orientation
00679           DOMElement* posElem = e.getFirstChildElement(robotElem,"position");
00680           String posText = e.getContainedText(posElem);
00681           Point3 position( e.toVector3(posText) );
00682           
00683           DOMElement* orientElem = e.getFirstChildElement(robotElem, "orientation");
00684           String orientText = e.getContainedText(orientElem);
00685           Vector v( e.toVector(orientText,true) );
00686           Orient orientation;
00687           if (v.size() == 4)
00688             orientation = Orient(v, Orient::Quat);
00689           else if (v.size() == 3)
00690             orientation = Orient(v, Orient::EulerRPY);
00691           else
00692             throw externalization_error(Exception("robot orientation must have either 3(EulerRPY) or 4(Quaternion) elements)"));
00693           
00694           // get if robot anchored
00695           String anchoredString = e.getDefaultedElementAttribute(robotElem, "anchored", "false");
00696           bool anchored = (anchoredString == "true");
00697           if (!anchored && (anchoredString != "false"))
00698             throw externalization_error(Exception("'anchored' attribute of element 'robot' must be either 'true' or 'false'"));
00699           
00700           ref<RobotDescription> rd(newRobotDescription());
00701           rd->externalize(e, format, version);
00702           addRobot(rd, position, orientation, anchored);
00703           
00704           robotElem = e.getFirstChildElement(envElem, "robot",false);
00705         }
00706   
00707   
00708         // read in tools
00709         DOMElement* toolElem = e.getFirstChildElement(envElem, "tool",false);
00710         while (toolElem) {
00711           // get position & orientation
00712           DOMElement* posElem = e.getFirstChildElement(toolElem,"position");
00713           String posText = e.getContainedText(posElem);
00714           Point3 position( e.toVector3(posText) );
00715           
00716           DOMElement* orientElem = e.getFirstChildElement(toolElem, "orientation");
00717           String orientText = e.getContainedText(orientElem);
00718           Vector v( e.toVector(orientText,true) );
00719           Orient orientation;
00720           if (v.size() == 4)
00721             orientation = Orient(v, Orient::Quat);
00722           else if (v.size() == 3)
00723             orientation = Orient(v, Orient::EulerRPY);
00724           else
00725             throw externalization_error(Exception("tool orientation must have either 3(EulerRPY) or 4(Quaternion) elements)"));
00726           
00727           ref<ToolDescription> td(NewObj ToolDescription());
00728           td->externalize(e, format, version);
00729           
00730           addTool(td, position, orientation);
00731           
00732           toolElem = e.getFirstChildElement(envElem, "tool",false);
00733         }
00734 
00735         
00736         // read in obstacles
00737         DOMElement* obstElem = e.getFirstChildElement(envElem, "obstacle",false);
00738         while (obstElem) {
00739           String name( e.getDefaultedElementAttribute(obstElem, "name", "obstacle") );
00740           
00741           // read in position & orientation
00742           DOMElement* posElem = e.getFirstChildElement(obstElem, "position");
00743           String posText = e.getContainedText(posElem);
00744           Point3 position( e.toVector3(posText) );
00745           
00746           DOMElement* orientElem = e.getFirstChildElement(obstElem, "orientation");
00747           String orientText = e.getContainedText(orientElem);
00748           Vector v( e.toVector(orientText,true) );
00749           Orient orientation;
00750           if (v.size() == 4)
00751             orientation = Orient(v, Orient::Quat);
00752           else if (v.size() == 3)
00753             orientation = Orient(v, Orient::EulerRPY);
00754           else
00755             throw externalization_error(Exception("obstacle orientation must have either 3(EulerRPY) or 4(Quaternion) elements)"));
00756           
00757           // optional material
00758           DOMElement* matElem = e.getFirstChildElement(obstElem, "material",false);
00759           ref<Material> mat(NewObj Material());
00760           if (matElem) {
00761             e.pushContext(obstElem); 
00762             mat->externalize(e, format, version);
00763             e.popContext();
00764           }
00765           
00766           // get obstacle parameters & construct obstacles
00767           ref<SolidObstacle> obstacle;
00768           Obstacle::ObstacleType type;
00769           if ( e.getElementAttribute(obstElem, "type") == "box" ) {
00770             type = Obstacle::BoxObstacle;
00771             
00772             DOMElement* dElem = e.getFirstChildElement(obstElem, "dimensions");
00773             String dimText = e.getContainedText(dElem);
00774             Dimension3 dims( e.toVector3( dimText ) );
00775             
00776             addBoxObstacle(dims,position,orientation,mat,name);
00777           }
00778           else if ( e.getElementAttribute(obstElem, "type") == "sphere" ) {
00779             type = Obstacle::SphereObstacle;
00780             
00781             DOMElement* rElem = e.getFirstChildElement(obstElem, "radius",false);
00782             Real radius=1.0;
00783             if (rElem) 
00784               radius = base::stringToReal( e.getContainedText(rElem) );
00785             
00786             addSphereObstacle(radius, position,orientation,mat,name);
00787           }
00788           else
00789             throw externalization_error(Exception("unsupported obstacle type"));
00790           
00791           e.removeElement(obstElem);
00792           
00793           obstElem = e.getFirstChildElement(envElem, "obstacle",false);
00794         }
00795         
00796         e.popContext();
00797       }
00798 
00799       e.removeElement(envElem);
00800 
00801     }
00802 
00803   }
00804 
00805 }
00806 

Generated on Thu Jul 29 15:56:40 2004 for OpenSim by doxygen 1.3.6