Robot Simulator of the Robotics Group for Self-Organization of Control: substance.h Source File

# substance.h

Go to the documentation of this file.

    00001 /***************************************************************************
    00002  *   Copyright (C) 2005-2011 LpzRobots development team                    *
    00003  *    Georg Martius  <georg dot martius at web dot de>                     *
    00004  *    Frank Guettler <guettler at informatik dot uni-leipzig dot de        *
    00005  *    Frank Hesse    <frank at nld dot ds dot mpg dot de>                  *
    00006  *    Ralf Der       <ralfder at mis dot mpg dot de>                       *
    00007  *    Guillaume de Chambrier <s0672742 at sms dot ed dot ac dot uk>        *
    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 /*
    00026 This file concerns material implementation in the simulator.
    00027
    00028 Terminology:
    00029 Since "Material" is used for OpenGL stuff and also in OSG
    00030  we should use something else for the physical material: substance
    00031
    00032 So how to implement substance to cover all collission cases and requirements.
    00033 It would be nice to keep the collisioncontrol as it is for compatibility reasons.
    00034 In general:
    00035
    00036 - every ode geom should get a user data pointer to the primitive
    00037 - primitive has a certain substance
    00038 - 2 substance define collision parameters
    00039 - also an optional callback function for user defined handling
    00040 - collission detection is done globally.
    00041 - via joint connected geoms are stored in a set (globally)
    00042 - spaces are globally registered
    00043
    00044  ***************************************************************************/
    00045 #ifndef __SUBSTANCE_H
    00046 #define __SUBSTANCE_H
    00047
    00048 #include<ode-dbl/common.h>
    00049 #include<ode-dbl/contact.h>
    00050
    00051 namespace lpzrobots {
    00052
    00053   //      Todo: maybe add bounce
    00054
    00055   class GlobalData;
    00056   class Substance;
    00057   class Axis;
    00058
    00059   /** function to be called at a collision event between the two geoms.
    00060       @param params surface parameter, which should be changed/calculated by this function
    00061       @param globaldata global information
    00062       @param userdata pointer to user data for this callback (stored in substance)
    00063       @param contacts array of contact information
    00064       @param numContacts length of contact information array
    00065       @param o1 geom corresponding to substance of this callback
    00066       @param o2 other geom
    00067       @param s1 substance of this callback
    00068       @param s2 other substance
    00069       @return 0 if collision should not be treated;
    00070               1 if collision should be treated otherwise (by other callback or standard methods);
    00071               2 if collision to be treated and parameters for collision are set in params
    00072    */
    00073   typedef int (*CollisionCallback)(dSurfaceParameters& params, GlobalData& globaldata, void *userdata,
    00074                                    dContact* contacts, int numContacts,
    00075                                    dGeomID o1, dGeomID o2, const Substance& s1, const Substance& s2);
    00076
    00077   /**
    00078      Physical substance definition, used for collision detection/treatment
    00079      What we need is mu, slip and kp,kd parameter for the collision
    00080      Definition of substance parameters:
    00081      <pre>
    00082        Parameter    interval  collision_parameter
    00083        roughness:  [0-]      mu   = roughness1*roughness2
    00084        slip:       [0-]      slip = slip1+slip2
    00085        hardness:   [0-]      kp   = hardness1 * hardness2 / (hardness1 + hardness2) (two springs serial)
    00086        elasticity: [0-1]     kd   = (1-elasticity1) * s2.hardness + (1-elasticity2) * s1.hardness) /
    00087                                     (s1.hardness + s2.hardness);
    00088      </pre>
    00089      For the calculation of the spring/damping constant we use the following schema:
    00090      The collision can be considered as 2 springs serially connected.
    00091      The spring constant of each collision side is given by hardness (here kp). The spring constant of
    00092      the entire spring is given by \f[ 1/kp = 1/kp_1 + 1/kp_2\f].
    00093      The damping (kd) is derived from the elasticity (e), but it is more difficult to compute.
    00094      Consider the damping in form of energy lost.
    00095      We can write the energy or work done by each spring as: \f[ W_i = F*s_i  = F^2/p \f] with \f[s_i=F*kp_i\f].
    00096      The energy lost though damping is \f[ W_1^D = W_i*(1-e_i) \f].
    00097      The final damping is now: \f[ kd = (1-e) = W^D/W = \frac{(1-e_1)/kp_1 + (1-e_2)/kp_2}{1/kp_1 + 1/kp_2}
    00098      = \frac{(1-e_1)kp_2 + (1-e_2)kp_1}{kp_1+kp_2}\f].
    00099
    00100      Note that you cannot add any member variables to derived classes
    00101       since they do not fit into the substance object in OdeHandle!
    00102  */
    00103   class Substance {
    00104   public:
    00105     Substance();
    00106     Substance( float roughness, float slip, float hardness, float elasticity);
    00107
    00108   public:
    00109
    00110     float roughness;
    00111     float slip;
    00112     float hardness;
    00113     float elasticity;
    00114
    00115     void setCollisionCallback(CollisionCallback func, void* userdata);
    00116
    00117     CollisionCallback callback;
    00118     void* userdata;
    00119
    00120   public:
    00121     /// Combination of two surfaces
    00122     static void getSurfaceParams(dSurfaceParameters& sp, const Substance& s1, const Substance& s2, double stepsize);
    00123
    00124     static void printSurfaceParams(const dSurfaceParameters& surfParams);
    00125
    00126     //// Factory methods
    00127
    00128     /// default substance is plastic with roughness=0.8
    00129     static Substance getDefaultSubstance();
    00130     void toDefaultSubstance();
    00131
    00132     /// very hard and elastic with slip roughness [0.1-1]
    00133     static Substance getMetal(float roughness);
    00134     /// very hard and elastic with slip roughness [0.1-1]
    00135     void toMetal(float roughness);
    00136
    00137     /// high roughness, no slip, very elastic, hardness : [5-50]
    00138     static Substance getRubber(float hardness);
    00139     /// high roughness, no slip, very elastic, hardness : [5-50]
    00140     void toRubber(float hardness);
    00141
    00142     /// medium slip, a bit elastic, medium hardness, roughness [0.5-2]
    00143     static Substance getPlastic(float roughness);
    00144     /// medium slip, a bit elastic, medium hardness, roughness [0.5-2]
    00145     void toPlastic(float roughness);
    00146
    00147     /// large slip, not elastic, low hardness [1-30], high roughness
    00148     static Substance getFoam(float _hardness);
    00149     /// large slip, not elastic, low hardness [1-30], high roughness
    00150     void toFoam(float _hardness);
    00151
    00152     /** variable slip and roughness [0-1], not elastic, high hardness for solid snow
    00153         slip = 1 <--> roughness=0.0, slip = 0 <--> roughnes=1.0 */
    00154     static Substance getSnow(float _slip);
    00155     /** variable slip and roughness, not elastic, high hardness for solid snow
    00156         slip = 1 <--> roughness=0.0, slip = 0 <--> roughnes=1.0 */
    00157     void toSnow(float _slip);
    00158
    00159     /// @see toNoContact()
    00160     static Substance getNoContact();
    00161     /** set the collsion callback to ignores everything
    00162         Usually it is better to use the "ignorePairs" from odeHandle but
    00163         if this particular one substance should not collide with any other, this is easier.
    00164         WARNING: this sets the collisionCallback. This will not convert to other
    00165         substances without manually setting the callback to 0
    00166      */
    00167     void toNoContact();
    00168
    00169     /** enables anisotrop friction.
    00170         The friction along the given axis is ratio fold of the friction in the other directions.
    00171         If ratio = 0.1 and axis=Axis(0,0,1) then the fiction along the z-axis
    00172          is 1/10th of the normal friction.
    00173         Useful  to mimic scales of snakes or the like.
    00174         WARNING: this sets the collisionCallback!
    00175         To disable the collisionCallback has to set to 0 manually
    00176     */
    00177     void toAnisotropFriction(double ratio, const Axis& axis);
    00178   };
    00179
    00180
    00181   class DebugSubstance : public Substance {
    00182   public:
    00183     DebugSubstance();
    00184     DebugSubstance( float roughness, float slip, float hardness, float elasticity);
    00185   protected:
    00186     static int dbg_output(dSurfaceParameters& params, GlobalData& globaldata, void *userdata,
    00187                       dContact* contacts, int numContacts,
    00188                       dGeomID o1, dGeomID o2, const Substance& s1, const Substance& s2);
    00189   };
    00190
    00191 }
    00192
    00193 #endif
    00194
    00195