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
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 #include <assert.h>
00129 #include <selforg/matrix.h>
00130 #include <osg/Matrix>
00131 #include "sphererobot3masses.h"
00132
00133 #include "irsensor.h"
00134 #include "osgprimitive.h"
00135 #include "mathutils.h"
00136
00137
00138 using namespace osg;
00139 using namespace std;
00140
00141 namespace lpzrobots {
00142
00143
00144 void Sphererobot3MassesConf::destroy(){
00145 for(list<Sensor*>::iterator i = sensors.begin(); i != sensors.end(); i++){
00146 if(*i) delete *i;
00147 }
00148 sensors.clear();
00149 }
00150
00151 const int Sphererobot3Masses::servono;
00152
00153
00154
00155
00156 Sphererobot3Masses::Sphererobot3Masses ( const OdeHandle& odeHandle, const OsgHandle& osgHandle,
00157 const Sphererobot3MassesConf& conf,
00158 const std::string& name,
00159 double transparency)
00160 : OdeRobot ( odeHandle, osgHandle, name,
00161 "$Id: sphererobot3masses.cpp,v 1.20 2008/05/07 16:45:52 martius Exp $"),
00162 conf(conf), transparency(transparency)
00163 {
00164 numberaxis=3;
00165 init();
00166 }
00167
00168
00169
00170
00171 Sphererobot3Masses::Sphererobot3Masses ( const OdeHandle& odeHandle,
00172 const OsgHandle& osgHandle,
00173 const Sphererobot3MassesConf& conf,
00174 const std::string& name,
00175 const std::string& revision,
00176 double transparency)
00177 : OdeRobot ( odeHandle, osgHandle, name, revision),
00178 conf(conf),transparency(transparency)
00179 {
00180 numberaxis=3;
00181 init();
00182 }
00183
00184
00185 void Sphererobot3Masses::init(){
00186 created = false;
00187 memset(object, 0,sizeof(void*) * Last);
00188 memset(joint, 0,sizeof(void*) * servono);
00189 memset(axis, 0,sizeof(void*) * servono);
00190 memset(servo, 0,sizeof(void*) * servono);
00191
00192 this->conf.pendulardiameter = conf.diameter/7;
00193 }
00194
00195 Sphererobot3Masses::~Sphererobot3Masses()
00196 {
00197 destroy();
00198 if(conf.irSensorTempl) delete conf.irSensorTempl;
00199 }
00200
00201 void Sphererobot3Masses::update()
00202 {
00203 for (int i=0; i < Last; i++) {
00204 if(object[i]) object[i]->update();
00205 }
00206 Matrix pose(object[Base]->getPose());
00207 for (int i=0; i < servono; i++) {
00208 if(axis[i]){
00209 axis[i]->setMatrix(Matrix::rotate(M_PI/2, (i==1), (i==0), (i==2)) * pose);
00210 }
00211 }
00212 irSensorBank.update();
00213 }
00214
00215
00216
00217
00218
00219
00220
00221 int Sphererobot3Masses::getSensors ( sensor* sensors, int sensornumber )
00222 {
00223 int len=0;
00224 assert(created);
00225 if(!conf.motor_ir_before_sensors){
00226 FOREACH(list<Sensor*>, conf.sensors, i){
00227 len += (*i)->get(sensors+len, sensornumber-len);
00228 }
00229 }
00230
00231 if(conf.motorsensor){
00232 for ( unsigned int n = 0; n < numberaxis; n++ ) {
00233 sensors[len] = servo[n]->get() * 0.5;
00234 len++;
00235 }
00236 }
00237
00238
00239 if (conf.irAxis1 || conf.irAxis2 || conf.irAxis3 || conf.irRing || conf.irSide){
00240 len += irSensorBank.get(sensors+len, sensornumber-len);
00241 }
00242
00243 if(conf.motor_ir_before_sensors){
00244 FOREACH(list<Sensor*>, conf.sensors, i){
00245 len += (*i)->get(sensors+len, sensornumber-len);
00246 }
00247 }
00248
00249
00250 return len;
00251 }
00252
00253 void Sphererobot3Masses::setMotors ( const motor* motors, int motornumber ) {
00254 int len = min((unsigned)motornumber, numberaxis);
00255 for ( int n = 0; n < len; n++ ) {
00256 servo[n]->set(motors[n]);
00257 }
00258 }
00259
00260
00261 void Sphererobot3Masses::place(const osg::Matrix& pose){
00262 osg::Matrix p2;
00263 p2 = pose * osg::Matrix::translate(osg::Vec3(0, 0, conf.diameter/2));
00264 create(p2);
00265 };
00266
00267
00268 void Sphererobot3Masses::doInternalStuff(GlobalData& global){
00269
00270 dBodyID b = getMainPrimitive()->getBody();
00271 double friction = odeHandle.substance.roughness;
00272 const double* vel = dBodyGetAngularVel( b);
00273 if(fabs(vel[2])>0.2){
00274 dBodyAddTorque ( b , 0 , 0 , -0.05*friction*vel[2] );
00275 }
00276
00277 if(conf.brake){
00278 dBodyAddTorque ( b , -conf.brake*vel[0] , -conf.brake*vel[1] , -conf.brake*vel[2] );
00279 }
00280
00281 irSensorBank.reset();
00282 }
00283
00284 int Sphererobot3Masses::getMotorNumber(){
00285 return numberaxis;
00286 }
00287
00288 int Sphererobot3Masses::getSensorNumber() {
00289 int s=0;
00290 FOREACHC(list<Sensor*>, conf.sensors, i){
00291 s += (*i)->getSensorNumber();
00292 }
00293 return conf.motorsensor * numberaxis + s + irSensorBank.getSensorNumber();
00294 }
00295
00296
00297
00298
00299 void Sphererobot3Masses::create(const osg::Matrix& pose){
00300 if (created) {
00301 destroy();
00302 }
00303
00304
00305 odeHandle.createNewSimpleSpace(parentspace,true);
00306 Color c(osgHandle.color);
00307 c.alpha() = transparency;
00308 OsgHandle osgHandle_Base = osgHandle.changeColor(c);
00309 OsgHandle osgHandleX[3];
00310 osgHandleX[0] = osgHandle.changeColor(Color(1.0, 0.0, 0.0));
00311 osgHandleX[1] = osgHandle.changeColor(Color(0.0, 1.0, 0.0));
00312 osgHandleX[2] = osgHandle.changeColor(Color(0.0, 0.0, 1.0));
00313
00314
00315 object[Base] = new Sphere(conf.diameter/2);
00316
00317 object[Base]->init(odeHandle, conf.spheremass, osgHandle_Base);
00318 object[Base]->setPose(pose);
00319
00320 Pos p(pose.getTrans());
00321 Primitive* pendular[servono];
00322 memset(pendular, 0, sizeof(void*) * servono);
00323
00324
00325 for ( unsigned int n = 0; n < numberaxis; n++ ) {
00326 pendular[n] = new Sphere(conf.pendulardiameter/2);
00327 pendular[n]->init(odeHandle, conf.pendularmass, osgHandleX[n],
00328 Primitive::Body | Primitive::Draw);
00329 pendular[n]->setPose(pose);
00330
00331 joint[n] = new SliderJoint(object[Base], pendular[n],
00332 p, Axis((n==0), (n==1), (n==2))*pose);
00333 joint[n]->init(odeHandle, osgHandle, false);
00334
00335 joint[n]->setParam ( dParamLoStop, -1.1*conf.diameter*conf.pendularrange );
00336 joint[n]->setParam ( dParamHiStop, 1.1*conf.diameter*conf.pendularrange );
00337 joint[n]->setParam ( dParamStopCFM, 0.1);
00338 joint[n]->setParam ( dParamStopERP, 0.9);
00339 joint[n]->setParam ( dParamCFM, 0.001);
00340 servo[n] = new SliderServo(joint[n],
00341 -conf.diameter*conf.pendularrange,
00342 conf.diameter*conf.pendularrange,
00343
00344 conf.pendularmass*conf.motorpowerfactor,0.1,0.5);
00345
00346 axis[n] = new OSGCylinder(conf.diameter/100, conf.diameter - conf.diameter/100);
00347 axis[n]->init(osgHandleX[n], OSGPrimitive::Low);
00348 }
00349 object[Pendular1] = pendular[0];
00350 object[Pendular2] = pendular[1];
00351 object[Pendular3] = pendular[2];
00352
00353 double sensorrange = conf.irsensorscale * conf.diameter;
00354 RaySensor::rayDrawMode drawMode = conf.drawIRs ? RaySensor::drawAll : RaySensor::drawSensor;
00355 double sensors_inside=0.02;
00356 if(conf.irSensorTempl==0){
00357 conf.irSensorTempl=new IRSensor(conf.irCharacter);
00358 }
00359 irSensorBank.init(odeHandle, osgHandle );
00360 if (conf.irAxis1){
00361 for(int i=-1; i<2; i+=2){
00362 RaySensor* sensor = conf.irSensorTempl->clone();
00363 Matrix R = Matrix::rotate(i*M_PI/2, 1, 0, 0) *
00364 Matrix::translate(0,-i*(conf.diameter/2-sensors_inside),0 );
00365 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00366 }
00367 }
00368 if (conf.irAxis2){
00369 for(int i=-1; i<2; i+=2){
00370 RaySensor* sensor = conf.irSensorTempl->clone();
00371 Matrix R = Matrix::rotate(i*M_PI/2, 0, 1, 0) *
00372 Matrix::translate(i*(conf.diameter/2-sensors_inside),0,0 );
00373
00374 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00375 }
00376 }
00377 if (conf.irAxis3){
00378 for(int i=-1; i<2; i+=2){
00379 RaySensor* sensor = conf.irSensorTempl->clone();
00380 Matrix R = Matrix::rotate( i==1 ? 0 : M_PI, 1, 0, 0) *
00381 Matrix::translate(0,0,i*(conf.diameter/2-sensors_inside));
00382 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00383 }
00384 }
00385 if (conf.irRing){
00386 for(double i=0; i<2*M_PI; i+=M_PI/6){
00387 RaySensor* sensor = conf.irSensorTempl->clone();
00388 Matrix R = Matrix::translate(0,0,conf.diameter/2-sensors_inside) *
00389 Matrix::rotate( i, 0, 1, 0);
00390 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00391 }
00392 }
00393 if (conf.irSide){
00394 for(double i=0; i<2*M_PI; i+=M_PI/2){
00395 RaySensor* sensor = conf.irSensorTempl->clone();
00396 Matrix R = Matrix::translate(0,0,conf.diameter/2-sensors_inside) *
00397 Matrix::rotate( M_PI/2-M_PI/8, 1, 0, 0) * Matrix::rotate( i, 0, 1, 0);
00398 irSensorBank.registerSensor(sensor, object[Base], R, sensorrange, drawMode);
00399 sensor = new IRSensor(conf.irCharacter);
00400 irSensorBank.registerSensor(sensor, object[Base],
00401 R * Matrix::rotate( M_PI, 0, 0, 1),
00402 sensorrange, drawMode);
00403 }
00404 }
00405
00406 FOREACH(list<Sensor*>, conf.sensors, i){
00407 (*i)->init(object[Base]);
00408 }
00409
00410 created=true;
00411 }
00412
00413
00414
00415
00416 void Sphererobot3Masses::destroy(){
00417 if (created){
00418 for (int i=0; i<servono; i++){
00419 if(joint[i]) delete joint[i];
00420 if(servo[i]) delete servo[i];
00421 if(axis[i]) delete axis[i];
00422 }
00423 for (int i=0; i<Last; i++){
00424 if(object[i]) delete object[i];
00425 }
00426 irSensorBank.clear();
00427 odeHandle.deleteSpace();
00428 }
00429 created=false;
00430 }
00431
00432 }