00001 /*************************************************************************** 00002 * Copyright (C) 2005 by Robot Group Leipzig * 00003 * martius@informatik.uni-leipzig.de * 00004 * fhesse@informatik.uni-leipzig.de * 00005 * der@informatik.uni-leipzig.de * 00006 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program; if not, write to the * 00019 * Free Software Foundation, Inc., * 00020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00021 *************************************************************************** 00022 * * 00023 * DESCRIPTION * 00024 * * 00025 * $Log: substance.h,v $ 00026 * Revision 1.10 2010/03/29 16:28:21 martius 00027 * abstract ground rembers groundsubstance 00028 * comments and typos 00029 * osgprimitive uses white for empty texture 00030 * 00031 * Revision 1.9 2010/03/29 11:41:12 martius 00032 * todo comment moved 00033 * 00034 * Revision 1.8 2010/03/09 11:53:41 martius 00035 * renamed globally ode to ode-dbl 00036 * 00037 * Revision 1.7 2008/09/11 15:24:01 martius 00038 * motioncallback resurrected 00039 * noContact substance 00040 * use slider center of the connecting objects for slider drawing 00041 * 00042 * Revision 1.6 2008/08/27 19:12:02 martius 00043 * comment 00044 * 00045 * Revision 1.5 2008/02/14 14:41:48 der 00046 * added snow as a new substance 00047 * 00048 * Revision 1.4 2007/08/24 11:55:54 martius 00049 * collision callbacks get more information 00050 * 00051 * Revision 1.3 2007/07/17 07:20:29 martius 00052 * updated comments 00053 * 00054 * Revision 1.2 2007/07/03 13:14:57 martius 00055 * stepsize included, but not yet sorted out 00056 * changing stepsize varies the behaviour 00057 * 00058 * Revision 1.1 2007/03/16 10:50:32 martius 00059 * initial version 00060 * 00061 * 00062 * 00063 00064 This file concerns material implementation in the simulator. 00065 00066 Terminology: 00067 Since "Material" is used for OpenGL stuff and also in OSG 00068 we should use something else for the physical material: substance 00069 00070 So how to implement substance to cover all collission cases and requirements. 00071 It would be nice to keep the collisioncontrol as it is for compatibility reasons. 00072 In general: 00073 00074 - every ode geom should get a user data pointer to the primitive 00075 - primitive has a certain substance 00076 - 2 substance define collision parameters 00077 - also an optional callback function for user defined handling 00078 - collission detection is done globally. 00079 - via joint connected geoms are stored in a set (globally) 00080 - spaces are globally registered 00081 00082 00083 00084 ***************************************************************************/ 00085 #ifndef __SUBSTANCE_H 00086 #define __SUBSTANCE_H 00087 00088 #include<ode-dbl/common.h> 00089 #include<ode-dbl/contact.h> 00090 00091 namespace lpzrobots { 00092 00093 // Todo: maybe add bounce 00094 00095 class GlobalData; 00096 class Substance; 00097 00098 /** function to be called at a collision event between the two geoms. 00099 @param params surface parameter, which should be changed/calculated by this function 00100 @param globaldata global information 00101 @param userdata pointer to user data for this callback (stored in substance) 00102 @param contacts array of contact information 00103 @param numContacts length of contact information array 00104 @param o1 geom corresponding to substance of this callback 00105 @param o2 other geom 00106 @param s1 substance of this callback 00107 @param s2 other substance 00108 @return 0 if collision should not be treated; 00109 1 if collision should be treated otherwise (by other callback or standard methods); 00110 2 if collision to be treated and parameters for collision are set in params 00111 */ 00112 typedef int (*CollisionCallback)(dSurfaceParameters& params, GlobalData& globaldata, void *userdata, 00113 dContact* contacts, int numContacts, 00114 dGeomID o1, dGeomID o2, const Substance& s1, const Substance& s2); 00115 00116 /** 00117 Physical substance definition, used for collision detection/treatment 00118 What we need is mu, slip and kp,kd parameter for the collision 00119 Definition of substance parameters: 00120 <pre> 00121 Parameter interval collision_parameter 00122 roughness: [0-] mu = roughness1*roughness2 00123 slip: [0-] slip = slip1+slip2 00124 hardness: [0-] kp = hardness1 * hardness2 / (hardness1 + hardness2) (two springs serial) 00125 elasticity: [0-1] kd = (1-elasticity1) * s2.hardness + (1-elasticity2) * s1.hardness) / 00126 (s1.hardness + s2.hardness); 00127 </pre> 00128 For the calculation of the spring/damping constant we use the following schema: 00129 The collision can be considered as 2 springs serially connected. 00130 The spring constant of each collision side is given by hardness (here kp). The spring constant of 00131 the entire spring is given by \f[ 1/kp = 1/kp_1 + 1/kp_2\f]. 00132 The damping (kd) is derived from the elasticity (e), but it is more difficult to compute. 00133 Consider the damping in form of energy lost. 00134 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]. 00135 The energy lost though damping is \f[ W_1^D = W_i*(1-e_i) \f]. 00136 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} 00137 = \frac{(1-e_1)kp_2 + (1-e_2)kp_1}{kp_1+kp_2}\f]. 00138 */ 00139 class Substance { 00140 public: 00141 Substance(); 00142 Substance( float roughness, float slip, float hardness, float elasticity); 00143 00144 public: 00145 00146 float roughness; 00147 float slip; 00148 float hardness; 00149 float elasticity; 00150 00151 void setCollisionCallback(CollisionCallback func, void* userdata); 00152 00153 CollisionCallback callback; 00154 void* userdata; 00155 00156 public: 00157 /// Combination of two surfaces 00158 static void getSurfaceParams(dSurfaceParameters& sp, const Substance& s1, const Substance& s2, double stepsize); 00159 00160 static void printSurfaceParams(const dSurfaceParameters& surfParams); 00161 00162 //// Factory methods 00163 00164 /// default substance is plastic with roughness=0.8 00165 static Substance getDefaultSubstance(); 00166 void toDefaultSubstance(); 00167 00168 /// very hard and elastic with slip roughness [0.1-1] 00169 static Substance getMetal(float roughness); 00170 /// very hard and elastic with slip roughness [0.1-1] 00171 void toMetal(float roughness); 00172 00173 /// high roughness, no slip, very elastic, hardness : [5-50] 00174 static Substance getRubber(float hardness); 00175 /// high roughness, no slip, very elastic, hardness : [5-50] 00176 void toRubber(float hardness); 00177 00178 /// medium slip, a bit elastic, medium hardness, roughness [0.5-2] 00179 static Substance getPlastic(float roughness); 00180 /// medium slip, a bit elastic, medium hardness, roughness [0.5-2] 00181 void toPlastic(float roughness); 00182 00183 /// large slip, not elastic, low hardness [1-30], high roughness 00184 static Substance getFoam(float _hardness); 00185 /// large slip, not elastic, low hardness [1-30], high roughness 00186 void toFoam(float _hardness); 00187 00188 /** variable slip and roughness [0-1], not elastic, high hardness for solid snow 00189 slip = 1 <--> roughness=0.0, slip = 0 <--> roughnes=1.0 */ 00190 static Substance getSnow(float _slip); 00191 /** variable slip and roughness, not elastic, high hardness for solid snow 00192 slip = 1 <--> roughness=0.0, slip = 0 <--> roughnes=1.0 */ 00193 void toSnow(float _slip); 00194 00195 /// @see toNoContact() 00196 static Substance getNoContact(); 00197 /** collsion callback that ignores everything 00198 Usually it is better to use the "ignorePairs" from odeHandle but 00199 if this particular one should not collide with any, this is easier. 00200 WARNING: this sets the collisionCallback. This will not convert to other 00201 substances without manually setting the callback to 0 00202 */ 00203 void toNoContact(); 00204 }; 00205 00206 00207 class DebugSubstance : public Substance { 00208 public: 00209 DebugSubstance(); 00210 DebugSubstance( float roughness, float slip, float hardness, float elasticity); 00211 protected: 00212 static int dbg_output(dSurfaceParameters& params, GlobalData& globaldata, void *userdata, 00213 dContact* contacts, int numContacts, 00214 dGeomID o1, dGeomID o2, const Substance& s1, const Substance& s2); 00215 }; 00216 00217 } 00218 00219 #endif 00220 00221