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 #include "Robots/IRobot/IRobotSim.H"
00039 #include "Component/OptionManager.H"
00040 #include "Util/MathFunctions.H"
00041 #include "Util/Assert.H"
00042 #include "rutz/compat_snprintf.h"
00043 #include "Image/MatrixOps.H"
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <signal.h>
00047
00048
00049 namespace {
00050
00051 void nearCallback (void *data, dGeomID o1, dGeomID o2){
00052 IRobotSim *iRobotSim = (IRobotSim *)data;
00053 const int MaxContacts = 10;
00054
00055 double surface_mu = dInfinity;
00056
00057
00058 if ((o1 == iRobotSim->getRobotGeom() && o2 == iRobotSim->getGroundGeom()) ||
00059 (o2 == iRobotSim->getRobotGeom() && o1 == iRobotSim->getGroundGeom()))
00060 return;
00061
00062
00063 if (o1 == iRobotSim->getCasterGeom() || o2 == iRobotSim->getCasterGeom())
00064 surface_mu = 0;
00065
00066
00067
00068 dContact contact[MaxContacts];
00069 int nContacts = dCollide (o1,o2,MaxContacts,
00070 &contact[0].geom,sizeof(dContact));
00071 for (int i=0; i<nContacts; i++) {
00072
00073 contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
00074 dContactSoftERP | dContactSoftCFM | dContactApprox1;
00075 contact[i].surface.mu = surface_mu;
00076 contact[i].surface.slip1 = 0.1;
00077 contact[i].surface.slip2 = 0.1;
00078 contact[i].surface.soft_erp = 0.005;
00079 contact[i].surface.soft_cfm = 0.003;
00080
00081 dJointID c = dJointCreateContact (iRobotSim->getWorld(),
00082 iRobotSim->getContactgroup(),&contact[i]);
00083 dJointAttach (c,
00084 dGeomGetBody(contact[i].geom.g1),
00085 dGeomGetBody(contact[i].geom.g2));
00086 }
00087 }
00088 }
00089
00090
00091 IRobotSim::IRobotSim(OptionManager& mgr, const std::string& descrName,
00092 const std::string& tagName, bool showWorld) :
00093 ModelComponent(mgr, descrName, tagName),
00094 itsRobotStartZ(0.3),
00095 itsRobotRadius(0.33),
00096 itsRobotHeight(0.06),
00097 itsRobotWeight(1),
00098 itsRobotWheelRadius(0.02),
00099 itsRightWheelSpeed(0),
00100 itsLeftWheelSpeed(0),
00101 itsXPos(0),
00102 itsYPos(0),
00103 itsOri(0),
00104 itsRightEncoder(0),
00105 itsLeftEncoder(0),
00106 itsPrevRightWheelAng(0),
00107 itsPrevLeftWheelAng(0),
00108 itsWorldView(true),
00109 itsShowWorld(showWorld),
00110 itsWorldDisp(NULL)
00111 {
00112 pthread_mutex_init(&itsDispLock, NULL);
00113
00114 }
00115
00116 IRobotSim::~IRobotSim()
00117 {
00118 for(uint i=0; i<itsObjects.size(); i++)
00119 {
00120 Object obj = itsObjects[i];
00121 if (obj.texturePtr)
00122 delete obj.texturePtr;
00123 }
00124
00125 dSpaceDestroy(space);
00126 dWorldDestroy(world);
00127
00128 delete itsVP;
00129 delete itsWorldDisp;
00130 pthread_mutex_destroy(&itsDispLock);
00131 }
00132
00133 void IRobotSim::start2()
00134 {
00135
00136 world = dWorldCreate();
00137 space = dHashSpaceCreate(0);
00138 contactgroup = dJointGroupCreate(0);
00139 dWorldSetGravity(world,0,0,-0.5);
00140
00141 ground = dCreatePlane(space, 0, 0, 1, 0);
00142 dGeomSetCategoryBits(ground, GROUND_BITFIELD);
00143
00144
00145
00146
00147 dWorldSetContactMaxCorrectingVel (world,0.1);
00148
00149 dWorldSetContactSurfaceLayer(world, 0.0001);
00150
00151
00152
00153 }
00154
00155 void IRobotSim::initViewport()
00156 {
00157 itsVP = new ViewPort("IRobotSim", "grass.ppm", "sky.ppm");
00158
00159 makeRobot();
00160 makeWorld();
00161
00162
00163
00164
00165
00166 double xyz[3] = {0.6 , -1.5, 2};
00167 double hpr[3] = {90.0,-25,0.0};
00168 itsVP->dsSetViewpoint (xyz,hpr);
00169 }
00170
00171 void IRobotSim::makeRobot()
00172 {
00173 dMass mass;
00174
00175
00176 itsRobotBody = dBodyCreate(world);
00177 dMassSetZero(&mass);
00178 dMassSetCylinder(&mass,itsRobotWeight,3,itsRobotRadius,itsRobotHeight);
00179 dMassAdjust(&mass, itsRobotWeight);
00180 dBodySetMass(itsRobotBody,&mass);
00181
00182 dBodySetPosition(itsRobotBody,0,0,itsRobotStartZ);
00183 itsRobotGeom = dCreateCCylinder(space, itsRobotRadius, itsRobotHeight);
00184 dGeomSetBody(itsRobotGeom, itsRobotBody);
00185
00186
00187
00188
00189 dQuaternion q;
00190 dQFromAxisAndAngle (q,1,0,0,M_PI*0.5);
00191 dMassSetSphere (&mass,1,itsRobotWheelRadius);
00192 dMassAdjust (&mass,0.2);
00193
00194 itsRightWheelBody = dBodyCreate (world);
00195 dBodySetQuaternion (itsRightWheelBody,q);
00196 dBodySetMass (itsRightWheelBody,&mass);
00197 dGeomID rWheelSphere = dCreateSphere (space,itsRobotWheelRadius);
00198 dGeomSetBody (rWheelSphere,itsRightWheelBody);
00199 dBodySetPosition (itsRightWheelBody,-itsRobotRadius/2, itsRobotRadius,itsRobotStartZ-itsRobotHeight-0.01);
00200
00201
00202
00203 itsLeftWheelBody = dBodyCreate (world);
00204 dBodySetQuaternion (itsLeftWheelBody,q);
00205 dBodySetMass (itsLeftWheelBody,&mass);
00206 dGeomID lWheelSphere = dCreateSphere (space,itsRobotWheelRadius);
00207 dGeomSetBody (lWheelSphere,itsLeftWheelBody);
00208 dBodySetPosition (itsLeftWheelBody,-itsRobotRadius/2, -itsRobotRadius,itsRobotStartZ-itsRobotHeight-0.01);
00209
00210
00211
00212
00213 itsRightWheelJoint = dJointCreateHinge2 (world,0);
00214 dJointAttach (itsRightWheelJoint,itsRobotBody,itsRightWheelBody);
00215 const dReal *rWheelPos = dBodyGetPosition (itsRightWheelBody);
00216 dJointSetHinge2Anchor (itsRightWheelJoint,rWheelPos[0],rWheelPos[1],rWheelPos[2]);
00217 dJointSetHinge2Axis1 (itsRightWheelJoint,0,0,1);
00218 dJointSetHinge2Axis2 (itsRightWheelJoint,0,1,0);
00219
00220 dJointSetHinge2Param (itsRightWheelJoint,dParamSuspensionERP,0.002);
00221 dJointSetHinge2Param (itsRightWheelJoint,dParamSuspensionCFM,0.004);
00222
00223
00224
00225 dJointSetHinge2Param (itsRightWheelJoint,dParamLoStop,0);
00226 dJointSetHinge2Param (itsRightWheelJoint,dParamHiStop,0);
00227
00228 itsLeftWheelJoint = dJointCreateHinge2 (world,0);
00229 dJointAttach (itsLeftWheelJoint,itsRobotBody,itsLeftWheelBody);
00230 const dReal *lWheelPos = dBodyGetPosition (itsLeftWheelBody);
00231 dJointSetHinge2Anchor (itsLeftWheelJoint,lWheelPos[0],lWheelPos[1],lWheelPos[2]);
00232 dJointSetHinge2Axis1 (itsLeftWheelJoint,0,0,1);
00233 dJointSetHinge2Axis2 (itsLeftWheelJoint,0,1,0);
00234
00235 dJointSetHinge2Param (itsLeftWheelJoint,dParamSuspensionERP,0.002);
00236 dJointSetHinge2Param (itsLeftWheelJoint,dParamSuspensionCFM,0.004);
00237
00238
00239
00240 dJointSetHinge2Param (itsLeftWheelJoint,dParamLoStop,0);
00241 dJointSetHinge2Param (itsLeftWheelJoint,dParamHiStop,0);
00242
00243
00244
00245 dQFromAxisAndAngle (q,1,0,0,M_PI*0.5);
00246 dMassSetSphere (&mass,1,itsRobotWheelRadius);
00247 dMassAdjust (&mass,0.2);
00248
00249 itsCasterBody = dBodyCreate (world);
00250 dBodySetQuaternion (itsCasterBody,q);
00251 dBodySetMass (itsCasterBody,&mass);
00252 dGeomID itsCasterGeom = dCreateSphere (space,itsRobotWheelRadius);
00253 dGeomSetBody (itsCasterGeom,itsCasterBody);
00254 dBodySetPosition (itsCasterBody,itsRobotRadius, 0, itsRobotStartZ-itsRobotHeight-0.01);
00255
00256
00257
00258 dJointID casterJoint = dJointCreateHinge2 (world,0);
00259 dJointAttach (casterJoint,itsRobotBody,itsCasterBody);
00260 const dReal *casterPos = dBodyGetPosition (itsCasterBody);
00261 dJointSetHinge2Anchor (casterJoint,casterPos[0],casterPos[1],casterPos[2]);
00262 dJointSetHinge2Axis1 (casterJoint,0,0,1);
00263 dJointSetHinge2Axis2 (casterJoint,0,1,0);
00264
00265 dJointSetHinge2Param (casterJoint,dParamSuspensionERP,0.00002);
00266 dJointSetHinge2Param (casterJoint,dParamSuspensionCFM,0.00004);
00267 dJointSetHinge2Param (casterJoint,dParamLoStop,0);
00268 dJointSetHinge2Param (casterJoint,dParamHiStop,0);
00269
00270 }
00271
00272 void IRobotSim::drawRobot()
00273 {
00274
00275 dReal r, length;
00276
00277 dGeomCCylinderGetParams(itsRobotGeom,&r,&length);
00278
00279 itsVP->dsSetColor(1,1,0);
00280
00281
00282 itsVP->dsDrawCylinder(
00283 dBodyGetPosition(itsRobotBody),
00284 dBodyGetRotation(itsRobotBody),
00285 length,
00286 r);
00287
00288
00289 itsVP->dsSetColor(0,0,0);
00290 itsVP->dsDrawCylinder (dBodyGetPosition(itsRightWheelBody),
00291 dBodyGetRotation(itsRightWheelBody),0.02f,itsRobotWheelRadius);
00292 itsVP->dsDrawCylinder (dBodyGetPosition(itsLeftWheelBody),
00293 dBodyGetRotation(itsLeftWheelBody),0.02f,itsRobotWheelRadius);
00294
00295
00296 itsVP->dsDrawSphere (dBodyGetPosition(itsCasterBody),
00297 dBodyGetRotation(itsCasterBody),itsRobotWheelRadius);
00298
00299 }
00300
00301
00302 void IRobotSim::makeWorld()
00303 {
00304
00305 initRandomNumbersZero();
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 double initPos[3] = { -25.0, 25.0, 0.0};
00320 double objSize[3] = { 2, 2, 2};
00321 addObject(TOBJ, initPos, objSize, true, "./etc/textures/detail040.ppm");
00322
00323 initPos[0] = -5; initPos[1] = 16; initPos[2] = 0;
00324 objSize[0] = 3; objSize[1] = 2; objSize[2] = 5;
00325 addObject(TOBJ, initPos, objSize, true, "./etc/textures/build123.ppm");
00326
00327 initPos[0] = -7; initPos[1] = 7; initPos[2] = 0;
00328 objSize[0] = 6; objSize[1] = 4; objSize[2] = 10;
00329 addObject(TOBJ, initPos, objSize, true, "./etc/textures/build123.ppm");
00330
00331 initPos[0] = 5; initPos[1] = 10; initPos[2] = 0;
00332 objSize[0] = 3; objSize[1] = 2; objSize[2] = 5;
00333 addObject(TOBJ, initPos, objSize, true, "./etc/textures/build085.ppm");
00334
00335 initPos[0] = -5; initPos[1] = -5; initPos[2] = 0;
00336 objSize[0] = 3; objSize[1] = 2; objSize[2] = 5;
00337 addObject(TOBJ, initPos, objSize, true, "./etc/textures/build085.ppm");
00338
00339 initPos[0] = 5; initPos[1] = -10; initPos[2] = 0;
00340 objSize[0] = 3; objSize[1] = 2; objSize[2] = 5;
00341 addObject(TOBJ, initPos, objSize, true, "./etc/textures/brick.ppm");
00342
00343
00344
00345 objSize[0] = 0.1; objSize[1] = 3.5; objSize[2] = 0;
00346
00347 initPos[0] = 0.0; initPos[1] = 0.0; initPos[2] = 0;
00348 addObject(TREE, initPos, objSize, false);
00349
00350 initPos[0] = -1800/100; initPos[1] = 200/100; initPos[2] = 0;
00351 addObject(TREE, initPos, objSize, false);
00352
00353 initPos[0] = -1800/100; initPos[1] = 2300/100; initPos[2] = 0;
00354 addObject(TREE, initPos, objSize, false);
00355
00356 initPos[0] = 400/100; initPos[1] = 1800/100; initPos[2] = 0;
00357 addObject(TREE, initPos, objSize, false);
00358
00359 }
00360
00361 void IRobotSim::addObject(OBJECT_TYPE objType,
00362 double initPos[3],double objSize[3],
00363 bool addToSpace,
00364 const char* texture)
00365 {
00366
00367 dMass m;
00368
00369 Object obj;
00370 obj.body = dBodyCreate(world);
00371 obj.texturePtr = NULL;
00372
00373 dSpaceID spaceToAdd = 0;
00374 if (addToSpace)
00375 spaceToAdd = space;
00376
00377 switch(objType)
00378 {
00379 case BOX:
00380 dMassSetZero(&m);
00381 dMassSetBoxTotal(&m, 1, objSize[0], objSize[1], objSize[2]);
00382 dBodySetMass(obj.body, &m);
00383 obj.geom = dCreateBox(spaceToAdd, objSize[0], objSize[1], objSize[2]);
00384 dBodySetPosition(obj.body, initPos[0], initPos[1], initPos[2]);
00385 dGeomSetBody(obj.geom, obj.body);
00386 obj.color[0] = 0; obj.color[1] = 196; obj.color[2] = 127;
00387 obj.texture = ViewPort::WOOD;
00388 obj.type = BOX;
00389 break;
00390 case TREE:
00391 obj.geom = dCreateCCylinder(spaceToAdd, objSize[0], objSize[1]);
00392 dGeomSetBody(obj.geom, 0);
00393 dGeomSetPosition(obj.geom, initPos[0], initPos[1], initPos[2]);
00394 obj.texture = ViewPort::WOOD;
00395 obj.color[0] = 0.543; obj.color[1] = 0.270; obj.color[2] = 0.074;
00396 obj.type = TREE;
00397 break;
00398 case DS:
00399 itsVP->load3DSObject(obj.object, "./tests/spaceship.3ds");
00400 obj.object.scale = 0.01;
00401 obj.texture = ViewPort::OTHER;
00402 obj.texturePtr = new Texture("./etc/textures/spaceshiptexture.ppm");
00403 obj.geom = dCreateBox(spaceToAdd, objSize[0], objSize[1], objSize[2]);
00404 dGeomSetBody(obj.geom, 0);
00405 dGeomSetPosition(obj.geom, initPos[0], initPos[1], initPos[2]);
00406 obj.color[0] = 1.0; obj.color[1] = 1.0; obj.color[2] = 1.0;
00407 obj.type = DS;
00408 break;
00409 case TOBJ:
00410 sprintf(obj.object.name, "Textured Object");
00411 obj.object.vertices_qty = 8;
00412 obj.object.vertex.resize(8);
00413 obj.object.vertex[0] = ViewPort::vertex_type(0, 0, objSize[2]);
00414 obj.object.vertex[1] = ViewPort::vertex_type( objSize[0], 0, objSize[2]);
00415 obj.object.vertex[2] = ViewPort::vertex_type( objSize[0], 0, 0);
00416 obj.object.vertex[3] = ViewPort::vertex_type( 0, 0, 0);
00417
00418 obj.object.vertex[4] = ViewPort::vertex_type( 0, objSize[1], objSize[2]);
00419 obj.object.vertex[5] = ViewPort::vertex_type( objSize[0], objSize[1], objSize[2]);
00420 obj.object.vertex[6] = ViewPort::vertex_type( objSize[0], objSize[1], 0);
00421 obj.object.vertex[7] = ViewPort::vertex_type( 0, objSize[1], 0);
00422
00423
00424 obj.object.polygons_qty = 12;
00425 obj.object.polygon.resize(12);
00426 obj.object.polygon[0] = ViewPort::polygon_type(0, 1, 4);
00427 obj.object.polygon[1] = ViewPort::polygon_type(1, 5, 4);
00428 obj.object.polygon[2] = ViewPort::polygon_type(1, 2, 5);
00429 obj.object.polygon[3] = ViewPort::polygon_type(2, 6, 5);
00430 obj.object.polygon[4] = ViewPort::polygon_type(2, 3, 6);
00431 obj.object.polygon[5] = ViewPort::polygon_type(3, 7, 6);
00432 obj.object.polygon[6] = ViewPort::polygon_type(3, 0, 7);
00433 obj.object.polygon[7] = ViewPort::polygon_type(0, 4, 7);
00434 obj.object.polygon[8] = ViewPort::polygon_type(4, 5, 7);
00435 obj.object.polygon[9] = ViewPort::polygon_type(5, 6, 7);
00436 obj.object.polygon[10] = ViewPort::polygon_type(3, 2, 0);
00437 obj.object.polygon[11] = ViewPort::polygon_type(2, 1, 0);
00438
00439 obj.object.mapcoord.resize(8);
00440 obj.object.mapcoord[0] = ViewPort::mapcoord_type(0.0, 0.0);
00441 obj.object.mapcoord[1] = ViewPort::mapcoord_type(1.0, 0.0);
00442 obj.object.mapcoord[2] = ViewPort::mapcoord_type(1.0, 1.0);
00443 obj.object.mapcoord[3] = ViewPort::mapcoord_type(0.0, 1.0);
00444 obj.object.mapcoord[4] = ViewPort::mapcoord_type(0.0, 0.0);
00445 obj.object.mapcoord[5] = ViewPort::mapcoord_type(0.0, 1.0);
00446 obj.object.mapcoord[6] = ViewPort::mapcoord_type(1.0, 1.0);
00447 obj.object.mapcoord[7] = ViewPort::mapcoord_type(0.0, 1.0);
00448
00449
00450 obj.object.scale = 1;
00451 if (texture)
00452 {
00453 obj.texture = ViewPort::OTHER;
00454 obj.texturePtr = new Texture(texture);
00455 }
00456 obj.geom = dCreateBox(spaceToAdd, objSize[0], objSize[1], objSize[2]);
00457 dGeomSetBody(obj.geom, 0);
00458 dGeomSetPosition(obj.geom, initPos[0], initPos[1], initPos[2]);
00459 obj.color[0] = 256; obj.color[1] = 256; obj.color[2] = 256;
00460 obj.type = DS;
00461 break;
00462
00463
00464 default:
00465 LINFO("Unknown object");
00466 break;
00467 }
00468 itsObjects.push_back(obj);
00469
00470
00471 }
00472
00473
00474
00475 void IRobotSim::drawWorld()
00476 {
00477
00478 for(uint i=0; i<itsObjects.size(); i++)
00479 {
00480 Object obj = itsObjects[i];
00481
00482 itsVP->dsSetColor(obj.color[0],obj.color[1],obj.color[2]);
00483
00484 itsVP->dsSetTexture(obj.texture, obj.texturePtr);
00485
00486 const dReal *bodyPos = dGeomGetPosition(obj.geom);
00487 const dReal *bodyRot = dGeomGetRotation(obj.geom);
00488
00489 switch(obj.type)
00490 {
00491 case BOX:
00492 dReal size[3];
00493 dGeomBoxGetLengths(obj.geom,size);
00494 itsVP->dsDrawBox(bodyPos, bodyRot, size);
00495 break;
00496 case TREE:
00497 dReal r, length;
00498 dGeomCCylinderGetParams(obj.geom,&r,&length);
00499
00500
00501
00502 dReal pos[3];
00503 pos[0] = bodyPos[0];
00504 pos[1] = bodyPos[1];
00505 pos[2] = bodyPos[2] - r;
00506
00507 itsVP->dsDrawCylinder(pos, bodyRot, length, r);
00508
00509
00510 pos[2] = bodyPos[2] + length/2;
00511
00512 itsVP->dsSetTexture(ViewPort::TREE);
00513 itsVP->dsSetColor(0,1,0);
00514 itsVP->dsDrawSphere (pos,
00515 dBodyGetRotation(obj.body),r*4);
00516
00517 break;
00518 case DS:
00519 case TOBJ:
00520 itsVP->dsDraw3DSObject(bodyPos, bodyRot, obj.object);
00521 break;
00522
00523 default:
00524 break;
00525 }
00526 }
00527 }
00528
00529 void IRobotSim::handleWinEvents(XEvent& event)
00530 {
00531 }
00532
00533 void IRobotSim::updateSensors()
00534 {
00535
00536
00537 const dReal *pos = dBodyGetPosition(itsRobotBody);
00538 const dReal *R = dBodyGetRotation(itsRobotBody);
00539
00540 itsXPos = pos[0];
00541 itsYPos = pos[1];
00542 itsOri = atan2(R[4], R[0]);
00543 if (itsOri < 0) itsOri += M_PI*2;
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 }
00571
00572 void IRobotSim::simLoop()
00573 {
00574
00575
00576 dJointSetHinge2Param (itsRightWheelJoint,dParamVel2,itsRightWheelSpeed);
00577 dJointSetHinge2Param (itsRightWheelJoint,dParamFMax2,0.5);
00578
00579 dJointSetHinge2Param (itsLeftWheelJoint,dParamVel2,itsLeftWheelSpeed);
00580 dJointSetHinge2Param (itsLeftWheelJoint,dParamFMax2,0.5);
00581
00582
00583 updateSensors();
00584
00585 dSpaceCollide (space,this,&nearCallback);
00586
00587 dWorldStep(world,0.1);
00588
00589 dJointGroupEmpty (contactgroup);
00590
00591 if (itsShowWorld)
00592 {
00593 itsWorldDisp->drawImage(flipVertic(getFrame(0)));
00594 }
00595 }
00596
00597
00598 Image<PixRGB<byte> > IRobotSim::getFrame(int camera)
00599 {
00600 const dReal *bodyPos = dBodyGetPosition(itsRobotBody);
00601 const dReal *bodyR = dBodyGetRotation(itsRobotBody);
00602
00603 double cam_xyz[3], cam_hpr[3] = {0.0,0.0,0.0};
00604
00605 switch (camera)
00606 {
00607 case 0:
00608 cam_xyz[0] = 0;
00609 cam_xyz[1] = 0;
00610 cam_xyz[2] = 40;
00611
00612 cam_hpr[0] = 90.0;
00613 cam_hpr[1] = -90.0;
00614 cam_hpr[2] = 0.0;
00615
00616 break;
00617 case 1:
00618 cam_xyz[0] = bodyPos[0];
00619 cam_xyz[1] = bodyPos[1];
00620 cam_xyz[2] = bodyPos[2] + 1;
00621
00622 cam_hpr[0] = (atan2(bodyR[4], bodyR[0])*180/M_PI) + 180;
00623
00624 break;
00625 case 2:
00626 cam_xyz[0] = bodyPos[0];
00627 cam_xyz[1] = bodyPos[1];
00628 cam_xyz[2] = bodyPos[2];
00629
00630 cam_hpr[0] = (atan2(bodyR[4], bodyR[0])*180/M_PI) + 90;
00631 cam_hpr[1] = -90;
00632
00633
00634 break;
00635 }
00636 pthread_mutex_lock(&itsDispLock);
00637 if (camera != -1)
00638 itsVP->dsSetViewpoint (cam_xyz,cam_hpr);
00639 itsVP->initFrame();
00640 drawRobot();
00641 drawWorld();
00642 itsVP->updateFrame();
00643 pthread_mutex_unlock(&itsDispLock);
00644
00645
00646 return itsVP->getFrame();
00647
00648 }
00649
00650 void IRobotSim::getSensors(float &xPos, float &yPos, float &ori)
00651 {
00652 xPos = itsXPos;
00653 yPos = itsYPos;
00654 ori = itsOri;
00655
00656 if (false)
00657 {
00658
00659 int idum = getIdum();
00660 xPos += gasdev(idum)*0.5;
00661 yPos += gasdev(idum)*0.5;
00662 ori += gasdev(idum)*0.2;
00663 }
00664 }
00665
00666 void IRobotSim::setMotors(double rightSpeed, double leftSpeed)
00667 {
00668 itsRightWheelSpeed = rightSpeed;
00669 itsLeftWheelSpeed = leftSpeed;
00670 }
00671
00672
00673
00674
00675
00676