enki/PhysicalEngine.h

Go to the documentation of this file.
00001 /*
00002     Enki - a fast 2D robot simulator
00003     Copyright (C) 1999-2008 Stephane Magnenat <stephane at magnenat dot net>
00004     Copyright (C) 2004-2005 Markus Waibel <markus dot waibel at epfl dot ch>
00005     Copyright (c) 2004-2005 Antoine Beyeler <abeyeler at ab-ware dot com>
00006     Copyright (C) 2005-2006 Laboratory of Intelligent Systems, EPFL, Lausanne
00007     Copyright (C) 2006-2008 Laboratory of Robotics Systems, EPFL, Lausanne
00008     See AUTHORS for details
00009 
00010     This program is free software; the authors of any publication 
00011     arising from research using this software are asked to add the 
00012     following reference:
00013     Enki - a fast 2D robot simulator
00014     http://lis.epfl.ch/enki
00015     Stephane Magnenat <stephane at magnenat dot net>,
00016     Markus Waibel <markus dot waibel at epfl dot ch>
00017     Laboratory of Intelligent Systems, EPFL, Lausanne.
00018 
00019     You can redistribute this program and/or modify
00020     it under the terms of the GNU General Public License as published by
00021     the Free Software Foundation; either version 2 of the License, or
00022     (at your option) any later version.
00023 
00024     This program is distributed in the hope that it will be useful,
00025     but WITHOUT ANY WARRANTY; without even the implied warranty of
00026     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027     GNU General Public License for more details.
00028 
00029     You should have received a copy of the GNU General Public License
00030     along with this program; if not, write to the Free Software
00031     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00032 */
00033 
00034 #ifndef __ENKI_PHYSICALENGINE_H
00035 #define __ENKI_PHYSICALENGINE_H
00036 
00037 #include "Geometry.h"
00038 #include "Types.h"
00039 #include "Random.h"
00040 #include "Interaction.h"
00041 #include "BluetoothBase.h"
00042 #include <iostream>
00043 #include <set>
00044 #include <vector>
00045 #include <valarray>
00046 
00047 
00124 
00125 namespace Enki
00126 {
00127     class World;
00128 
00130 
00131     class PhysicalObject
00132     {
00133         friend class World;
00134         
00135     public:         // inner classes
00136         
00137         // User data
00138         
00140         class UserData
00141         {
00142         public:
00143             bool deletedWithObject; 
00144             
00145         public:
00147             virtual ~UserData() {}
00148         };
00149         
00151         UserData *userData;
00152         
00153         // Physics
00154         
00155         // physical constant
00156         static const double g;
00157         
00158         // physical parameters constants
00159         
00161         double collisionElasticity;
00163         double dryFrictionCoefficient;
00165         double viscousFrictionCoefficient;
00167         double viscousMomentFrictionCoefficient;
00168         
00169         // physics state variables
00170         
00171         // space coordinates
00172         
00174         Point pos;
00176         double angle;
00177         
00178         // space coordinates derivatives
00179         
00181         Vector speed;
00183         double angSpeed;
00184         
00185         // space coordinates double-derivatives
00186         
00187         /*
00188         The only accelerations we have for now are friction and are computed inside PhysicalObject::step()
00189         Both collisions and forces due to wheels of differential wheeled robots are computed instantly
00190         
00192         Vector acc;
00194         double angAcc;
00195         
00197         double staticFrictionThreshold;
00198         */
00199         
00200         // Geometry
00201         
00203         class Part
00204         {
00205         public:
00207             Part(const Polygone& shape, double height);
00209             Part(const Polygone& shape, double height, const Textures& textures);
00211             Part(double l1, double l2, double height);
00212             
00214             void updateRadius(double& radius);
00215             
00216             // getters
00217             inline double getHeight() const { return height; }
00218             inline const Polygone& getShape() const { return shape; }
00219             inline const Polygone& getTransformedShape() const { return transformedShape; }
00220             inline const Textures& getTextures() const { return textures; }
00221             inline bool isTextured() const { return !textures.empty(); }
00222             
00223         private:
00224             friend class PhysicalObject;
00225             // geometrical properties
00226             
00228             double height;
00230             Polygone shape;
00232             Polygone transformedShape;
00233             
00234             // visual properties
00235             
00237             Textures textures;
00238         
00239         private:
00241             void computeTransformedShape(const Matrix22& rot, const Point& trans);
00242         };
00243         
00245         struct Hull:std::vector<Part>
00246         {
00248             Hull() {}
00250             Hull(const Part& part) : std::vector<Part>(1, part) {}
00252             Polygone getConvexHull() const;
00253         };
00254         
00255     private:        // variables
00256         
00257         // Physics
00258         
00259         // mass and inertia tensor
00260         
00262         double mass;
00264         double momentOfInertia;
00265         
00266         // Geometry
00267         
00269         Hull hull;
00271         double r;
00273         double height;
00275         Color color;
00277         double infraredReflectiveness;
00278         
00279     public:         // methods
00280         
00282         PhysicalObject();
00284         virtual ~PhysicalObject();
00285         
00286         // getters
00287         
00288         inline double getRadius() const { return r; }
00289         inline double getHeight() const { return height; }
00290         inline bool isCylindric() const { return hull.empty(); }
00291         inline const Hull& getHull() const { return hull; }
00292         inline const Color& getColor() const { return color; }
00293         inline double getInfraredReflectiveness() const { return infraredReflectiveness; }
00294         inline double getMass() const { return mass; }
00295         inline double getMomentOfInertia() const { return momentOfInertia; }
00296         
00297         // setters
00298         
00300         void setCylindric(double radius, double height, double mass);
00302         void setRectangular(double l1, double l2, double height, double mass);
00304         void setCustomHull(const Hull& hull, double mass);
00306         void setColor(const Color &color);
00308         void setInfraredReflectiveness(double value);
00309 
00310     private:        // setup methods
00311         
00313         void computeMomentOfInertia();
00315         void setupCenterOfMass();
00317         void computeTransformedShape();
00318     
00319     protected:      // physical actions
00320         
00321         /*//! A physics simulation step for this object. It is considered as deinterlaced. The position and orientation are updated.
00322         virtual void physicsStep(double dt);*/
00324         virtual void controlStep(double dt) { }
00326         virtual void applyForces(double dt);
00327 
00328         
00330         virtual void initLocalInteractions(double dt, World* w) { }
00332         virtual void doLocalInteractions(double dt, World *w, PhysicalObject *o) { }
00334         virtual void doLocalWallsInteraction(double dt, World* w) { }
00336         virtual void finalizeLocalInteractions(double dt, World* w) { }
00337 
00339         virtual void initGlobalInteractions(double dt, World* w) { }
00341         virtual void doGlobalInteractions(double dt, World* w) { }
00343         virtual void finalizeGlobalInteractions(double dt, World* w) { }
00344 
00345     private:        // physical actions
00346         
00348         void initPhysicsInteractions(double dt);
00350         void finalizePhysicsInteractions(double dt);
00351         
00353         void collideWithStaticObject(const Vector &n, const Point &cp);
00355         void collideWithObject(PhysicalObject &that, const Point &cp, const Vector &dist);
00356     };
00357 
00359 
00360     class Robot: public PhysicalObject
00361     {
00362     protected:
00364         std::vector<LocalInteraction *> localInteractions;
00366         std::vector<GlobalInteraction *> globalInteractions;
00367         
00368     public:
00370         void addLocalInteraction(LocalInteraction *li);
00372         void addGlobalInteraction(GlobalInteraction *gi) {globalInteractions.push_back(gi);}
00374         virtual void initLocalInteractions(double dt, World* w);
00376         virtual void doLocalInteractions(double dt, World *w, PhysicalObject *po);
00378         virtual void doLocalWallsInteraction(double dt, World* w);
00380         virtual void finalizeLocalInteractions(double dt, World* w);
00381         
00383         virtual void doGlobalInteractions(double dt, World* w);
00385         void sortLocalInteractions(void);
00386     };
00387 
00389 
00392     class World
00393     {
00394     public:
00396         enum WallsType
00397         {
00398             WALLS_SQUARE = 0,   
00399             WALLS_CIRCULAR,     
00400             WALLS_NONE          
00401         };
00402         
00404         const WallsType wallsType;
00406         const double w;
00408         const double h;
00410         const double r;
00411         /* Texture of world walls is disabled now, re-enable a proper support if required
00413         Texture wallTextures[4];*/
00415         const Color wallsColor;
00416         
00417         typedef std::set<PhysicalObject *> Objects;
00418         typedef Objects::iterator ObjectsIterator;
00419         
00421         Objects objects;
00423         BluetoothBase* bluetoothBase;
00424 
00426         void collideCircleWithShape(PhysicalObject *circularObject, PhysicalObject *shapedObject, const Polygone &shape);
00428         void collideObjects(PhysicalObject *object1, PhysicalObject *object2);
00430         void collideWithSquareWalls(PhysicalObject *object);
00432         void collideWithCircularWalls(PhysicalObject *object);
00434         bool isPointInside(const Point &p, const Point &c, const Polygone &bs, Vector *distVector);
00435 
00436     public:
00438         World(double width, double height, const Color& wallsColor = Color::gray);
00440         World(double r, const Color& wallsColor = Color::gray);
00442         World();
00444         ~World();
00445         
00447         void step(double dt, unsigned physicsOversampling = 1);
00450         void addObject(PhysicalObject *o);
00452         void removeObject(PhysicalObject *o);
00454         void disconnectExternalObjectsUserData();
00456         void setRandomSeed(unsigned long seed);
00458         void initBluetoothBase();
00460         BluetoothBase* getBluetoothBase();
00461     };
00462     
00464     extern FastRandom random;
00465 }
00466 
00467 #endif

Generated on Sun Mar 1 03:10:09 2009 for Enki by  doxygen 1.5.1