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

robot/TestRobot

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: TestRobot 1039 2004-02-11 20:50:52Z jungd $
00019   $Revision: 1.9 $
00020   $Date: 2004-02-11 15:50:52 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #ifndef _ROBOT_TESTROBOT_
00026 #define _ROBOT_TESTROBOT_
00027 
00028 #include <robot/Robot>
00029 
00030 #include <base/VFile>
00031 #include <base/Vector>
00032 #include <robot/BasicControlInterface>
00033 #include <robot/KinematicChain>
00034 #include <robot/ToolDescription>
00035 
00036 
00037 namespace robot {
00038 
00039 
00040 /**
00041  * A concrete Robot class that doesn't correspond to any
00042  *  real robot.  It is useful for testing. 
00043  *  The RobotDescription provided depends on the constructor used for instantiation.
00044  */
00045 class TestRobot : public Robot 
00046 {
00047 public:
00048   enum JointType { Prismatic = KinematicChain::Link::Prismatic,
00049                    Revolute = KinematicChain::Link::Revolute };
00050 
00051   /// instantiate default robot (fixed platform with a single Puma manipulator)
00052   TestRobot();
00053 
00054   /// instantiate robot from file specification
00055   TestRobot(ref<base::VFile> robotSpecification,
00056             const base::Point3& initialPosition, const base::Orient& initialOrientation);
00057 
00058   /// instantiate robot from a description
00059   TestRobot(ref<const robot::RobotDescription> robotDescription,
00060                   const base::Point3& initialPosition, const base::Orient& initialOrientation);
00061 
00062   /// instantiate a fixed platform with a single manipulator specified via D-H parameters
00063   TestRobot(const base::IVector& jointType, const base::Vector& alpha, const base::Vector& a, const base::Vector& d, const base::Vector& theta);
00064 
00065 
00066   virtual String className() const { return String("TestRobot"); }
00067 
00068   virtual array<std::pair<String,String> > controlInterfaces() const; 
00069 
00070   /**
00071    * TestRobot provides the following ControlInterfaces (name:type):
00072    *
00073    *  platformPosition:PlatformPositionControl        
00074    *    - outputs control the x,y and angle of the platform w.r.t to the world coordinate frame.
00075    *       The angle is clockwise relative to the x-axis (about z).
00076    *
00077    *  manipulatorPositionN:JointPositionControl
00078    *    - outputs control the position of a manipulators joints (angle for revolute joints
00079    *      and extension for prismatic joints)
00080    *
00081    *  manipulatorProximityN:LinkProximitySensors
00082    *     - Inputs provide proximity sensor information.
00083    *
00084    *  manipulatorToolGripN:ToolGripControl
00085    *     - single scalar input represents tool proximity to tool grip mechanism.
00086    *       0 => not in range to be grasped, 1 => in range to be grasped (or currently grasped)
00087    *       single scalar output controls tool gripper latch
00088    *       1 => grasp/latch tool, 0 => ungrasp/unlatch tool
00089    *
00090    *  toolPositionN:JointPositionControl
00091    *     - joint position for tool joints (if any).  Note that the inputSize() and outputSize()
00092    *       change dynamically depending on which tool is grasped (0 when no tool is grasped)
00093    *
00094    */
00095   virtual ref<ControlInterface> getControlInterface(String interfaceName="") throw(std::invalid_argument);
00096 
00097   virtual bool isDescriptionProvided() const { return true; }
00098 
00099   const base::Point3 getPosition() const          ///< get world frame position of robot
00100     { return position; }             
00101   const base::Orient getOrientation() const       ///< get world frame orientation of robot
00102     { return orientation; }       
00103   void setPosition(const base::Point3& pos)       ///< set world frame position of robot
00104     { position = pos; }          
00105   void setOrientation(const base::Orient& orient) ///< set world frame orientation of robot
00106     { orientation = orient; }
00107   
00108   /// because tools are not physically simulated, we can 'magically' indicate that
00109   ///  a tool is within grasping range of the end-effector
00110   void placeToolInProximity(ref<const ToolDescription> toolDescription, Int manipIndex=0);
00111 
00112   /// remove any tool from within grasping range of the end-effector
00113   void removeToolFromProximity(Int manipIndex=0);
00114 
00115 
00116 protected:
00117   void create(String manipName, const base::IVector& jointType, const base::Vector& alpha, const base::Vector& a, const base::Vector& d, const base::Vector& theta);
00118   void initManipulators();
00119 
00120   base::Point3 position;    ///< world frame position of robot
00121   base::Orient orientation; ///< world frame orientation of robot
00122 
00123   array<Vector> qa;  ///< joint parameters of manipulators
00124   array<Vector> tqa; ///< joint parameters of tools (index corresponds to manipulators (qa) - i.e. at most one tool per manipulator)
00125 
00126   array<bool>            toolProximity; ///< is a tool in proximity of manipulator end-effector?
00127   array<bool>            toolGrasped;   ///< is manipulator grasping a tool?
00128   array<ref<const ToolDescription> > tools;         ///< which tool (in proximity and possibly being grasped)
00129 
00130 
00131   class ManipulatorControlInterface : public BasicControlInterface
00132   {
00133   public:
00134     ManipulatorControlInterface(const String& name, const String& type, ref<TestRobot> robot, Int manipIndex)
00135       : BasicControlInterface(name, type, 
00136                               robot->qa[manipIndex].size(), robot->qa[manipIndex].size()
00137                               ),
00138             robot(robot), mi(manipIndex) {}
00139 
00140     ManipulatorControlInterface(const ManipulatorControlInterface& mci)
00141       : BasicControlInterface(mci), robot(mci.robot), mi(mci.mi) {}
00142 
00143     virtual String className() const { return String("ManipulatorControlInterface"); }
00144     virtual Object& clone() const { return *NewObj ManipulatorControlInterface(*this); } 
00145 
00146     virtual String        inputName(Int i) const
00147       { return String("jointPosition")+base::intToString(i); }
00148 
00149     virtual Real          getInput(Int i) const
00150     { 
00151       Assert(i < inputSize());
00152       return robot->qa[mi][i];
00153     }
00154     
00155     virtual const Vector& getInputs() const 
00156     {
00157       return robot->qa[mi];
00158     }
00159     
00160     virtual String outputName(Int i) const
00161     { 
00162       return String("jointPosition")+base::intToString(i); 
00163     }
00164     
00165     virtual void   setOutput(Int i, Real value)
00166     {
00167       Assert(i < outputSize());
00168       robot->qa[mi][i]=value;
00169     }
00170     
00171     virtual void   setOutputs(const Vector& values) 
00172     {
00173       Assert(values.size() == robot->qa[mi].size());
00174       robot->qa[mi] = values;
00175     }
00176 
00177   protected:
00178     ref<TestRobot> robot;
00179     Int mi;
00180   }; 
00181 
00182 
00183 
00184 
00185   class ToolControlInterface : public BasicControlInterface
00186   {
00187   public:
00188     ToolControlInterface(const String& name, const String& type, ref<TestRobot> robot, Int manipIndex, bool gripControl)
00189       : BasicControlInterface(name, type, gripControl?1:0, gripControl?1:0),
00190         gripControl(gripControl), robot(robot), mi(manipIndex) {}
00191     
00192     ToolControlInterface(const ToolControlInterface& tci)
00193       : BasicControlInterface(tci), gripControl(tci.gripControl), 
00194         robot(tci.robot), mi(tci.mi) {}
00195 
00196     virtual String className() const { return String("ToolControlInterface"); }
00197     virtual Object& clone() const { return *NewObj ToolControlInterface(*this); }
00198 
00199     virtual Int           inputSize() const 
00200     {
00201       return (gripControl)?1:robot->tqa[mi].size();
00202     }
00203 
00204     virtual String        inputName(Int i) const
00205       { return gripControl?String("toolProximity"):String("jointPosition")+base::intToString(i); }
00206 
00207     virtual Real          getInput(Int i) const
00208       { 
00209         Assert(i < inputSize());
00210         if (gripControl) 
00211           return (robot->toolProximity[mi]?1.0:0.0);
00212         return robot->tqa[mi][i];
00213       }
00214 
00215     virtual const Vector& getInputs() const 
00216     {
00217       lastInputs.resize(inputSize());
00218       for(Int i=0; i<lastInputs.size(); i++)
00219         lastInputs[i] = getInput(i);
00220       return lastInputs;
00221     }
00222 
00223     virtual Int    outputSize() const 
00224     {
00225       return (gripControl)?1:robot->tqa[mi].size();
00226     }
00227 
00228     virtual String outputName(Int i) const
00229       { 
00230         return gripControl?String("toolGrasp"):String("jointPosition")+base::intToString(i); 
00231       }
00232 
00233     virtual void   setOutput(Int i, Real value)
00234       {
00235         Assert(i < outputSize());
00236         if (gripControl) {
00237           if (Math::equals(value,0)) {
00238             robot->toolGrasped[mi]=false;
00239             robot->tqa[mi].resize(0); // can't control an ungrasped tool
00240           }
00241           else
00242             if (robot->toolProximity[mi]) { // can only grasp when a tool is in proximity
00243               if (!robot->toolGrasped[mi]) {
00244                 robot->toolGrasped[mi]=true;
00245                 // set initial configuration to 0
00246                 robot->tqa[mi].reset( zeroVector(robot->tools[mi]->getKinematicChain().dof()) );
00247               }
00248             }
00249           return;
00250         }
00251         robot->tqa[mi][i]=value;
00252       }
00253 
00254   virtual void   setOutputs(const Vector& values) 
00255     {
00256       numOutputs = outputSize();
00257       BasicControlInterface::setOutputs(values);
00258     }
00259 
00260   protected:
00261     bool gripControl; ///< is this a ToolGripControl? (or a JointPositionControl)
00262     ref<TestRobot> robot;
00263     Int mi;
00264   };
00265 
00266 
00267 
00268 
00269   class PlatformControlInterface : public BasicControlInterface
00270   {
00271   public:
00272     PlatformControlInterface(const String& name, const String& type, 
00273                              ref<TestRobot> robot, bool mobilePlatform)
00274       : BasicControlInterface(name, type,mobilePlatform?3:0,mobilePlatform?3:0),
00275         robot(robot) {}
00276 
00277     PlatformControlInterface(const PlatformControlInterface& pci)
00278       : BasicControlInterface(pci), robot(pci.robot) {}
00279 
00280     virtual String className() const { return String("PlatformControlInterface"); }
00281     virtual Object& clone() const { return *NewObj PlatformControlInterface(*this); } 
00282 
00283     virtual String        inputName(Int i) const
00284     { return (i==0)?String("worldX"):( (i==1)?String("worldY"):String("worldTheta") ); }
00285 
00286     virtual Real          getInput(Int i) const
00287       { 
00288         Assert(i < inputSize());
00289         if (i==0) return robot->position.x;
00290         if (i==1) return robot->position.y;
00291         // extract rotation about Z-axis component
00292         Vector3 xaxis(1,0,0);
00293         Vector3 txaxis = robot->orientation.getQuat4().rotate(xaxis);
00294         txaxis.z=0; txaxis.normalize(); // project into x-y plane
00295         Real angle = Math::acos(xaxis.dot(txaxis));
00296         ///!!! check this works for a full circle - as acos(dot) is just the angle between vectors
00297         return Math::normalizeAngle(angle);
00298       }
00299 
00300     virtual String outputName(Int i) const
00301       { 
00302         return (i==0)?String("worldX"):( (i==1)?String("worldY"):String("worldTheta") ); 
00303       }
00304 
00305     virtual void   setOutput(Int i, Real value)
00306       {
00307         Assert(i < outputSize());
00308         if ((i==0)||(i==1)) {
00309           base::Point3 newpos( robot->position );
00310           if (i==0) newpos.x = value;
00311           if (i==1) newpos.y = value;
00312           robot->position = newpos;
00313         }
00314         else {
00315           base::Orient neworient( robot->orientation );
00316           // !!! for now we ignore the rotation components about y,z axes and
00317           //  just create a rot about z-axis by value
00318           neworient = base::Orient(base::Quat4(base::Vector3(0,0,1),value));
00319           robot->orientation = neworient;
00320         }
00321       }
00322 
00323   protected:
00324     ref<TestRobot> robot;
00325   };
00326 
00327   
00328   
00329   
00330   class ProximitySensorInterface : public BasicControlInterface
00331   {
00332   public:
00333     ProximitySensorInterface(const String& name, const String& type, 
00334                              ref<TestRobot> robot, Int manipIndex)
00335       : BasicControlInterface(name, type,4,0),
00336         robot(robot), mi(manipIndex) {}
00337 
00338     ProximitySensorInterface(const ProximitySensorInterface& psi)
00339       : BasicControlInterface(psi), robot(psi.robot), mi(psi.mi) {}
00340 
00341     virtual String className() const { return String("ProximitySensorInterface"); }
00342     virtual Object& clone() const { return *NewObj ProximitySensorInterface(*this); } 
00343 
00344     virtual String        inputName(Int i) const
00345     {
00346       return (i==0)?String("link"):String("xyz").substr(i-1,1);
00347     }
00348 
00349     virtual Real          getInput(Int i) const
00350       { 
00351         Assert(i < inputSize());
00352         return 0;
00353       }
00354 
00355     virtual String outputName(Int i) const
00356       { 
00357         return String();
00358       }
00359 
00360     virtual void   setOutput(Int i, Real value)
00361       { Assert(i < outputSize()); }
00362 
00363   protected:
00364     ref<TestRobot> robot;
00365     Int mi;
00366   };
00367 
00368 };
00369 
00370 
00371 } // robot
00372 
00373 #endif

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