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

robot/sim/SimulatedRobot

Go to the documentation of this file.
00001 /* **-*-c++-*-**************************************************************
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 1033 2004-02-11 20:47:52Z jungd $
00019   $Revision: 1.22 $
00020   $Date: 2004-02-11 15:47:52 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #ifndef _ROBOT_SIM_SIMULATEDROBOT_
00026 #define _ROBOT_SIM_SIMULATEDROBOT_
00027 
00028 #include <robot/sim/sim>
00029 
00030 #include <robot/Robot>
00031 
00032 #include <base/VFile>
00033 #include <base/Externalizable>
00034 #include <base/Point3>
00035 #include <base/Orient>
00036 
00037 #include <physics/SolidSystem>
00038 #include <physics/Spatial>
00039 #include <physics/SpatialGroup>
00040 #include <physics/CollidableProvider>
00041 
00042 #include <robot/BasicControlInterface>
00043 #include <robot/ToolDescription>
00044 #include <robot/sim/SimulatedPlatform>
00045 #include <robot/sim/SimulatedSerialManipulator>
00046 #include <robot/sim/SimulatedTool>
00047 
00048 
00049 namespace robot {
00050 namespace sim {
00051 
00052 
00053 /**
00054  * A concrete Robot class that instantiates a simulated robot
00055  *  according to a supplied specification.  Simulated by adding
00056  *  bodies, joints and motors to solidSystem.
00057  */
00058 class SimulatedRobot : public Robot, public physics::Spatial, public physics::CollidableProvider, public base::Externalizable
00059 {
00060 public:
00061   SimulatedRobot(ref<base::VFile> robotSpecification,
00062                  const base::Point3& initialPosition, const base::Orient& initialOrientation,
00063                  ref<physics::SolidSystem> solidSystem, bool dynamic=true);
00064 
00065   SimulatedRobot(ref<const robot::RobotDescription> robotDescription,
00066                  const base::Point3& initialPosition, const base::Orient& initialOrientation,
00067                  ref<physics::SolidSystem> solidSystem, bool dynamic=true);
00068                  
00069 
00070   virtual String className() const { return String("SimulatedRobot"); }
00071   
00072   // factory
00073   virtual ref<PlatformDescription>    newPlatformDescription() const { return ref<PlatformDescription>(NewObj PlatformDescription()); }
00074   virtual ref<ManipulatorDescription> newManipulatorDescription() const { return ref<ManipulatorDescription>(NewObj ManipulatorDescription()); }
00075 
00076 
00077   virtual void setDynamic(bool enabled);
00078   
00079   virtual void setSolidSystem(ref<physics::SolidSystem> solidSystem)
00080     { this->solidSystem = solidSystem; }
00081     
00082     
00083   virtual array<std::pair<String,String> > controlInterfaces() const; 
00084 
00085   /**
00086    * SimulatedRobot provides the following ControlInterfaces (name:type):
00087    *
00088    *  platform:PlatformControl                        (only available when dynamic==true)
00089    *    - outputs control drive and stearing motors, depending on the specific platform
00090    *      (possibly none e.g. for a fixed platform)
00091    *      For the basic non-holonomic mobile platform, the first two inputs control
00092    *       the left & right drive motor torques and the third control the steering motor
00093    *       torque.  The inputs provide the angular velocity of the drive wheels and the
00094    *       steering angle.
00095    *
00096    *  platformVelocity:PlatformVelocityControl        (only available when dynamic==true)
00097    *    - As for PlatformControl, but the outputs control target velocity instead of
00098    *       torque.
00099    *
00100    *  platformPosition:PlatformPositionControl        (only available when dynamic==false)
00101    *    - outputs control the x,y and angle of the platform w.r.t to the world coordinate frame.
00102    *       The angle is clockwise relative to the x-axis (about z).
00103    *
00104    *  manipulatorN:JointForceControl                  (only available when dynamic==true)
00105    *     - where N is the manipulator number (from 1). 
00106    *       Outputs control joint force/torque and corresponding inputs give joint position.
00107    *
00108    *  manipulatorVelocityN:JointVelocityControl       (only available when dynamic==true)
00109    *     - where N is the manipulator number (from 1).  Outputs control joint velocity
00110    *       and corresponding inputs give joint position.
00111    *
00112    *  manipulatorPositionN:JointPositionControl       
00113    *    - outputs control the position of a manipulators joints (angle for revolute joints,
00114    *      extension for prismatic joints etc.)
00115    *
00116    *  manipulatorProximityN:LinkProximitySensors
00117    *     - where N is the manipulator number (from 1).
00118    *     - Inputs provide proximity sensor information for each link.  Each sequence of 5
00119    *        inputs provides the following information on the sensors of a single link:
00120    *        0: distance to closest object detected by proximity sensors on the link (or 0 if none detected)
00121    *        1-3: (x,y,z) direction vector to the closest object detected by proximity sensors on the link
00122    *        4: the distance along the link x-axis of the proximity sensor that detected the closest object to the link
00123    *       e.g. l*5 + 0  is the distance to the closest object detected by link l=[0..LastLink] 
00124    *     - There are no outputs
00125    *
00126    *  manipulatorToolGripN:ToolGripControl
00127    *     - single scalar input represents tool proximity to tool grip mechanism.
00128    *       0 => not in range to be grasped, 1 => in range to be grasped (or currently grasped)
00129    *       single scalar output controls tool gripper latch
00130    *       1 => grasp/latch tool, 0 => ungrasp/unlatch tool
00131    *
00132    *  toolN:JointForceControl                         (only available when dynamic==true)
00133    *     - joint force/torque output for tool joints (if any); and joint position inputs.
00134    *       Note that the inputSize() and outputSize()
00135    *       change dynamically depending on which tool is grasped (0 when no tool is grasped)
00136    *
00137    *  toolVelocityN:JointVelocityControl              (only available when dynamic==true)
00138    *     - joint velocity output for tool joints (if any); and joint position inputs.
00139    *       Note that the inputSize() and outputSize()
00140    *       change dynamically depending on which tool is grasped (0 when no tool is grasped)
00141    *
00142    *  toolPositionN:JointPositionControl              (only available when dynamic==false)
00143    *     - joint position for tool joints (if any).  Note that the inputSize() and outputSize()
00144    *       change dynamically depending on which tool is grasped (0 when no tool is grasped)
00145    *
00146    */
00147   virtual ref<ControlInterface> getControlInterface(String interfaceName="") throw(std::invalid_argument);
00148 
00149   virtual bool isDescriptionProvided() const { return true; }
00150 
00151   virtual ref<physics::Solid> getPlatformSolid() const { return platform->getPlatformSolid(); }
00152 
00153   
00154   // Spatial
00155   // NB: these are intended for static simulations.  Setting the configuration in a dynamic simulation
00156   //      will result in unrealistic motions - and possibly large forces/instability of system
00157   virtual void   setPosition(const Point3& pos);
00158   virtual Point3 getPosition() const;
00159   virtual void   setOrientation(const Orient& orient);
00160   virtual Orient getOrientation() const;
00161   virtual void   setConfiguration(const base::Transform& configuration);
00162   virtual base::Transform getConfiguration() const;
00163 
00164   
00165   /// test if tool is in position to be grasped by any end-effectors.
00166   bool checkProximity(ref<SimulatedTool> tool);
00167 
00168   /// 'magically' transport a tool to within grasping range of the end-effector
00169   void placeToolInProximity(ref<SimulatedTool> tool, Int manipIndex=0);
00170 
00171   /// gasp tool (if a suitable one is within grasping proximity of the end-effector)
00172   ///  returns true if a tool was grasped
00173   bool graspTool(Int manipIndex=0);
00174 
00175   /// release grasp
00176   void releaseGrasp(Int manipIndex=0); 
00177 
00178   
00179   // CollidableProvider
00180   virtual ref<physics::Collidable> createCollidable(CollidableFlags flags = 0);
00181   
00182   // Externalizable
00183   virtual bool formatSupported(String format, Real version = 1.0, ExternalizationType type = IO) const; ///< query if specific format is supported (for input, output or both)
00184   virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0); ///< read or write object state to Externalizer
00185 
00186 protected:
00187   /// construct the physical robot from loaded spec by adding bodies, joints and motors into solidSystem
00188   void construct(const base::Point3& initialPosition, const base::Orient& initialOrientation);
00189 
00190   ref<SimulatedPlatform>              platform;     ///< simulated robot platform
00191   reflist<SimulatedSerialManipulator> manipulators; ///< simulated manipulators
00192 
00193   ref<physics::SolidSystem> solidSystem;  ///< SolidSystem into which the robot's physical parts will be added
00194 
00195   ref<physics::SpatialGroup> spatialGroup;   ///< a group containing the platform and manipulators
00196 
00197   /// if true, full physics is simulated; if false, the Solids that comprise the Robot only have a position/orientation - no velocity/acceleration
00198   ///  (and the position based ControlInterfaces can be used instead of the velocity & force/torque interfaces)
00199   bool dynamic; 
00200   
00201 
00202   /// ForceControl & VelControl require a dynamic simulation; PosControl will also function for
00203   ///  simple non-dynamic simulations
00204   enum ControlType { ForceControl, VelControl, PosControl };
00205   
00206 
00207   class ManipulatorControlInterface : public BasicControlInterface
00208   {
00209   public:
00210     ManipulatorControlInterface(const String& name, const String& type, 
00211                                 ref<SimulatedSerialManipulator> sm, ControlType controlType = ForceControl)
00212       : BasicControlInterface(name, type,
00213                               sm->getManipulatorDescription()->getKinematicChain().dof(),
00214                               sm->getManipulatorDescription()->getKinematicChain().dof() ),
00215         sm(sm), controlType(controlType) {}
00216 
00217     ManipulatorControlInterface(const ManipulatorControlInterface& mci)
00218       : BasicControlInterface(mci), sm(mci.sm), controlType(mci.controlType) {}
00219 
00220     virtual String className() const { return String("ManipulatorControlInterface"); }
00221     virtual Object& clone() const { return *NewObj ManipulatorControlInterface(*this); } 
00222 
00223     virtual String        inputName(Int i) const
00224       { return String("jointPosition")+base::intToString(i); }
00225 
00226     virtual Real          getInput(Int i) const
00227       { 
00228         Assert(i < inputSize());
00229         return sm->getJointPos(i+1);
00230       }
00231 
00232     virtual String outputName(Int i) const
00233       { 
00234         if (controlType == ForceControl)
00235           return String("jointForce")+base::intToString(i); 
00236         else if (controlType == VelControl)
00237           return String("jointVelocity")+base::intToString(i); 
00238         else
00239           return String("jointPosition")+base::intToString(i); 
00240       }
00241 
00242     virtual void   setOutput(Int i, Real value)
00243       {
00244         Assert(i < outputSize());
00245         if (controlType == ForceControl)
00246           sm->setJointForce(i+1, value);
00247         else if (controlType == VelControl)
00248           sm->setJointVel(i+1, value);
00249         else
00250           sm->setJointPos(i+1, value);
00251       }
00252 
00253   protected:
00254     ref<SimulatedSerialManipulator> sm;
00255     ControlType controlType;
00256   };
00257 
00258 
00259 
00260 
00261   class ToolControlInterface : public BasicControlInterface
00262   {
00263   public:
00264     ToolControlInterface(const String& name, const String& type, ref<SimulatedSerialManipulator> sm, 
00265                          bool gripControl, ControlType controlType = ForceControl)
00266       : BasicControlInterface(name, type, gripControl?1:0, gripControl?1:0),
00267         gripControl(gripControl), sm(sm), controlType(controlType) {}
00268     
00269     ToolControlInterface(const ToolControlInterface& tci)
00270       : BasicControlInterface(tci), gripControl(tci.gripControl), 
00271         sm(tci.sm), controlType(tci.controlType) {}
00272 
00273     virtual String className() const { return String("ToolControlInterface"); }
00274     virtual Object& clone() const { return *NewObj ToolControlInterface(*this); }
00275 
00276     virtual Int           inputSize() const 
00277     {
00278       if (gripControl) return 1;
00279       if (sm->isToolGrasped()) return sm->getToolInProximity()->getToolDescription()->getKinematicChain().dof();
00280       return 0;
00281     }
00282 
00283     virtual String        inputName(Int i) const
00284       { return gripControl?String("toolProximity"):String("jointPosition")+base::intToString(i); }
00285 
00286     virtual Real          getInput(Int i) const
00287       { 
00288         Assert(i < inputSize());
00289         if (gripControl) {
00290           if (sm->isToolGrasped()) return 1;
00291           if (sm->getToolInProximity())
00292             return sm->checkProximity(sm->getToolInProximity())?1.0:0.0;
00293         }
00294         if (sm->isToolGrasped()) 
00295           return sm->getToolInProximity()->getJointPos(i+1);
00296         return 0;
00297       }
00298 
00299     virtual const Vector& getInputs() const 
00300       {
00301         Int s = inputSize();
00302         lastInputs.resize(s);
00303         for(Int i=0; i<s; i++)
00304           lastInputs[i] = getInput(i);
00305         return lastInputs;
00306       }
00307 
00308     virtual Int    outputSize() const 
00309       {
00310         if (gripControl) return 1;
00311         if (sm->isToolGrasped()) return sm->getToolInProximity()->getToolDescription()->getKinematicChain().dof();
00312         return 0;
00313       }
00314 
00315     virtual String outputName(Int i) const
00316       { 
00317         if (gripControl) return String("toolGrasp");
00318         if (controlType==ForceControl) return String("jointForce")+base::intToString(i);
00319         else if (controlType==VelControl) return String("jointVelocity")+base::intToString(i);
00320         else return String("jointPosition")+base::intToString(i);
00321       }
00322 
00323     virtual void   setOutput(Int i, Real value)
00324       {
00325         Assert(i < outputSize());
00326         if (gripControl) {
00327           if (Math::equals(value,0)) 
00328             sm->releaseGrasp();
00329           else
00330             sm->graspTool();
00331           return;
00332         }
00333         if (sm->isToolGrasped()) {
00334           if (controlType==ForceControl)
00335             sm->getToolInProximity()->setJointForce(i+1, value);
00336           else if (controlType==VelControl)
00337             sm->getToolInProximity()->setJointVel(i+1, value);
00338           else 
00339             sm->getToolInProximity()->setJointPos(i+1, value);
00340         }
00341       }
00342 
00343     virtual void   setOutputs(const Vector& values) 
00344       {
00345         numOutputs = outputSize();
00346         BasicControlInterface::setOutputs(values);
00347       }
00348 
00349   protected:
00350     bool gripControl; ///< is this a ToolGripControl? (or a JointPositionControl)
00351     ref<SimulatedSerialManipulator> sm;
00352     ControlType controlType;
00353    };
00354 
00355 
00356 
00357 
00358   class PlatformControlInterface : public BasicControlInterface
00359   {
00360   public:
00361     PlatformControlInterface(const String& name, const String& type, 
00362                              ref<SimulatedRobot> sr, ref<SimulatedPlatform> sp, 
00363                              ControlType controlType=ForceControl)
00364       : BasicControlInterface(name, type,
00365                               sp->getPlatformDescription()->isMobile()?3:0,
00366                               sp->getPlatformDescription()->isMobile()?3:0),
00367         sr(sr), sp(sp), controlType(controlType) {}
00368 
00369     PlatformControlInterface(const PlatformControlInterface& pci)
00370       : BasicControlInterface(pci), sr(pci.sr), sp(pci.sp), controlType(pci.controlType) {}
00371 
00372     virtual String className() const { return String("PlatformControlInterface"); }
00373     virtual Object& clone() const { return *NewObj PlatformControlInterface(*this); } 
00374 
00375     virtual String        inputName(Int i) const
00376     {
00377       if (controlType != PosControl)
00378         return (i==0)?String("leftDriveWheelVelocity"):( (i==1)?String("rightDriveWheelVelocity"):String("steeringAngle") );
00379       else
00380         return (i==0)?String("x"):( (i==1)?String("y"):String("theta") );
00381     }
00382 
00383     virtual Real          getInput(Int i) const
00384       { 
00385         Assert(i < inputSize());
00386         if (controlType != PosControl) {
00387           if (i==0) return sp->getLeftBackWheelVel();
00388           if (i==1) return sp->getRightBackWheelVel();
00389           return sp->getSteeringAngle();
00390         }
00391         else {
00392           if (i==0) return sp->getPosition2D().x;
00393           if (i==1) return sp->getPosition2D().y;
00394           return sp->getOrientation2D();
00395         }
00396       }
00397 
00398     virtual String outputName(Int i) const
00399       { 
00400         if (controlType==ForceControl) 
00401           return (i==0)?String("leftDriveWheelTorque"):( (i==1)?String("rightDriveWheelTorque"):String("steeringTorque") ); 
00402         else if (controlType==VelControl)
00403           return (i==0)?String("leftDriveWheelVelocity"):( (i==1)?String("rightDriveWheelVelocity"):String("steeringVelocity") );
00404         else
00405           return (i==0)?String("x"):( (i==1)?String("y"):String("theta") );
00406       }
00407 
00408     virtual void   setOutput(Int i, Real value)
00409       {
00410         Assert(i < outputSize());
00411         if (controlType==ForceControl) {
00412           if (i==0)
00413             sp->setLeftBackWheelTorque(value);
00414           else {
00415             if (i==1)
00416               sp->setRightBackWheelTorque(value);
00417             else
00418               sp->setSteeringTorque(value);
00419           }
00420         }
00421         else if (controlType==VelControl) {
00422           if (i==0)
00423             sp->setLeftBackWheelVel(value);
00424           else {
00425             if (i==1)
00426               sp->setRightBackWheelVel(value);
00427             else
00428               sp->setSteeringVel(value);
00429           }
00430         }
00431         else {
00432           // move the robot
00433           Point2 p( sr->getPosition2D() );
00434           Real theta = sr->getOrientation2D();
00435           if (i==0) 
00436             sr->setPosition2D( Point2(value, p.y), theta );
00437           else {
00438             if (i==1) 
00439               sr->setPosition2D( Point2(p.x, value), theta );
00440             else 
00441               sr->setPosition2D( p, value );
00442           }
00443         }
00444       }
00445 
00446   protected:
00447     ref<SimulatedRobot> sr;
00448     ref<SimulatedPlatform> sp;
00449     ControlType controlType;
00450   };
00451 
00452   
00453 
00454   class ProximitySensorInterface : public BasicControlInterface
00455   {
00456   public:
00457     ProximitySensorInterface(const String& name, const String& type,
00458                              ref<SimulatedSerialManipulator> sm)
00459       : BasicControlInterface(name, type, (sm->getManipulatorDescription()->getKinematicChain().size()+1)*5, 0),
00460         sm(sm) {}
00461       
00462    ProximitySensorInterface(const ProximitySensorInterface& psi)
00463      : BasicControlInterface(psi), sm(psi.sm) {}
00464   
00465     virtual String className() const { return String("ProximitySensorInterface"); }
00466     virtual Object& clone() const { return *NewObj ProximitySensorInterface(*this); }
00467     
00468     virtual String        inputName(Int i) const
00469       {
00470         Assert(i < inputSize() );
00471         Int linkNo = (i/5);
00472         Int dataIndex = i%5;
00473         String name(String("proximitySensor")+base::intToString(linkNo));
00474         switch (dataIndex) {
00475           case 0: name+=" distance"; break;
00476           case 1: name+=" normal.x"; break;
00477           case 2: name+=" normal.y"; break;
00478           case 3: name+=" normal.z"; break;
00479           case 4: name+=" sensor position"; break;
00480           default:;
00481         }
00482         return name;
00483       }
00484   
00485     virtual String outputName(Int i) const { Assertm(false,"interface has outputs"); return ""; }
00486 
00487     virtual Real          getInput(Int i) const
00488     {
00489       Assert(i < inputSize());
00490       Int linkNo = (i/5);
00491       Int dataIndex = i%5;
00492       switch (dataIndex) {
00493           case 0: return sm->getClosestObjectDistance(linkNo);
00494           case 1: return sm->getClosestObjectDirection(linkNo).x;
00495           case 2: return sm->getClosestObjectDirection(linkNo).y;
00496           case 3: return sm->getClosestObjectDirection(linkNo).z;
00497           case 4: return sm->getClosestObjectSensorPosition(linkNo);
00498           default:;
00499       }
00500       return 0;
00501     }
00502     
00503     
00504     virtual void   setOutput(Int i, Real value) { Assertm(false,"interface has outputs"); }
00505     
00506   protected:
00507     ref<SimulatedSerialManipulator> sm;
00508   };
00509     
00510 
00511 };
00512 
00513 
00514 
00515 }
00516 } // robot::sim
00517 
00518 #endif

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