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.7 2008/09/11 15:24:01 martius 00027 * motioncallback resurrected 00028 * noContact substance 00029 * use slider center of the connecting objects for slider drawing 00030 * 00031 * Revision 1.6 2008/08/27 19:12:02 martius 00032 * comment 00033 * 00034 * Revision 1.5 2008/02/14 14:41:48 der 00035 * added snow as a new substance 00036 * 00037 * Revision 1.4 2007/08/24 11:55:54 martius 00038 * collision callbacks get more information 00039 * 00040 * Revision 1.3 2007/07/17 07:20:29 martius 00041 * updated comments 00042 * 00043 * Revision 1.2 2007/07/03 13:14:57 martius 00044 * stepsize included, but not yet sorted out 00045 * changing stepsize varies the behaviour 00046 * 00047 * Revision 1.1 2007/03/16 10:50:32 martius 00048 * initial version 00049 * 00050 * 00051 * 00052 00053 This file concerns material implementation in the simulator. 00054 00055 Terminology: 00056 Since "Material" is used for OpenGL stuff and also in OSG 00057 we should use something else for the physical material: substance 00058 00059 So how to implement substance to cover all collission cases and requirements. 00060 It would be nice to keep the collisioncontrol as it is for compatibility reasons. 00061 In general: 00062 00063 - every ode geom should get a user data pointer to the primitive 00064 - primitive has a certain substance 00065 - 2 substance define collision parameters 00066 - also an optional callback function for user defined handling 00067 - collission detection is done globally. 00068 - via joint connected geoms are stored in a set (globally) 00069 - spaces are globally registered 00070 00071 00072 00073 ***************************************************************************/ 00074 #ifndef __SUBSTANCE_H 00075 #define __SUBSTANCE_H 00076 00077 #include<ode/common.h> 00078 #include<ode/contact.h> 00079 00080 namespace lpzrobots { 00081 00082 class GlobalData; 00083 class Substance; 00084 00085 /** function to be called at a collision event between the two geoms. 00086 @param params surface parameter, which should be changed/calculated by this function 00087 @param globaldata global information 00088 @param userdata pointer to user data for this callback (stored in substance) 00089 @param contacts array of contact information 00090 @param numContacts length of contact information array 00091 @param o1 geom corresponding to substance of this callback 00092 @param o2 other geom 00093 @param s1 substance of this callback 00094 @param s2 other substance 00095 @return 0 if collision should not be treated; 00096 1 if collision should be treated otherwise (by other callback or standard methods); 00097 2 if collision to be treated and parameters for collision are set in params 00098 */ 00099 typedef int (*CollisionCallback)(dSurfaceParameters& params, GlobalData& globaldata, void *userdata, 00100 dContact* contacts, int numContacts, 00101 dGeomID o1, dGeomID o2, const Substance& s1, const Substance& s2); 00102 00103 /** 00104 Physical substance definition, used for collision detection/treatment 00105 What we need is mu, slip and kp,kd parameter for the collision 00106 Definition of substance parameters: 00107 <pre> 00108 Parameter interval collision_parameter 00109 roughness: [0-] mu = roughness1*roughness2 00110 slip: [0-] slip = slip1+slip2 00111 hardness: [0-] kp = hardness1 * hardness2 / (hardness1 + hardness2) (two springs serial) 00112 elasticity: [0-1] kd = (1-elasticity1) * s2.hardness + (1-elasticity2) * s1.hardness) / 00113 (s1.hardness + s2.hardness); 00114 </pre> 00115 For the calculation of the spring/damping constant we use the following schema: 00116 The collision can be considered as 2 springs serially connected. 00117 The spring constant of each collision side is given by hardness (here kp). The spring constant of 00118 the entire spring is given by \f[ 1/kp = 1/kp_1 + 1/kp_2\f]. 00119 The damping (kd) is derived from the elasticity (e), but it is more difficult to compute. 00120 Consider the damping in form of energy lost. 00121 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]. 00122 The energy lost though damping is \f[ W_1^D = W_i*(1-e_i) \f]. 00123 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} 00124 = \frac{(1-e_1)kp_2 + (1-e_2)kp_1}{kp_1+kp_2}\f]. 00125 00126 Todo: maybe add bounce 00127 */ 00128 class Substance { 00129 public: 00130 Substance(); 00131 Substance( float roughness, float slip, float hardness, float elasticity); 00132 00133 public: 00134 00135 float roughness; 00136 float slip; 00137 float hardness; 00138 float elasticity; 00139 00140 void setCollisionCallback(CollisionCallback func, void* userdata); 00141 00142 CollisionCallback callback; 00143 void* userdata; 00144 00145 public: 00146 /// Combination of two surfaces 00147 static void getSurfaceParams(dSurfaceParameters& sp, const Substance& s1, const Substance& s2, double stepsize); 00148 00149 static void printSurfaceParams(const dSurfaceParameters& surfParams); 00150 00151 //// Factory methods 00152 00153 /// default substance is plastic with roughness=0.8 00154 static Substance getDefaultSubstance(); 00155 void toDefaultSubstance(); 00156 00157 /// very hard and elastic with slip roughness [0.1-1] 00158 static Substance getMetal(float roughness); 00159 /// very hard and elastic with slip roughness [0.1-1] 00160 void toMetal(float roughness); 00161 00162 /// high roughness, no slip, very elastic, hardness : [5-50] 00163 static Substance getRubber(float hardness); 00164 /// high roughness, no slip, very elastic, hardness : [5-50] 00165 void toRubber(float hardness); 00166 00167 /// medium slip, a bit elastic, medium hardness, roughness [0.5-2] 00168 static Substance getPlastic(float roughness); 00169 /// medium slip, a bit elastic, medium hardness, roughness [0.5-2] 00170 void toPlastic(float roughness); 00171 00172 /// large slip, not elastic, low hardness [1-30], high roughness 00173 static Substance getFoam(float _hardness); 00174 /// large slip, not elastic, low hardness [1-30], high roughness 00175 void toFoam(float _hardness); 00176 00177 /** variable slip and roughness [0-1], not elastic, high hardness for solid snow 00178 slip = 1 <--> roughness=0.0, slip = 0 <--> roughnes=1.0 */ 00179 static Substance getSnow(float _slip); 00180 /** variable slip and roughness, not elastic, high hardness for solid snow 00181 slip = 1 <--> roughness=0.0, slip = 0 <--> roughnes=1.0 */ 00182 void toSnow(float _slip); 00183 00184 /// @see toNoContact() 00185 static Substance getNoContact(); 00186 /** collsion callback that ignores everything 00187 Usually it is better to use the "ignorePairs" from odeHandle but 00188 if this particular one should not collide with any, this is easier. 00189 WARNING: this sets the collisionCallback. This will not convert to other 00190 substances without manually setting the callback to 0 00191 */ 00192 void toNoContact(); 00193 00194 00195 00196 }; 00197 00198 } 00199 00200 #endif 00201 00202