IRobotSim.C

Go to the documentation of this file.
00001 /*!@file Robots/IRobot/IRobotSim.C IRobot Simulator */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL $
00035 // $Id $
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     //Dont colide the robot with the ground
00058     if ((o1 == iRobotSim->getRobotGeom() && o2 == iRobotSim->getGroundGeom()) ||
00059         (o2 == iRobotSim->getRobotGeom() && o1 == iRobotSim->getGroundGeom()))
00060       return;
00061 
00062     //If we are contacted with a castor, then set the contact to slip
00063     if (o1 == iRobotSim->getCasterGeom() || o2 == iRobotSim->getCasterGeom())
00064       surface_mu = 0;
00065 
00066 
00067     //create a contact joint to simulate collisions
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       //contact[i].surface.mode = dContactSoftCFM ; //| dContactBounce; // | dContactSoftCFM;
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), //the start loc of the robot
00095   itsRobotRadius(0.33), //the radius of the sub in meters
00096   itsRobotHeight(0.06), //the radius of the sub in meters
00097   itsRobotWeight(1), // the weight of the sub in kg
00098   itsRobotWheelRadius(0.02), // the wheel size
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   //        setDrawStuff();
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   //dWorldSetCFM (world,1e-6);
00145   //dWorldSetERP (world,1);
00146   //dWorldSetAutoDisableFlag (world,1);
00147   dWorldSetContactMaxCorrectingVel (world,0.1);
00148   //set the contact penetration
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   //Overhead cam
00163   //double xyz[3] = {0 , 0, 40};
00164   //double hpr[3] = {90.0,-90,0.0};
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   //The body
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   //dGeomSetCategoryBits(itsRobotGeom,ROBOT_BITFIELD);
00186   //dGeomSetCollideBits(itsRobotGeom,!ROBOT_BITFIELD && !GROUND_BITFIELD); //don't colide with the ground
00187 
00188   // wheel bodies
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   //dGeomSetCategoryBits(rWheelSphere,ROBOT_BITFIELD);
00201   //dGeomSetCollideBits(rWheelSphere,!ROBOT_BITFIELD); //don't colide with the Robot
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   //dGeomSetCategoryBits(lWheelSphere,ROBOT_BITFIELD);
00210   //dGeomSetCollideBits(lWheelSphere,!ROBOT_BITFIELD); //don't colide with the Robot
00211 
00212   //Wheel hinges
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   // set joint suspension
00220   dJointSetHinge2Param (itsRightWheelJoint,dParamSuspensionERP,0.002);
00221   dJointSetHinge2Param (itsRightWheelJoint,dParamSuspensionCFM,0.004);
00222 
00223   // lock all wheels along the steering axis
00224   // set stops to make sure wheels always stay in alignment
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   // set joint suspension
00235   dJointSetHinge2Param (itsLeftWheelJoint,dParamSuspensionERP,0.002);
00236   dJointSetHinge2Param (itsLeftWheelJoint,dParamSuspensionCFM,0.004);
00237 
00238   // lock all wheels along the steering axis
00239   // set stops to make sure wheels always stay in alignment
00240   dJointSetHinge2Param (itsLeftWheelJoint,dParamLoStop,0);
00241   dJointSetHinge2Param (itsLeftWheelJoint,dParamHiStop,0);
00242 
00243 
00244   //Create the castor
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   //dGeomSetCategoryBits(itsCasterGeom,ROBOT_BITFIELD);
00256   //dGeomSetCollideBits(itsCasterGeom,!ROBOT_BITFIELD); //don't colide with the Robot
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   // set joint suspension
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   //double r, length;
00275   dReal r, length;
00276 
00277   dGeomCCylinderGetParams(itsRobotGeom,&r,&length);
00278 
00279   itsVP->dsSetColor(1,1,0);
00280 
00281   //Draw Body
00282   itsVP->dsDrawCylinder(
00283       dBodyGetPosition(itsRobotBody),
00284       dBodyGetRotation(itsRobotBody),
00285       length,
00286       r);
00287 
00288   //Draw Wheels
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   //Draw Caster
00296   itsVP->dsDrawSphere (dBodyGetPosition(itsCasterBody),
00297       dBodyGetRotation(itsCasterBody),itsRobotWheelRadius);
00298 
00299 }
00300 
00301 
00302 void IRobotSim::makeWorld()
00303 {
00304 
00305   initRandomNumbersZero();
00306 
00307   //Draw 50 random trees
00308   //for(int i=0; i<50; i++)
00309   //{
00310   //  double initPos[3] = { 0, 0, 0};
00311   //  double objSize[3] = { 0.20, 3.5, 0.0};
00312 
00313   //  initPos[0] = (randomDouble()*50-25) + 2;
00314   //  initPos[1] = (randomDouble()*50-25) + 2;
00315 
00316   //  addObject(TREE, initPos, objSize);
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   //Place trees at waypoints
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; //1 0 0 Red object
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; //1 0 0 Red object
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; //1 0 0 Red object
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]); //, // vertex v0
00414       obj.object.vertex[1] = ViewPort::vertex_type( objSize[0], 0, objSize[2]); // vertex v1
00415       obj.object.vertex[2] = ViewPort::vertex_type( objSize[0], 0, 0); // vertex v2
00416       obj.object.vertex[3] = ViewPort::vertex_type( 0, 0, 0); // vertex v3
00417 
00418       obj.object.vertex[4] = ViewPort::vertex_type( 0, objSize[1], objSize[2]); // vertex v4
00419       obj.object.vertex[5] = ViewPort::vertex_type( objSize[0], objSize[1], objSize[2]); // vertex v5
00420       obj.object.vertex[6] = ViewPort::vertex_type( objSize[0], objSize[1], 0); // vertex v6
00421       obj.object.vertex[7] = ViewPort::vertex_type( 0, objSize[1], 0); // vertex v7
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); // polygon v0,v1,v4
00427       obj.object.polygon[1] = ViewPort::polygon_type(1, 5, 4); // polygon v1,v5,v4
00428       obj.object.polygon[2] = ViewPort::polygon_type(1, 2, 5); // polygon v1,v2,v5
00429       obj.object.polygon[3] = ViewPort::polygon_type(2, 6, 5); // polygon v2,v6,v5
00430       obj.object.polygon[4] = ViewPort::polygon_type(2, 3, 6); // polygon v2,v3,v6
00431       obj.object.polygon[5] = ViewPort::polygon_type(3, 7, 6); // polygon v3,v7,v6
00432       obj.object.polygon[6] = ViewPort::polygon_type(3, 0, 7); // polygon v3,v0,v7
00433       obj.object.polygon[7] = ViewPort::polygon_type(0, 4, 7); // polygon v0,v4,v7
00434       obj.object.polygon[8] = ViewPort::polygon_type(4, 5, 7); // polygon v4,v5,v7
00435       obj.object.polygon[9] = ViewPort::polygon_type(5, 6, 7); // polygon v5,v6,v7
00436       obj.object.polygon[10] = ViewPort::polygon_type(3, 2, 0); // polygon v3,v2,v0
00437       obj.object.polygon[11] = ViewPort::polygon_type(2, 1, 0); // polygon v2,v1,v0
00438 
00439       obj.object.mapcoord.resize(8);
00440       obj.object.mapcoord[0] = ViewPort::mapcoord_type(0.0, 0.0); // mapping coordinates for vertex v0
00441       obj.object.mapcoord[1] = ViewPort::mapcoord_type(1.0, 0.0); // mapping coordinates for vertex v1
00442       obj.object.mapcoord[2] = ViewPort::mapcoord_type(1.0, 1.0); // mapping coordinates for vertex v2
00443       obj.object.mapcoord[3] = ViewPort::mapcoord_type(0.0, 1.0); // mapping coordinates for vertex v3
00444       obj.object.mapcoord[4] = ViewPort::mapcoord_type(0.0, 0.0); // mapping coordinates for vertex v4
00445       obj.object.mapcoord[5] = ViewPort::mapcoord_type(0.0, 1.0); // mapping coordinates for vertex v5
00446       obj.object.mapcoord[6] = ViewPort::mapcoord_type(1.0, 1.0); // mapping coordinates for vertex v6
00447       obj.object.mapcoord[7] = ViewPort::mapcoord_type(0.0, 1.0); // mapping coordinates for vertex v7
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         //Move the cylinder down by the r since its a capted cylinder
00501         //The cap cylinder is used wince its is more stable
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         //Draw the top of the tree
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   //GPS sensor update
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]);      //greek Y
00543   if (itsOri < 0) itsOri += M_PI*2;
00544 
00545 
00546 
00547   //Encoder sensors
00548 //itsRoll  = atan2(R[9], R[10]) + M_PI/2;     //phi correct for initial rotation
00549 //  itsPitch = asin(-R[8]);            //theta
00550 //  itsYaw   = atan2(R[4], R[0]);
00551 //  const dReal *rightR = dBodyGetRotation(itsRightWheelBody);
00552 //  //const dReal *leftR = dBodyGetRotation(itsLeftWheelBody);
00553 //
00554 //  int rightWheelAng = (int)((asin(-rightR[8]) + M_PI/2)*180/M_PI);
00555 //  //int leftWheelAng = (int)((asin(-leftR[8]) + M_PI/2)*180/M_PI);
00556 //
00557 //  int tick;
00558 //  if (itsPrevRightWheelAng > rightWheelAng)
00559 //    tick = 1;
00560 //  else
00561 //    tick = 0;
00562 //  LINFO("Ang %i %i %i", rightWheelAng*(tick*-1) + tick*+180, itsPrevRightWheelAng - rightWheelAng, tick);
00563 //
00564 //  itsPrevRightWheelAng = rightWheelAng;
00565 
00566   // LINFO("(%f,%f) Depth %f, roll %f pitch %f yaw %f",
00567   //     itsXPos, itsYPos, itsDepth,
00568   //     itsRoll, itsPitch, itsYaw);
00569 
00570 }
00571 
00572 void IRobotSim::simLoop()
00573 {
00574 
00575   //Move the robot
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   //update the sensors
00583   updateSensors();
00584 
00585   dSpaceCollide (space,this,&nearCallback); //check for collisions
00586 
00587   dWorldStep(world,0.1);
00588 
00589   dJointGroupEmpty (contactgroup); //delete the contact joints
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: //world camera
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; //yaw
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; //yaw
00631       cam_hpr[1]   = -90; //yaw
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     //Add some random gauss noise to the sensor
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 /* So things look consistent in everyone's emacs... */
00674 /* Local Variables: */
00675 /* indent-tabs-mode: nil */
00676 /* End: */
Generated on Sun May 8 08:41:22 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3