00001 /*!@file BeoSub/HarrierSim.C Sub 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: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/HarrierBot/HarrierSim.C $ 00035 // $Id: HarrierSim.C 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #include "Robots/HarrierBot/HarrierSim.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 HarrierSim *subSim = (HarrierSim *)data; 00053 const int MaxContacts = 10; 00054 00055 //create a contact joint to simulate collisions 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 ; //| dContactBounce; // | 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 (subSim->getWorld(), 00068 subSim->getContactgroup(),&contact[i]); 00069 dJointAttach (c, 00070 dGeomGetBody(contact[i].geom.g1), 00071 dGeomGetBody(contact[i].geom.g2)); 00072 } 00073 } 00074 } 00075 00076 // ###################################################################### 00077 HarrierSim::HarrierSim(OptionManager& mgr, const std::string& descrName, 00078 const std::string& tagName, bool showWorld) : 00079 ModelComponent(mgr, descrName, tagName), 00080 itsHarrierLength(7.0), //the length of sub in meters 00081 itsHarrierWidth(4.0), //the radius of the sub in meters 00082 itsHarrierWeight(30), // the weight of the sub in kg 00083 vp(new ViewPort("HarrierSim")), 00084 itsPanThruster(0), 00085 itsPitchThruster(0), 00086 itsRollThruster(0), 00087 itsUpThruster(0), 00088 itsXPos(0), 00089 itsYPos(0), 00090 itsDepth(0), 00091 itsRoll(0), 00092 itsPitch(0), 00093 itsYaw(0), 00094 itsWorldView(true), 00095 itsShowWorld(showWorld), 00096 itsWorldDisp(NULL) 00097 { 00098 00099 pthread_mutex_init(&itsDispLock, NULL); 00100 00101 00102 } 00103 00104 HarrierSim::~HarrierSim() 00105 { 00106 dSpaceDestroy(space); 00107 dWorldDestroy(world); 00108 00109 delete vp; 00110 delete itsWorldDisp; 00111 pthread_mutex_destroy(&itsDispLock); 00112 } 00113 00114 void HarrierSim::start2() 00115 { 00116 // setDrawStuff(); 00117 world = dWorldCreate(); 00118 space = dHashSpaceCreate(0); 00119 contactgroup = dJointGroupCreate(0); 00120 ground = dCreatePlane(space, 0, 0, 1, 0); 00121 dWorldSetGravity(world,0,0,-0.5); 00122 00123 dWorldSetCFM (world,1e-6); 00124 dWorldSetERP (world,1); 00125 //dWorldSetAutoDisableFlag (world,1); 00126 dWorldSetContactMaxCorrectingVel (world,0.1); 00127 //set the contact penetration 00128 dWorldSetContactSurfaceLayer(world, 0.001); 00129 00130 00131 makeHarrier(); 00132 00133 itsHarrierObject = vp->load3DSObject("./etc/spaceship.3ds", "./etc/textures/spaceshiptexture.ppm"); 00134 itsHarrierObject.scale = 0.1; 00135 00136 00137 //set the viewpoint 00138 double xyz[3] = {0 , 25.0, 20}; 00139 double hpr[3] = {-90.0,-35,0.0}; 00140 vp->dsSetViewpoint (xyz,hpr); 00141 vp->setZoom(1.5); 00142 00143 } 00144 00145 void HarrierSim::makeHarrier() 00146 { 00147 dMass mass; 00148 itsHarrierBody = dBodyCreate(world); 00149 //pos[0] = 0; pos[1] = 1.0*5; pos[2] = 1.80; 00150 00151 dBodySetPosition(itsHarrierBody,0,0.2*5,4.94); 00152 00153 dMatrix3 R; 00154 dRFromAxisAndAngle (R,1,0,0,0); 00155 dBodySetRotation(itsHarrierBody, R); 00156 dMassSetZero(&mass); 00157 dMassSetBoxTotal(&mass, itsHarrierWeight,itsHarrierWidth, itsHarrierLength, 0.5); 00158 //dMassSetCappedCylinderTotal(&mass,itsHarrierWeight,3,itsHarrierWidth,itsHarrierLength/2); 00159 dMassRotate(&mass, R); 00160 dBodySetMass(itsHarrierBody,&mass); 00161 itsHarrierGeom = dCreateBox(space, itsHarrierWidth, itsHarrierLength, 0.5); 00162 dGeomSetRotation(itsHarrierGeom, R); 00163 dGeomSetBody(itsHarrierGeom, itsHarrierBody); 00164 } 00165 00166 void HarrierSim::drawHarrier() 00167 { 00168 00169 // vp->dsSetColor(1,1,0); 00170 00171 vp->dsDraw3DSObject(dBodyGetPosition(itsHarrierBody), 00172 dBodyGetRotation(itsHarrierBody), 00173 itsHarrierObject); 00174 00175 //double sides[3] = {itsHarrierWidth, itsHarrierLength, 0.5}; 00176 //vp->dsDrawBox( 00177 // dBodyGetPosition(itsHarrierBody), 00178 // dBodyGetRotation(itsHarrierBody), 00179 // sides); 00180 00181 } 00182 00183 //void HarrierSim::updateSensors(const double *pos, const double *R) 00184 void HarrierSim::updateSensors(const dReal *pos, const dReal *R) 00185 { 00186 itsXPos = pos[0]; 00187 itsYPos = pos[1]; 00188 itsDepth = pos[2]; 00189 itsRoll = atan2(R[9], R[10]) + M_PI/2; //phi correct for initial rotation 00190 itsPitch = asin(-R[8]); //theta 00191 itsYaw = atan2(R[4], R[0]); //greek Y 00192 00193 if (itsYaw < 0) itsYaw += M_PI*2; 00194 // LINFO("(%f,%f) Depth %f, roll %f pitch %f yaw %f", 00195 // itsXPos, itsYPos, itsDepth, 00196 // itsRoll, itsPitch, itsYaw); 00197 00198 } 00199 00200 void HarrierSim::simLoop() 00201 { 00202 00203 //set the trusters 00204 float thVar = 5.0; 00205 dBodyAddRelForceAtRelPos(itsHarrierBody,0,itsUpThruster+randomDoubleFromNormal(thVar),0, 0,0,itsHarrierLength/4); 00206 dBodyAddRelForceAtRelPos(itsHarrierBody,0,itsUpThruster+randomDoubleFromNormal(thVar),0, 0,0,-itsHarrierLength/4); 00207 dBodyAddRelForceAtRelPos(itsHarrierBody,0,itsUpThruster+randomDoubleFromNormal(thVar),0, itsHarrierLength/4,0,0); 00208 dBodyAddRelForceAtRelPos(itsHarrierBody,0,itsUpThruster+randomDoubleFromNormal(thVar),0, -itsHarrierLength/4,0,0); 00209 00210 00211 dBodyAddRelForceAtRelPos(itsHarrierBody,itsPanThruster,0,0, 0,0,itsHarrierLength/2); 00212 00213 dBodyAddRelForceAtRelPos(itsHarrierBody,0,itsPitchThruster,0, 0,0,itsHarrierLength/2); 00214 dBodyAddRelForceAtRelPos(itsHarrierBody,0,-itsPitchThruster,0, 0,0,-1*itsHarrierLength/2); 00215 00216 dBodyAddRelForceAtRelPos(itsHarrierBody,0,itsRollThruster,0, itsHarrierWidth*2,0,0); 00217 dBodyAddRelForceAtRelPos(itsHarrierBody,0,-itsRollThruster,0, -1*itsHarrierWidth*2,0,0); 00218 00219 //Apply a viscosity water force 00220 //applyHydrodynamicForces(0.5); 00221 00222 //Folow the sub with the camera 00223 // const double *bodyPos = dBodyGetPosition(itsSubBody); 00224 //const double *bodyR = dBodyGetRotation(itsSubBody); 00225 const dReal *bodyPos = dBodyGetPosition(itsHarrierBody); 00226 const dReal *bodyR = dBodyGetRotation(itsHarrierBody); 00227 00228 updateSensors(bodyPos, bodyR); 00229 00230 dSpaceCollide (space,this,&nearCallback); //check for collisions 00231 00232 dWorldStep(world,0.1); 00233 00234 dJointGroupEmpty (contactgroup); //delete the contact joints 00235 00236 } 00237 00238 00239 Image<PixRGB<byte> > HarrierSim::getFrame(int camera) 00240 { 00241 const dReal *bodyPos = dBodyGetPosition(itsHarrierBody); 00242 const dReal *bodyR = dBodyGetRotation(itsHarrierBody); 00243 00244 double cam_xyz[3], cam_hpr[3] = {0.0,0.0,0.0}; 00245 00246 switch (camera) 00247 { 00248 case 0: //world camera 00249 cam_xyz[0] = bodyPos[0]; 00250 cam_xyz[1] = bodyPos[1]-5; 00251 cam_xyz[2] = 20; 00252 00253 cam_hpr[0] = 90.0; 00254 cam_hpr[1] = -45.0; 00255 cam_hpr[2] = 0.0; 00256 00257 break; 00258 case 1: 00259 cam_xyz[0] = bodyPos[0]; 00260 cam_xyz[1] = bodyPos[1]; 00261 cam_xyz[2] = bodyPos[2]; 00262 00263 cam_hpr[0] = (atan2(bodyR[4], bodyR[0])*180/M_PI) + 90; //yaw 00264 00265 break; 00266 case 2: 00267 cam_xyz[0] = bodyPos[0]; 00268 cam_xyz[1] = bodyPos[1]; 00269 cam_xyz[2] = bodyPos[2]; 00270 00271 cam_hpr[0] = (atan2(bodyR[4], bodyR[0])*180/M_PI) + 90; //yaw 00272 cam_hpr[1] = -90; //yaw 00273 00274 00275 break; 00276 } 00277 pthread_mutex_lock(&itsDispLock); 00278 if (camera != -1) 00279 vp->dsSetViewpoint (cam_xyz,cam_hpr); 00280 vp->initFrame(); 00281 drawHarrier(); 00282 vp->updateFrame(); 00283 pthread_mutex_unlock(&itsDispLock); 00284 00285 00286 return vp->getFrame(); 00287 00288 } 00289 00290 void HarrierSim::getSensors(float &xPos, float &yPos, float &depth, 00291 float &roll, float &pitch, float &yaw) 00292 { 00293 00294 xPos = itsXPos; 00295 yPos = itsYPos; 00296 depth = itsDepth; 00297 roll = itsRoll; 00298 pitch = itsPitch; 00299 yaw = itsYaw; 00300 00301 } 00302 00303 void HarrierSim::setThrusters(float panThruster, float pitchThruster, float rollThruster, float upThruster) 00304 { 00305 00306 itsPanThruster = panThruster; 00307 itsPitchThruster = pitchThruster; 00308 itsRollThruster = rollThruster; 00309 itsUpThruster = upThruster; 00310 } 00311 00312 // ###################################################################### 00313 /* So things look consistent in everyone's emacs... */ 00314 /* Local Variables: */ 00315 /* indent-tabs-mode: nil */ 00316 /* End: */