primitive.h

Go to the documentation of this file.
00001  
00002 /***************************************************************************
00003  *   Copyright (C) 2005-2011 LpzRobots development team                    *
00004  *    Georg Martius  <georg dot martius at web dot de>                     *
00005  *    Frank Guettler <guettler at informatik dot uni-leipzig dot de        *
00006  *    Frank Hesse    <frank at nld dot ds dot mpg dot de>                  *
00007  *    Ralf Der       <ralfder at mis dot mpg dot de>                       *
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  *   This program is distributed in the hope that it will be useful,       *
00015  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017  *   GNU General Public License for more details.                          *
00018  *                                                                         *
00019  *   You should have received a copy of the GNU General Public License     *
00020  *   along with this program; if not, write to the                         *
00021  *   Free Software Foundation, Inc.,                                       *
00022  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00023  *                                                                         *
00024  ***************************************************************************/
00025 #ifndef __PRIMITIVE_H
00026 #define __PRIMITIVE_H
00027 
00028 #include <ode-dbl/common.h>
00029 #include <selforg/storeable.h>
00030 
00031 #include <vector>
00032 
00033 #include "pos.h"
00034 #include "pose.h"
00035 #include "substance.h"
00036 // another forward declaration "block"
00037 #include "osgforwarddecl.h"
00038 
00039 namespace lpzrobots {
00040 
00041    /***** begin of forward declaration block *****/
00042    class BoundingShape;
00043    class OSGPrimitive;
00044    class OSGPlane;
00045    class OSGBox;
00046    class OSGBoxTex;
00047    class OSGSphere;
00048    class OSGCapsule;
00049    class OSGCylinder;
00050    class OSGDummy;
00051    class OSGMesh;
00052    class TextureDescr;
00053 
00054    /* typedef */ struct GlobalData;
00055 
00056    class OdeHandle;
00057    class OsgHandle;
00058    class Color;
00059    /*****  end of forward declaration block  *****/
00060 
00061 
00062 /// returns the osg (4x4) pose matrix of the ode geom
00063 Pose osgPose( dGeomID geom );
00064 /// returns the osg (4x4) pose matrix of the ode body
00065 Pose osgPose( dBodyID body );
00066 /// converts a position vector and a rotation matrix from ode to osg 4x4 matrix
00067 Pose osgPose( const double * position , const double * rotation );
00068 /// converts the rotation component of pose into an ode rotation matrix
00069 void odeRotation( const Pose& pose , dMatrix3& odematrix);
00070 
00071 /** counts number of max velocity violations at joints 
00072  * (Attention, this is a global variable, initialized to 0 at start)   
00073  */ 
00074 extern int globalNumVelocityViolations;
00075 
00076 /**
00077    Interface class for primitives represented in the physical and graphical world.
00078    This is intended to bring OSG and ODE together and hide most implementation details.
00079 */
00080 class Primitive : public Storeable {
00081 public:
00082   /** Body means that it is a dynamic object with a body.
00083       Geom means it has a geometrical represenation used for collision detection.
00084       Draw means the primitive is drawn
00085       _Child and _Transform are only used internally and used for transformed geoms.
00086   */
00087 
00088   /* typedef */ enum Modes {Body=1, Geom=2, Draw=4, _Child=8, _Transform=16};
00089   /* typedef */ enum Category { Dyn=1, Stat=2};
00090 
00091 
00092   Primitive ();
00093   virtual ~Primitive ();
00094   /** registers primitive in ODE and OSG. 
00095       @param osgHandle scruct with ODE variables inside (to specify space, world...)
00096       @param mass Mass of the object in ODE (if withBody = true)
00097       @param osgHandle scruct with OSG variables inside (scene node, color ...)
00098       @param mode is a conjuction of Modes.
00099    */
00100   virtual void init(const OdeHandle& odeHandle, double mass,
00101                     const OsgHandle& osgHandle,
00102                     char mode = Body | Geom | Draw)  = 0 ;
00103 
00104   /** Updates the OSG nodes with ODE coordinates.
00105       This function must be overloaded (usually calls setMatrix of OsgPrimitives)
00106    */
00107   virtual void update() =0 ;
00108 
00109   /// returns the assoziated osg primitive if there or 0
00110   virtual OSGPrimitive* getOSGPrimitive() = 0;
00111 
00112   /// sets the color for the underlaying osgprimitive
00113   virtual void setColor(const Color& color);
00114 
00115   /// sets the color using the colorschema of osgHandle
00116   virtual void setColor(const std::string& color);
00117 
00118   /// assigns a texture to the primitive
00119   virtual void setTexture(const std::string& filename);
00120   /// assigns a texture to the primitive, you can choose if the texture should be repeated
00121   virtual void setTexture(const TextureDescr& texture);
00122   /** assigns a texture to the x-th surface of the primitive.
00123       You can choose how often to repeat
00124       negative values of repeat correspond to length units. 
00125       E.g. assume a rectangle of size 5 in x direction: with repeatOnX = 2 the texture would be two times
00126       rereated. With repeatOnX = -2 the texture would be 2.5 times repeated because the texture is 
00127       made to have the size 2 
00128    */
00129   virtual void setTexture(int surface, const TextureDescr& texture);
00130   /// assign a set of texture to the surfaces of the primitive
00131   virtual void setTextures(const std::vector<TextureDescr>& textures);
00132 
00133 
00134   /// set the position of the primitive (orientation is preserved)
00135   virtual void setPosition(const Pos& pos);
00136   /// set the pose of the primitive
00137   virtual void setPose(const Pose& pose);
00138   /// returns the position
00139   virtual Pos getPosition() const;
00140   /// returns the pose
00141   virtual Pose getPose() const;
00142   /// returns the velocity
00143   virtual Pos getVel() const;  
00144   /// returns the angular velocity
00145   virtual Pos getAngularVel() const;
00146 
00147   /** apply a force (in world coordinates) to the primitive and 
00148       returns true if it was possible */
00149   virtual bool applyForce(osg::Vec3 force);
00150   /** @see applyForce(osg::Vec3) */
00151   virtual bool applyForce(double x, double y, double z);
00152 
00153   /** apply a torque (in world coordinates) to the primitive and 
00154       returns true if it was possible
00155    */
00156   virtual bool applyTorque(osg::Vec3 torque);
00157   /** @see applyTorque(osg::Vec3) */
00158   virtual bool applyTorque(double x, double y, double z);
00159 
00160   /// sets the mass of the body (uniform)
00161   virtual void setMass(double mass) = 0;
00162   /** sets full mass specification
00163     \param cg center of gravity vector
00164     \param I  3x3 interia tensor
00165   */
00166   void setMass(double mass, double cgx, double cgy, double cgz,
00167                double I11, double I22, double I33,
00168                double I12, double I13, double I23);
00169 
00170   /// returns ODE geomID if there
00171   dGeomID getGeom() const { return geom; }
00172   /// returns ODE bodyID if there
00173   dBodyID getBody() const { return body; }
00174 
00175   /// checks whether the object has higher velocity than maxVel and limits it in case
00176   bool limitLinearVel(double maxVel);
00177 
00178   /// checks whether the object has higher velocity than maxVel and limits it in case
00179   bool limitAngularVel(double maxVel);
00180 
00181   /** applies a force to the body to decellerate its linear and angular velocity with
00182       the given factors. (depends on stepwidth!)
00183    */
00184   void decellerate(double factorLin, double factorAng);
00185 
00186 
00187   /// return the given point transformed to local coordinates of the primitive
00188   osg::Vec3 toLocal(const osg::Vec3& pos) const;
00189   /** return the given vector or axis transformed to local coordinates
00190       of the primitive (translation depends on the 4th coordinate)
00191   */
00192   osg::Vec4 toLocal(const osg::Vec4& axis) const;
00193 
00194   /// transforms the given point in local corrds of the primitive to global coordinates
00195   osg::Vec3 toGlobal(const osg::Vec3& pos) const;
00196   /**  transforms the given vector or axis in local corrds of the primitive to global coordinates
00197        (translation depends on the 4th coordinate)
00198   */
00199   osg::Vec4 toGlobal(const osg::Vec4& axis) const;
00200 
00201   /**
00202    * 20091023; guettler:
00203    * hack for tasked simulations; there are some problems if running in parallel mode,
00204    * if you do not destroy the geom, everything is fine (should be no problem because world is destroying geoms too)
00205    * @param _destroyGeom set this to false if geoms must not be destroyed if the primitive is destroyed
00206    */
00207   static void setDestroyGeomFlag(bool _destroyGeom) {
00208     destroyGeom = _destroyGeom;
00209   }
00210 
00211   int getNumVelocityViolations(){ return numVelocityViolations; }
00212 
00213   void setSubstance(Substance substance);
00214 
00215   /* **** storable interface *******/
00216   virtual bool store(FILE* f) const;
00217   
00218   virtual bool restore(FILE* f);  
00219 
00220 
00221 protected:
00222   /** attaches geom to body (if any) and sets the category bits and collision bitfields.
00223       assumes: mode & Geom != 0
00224    */
00225   virtual void attachGeomAndSetColliderFlags();
00226 
00227 public:
00228   Substance substance; // substance description
00229 protected:
00230   dGeomID geom;
00231   dBodyID body;
00232   char mode;
00233   bool substanceManuallySet;
00234   int numVelocityViolations; ///< number of times the maximal velocity was exceeded
00235 
00236   // 20091023; guettler:
00237   // hack for tasked simulations; there are some problems if running in parallel mode,
00238   // if you do not destroy the geom, everything is fine (should be no problem because world is destroying geoms too)
00239   static bool destroyGeom;
00240 };
00241 
00242 
00243 /** Plane primitive */
00244 class Plane : public Primitive {
00245 public:
00246   Plane();
00247   virtual ~Plane();
00248   virtual void init(const OdeHandle& odeHandle, double mass, 
00249                     const OsgHandle& osgHandle,
00250                     char mode = Body | Geom | Draw) ;
00251 
00252   virtual void update();  
00253   virtual OSGPrimitive* getOSGPrimitive();
00254 
00255   virtual void setMass(double mass);
00256 
00257 protected:
00258   OSGPlane* osgplane;
00259 };
00260 
00261 
00262 /** Box primitive */
00263 class Box : public Primitive {
00264 public:
00265 
00266   Box(float lengthX, float lengthY, float lengthZ);
00267   Box(const osg::Vec3& dim);
00268 
00269   virtual ~Box();
00270 
00271   virtual void init(const OdeHandle& odeHandle, double mass,
00272                     const OsgHandle& osgHandle,
00273                     char mode = Body | Geom | Draw) ;
00274 
00275   virtual void update();
00276   virtual OSGPrimitive* getOSGPrimitive();
00277 
00278   virtual void setMass(double mass);
00279 protected:
00280   OSGBoxTex* osgbox;
00281 };
00282 
00283 
00284 /** Sphere primitive */
00285 class Sphere : public Primitive {
00286 public:
00287   Sphere(float radius);
00288   virtual ~Sphere();
00289 
00290   virtual void init(const OdeHandle& odeHandle, double mass, 
00291                     const OsgHandle& osgHandle,
00292                     char mode = Body | Geom | Draw) ;
00293 
00294   virtual void update();
00295   virtual OSGPrimitive* getOSGPrimitive();
00296 
00297   virtual void setMass(double mass);
00298 
00299 protected:
00300   OSGSphere* osgsphere;
00301 };
00302 
00303 /** Capsule primitive */
00304 class Capsule : public Primitive {
00305 public:
00306   Capsule(float radius, float height);
00307   virtual ~Capsule();
00308   virtual void init(const OdeHandle& odeHandle, double mass,
00309                     const OsgHandle& osgHandle,
00310                     char mode = Body | Geom | Draw) ;
00311 
00312   virtual void update();
00313   virtual OSGPrimitive* getOSGPrimitive();
00314 
00315   virtual void setMass(double mass);
00316 
00317 protected:
00318   OSGCapsule* osgcapsule;
00319 };
00320 
00321 /** Cylinder primitive */
00322 class Cylinder : public Primitive {
00323 public:
00324   Cylinder(float radius, float height);
00325   virtual ~Cylinder();
00326   virtual void init(const OdeHandle& odeHandle, double mass,
00327                     const OsgHandle& osgHandle,
00328                     char mode = Body | Geom | Draw) ;
00329 
00330   virtual void update();
00331   virtual OSGPrimitive* getOSGPrimitive();
00332 
00333   virtual void setMass(double mass);
00334 protected:
00335   OSGCylinder* osgcylinder;
00336 };
00337 
00338 /** Ray primitive 
00339     The actual visual representation can have different length than the
00340     ray object. This is specified by length. 
00341     SetLength is an efficient way to change the length at runtime.
00342 */
00343 class Ray : public Primitive {
00344 public:
00345   Ray(double range, float thickness, float length);
00346   virtual ~Ray();
00347   virtual void init(const OdeHandle& odeHandle, double mass,
00348       const OsgHandle& osgHandle,
00349       char mode = Geom | Draw) ;
00350   
00351   void setLength(float len);
00352   virtual void update();
00353   virtual OSGPrimitive* getOSGPrimitive();
00354     
00355   virtual void setMass(double mass);
00356 protected:
00357   double range;
00358   float thickness;
00359   float length;
00360   OSGBox* osgbox;
00361 };
00362 
00363 
00364 
00365 
00366 /** Mesh primitive */
00367 class Mesh : public Primitive {
00368 public:
00369   Mesh(const std::string& filename,float scale);
00370   virtual ~Mesh();
00371   virtual void init(const OdeHandle& odeHandle, double mass,
00372                     const OsgHandle& osgHandle,
00373                     char mode = Body | Geom | Draw) ;
00374   virtual void update();
00375   virtual OSGPrimitive* getOSGPrimitive();
00376   virtual float getRadius();
00377 
00378   virtual void setMass(double mass);
00379 
00380   /**
00381    * Sets the BoundingShape externally (e.g. XMLBoundingShape).
00382    * Any existing BoundingShape will be deleted.
00383    */
00384   virtual void setBoundingShape(BoundingShape* boundingShape);
00385 
00386   virtual void setPose(const Pose& pose);
00387 
00388 protected:
00389   OSGMesh* osgmesh;
00390   const std::string filename;
00391   float scale;
00392   BoundingShape* boundshape;
00393   Pose poseWithoutBodyAndGeom;
00394 
00395 };
00396 
00397 
00398 /**
00399    Primitive for transforming a geom (primitive without body) 
00400     in respect to a body (primitive with body). 
00401    Hides complexity of ODE TransformGeoms. 
00402 */
00403 class Transform : public Primitive {
00404 public:
00405   /** 
00406       @param parent primitive should have a body and should be initialised
00407       @param child  is transformed by pose in respect to parent. 
00408       This Primitive must NOT have a body and should not be initialised
00409   */
00410   Transform(Primitive* parent, Primitive* child, const Pose& pose);
00411 
00412   /// destructor deletes child object
00413   ~Transform();
00414 
00415   /** initialised the transform object. This automatically 
00416       initialises the child geom. 
00417       @param mass mass of the child
00418       @param mode is the mode for the child, except that Body bit is ignored (child can't have a body)
00419    */
00420   virtual void init(const OdeHandle& odeHandle, double mass,
00421                     const OsgHandle& osgHandle,
00422                     char mode = Body | Geom | Draw);
00423 
00424   virtual void update();
00425   virtual OSGPrimitive* getOSGPrimitive();
00426 
00427   virtual void setMass(double mass);
00428 protected:
00429   Primitive* parent;
00430   Primitive* child;
00431   Pose pose;
00432 };
00433 
00434 /**
00435    Dummy Primitive which returns 0 for geom and body. 
00436    Only useful for representing the static world in terms of primitives
00437    or if virtual objects are created, but then the position and speed has
00438    to be set manually.
00439 */
00440 class DummyPrimitive : public Primitive {
00441 public:
00442   
00443   DummyPrimitive() {     
00444     body=0;
00445     geom=0;
00446   }
00447   virtual void init(const OdeHandle& odeHandle, double mass, 
00448                     const OsgHandle& osgHandle, char mode = Body | Geom | Draw) {
00449   }
00450   virtual void update() {}
00451   virtual OSGPrimitive* getOSGPrimitive() { return 0; }
00452 
00453   virtual void setMass(double mass) {}
00454 
00455   virtual void setPosition(Pos pos){
00456     this->pos=pos;
00457   }
00458   virtual Pos getPosition() const {
00459     return pos;
00460   }
00461   virtual void setVel(Pos vel){
00462     this->vel=vel;
00463   }
00464   virtual Pos getVel() const {
00465     return vel;
00466   }
00467   
00468 private:
00469   Pos vel;
00470   Pos pos;
00471 };
00472 
00473 
00474 }
00475 #endif
00476 
Generated on Thu Jun 28 14:45:37 2012 for Robot Simulator of the Robotics Group for Self-Organization of Control by  doxygen 1.6.3