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 "Beobot/BeoBotSim.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     BeoBotSim *beoBotSim = (BeoBotSim *)data;
00053     const int MaxContacts = 10;
00054 
00055     
00056     dContact contact[MaxContacts];
00057     int nContacts = dCollide (o1,o2,MaxContacts,
00058         &contact[0].geom,sizeof(dContact));
00059     for (int i=0; i<nContacts; i++) {
00060       contact[i].surface.mode = dContactSoftCFM ; 
00061       contact[i].surface.mu = 0.5;
00062       contact[i].surface.mu2 = 0.5;
00063       contact[i].surface.bounce = 0.01;
00064       contact[i].surface.bounce_vel = 0.01;
00065       contact[i].surface.soft_cfm = 0.001;
00066 
00067       dJointID c = dJointCreateContact (beoBotSim->getWorld(),
00068           beoBotSim->getContactgroup(),&contact[i]);
00069       dJointAttach (c,
00070           dGeomGetBody(contact[i].geom.g1),
00071           dGeomGetBody(contact[i].geom.g2));
00072     }
00073   }
00074 }
00075 
00076 
00077 BeoBotSim::BeoBotSim(OptionManager& mgr, const std::string& descrName,
00078     const std::string& tagName, bool showWorld) :
00079   ModelComponent(mgr, descrName, tagName),
00080   itsCarLength(1.5), 
00081   itsCarWidth(2.0),
00082   itsCarWeight(30), 
00083 
00084 
00085   vp(new ViewPort("BeoBotSim")),
00086   itsSpeed(0),
00087   itsSteeringAng(0),
00088   itsWorldView(true),
00089   itsShowWorld(showWorld),
00090   itsWorldDisp(NULL)
00091 {
00092 
00093   if (itsShowWorld)
00094   {
00095     itsWorldDisp = new XWinManaged(vp->getDims(), -1, -1, "World View");
00096   }
00097 
00098   pthread_mutex_init(&itsDispLock, NULL);
00099 
00100 }
00101 
00102 BeoBotSim::~BeoBotSim()
00103 {
00104   dSpaceDestroy(space);
00105   dWorldDestroy(world);
00106 
00107   delete vp;
00108   delete itsWorldDisp;
00109   pthread_mutex_destroy(&itsDispLock);
00110 }
00111 
00112 void BeoBotSim::start2()
00113 {
00114   
00115   world = dWorldCreate();
00116   space = dHashSpaceCreate(0);
00117   contactgroup = dJointGroupCreate(0);
00118   ground = dCreatePlane(space, 0, 0, 1, 0);
00119   dWorldSetGravity(world,0,0,-9.8);
00120 
00121   dWorldSetCFM (world,1e-6);
00122   dWorldSetERP (world,1);
00123   
00124   dWorldSetContactMaxCorrectingVel (world,0.1);
00125   
00126   dWorldSetContactSurfaceLayer(world, 0.001);
00127 
00128 
00129   makeCar();
00130 
00131   
00132   double xyz[3] = {0 , -3.0, 15};
00133   double hpr[3] = {90.0,-45,0.0};
00134   vp->dsSetViewpoint (xyz,hpr);
00135 
00136 }
00137 
00138 void BeoBotSim::makeCar()
00139 {
00140   dMass mass;
00141   itsCarBody = dBodyCreate(world);
00142   dBodySetPosition(itsCarBody,0.66*5,4.33*5,1); 
00143 
00144   dMatrix3 R;
00145   dRFromAxisAndAngle (R,1,0,0,-M_PI/2);
00146   dBodySetRotation(itsCarBody, R);
00147   dMassSetZero(&mass);
00148   dMassSetCappedCylinderTotal(&mass,itsCarWeight,3,itsCarWidth,itsCarLength);
00149   dMassRotate(&mass, R);
00150   dBodySetMass(itsCarBody,&mass);
00151   itsCarGeom = dCreateCCylinder(space, itsCarWidth, itsCarLength);
00152   dGeomSetRotation(itsCarGeom, R);
00153   dGeomSetBody(itsCarGeom, itsCarBody);
00154 
00155 }
00156 
00157 void BeoBotSim::drawCar()
00158 {
00159   
00160   dReal r, length;
00161 
00162   dGeomCCylinderGetParams(itsCarGeom,&r,&length);
00163 
00164   vp->dsSetColor(1,1,0);
00165   vp->dsDrawCappedCylinder(
00166       dBodyGetPosition(itsCarBody),
00167       dBodyGetRotation(itsCarBody),
00168       length,
00169       r);
00170 
00171 }
00172 
00173 void BeoBotSim::drawArena()
00174 {
00175 
00176   double pos[3];
00177 
00178   pos[0] = 0; pos[1] = 1.0*5; pos[2] = 1.80;
00179   drawGate(pos);
00180 
00181   pos[0] = 0.16*5; pos[1] = 3.8*5; pos[2] = 1.83;
00182   drawBuoy(pos);
00183 
00184   pos[0] = 0.66*5; pos[1] = 4.33*5; pos[2] = 0.6;
00185   drawPipeline(0, pos);
00186 
00187   pos[0] = 1.16*5; pos[1] = 4.66*5; pos[2] = 0.6;
00188   drawBin(0, pos);
00189 
00190   pos[0] = 1.75*5; pos[1] = 4.91*5; pos[2] = 0.6;
00191   drawPipeline(M_PI/4, pos);
00192 
00193   pos[0] = 2.33*5; pos[1] = 5.41*5; pos[2] = 0.6;
00194   drawPipeline(0, pos);
00195 
00196   pos[0] = 3.0*5; pos[1] = 5.25*5; pos[2] = 0.6;
00197   drawPipeline(-M_PI/4, pos);
00198 
00199   pos[0] = 3.5*5; pos[1] = 4.083*5; pos[2] = 0.6;
00200   drawBin(M_PI/2, pos);
00201 
00202   pos[0] = 3.5*5; pos[1] = 4.083*5; pos[2] = 1.83;
00203   drawBuoy(pos);
00204 
00205   pos[0] = 3.83*5; pos[1] = 4.33*5; pos[2] = 0.6;
00206   drawPipeline(-M_PI/4, pos);
00207 
00208 
00209   pos[0] = 4.75*5; pos[1] = 3.5*5; pos[2] = 0.6;
00210   drawPinger(pos);
00211 }
00212 
00213 
00214 void BeoBotSim::drawGate(const double *gatePos)
00215 {
00216   double pos[3];
00217   double R[12];
00218   
00219   vp->dsSetColor(0,0,0);
00220   
00221   pos[0] = gatePos[0]; pos[1] = gatePos[1]; pos[2] = gatePos[2];
00222 
00223   dRFromAxisAndAngle (R,0,1,0,-M_PI/2);
00224   vp->dsDrawCappedCylinder(pos, R, 3.05f, 0.1f);
00225 
00226   
00227   dRSetIdentity(R);
00228   pos[0] = gatePos[0]-(3.05/2); pos[1] = gatePos[1]; pos[2] = gatePos[2]/2;
00229   vp->dsDrawCappedCylinder(pos, R, 1.83, 0.1);
00230 
00231   pos[0] = gatePos[0]+(3.05/2); pos[1] = gatePos[1]; pos[2] = gatePos[2]/2;
00232   vp->dsDrawCappedCylinder(pos, R, 1.83, 0.1);
00233 }
00234 
00235 
00236 void BeoBotSim::drawBuoy(const double *bouyPos)
00237 {
00238   static int frame = 0;
00239   static bool bouyOn = false;
00240   double pos[3];
00241   double R[12];
00242 
00243   
00244   
00245   if (frame++ > 5) 
00246   {
00247     bouyOn = !bouyOn;
00248     frame = 0;
00249   }
00250 
00251   if (bouyOn)
00252     vp->dsSetColor(1,0,0);
00253   else
00254     vp->dsSetColor(0.5,0,0);
00255   pos[0] = bouyPos[0]; pos[1] = bouyPos[1]; pos[2] = bouyPos[2];
00256   dRSetIdentity(R);
00257   vp->dsDrawSphere(pos, R, 0.20);
00258   double pos1[3];
00259   vp->dsSetColor(0,0,0);
00260   pos1[0] = pos[0]; pos1[1] = pos[1]; pos1[2] = 0;
00261   vp->dsDrawLine(pos, pos1);
00262 
00263 }
00264 
00265 void BeoBotSim::drawPipeline(const double ori, const double *pipePos)
00266 {
00267 
00268   double sides[3] = {1.2, 0.15, 0.1};
00269   double R[12];
00270 
00271   dRFromAxisAndAngle (R,0,0,1,ori);
00272 
00273   vp->dsSetColor(1,0.5,0);
00274 
00275   vp->dsDrawBox(pipePos, R, sides);
00276 }
00277 
00278 void BeoBotSim::drawBin(const double ori, const double *binPos)
00279 {
00280 
00281   double sides[3];
00282   double R[12];
00283 
00284   dRFromAxisAndAngle (R,0,0,1,ori);
00285 
00286   vp->dsSetColor(1,1,1);
00287   sides[0] = 0.6; sides[1] = 0.8; sides[2] = 0.1;
00288   vp->dsDrawBox(binPos, R, sides);
00289 
00290   vp->dsSetColor(0,0,0);
00291   sides[0] = 0.3; sides[1] = 0.6; sides[2] = 0.15;
00292   vp->dsDrawBox(binPos, R, sides);
00293 }
00294 
00295 void BeoBotSim::drawPinger(const double *pingerPos)
00296 {
00297   double pos[3];
00298   double R[12];
00299 
00300   vp->dsSetColor(1,1,1);
00301   pos[0] = pingerPos[0]; pos[1] = pingerPos[1]; pos[1] = pingerPos[2] + 1.2/2;
00302   vp->dsDrawCappedCylinder(pos, R, 1.2, 0.1);
00303 
00304 }
00305 
00306 
00307 void BeoBotSim::handleWinEvents(XEvent& event)
00308 {
00309 }
00310 
00311 
00312 void BeoBotSim::simLoop()
00313 {
00314 
00315   
00316   dBodyAddRelTorque(itsCarBody,0, itsSteeringAng, 0);
00317   dBodyAddRelForceAtRelPos(itsCarBody,0,0,itsSpeed, 0,0,0);
00318 
00319   
00320   
00321   
00322       
00323       
00324 
00325 
00326 
00327  dSpaceCollide (space,this,&nearCallback); 
00328  dWorldStep(world,0.1);
00329  dJointGroupEmpty (contactgroup); 
00330 
00331   if (itsShowWorld)
00332   {
00333     itsWorldDisp->drawImage(flipVertic(getFrame(0)));
00334   }
00335 }
00336 
00337 
00338 Image<PixRGB<byte> > BeoBotSim::getFrame(int camera)
00339 {
00340   const dReal *bodyPos = dBodyGetPosition(itsCarBody);
00341   const dReal *bodyR = dBodyGetRotation(itsCarBody);
00342 
00343   double cam_xyz[3], cam_hpr[3] = {0.0,0.0,0.0};
00344 
00345   switch (camera)
00346   {
00347     case 0: 
00348       cam_xyz[0] = bodyPos[0];
00349       cam_xyz[1] =  bodyPos[1]-5;
00350       cam_xyz[2] =  10;
00351 
00352       cam_hpr[0]   = 90.0;
00353       cam_hpr[1]   = -45.0;
00354       cam_hpr[2]   = 0.0;
00355 
00356       break;
00357     case 1:
00358       cam_xyz[0] = bodyPos[0];
00359       cam_xyz[1] = bodyPos[1];
00360       cam_xyz[2] = bodyPos[2];
00361 
00362       cam_hpr[0]   = (atan2(bodyR[4], bodyR[0])*180/M_PI) + 90; 
00363 
00364       break;
00365     case 2:
00366       cam_xyz[0] = bodyPos[0];
00367       cam_xyz[1] = bodyPos[1];
00368       cam_xyz[2] = bodyPos[2];
00369 
00370       cam_hpr[0]   = (atan2(bodyR[4], bodyR[0])*180/M_PI) + 90; 
00371           
00372 
00373 
00374       break;
00375   }
00376   pthread_mutex_lock(&itsDispLock);
00377   if (camera != -1)
00378     vp->dsSetViewpoint (cam_xyz,cam_hpr);
00379   vp->initFrame();
00380   drawCar();
00381   drawArena();
00382   vp->updateFrame();
00383   pthread_mutex_unlock(&itsDispLock);
00384 
00385 
00386   return vp->getFrame();
00387 
00388 }
00389 
00390 
00391 void BeoBotSim::setSpeed(float spd)
00392 {
00393     itsSpeed = spd;
00394 
00395 }
00396 
00397 void BeoBotSim::setSteering(float angle)
00398 {
00399     itsSteeringAng = angle;
00400 
00401 }
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412