00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "schlange.h"
00048
00049 namespace lpzrobots {
00050
00051 Schlange::Schlange ( const OdeHandle& odeHandle, const OsgHandle& osgHandle,
00052 const SchlangeConf& conf, const char* name )
00053 : OdeRobot( odeHandle, osgHandle, name), conf(conf) {
00054
00055
00056 Configurable::insertCVSInfo(this->name, "$RCSfile: schlange.cpp,v $",
00057 "$Revision: 1.20.4.6 $");
00058 created=false;
00059 }
00060
00061 Schlange::~Schlange()
00062 {
00063 if(created) destroy();
00064 }
00065
00066
00067 void Schlange::place(const osg::Matrix& pose){
00068
00069
00070
00071 create(pose * osg::Matrix::translate(osg::Vec3(0, 0, conf.segmDia/2)));
00072 }
00073
00074 void Schlange::update(){
00075 assert(created);
00076 for (vector<Primitive*>::iterator i = objects.begin(); i!= objects.end(); i++){
00077 if(*i) (*i)->update();
00078 }
00079 for (vector<Joint*>::iterator i = joints.begin(); i!= joints.end(); i++){
00080 if(*i) (*i)->update();
00081 }
00082 }
00083
00084 void Schlange::doInternalStuff(const GlobalData& global){
00085 if(created){
00086
00087 dSpaceCollide(odeHandle.space, this, mycallback);
00088 }
00089 }
00090
00091 void Schlange::mycallback(void *data, dGeomID o1, dGeomID o2)
00092 {
00093 Schlange* me = (Schlange*) data;
00094 int i=0;
00095 int o1_index= -1;
00096 int o2_index= -1;
00097 for (vector<Primitive*>::iterator n = me->objects.begin(); n!= me->objects.end(); n++, i++){
00098 if( (*n)->getGeom() == o1)
00099 o1_index=i;
00100 if( (*n)->getGeom() == o2)
00101 o2_index=i;
00102 }
00103
00104 if(o1_index >= 0 && o2_index >= 0 && abs(o1_index - o2_index) > 1){
00105
00106 int i,n;
00107 const int N = 10;
00108 dContact contact[N];
00109 n = dCollide (o1, o2, N, &contact[0].geom, sizeof(dContact));
00110 for (i=0; i<n; i++) {
00111 contact[i].surface.mode = 0;
00112 contact[i].surface.mu = 0;
00113 contact[i].surface.mu2 = 0;
00114 dJointID c = dJointCreateContact( me->odeHandle.world, me->odeHandle.jointGroup, &contact[i]);
00115 dJointAttach ( c , dGeomGetBody(contact[i].geom.g1) , dGeomGetBody(contact[i].geom.g2)) ;
00116 }
00117 }
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 bool Schlange::collisionCallback(void *data, dGeomID o1, dGeomID o2)
00130 {
00131
00132 if( o1 == (dGeomID)odeHandle.space || o2 == (dGeomID)odeHandle.space ){
00133 int i,n;
00134 const int N = 20;
00135 dContact contact[N];
00136 n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
00137 for (i=0; i<n; i++){
00138
00139
00140 contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
00141 dContactSoftERP | dContactSoftCFM | dContactApprox1;
00142 contact[i].surface.slip1 = 0.001;
00143 contact[i].surface.slip2 = 0.001;
00144 contact[i].surface.mu = conf.frictionGround;
00145
00146 contact[i].surface.soft_erp = 0.9;
00147 contact[i].surface.soft_cfm = 0.001;
00148
00149 dJointID c = dJointCreateContact( odeHandle.world, odeHandle.jointGroup, &contact[i]);
00150 dJointAttach ( c , dGeomGetBody(contact[i].geom.g1) , dGeomGetBody(contact[i].geom.g2));
00151 }
00152 return true;
00153 }
00154 return false;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 Configurable::paramlist Schlange::getParamList() const{
00164 paramlist list;
00165 list += pair<paramkey, paramval> (string("frictionground"), conf.frictionGround);
00166 list += pair<paramkey, paramval> (string("frictionjoint"), conf.frictionJoint);
00167 list += pair<paramkey, paramval> (string("motorpower"), conf.motorPower);
00168 list += pair<paramkey, paramval> (string("sensorfactor"), conf.sensorFactor);
00169 return list;
00170 }
00171
00172
00173 Configurable::paramval Schlange::getParam(const paramkey& key) const{
00174 if(key == "frictionground") return conf.frictionGround;
00175 else if(key == "frictionjoint") return conf.frictionJoint;
00176 else if(key == "motorpower") return conf.motorPower;
00177 else if(key == "sensorfactor") return conf.sensorFactor;
00178 else return Configurable::getParam(key) ;
00179 }
00180
00181 bool Schlange::setParam(const paramkey& key, paramval val){
00182 if(key == "frictionground") conf.frictionGround = val;
00183 else if(key == "motorpower") conf.motorPower = val;
00184 else if(key == "sensorfactor") conf.sensorFactor = val;
00185 else if(key == "frictionjoint") {
00186 conf.frictionJoint = val;
00187 for (vector<AngularMotor*>::iterator i = frictionmotors.begin(); i!= frictionmotors.end(); i++){
00188 if (*i) (*i)->setPower(conf.frictionJoint);
00189 }
00190 } else
00191 return Configurable::setParam(key, val);
00192 return true;
00193 }
00194
00195
00196 int Schlange::getSegmentsPosition(vector<Position> &poslist){
00197 assert(created);
00198 for(int n = 0; n < conf.segmNumber; n++){
00199 Pos p(objects[n]->getPosition());
00200 poslist.push_back(p.toPosition());
00201 }
00202 return conf.segmNumber;
00203 }
00204
00205
00206
00207
00208
00209
00210 void Schlange::create(const osg::Matrix& pose){
00211 if (created) {
00212 destroy();
00213 }
00214
00215 odeHandle.space = dSimpleSpaceCreate (parentspace);
00216
00217 int half = conf.segmNumber/2;
00218 for ( int n = 0; n < conf.segmNumber; n++ ) {
00219 Primitive* p = new Capsule(conf.segmDia/2 , conf.segmLength);
00220 p->init(odeHandle, conf.segmMass, osgHandle);
00221 p->setPose(osg::Matrix::rotate(M_PI/2, 0, 1, 0) *
00222 osg::Matrix::translate((n-half)*conf.segmLength, 0 , conf.segmDia/2) *
00223 pose);
00224 p->getOSGPrimitive()->setTexture("Images/wood.rgb");
00225 objects.push_back(p);
00226 }
00227
00228 created=true;
00229 };
00230
00231
00232
00233
00234 void Schlange::destroy(){
00235 if (created){
00236 for (vector<Primitive*>::iterator i = objects.begin(); i!= objects.end(); i++){
00237 if(*i) delete *i;
00238 }
00239 objects.clear();
00240 for (vector<Joint*>::iterator i = joints.begin(); i!= joints.end(); i++){
00241 if(*i) delete *i;
00242 }
00243 joints.clear();
00244 for (vector<AngularMotor*>::iterator i = frictionmotors.begin(); i!= frictionmotors.end(); i++){
00245 if(*i) delete *i;
00246 }
00247 frictionmotors.clear();
00248 dSpaceDestroy(odeHandle.space);
00249 }
00250 created=false;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 }
00284
00285
00286