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
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #include <assert.h>
00076 #include <selforg/matrix.h>
00077 #include <osg/Matrix>
00078 #include "sphererobot3masses.h"
00079
00080 #include "irsensor.h"
00081 #include "invisibleprimitive.h"
00082 #include "osgprimitive.h"
00083
00084
00085 using namespace osg;
00086 using namespace std;
00087
00088 namespace lpzrobots {
00089
00090 const int Sphererobot3Masses::servono;
00091
00092
00093
00094
00095 Sphererobot3Masses::Sphererobot3Masses ( const OdeHandle& odeHandle, const OsgHandle& osgHandle,
00096 const Sphererobot3MassesConf& conf, const std::string& name,
00097 double transparency)
00098 : OdeRobot ( odeHandle, osgHandle, name, "$Id: sphererobot3masses.cpp,v 1.3 2006/07/20 17:19:45 martius Exp $"), conf(conf)
00099 {
00100
00101 created = false;
00102 memset(object, 0,sizeof(void*) * Last);
00103 memset(joint, 0,sizeof(void*) * servono);
00104 memset(axis, 0,sizeof(void*) * servono);
00105 memset(servo, 0,sizeof(void*) * servono);
00106
00107 this->conf.pendulardiameter = conf.diameter/7;
00108 this->transparency=transparency;
00109
00110 }
00111
00112 Sphererobot3Masses::~Sphererobot3Masses()
00113 {
00114 destroy();
00115 }
00116
00117 void Sphererobot3Masses::update()
00118 {
00119 for (int i=0; i < Last; i++) {
00120 if(object[i]) object[i]->update();
00121 }
00122 Matrix pose(object[Base]->getPose());
00123 for (int i=0; i < servono; i++) {
00124 if(axis[i]){
00125 axis[i]->setMatrix(Matrix::rotate(M_PI/2, (i==1), (i==0), (i==2)) * pose);
00126 }
00127 }
00128 irSensorBank.update();
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 int Sphererobot3Masses::getSensors ( sensor* sensors, int sensornumber )
00138 {
00139 int len=0;
00140 matrix::Matrix A = odeRto3x3RotationMatrix ( dBodyGetRotation ( object[Base]->getBody() ) );
00141
00142 if(conf.motorsensor){
00143 for ( int n = 0; n < servono; n++ ) {
00144 sensors[len] = servo[n]->get() * 0.2;
00145 len++;
00146 }
00147 }
00148 if(conf.axisZsensor){
00149
00150
00151
00152
00153 len += A.column(2).convertToBuffer(sensors+len, sensornumber-len);
00154 }
00155 if(conf.axisXYZsensor){
00156
00157 len += A.convertToBuffer(sensors + len , sensornumber -len);
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 if (conf.irAxis1 || conf.irAxis2 || conf.irAxis3){
00167 len += irSensorBank.get(sensors+len, sensornumber-len);
00168 }
00169
00170 return len;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179 void Sphererobot3Masses::setMotors ( const motor* motors, int motornumber ) {
00180 int len = min(motornumber, servono);
00181 for ( int n = 0; n < len; n++ ) {
00182 servo[n]->set(motors[n]);
00183 }
00184 }
00185
00186
00187 void Sphererobot3Masses::place(const osg::Matrix& pose){
00188 osg::Matrix p2;
00189 p2 = pose * osg::Matrix::translate(osg::Vec3(0, 0, conf.diameter/2));
00190 create(p2);
00191 };
00192
00193
00194 void Sphererobot3Masses::doInternalStuff(const GlobalData& global){
00195 irSensorBank.reset();
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 bool Sphererobot3Masses::collisionCallback(void *data, dGeomID o1, dGeomID o2) {
00207
00208 if( o1 == (dGeomID)odeHandle.space || o2 == (dGeomID)odeHandle.space) {
00209 if(o1 == (dGeomID)odeHandle.space) irSensorBank.sense(o2);
00210 if(o2 == (dGeomID)odeHandle.space) irSensorBank.sense(o1);
00211
00212
00213 int i,n;
00214 const int N = 40;
00215 dContact contact[N];
00216
00217 n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
00218 for (i=0; i<n; i++) {
00219 if( contact[i].geom.g1 == object[Base]->getGeom() || contact[i].geom.g2 == object[Base]->getGeom() ){
00220
00221 contact[i].surface.mode = dContactSlip1 | dContactSlip2 | dContactApprox1;
00222
00223 contact[i].surface.mu = 2.0;
00224 contact[i].surface.slip1 = 0.005;
00225 contact[i].surface.slip2 = 0.005;
00226
00227
00228 dJointID c = dJointCreateContact( odeHandle.world, odeHandle.jointGroup, &contact[i]);
00229 dJointAttach ( c , dGeomGetBody(contact[i].geom.g1) , dGeomGetBody(contact[i].geom.g2));
00230 }
00231 }
00232 return true;
00233 } else {
00234 return false;
00235 }
00236 }
00237
00238
00239
00240
00241
00242
00243 int Sphererobot3Masses::getMotorNumber(){
00244 return servono;
00245 }
00246
00247
00248
00249
00250
00251 int Sphererobot3Masses::getSensorNumber() {
00252 return conf.motorsensor * servono + conf.axisZsensor * servono + conf.axisXYZsensor * servono * 3
00253 + (conf.irAxis1 + conf.irAxis2 + conf.irAxis3) * 2;
00254 }
00255
00256
00257
00258
00259
00260 void Sphererobot3Masses::create(const osg::Matrix& pose){
00261 if (created) {
00262 destroy();
00263 }
00264
00265
00266 odeHandle.space = dSimpleSpaceCreate (parentspace);
00267 Color c(osgHandle.color);
00268 c.alpha() = transparency;
00269 OsgHandle osgHandle_Base = osgHandle.changeColor(c);
00270 OsgHandle osgHandleX[3];
00271 osgHandleX[0] = osgHandle.changeColor(Color(1.0, 0.0, 0.0));
00272 osgHandleX[1] = osgHandle.changeColor(Color(0.0, 1.0, 0.0));
00273 osgHandleX[2] = osgHandle.changeColor(Color(0.0, 0.0, 1.0));
00274
00275
00276 object[Base] = new Sphere(conf.diameter/2);
00277
00278 object[Base]->init(odeHandle, conf.spheremass, osgHandle_Base);
00279 object[Base]->setPose(pose);
00280
00281 Pos p(pose.getTrans());
00282 Primitive* pendular[3];
00283
00284
00285 for ( unsigned int n = 0; n < 3; n++ ) {
00286 pendular[n] = new Sphere(conf.pendulardiameter/2);
00287 pendular[n]->init(odeHandle, conf.pendularmass, osgHandleX[n],
00288 Primitive::Body | Primitive::Draw);
00289 pendular[n]->setPose(pose);
00290
00291 joint[n] = new SliderJoint(object[Base], pendular[n],
00292 p, osg::Vec3((n==0), (n==1), (n==2)));
00293 joint[n]->init(odeHandle, osgHandle, false);
00294
00295 joint[n]->setParam ( dParamLoStop, -1.1*conf.diameter*conf.pendularrange );
00296 joint[n]->setParam ( dParamHiStop, 1.1*conf.diameter*conf.pendularrange );
00297 joint[n]->setParam ( dParamStopCFM, 0.1);
00298 joint[n]->setParam ( dParamStopERP, 0.9);
00299 joint[n]->setParam ( dParamCFM, 0.001);
00300 servo[n] = new SliderServo(joint[n],
00301 -conf.diameter*conf.pendularrange,
00302 conf.diameter*conf.pendularrange,
00303 conf.pendularmass);
00304
00305 axis[n] = new OSGCylinder(conf.diameter/100, conf.diameter - conf.diameter/100);
00306 axis[n]->init(osgHandleX[n], OSGPrimitive::Low);
00307 }
00308 object[Pendular1] = pendular[0];
00309 object[Pendular2] = pendular[1];
00310 object[Pendular3] = pendular[2];
00311
00312 double sensorrange = conf.irsensorscale * conf.diameter;
00313 RaySensor::rayDrawMode drawMode = conf.drawIRs ? RaySensor::drawAll : RaySensor::drawSensor;
00314
00315 irSensorBank.init(odeHandle, osgHandle );
00316 if (conf.irAxis1){
00317 for(int i=-1; i<2; i+=2){
00318 IRSensor* sensor = new IRSensor(1.5);
00319 Matrix R = Matrix::rotate(i*M_PI/2, 1, 0, 0) * Matrix::translate(0,-i*conf.diameter/2,0 );
00320 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00321 }
00322 }
00323 if (conf.irAxis2){
00324 for(int i=-1; i<2; i+=2){
00325 IRSensor* sensor = new IRSensor(1.5);
00326 Matrix R = Matrix::rotate(i*M_PI/2, 0, 1, 0) * Matrix::translate(i*conf.diameter/2,0,0 );
00327
00328 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00329 }
00330 }
00331 if (conf.irAxis3){
00332 for(int i=-1; i<2; i+=2){
00333 IRSensor* sensor = new IRSensor(1.5);
00334 Matrix R = Matrix::rotate( i==1 ? 0 : M_PI, 1, 0, 0) * Matrix::translate(0,0,i*conf.diameter/2);
00335 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00336 }
00337 }
00338 }
00339
00340
00341
00342
00343 void Sphererobot3Masses::destroy(){
00344 if (created){
00345 for (int i=0; i<Last; i++){
00346 if(object[i]) delete object[i];
00347 }
00348 for (int i=0; i<servono; i++){
00349 if(joint[i]) delete joint[i];
00350 if(servo[i]) delete servo[i];
00351 if(axis[i]) delete axis[i];
00352 }
00353 irSensorBank.clear();
00354 dSpaceDestroy(odeHandle.space);
00355 }
00356 created=false;
00357 }
00358
00359 }
00360