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

robot/sim/SimulatedRobot.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2002 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: SimulatedRobot.cpp 1033 2004-02-11 20:47:52Z jungd $
00019   $Revision: 1.23 $
00020   $Date: 2004-02-11 15:47:52 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <robot/sim/SimulatedRobot>
00026 
00027 #include <sstream>
00028 
00029 #include <base/SimpleXMLSerializer>
00030 #include <base/Externalizer>
00031 #include <base/Orient>
00032 
00033 #include <physics/Box>
00034 #include <physics/Solid>
00035 #include <physics/ConstraintGroup>
00036 #include <physics/FixedConstraint>
00037 #include <physics/CollisionCuller>
00038 #include <physics/CollisionDetector>
00039 
00040 #include <robot/sim/SimulatedPlatform>
00041 #include <robot/sim/SimulatedSerialManipulator>
00042 
00043 using robot::sim::SimulatedRobot;
00044 
00045 using base::array;
00046 using base::Point3;
00047 using base::VFile;
00048 using base::Externalizer;
00049 using base::Orient;
00050 using physics::Box;
00051 using physics::Solid;
00052 using physics::Spatial;
00053 using physics::SpatialGroup;
00054 using physics::ConstraintGroup;
00055 using physics::FixedConstraint;
00056 using physics::Collidable;
00057 using physics::CollidableGroup;
00058 using physics::CollisionCuller;
00059 using physics::CollisionDetector;
00060 using robot::sim::SimulatedPlatform;
00061 using robot::sim::SimulatedSerialManipulator;
00062  
00063 
00064 
00065  
00066 SimulatedRobot::SimulatedRobot(ref<base::VFile> robotSpecification,
00067                                const base::Point3& initialPosition, const base::Orient& initialOrientation,
00068                                ref<physics::SolidSystem> solidSystem, bool dynamic)
00069   : solidSystem(solidSystem), dynamic(dynamic) 
00070 {
00071   Assert(solidSystem!=0);
00072 
00073   // read in supported formats
00074   if (robotSpecification->extension() == "xml") {
00075 
00076     // read in parameters 
00077     try {
00078       Externalizer e(Externalizable::Input, robotSpecification);
00079       externalize(e,"xml",1.0);
00080     } catch (std::exception&) {
00081       throw std::invalid_argument(Exception("not a valid robot .xml file."));
00082     }
00083 
00084   }
00085   else
00086     throw std::invalid_argument(Exception("file format unsupported."));
00087 
00088   construct(initialPosition, initialOrientation);
00089 }
00090 
00091 
00092 SimulatedRobot::SimulatedRobot(ref<const robot::RobotDescription> robotDescription,
00093                                const base::Point3& initialPosition, const base::Orient& initialOrientation,
00094                                ref<physics::SolidSystem> solidSystem, bool dynamic)
00095   : solidSystem(solidSystem), dynamic(dynamic) 
00096 {
00097   Assert(solidSystem!=0);
00098 
00099   setRobotDescription( robotDescription );
00100 
00101   platform = ref<SimulatedPlatform>(NewObj SimulatedPlatform(robotDescription->platform(), solidSystem, dynamic));
00102   
00103   const array<ref<const ManipulatorDescription> > manips(robotDescription->manipulators());
00104   for (Int i=0; i<manips.size(); i++) {
00105     ref<SimulatedSerialManipulator> m(NewObj SimulatedSerialManipulator(manips[i], solidSystem, dynamic));
00106     manipulators.push_back(m);
00107   }
00108 
00109   construct(initialPosition, initialOrientation);
00110 }
00111 
00112 
00113 void SimulatedRobot::setDynamic(bool enabled)
00114 {
00115   platform->setDynamic(false);
00116   
00117   reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00118   reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00119   while (m != end) {
00120     (*m)->setDynamic(enabled);
00121     ++m;
00122   }
00123 }
00124 
00125 
00126 
00127 array<std::pair<String,String> > SimulatedRobot::controlInterfaces() const 
00128 {
00129   array<std::pair<String,String> > a;
00130   if (dynamic) {
00131     a.push_back(std::make_pair<String,String>("platform","PlatformControl"));
00132     a.push_back(std::make_pair<String,String>("platformVelocity","PlatformVelocityControl"));
00133   }
00134   else
00135     a.push_back(std::make_pair<String,String>("platformPosition","PlatformPositionControl"));
00136   
00137   for(Int m=0; m<getRobotDescription()->manipulators().size();m++) {
00138     ref<const ManipulatorDescription> md( getRobotDescription()->manipulators()[m] );
00139     ref<const SimulatedManipulatorDescription> smd;
00140     if (instanceof(*md, const SimulatedManipulatorDescription))
00141       smd = narrow_ref<const SimulatedManipulatorDescription>(md);
00142     else
00143       smd = ref<SimulatedManipulatorDescription>(NewObj SimulatedManipulatorDescription(*md));
00144     
00145     String n(base::intToString(m+1));
00146     if (dynamic) {
00147       a.push_back(std::make_pair<String,String>("manipulator"+n,"JointForceControl"));
00148       a.push_back(std::make_pair<String,String>("manipulatorVelocity"+n,"JointVelocityControl"));
00149       a.push_back(std::make_pair<String,String>("tool"+n,"JointForceControl"));
00150       a.push_back(std::make_pair<String,String>("toolVelocity"+n,"JointVelocityControl"));
00151     }
00152     else {
00153       a.push_back(std::make_pair<String,String>("manipulatorPosition"+n,"JointPositionControl"));
00154       a.push_back(std::make_pair<String,String>("toolPosition"+n,"JointPositionControl"));
00155     }
00156     if (smd->hasLinkProximitySensors())
00157       a.push_back(std::make_pair<String,String>("manipulatorProximity"+n,"LinkProximitySensors"));
00158     a.push_back(std::make_pair<String,String>("manipulatorToolGrip"+n,"ToolGripControl"));
00159   }
00160   return a; 
00161 }
00162 
00163 
00164 
00165 
00166 
00167 // Spatial
00168 
00169 void SimulatedRobot::setPosition(const Point3& pos)       
00170 { 
00171   spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00172   spatialGroup->setPosition(pos); 
00173 }
00174 
00175 Point3 SimulatedRobot::getPosition() const                  
00176 { 
00177   spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00178   return spatialGroup->getPosition(); 
00179 }
00180 
00181 void SimulatedRobot::setOrientation(const Orient& orient) 
00182 { 
00183   spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00184   spatialGroup->setOrientation(orient); 
00185 }
00186 
00187 Orient SimulatedRobot::getOrientation() const               
00188 { 
00189   spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00190   return spatialGroup->getOrientation(); 
00191 }
00192 
00193 void SimulatedRobot::setConfiguration(const base::Transform& configuration) 
00194 { 
00195   spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00196   spatialGroup->setConfiguration(configuration); 
00197 }
00198 
00199 base::Transform SimulatedRobot::getConfiguration() const    
00200 { 
00201   spatialGroup->updateGroupConfiguration( platform->getConfiguration() );
00202   return spatialGroup->getConfiguration(); 
00203 }
00204 
00205 
00206 
00207 
00208 
00209 
00210 bool SimulatedRobot::formatSupported(String format, Real version, ExternalizationType type) const
00211 {
00212   return ( ((format=="dh") || (format=="xml")) && (version==1.0) && (type==Input) );
00213 }
00214 
00215 
00216 void SimulatedRobot::externalize(base::Externalizer& e, String format, Real version)
00217 {
00218   if (format=="") format = String("xml");
00219 
00220   if (!formatSupported(format,version,e.ioType()))
00221     throw std::invalid_argument(Exception(String("format ")+format+" "+base::realToString(version)+" unsupported"));
00222 
00223   if (format == "dh") {
00224 
00225     if (e.isInput()) {
00226 
00227       spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup());
00228 
00229       // dh format doesn't specify anything about the platform, just instantiate the default
00230       ref<PlatformDescription> pd(NewObj PlatformDescription("platform",base::Dimension3(1,1,0.1), base::Vector3(0,0,0.05), false));
00231       platform = ref<SimulatedPlatform>(NewObj SimulatedPlatform(pd));
00232       spatialGroup->add(platform);
00233       
00234       // externalize SimulatedSerialManipulator
00235       //  (dh format only specifies a single manipulator)
00236       ref<SimulatedSerialManipulator> m(NewObj SimulatedSerialManipulator(solidSystem));
00237       m->externalize(e,format,version);
00238       manipulators.push_back(m);
00239       spatialGroup->add(m);
00240 
00241       // dh format doesn't specify the manipulator offset from the platform either
00242       array<Vector3> offsets(1);
00243       offsets[0] = Vector3(); // default to 0
00244 
00245       // construct RobotDescription
00246       array<ref<const ManipulatorDescription> > manipulatorDescrs(1);
00247       manipulatorDescrs[0] = m->getManipulatorDescription();
00248 
00249       setRobotDescription( ref<RobotDescription>(NewObj RobotDescription("robot",pd,manipulatorDescrs,offsets)) );
00250       
00251     }
00252 
00253   }
00254   else if (format == "xml") {
00255     
00256     if (e.isInput()) {
00257       // let the RobotDescription read the xml first,
00258       //  then look for simulation specific information
00259       
00260       ref<RobotDescription> rd(NewObj RobotDescription());
00261       rd->externalize(e, format, version);
00262   
00263       setRobotDescription( rd );
00264       
00265       spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup());
00266   
00267       platform = ref<SimulatedPlatform>(NewObj SimulatedPlatform(rd->platform()));
00268       spatialGroup->add(platform);
00269   
00270       const array<ref<const ManipulatorDescription> >& manips(rd->manipulators());
00271       for (Int i=0; i<manips.size(); i++) {
00272         ref<SimulatedSerialManipulator> m(NewObj SimulatedSerialManipulator(manips[i], solidSystem));
00273         manipulators.push_back(m);
00274         spatialGroup->add(m);
00275       }
00276       
00277     } // end input
00278 
00279   }
00280 
00281 }
00282 
00283 
00284 
00285 
00286 void SimulatedRobot::construct(const base::Point3& initialPosition, const base::Orient& initialOrientation)
00287 {
00288   Assert(solidSystem);
00289   spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup());
00290   spatialGroup->setPositionOrientation(initialPosition, initialOrientation);
00291 
00292   // construct the platform
00293   Assert(platform);
00294   platform->setSolidSystem(solidSystem);
00295   platform->construct(initialPosition, initialOrientation);
00296   spatialGroup->add(platform);
00297 
00298   ref<const RobotDescription> rd(getRobotDescription());
00299   ref<ConstraintGroup> cgroup(solidSystem->createConstraintGroup());
00300 
00301   Int manipulatorIndex=0;
00302   // for each manipulator, construct it and attach it to the platform
00303   reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00304   reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00305   while (m != end) {
00306     ref<SimulatedSerialManipulator> sm(*m);
00307 
00308     // construct (initial position of the manipulator is the position of the platform/robot + manip offset translation)
00309     Matrix4 offsetTransform; offsetTransform.setToTranslation(rd->manipulatorOffsets()[manipulatorIndex]);
00310     Matrix4 platformTransform(initialOrientation.getRotationMatrix3()); platformTransform.setTranslationComponent(initialPosition);
00311     Matrix4 manipTransform(platformTransform * offsetTransform);
00312     Vector3 manipPosition = manipTransform.column(4).toVector3();
00313     Orient  manipOrient = Matrix3(manipTransform);
00314 
00315     sm->setSolidSystem(solidSystem);
00316     sm->construct(manipPosition, manipOrient);
00317     spatialGroup->add(sm);
00318 
00319     // fix the manipulator base link to the platform
00320     ref<FixedConstraint> fixed(solidSystem->createFixedConstraint());
00321     cgroup->addConstraint(fixed);
00322     fixed->attach(platform->getPlatformSolid(), sm->getBaseSolid());
00323 
00324     ++m; ++manipulatorIndex;
00325   }
00326 
00327   if (manipulatorIndex > 0)
00328     solidSystem->addConstraintGroup(cgroup);
00329   
00330 }
00331 
00332 
00333 
00334 bool SimulatedRobot::checkProximity(ref<SimulatedTool> tool)
00335 {
00336   // ask each manipulator to check
00337   bool anyInProximity = false;
00338   reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00339   reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00340   while (m != end) {
00341     ref<SimulatedSerialManipulator> sm(*m);
00342     if (sm->checkProximity(tool))
00343       anyInProximity=true;
00344     ++m;
00345   }  
00346   return anyInProximity;
00347 }
00348 
00349 
00350 void SimulatedRobot::placeToolInProximity(ref<SimulatedTool> tool, Int manipIndex)
00351 {
00352   ref<SimulatedSerialManipulator> sm( base::elementAt(manipulators, manipIndex) );
00353 
00354   // new tool pos/orient
00355   tool->setPositionOrientation( sm->getEEPosition(), sm->getEEOrientation() );
00356   sm->setToolInProximity(tool);
00357 }
00358 
00359 
00360 bool SimulatedRobot::graspTool(Int manipIndex)
00361 {
00362   ref<SimulatedSerialManipulator> sm( base::elementAt(manipulators, manipIndex) );
00363   return sm->graspTool();
00364 }
00365 
00366 
00367 void SimulatedRobot::releaseGrasp(Int manipIndex)
00368 {
00369   ref<SimulatedSerialManipulator> sm( base::elementAt(manipulators, manipIndex) );
00370   sm->releaseGrasp();
00371 }
00372 
00373 
00374 ref<physics::Collidable> SimulatedRobot::createCollidable(CollidableFlags flags)
00375 {
00376   ref<CollisionCuller> cc(solidSystem->getCollisionCuller());
00377 
00378   ref<CollidableGroup> collidableGroup = cc->createCollidableGroup();
00379   ref<Collidable> platformCollidable( platform->createCollidable(flags) );
00380   collidableGroup->addCollidable(platformCollidable);
00381   ref<Collidable> platform( platformCollidable->findNamed("platformBody") );
00382   
00383   // for each manipulator, create a collidable
00384   reflist<SimulatedSerialManipulator>::iterator m = manipulators.begin();
00385   reflist<SimulatedSerialManipulator>::iterator end = manipulators.end();
00386   while (m != end) {
00387     ref<SimulatedSerialManipulator> sm(*m);
00388     ref<Collidable> smCollidable( sm->createCollidable(flags) );
00389     collidableGroup->addCollidable( smCollidable );
00390 
00391     // disable collision detection between platform and base link (& its proximity sensor Collidable)
00392     ref<Collidable> base( smCollidable->findNamed("baseLink") );
00393     if (platform && base)
00394       cc->collisionEnable(false,platform,base);
00395     ref<Collidable> baseSensor( smCollidable->findNamed("baseLink Sensor") );
00396     if (platform && baseSensor)
00397       cc->collisionEnable(false,platform,baseSensor);
00398     
00399     ++m;
00400   }
00401   
00402   return collidableGroup;
00403 }
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 ref<robot::ControlInterface> SimulatedRobot::getControlInterface(String interfaceName) throw(std::invalid_argument)
00412 {
00413   if (interfaceName == "") interfaceName = "platform";
00414 
00415   // these if's test the name string prefix, so don't forget to put the longer names before shorter ones
00416   //  with a common prefix.
00417   
00418   //  if (interfaceName.substr(0,20) == "manipulatorProximity")
00419   //    return proximitySensorControlInterface;
00420 
00421 
00422   ref<SimulatedRobot> self(this);
00423   if (interfaceName == "platformVelocity")
00424     return ref<robot::ControlInterface>(NewObj PlatformControlInterface(interfaceName, "PlatformVelocityControl", self, platform, VelControl));
00425   
00426   if (interfaceName == "platformPosition")
00427     return ref<robot::ControlInterface>(NewObj PlatformControlInterface(interfaceName, "PlatformPositionControl", self, platform, PosControl));
00428 
00429   if (interfaceName == "platform") 
00430     return ref<robot::ControlInterface>(NewObj PlatformControlInterface(interfaceName, "PlatformControl", self, platform, ForceControl));
00431 
00432 
00433   if (interfaceName.substr(0,19) == "manipulatorVelocity") {
00434     Int n = base::stringToInt(interfaceName.substr(19));
00435     if ((n<1) || (n > manipulators.size())) 
00436       throw std::invalid_argument(Exception("manipulator index out of range"));
00437     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00438     return ref<robot::ControlInterface>(NewObj ManipulatorControlInterface(interfaceName,"JointVelocityControl",manip,VelControl));
00439   }
00440 
00441   if (interfaceName.substr(0,19) == "manipulatorPosition") {
00442     Int n = base::stringToInt(interfaceName.substr(19));
00443     if ((n<1) || (n > manipulators.size())) 
00444       throw std::invalid_argument(Exception("manipulator index out of range"));
00445     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00446     return ref<robot::ControlInterface>(NewObj ManipulatorControlInterface(interfaceName,"JointPositionControl",manip,PosControl));
00447   }
00448 
00449   
00450   if (interfaceName.substr(0,19) == "manipulatorToolGrip") {
00451     Int n = base::stringToInt(interfaceName.substr(19));
00452     if ((n<1) || (n > manipulators.size())) 
00453       throw std::invalid_argument(Exception("manipulator index out of range"));
00454     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00455     return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"ToolGripControl", manip, true));
00456   }
00457 
00458   if (interfaceName.substr(0,20) == "manipulatorProximity") {
00459     Int n = base::stringToInt(interfaceName.substr(20));
00460     if ((n<1) || (n > manipulators.size())) 
00461       throw std::invalid_argument(Exception("manipulator index out of range"));
00462     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00463     if (manip->getManipulatorDescription()->hasLinkProximitySensors()) {
00464       return ref<robot::ControlInterface>(NewObj ProximitySensorInterface(interfaceName, "LinkProximitySensors", manip));
00465     }
00466     else
00467       throw std::invalid_argument(Exception(String("manipulator has no proximity sensors; invalid interface ")+interfaceName));
00468   }
00469   
00470   if (interfaceName.substr(0,11) == "manipulator") {
00471     Int n = base::stringToInt(interfaceName.substr(11));
00472     if ((n<1) || (n > manipulators.size())) 
00473       throw std::invalid_argument(Exception(String("manipulator index ")+base::intToString(n)+" out of range"));
00474     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00475     return ref<robot::ControlInterface>(NewObj ManipulatorControlInterface(interfaceName,"JointForceControl",manip));
00476   }
00477 
00478   
00479   if (interfaceName.substr(0,12) == "toolVelocity") {
00480     Int n = base::stringToInt(interfaceName.substr(12));
00481     if ((n<1) || (n > manipulators.size())) 
00482       throw std::invalid_argument(Exception("manipulator index out of range"));
00483     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00484     return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"JointVelocityControl", manip, false, VelControl));
00485   }
00486   
00487   if (interfaceName.substr(0,12) == "toolPosition") {
00488     Int n = base::stringToInt(interfaceName.substr(12));
00489     if ((n<1) || (n > manipulators.size())) 
00490       throw std::invalid_argument(Exception("manipulator index out of range"));
00491     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00492     return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"JointPositionControl", manip, false, PosControl));
00493   }
00494 
00495   if (interfaceName.substr(0,4) == "tool") {
00496     Int n = base::stringToInt(interfaceName.substr(4));
00497     if ((n<1) || (n > manipulators.size())) 
00498       throw std::invalid_argument(Exception("manipulator index out of range"));
00499     ref<SimulatedSerialManipulator> manip( base::elementAt(manipulators,n-1) );
00500     return ref<robot::ControlInterface>(NewObj ToolControlInterface(interfaceName,"JointForceControl", manip, false, ForceControl));
00501   }
00502 
00503   
00504   throw std::invalid_argument(Exception(String("unknown interface ")+interfaceName));
00505 }
00506 

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