Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

robot/sim/SimulatedPlatform.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2003 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: SimulatedPlatform.cpp 1033 2004-02-11 20:47:52Z jungd $
00019   $Revision: 1.12 $
00020   $Date: 2004-02-11 15:47:52 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <robot/sim/SimulatedPlatform>
00026 
00027 #include <base/Vector3>
00028 #include <base/PathName>
00029 #include <base/Externalizer>
00030 
00031 #include <gfx/Color3>
00032 #include <physics/Material>
00033 #include <physics/Box>
00034 #include <physics/Cylinder>
00035 #include <physics/Solid>
00036 #include <physics/HingeJoint>
00037 #include <physics/DoubleHingeJoint>
00038 #include <physics/Motor>
00039 #include <physics/CollisionCuller>
00040 #include <physics/CollisionDetector>
00041 
00042 
00043 using robot::sim::SimulatedPlatform;
00044 
00045 using base::Point3;
00046 using base::Orient;
00047 using base::PathName;
00048 using physics::Box;
00049 using physics::Cylinder;
00050 using physics::ConstraintGroup;
00051 using physics::SpatialGroup;
00052 using physics::Solid;
00053 using physics::HingeJoint;
00054 using physics::DoubleHingeJoint;
00055 using physics::Motor;
00056 using physics::Collidable;
00057 using physics::CollidableGroup;
00058 using physics::CollisionCuller;
00059 using physics::CollisionDetector;
00060 
00061 
00062 
00063 
00064 SimulatedPlatform::SimulatedPlatform(ref<const robot::PlatformDescription> platformDescription, ref<physics::SolidSystem> solidSystem, bool dynamic)
00065   : solidSystem(solidSystem), platformDescr(platformDescription), dynamic(true)
00066 {
00067   spatialGroup = ref<SpatialGroup>(NewObj SpatialGroup()); // a group to put all the Solids in
00068   platformSolids.resize(1);
00069   platformSolids[Platform] = ref<Solid>(0);
00070 }
00071 
00072 
00073 SimulatedPlatform::~SimulatedPlatform()
00074 {
00075   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00076     if (dynamic) {
00077       leftDriveHingeJoint->attachMotor(1,ref<Motor>(0));
00078       rightDriveHingeJoint->attachMotor(1,ref<Motor>(0));
00079       steeringHingeJoint->attachMotor(1,ref<Motor>(0));
00080       leftDriveHingeJoint = rightDriveHingeJoint = steeringHingeJoint = ref<HingeJoint>(0);
00081       wheelConstraintGroup->clear();
00082     }
00083   }
00084 }
00085 
00086 
00087 
00088 void SimulatedPlatform::setLeftBackWheelTorque(Real t)
00089 {
00090   if (!dynamic) return;
00091   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00092     leftDriveMotor->setMaxForce(t);
00093     leftDriveMotor->setTargetVel( (t>0)?10:-10 ); 
00094   }
00095 }
00096 
00097 
00098 void SimulatedPlatform::setLeftBackWheelVel(Real v, Real maxTorque)
00099 {
00100   if (!dynamic) return;
00101   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00102     leftDriveMotor->setTargetVel(v); 
00103     leftDriveMotor->setMaxForce(maxTorque);
00104   }
00105 }
00106 
00107 void SimulatedPlatform::setRightBackWheelTorque(Real t)
00108 {
00109   if (!dynamic) return;
00110   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00111     rightDriveMotor->setMaxForce(t);
00112     rightDriveMotor->setTargetVel( (t>0)?10:-10 ); 
00113   }
00114 }
00115 
00116 
00117 void SimulatedPlatform::setRightBackWheelVel(Real v, Real maxTorque)
00118 {
00119   if (!dynamic) return;
00120   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00121     rightDriveMotor->setTargetVel(v); 
00122     rightDriveMotor->setMaxForce(maxTorque);
00123   }
00124 }
00125 
00126 
00127 void SimulatedPlatform::setSteeringTorque(Real t)
00128 {
00129   if (!dynamic) return;
00130   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00131     steeringMotor->setMaxForce(t);
00132     steeringMotor->setTargetVel( (t>0)?10:-10 ); 
00133   }
00134 }
00135 
00136 
00137 void SimulatedPlatform::setSteeringVel(Real v, Real maxTorque)
00138 {
00139   if (!dynamic) return;
00140   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00141     steeringMotor->setTargetVel(v); 
00142     steeringMotor->setMaxForce(maxTorque);
00143   }
00144 }
00145 
00146 
00147 Real SimulatedPlatform::getLeftBackWheelVel() const
00148 {
00149   if (!dynamic) return 0;
00150   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00151     return leftDriveHingeJoint->getAngleRate();
00152   }
00153   return 0;
00154 }
00155 
00156 Real SimulatedPlatform::getRightBackWheelVel() const
00157 {
00158   if (!dynamic) return 0;
00159   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00160     return rightDriveHingeJoint->getAngleRate();
00161   }
00162   return 0;
00163 }
00164 
00165 
00166 Real SimulatedPlatform::getSteeringAngle() const
00167 {  
00168   if (!dynamic) return 0; //!!! fix me (or not? this isn't a 'position' control, is it?)
00169   if (platformSolids[Platform] && platformDescr->isMobile() && !platformDescr->isHolonomic()) {
00170     return steeringHingeJoint->getAngle();
00171   }
00172   return 0;
00173 }
00174 
00175 
00176 
00177 
00178 
00179 // Spatial
00180 
00181 void SimulatedPlatform::setPosition(const Point3& pos)       
00182 { 
00183   spatialGroup->setPosition(pos); 
00184 }
00185 
00186 Point3 SimulatedPlatform::getPosition() const                  
00187 {
00188   return spatialGroup->getPosition(); 
00189 }
00190 
00191 void SimulatedPlatform::setOrientation(const Orient& orient) 
00192 { 
00193   spatialGroup->setOrientation(orient);
00194 }
00195 
00196 Orient SimulatedPlatform::getOrientation() const               
00197 { 
00198   return spatialGroup->getOrientation(); 
00199 }
00200 
00201 void SimulatedPlatform::setConfiguration(const base::Transform& configuration) 
00202 { 
00203   spatialGroup->setConfiguration(configuration); 
00204 }
00205 
00206 base::Transform SimulatedPlatform::getConfiguration() const    
00207 { 
00208   return spatialGroup->getConfiguration(); 
00209 }
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 void SimulatedPlatform::construct(const base::Point3& initialPosition, const base::Orient& initialOrientation)
00220 {
00221   Assert(solidSystem);
00222   spatialGroup->clear();
00223   spatialGroup->setPositionOrientation(initialPosition, initialOrientation);
00224   
00225   ref<const robot::PlatformDescription> pd(platformDescr);
00226   platformSolids.resize(pd->isMobile()?MaxPlatformSolids:1);
00227 
00228   // make a platform Solid
00229   base::Dimension3 dim(pd->dimensions());
00230 
00231   ref<Box> pBox(NewObj Box(dim.x,dim.y,dim.z));
00232   ref<physics::Material> pMat(new physics::Material());
00233   pMat->setBaseColor(gfx::Color3(0.5,0.5,0.8));
00234   if (!pd->isMobile())
00235     pMat->setDensity(6); // make the platform heavy
00236   else
00237     pMat->setDensity(0.25);
00238   platformSolids[Platform] = ref<Solid>(solidSystem->createSolid(pBox, pMat)); 
00239   platformSolids[Platform]->setName(pd->getName());
00240   solidSystem->addSolid(platformSolids[Platform]);
00241   platformSolids[Platform]->setEnabled(dynamic);
00242 
00243   Quat4 orient(initialOrientation.getQuat4());
00244   Point3 spos( initialPosition - orient.rotate(pd->originOffset()) );
00245   platformSolids[Platform]->setPosition(spos);
00246   platformSolids[Platform]->setOrientation(orient);
00247   spatialGroup->add(platformSolids[Platform]);
00248 
00249 
00250   if (pd->isMobile()) { // add wheels
00251     
00252     const Real wheelWidth = 0.25;
00253     const Real wheelRadius = 0.40;
00254     const Real wheelOffsetDown = 0.65;
00255     const Real wheelPivotOffset = 0.22; // distance beween wheel origin and the steering pivot point (toward platform)
00256     const Real wheelMountLength = 0.4; // length of the left & right wheel mounts
00257 
00258     const Real L = pd->L(); // distance of drive axle back from platform origin
00259     const Real W = pd->W(); // distance between steering axle and drive axle
00260 
00261 
00262     if (pd->isHolonomic()) {
00263 
00264       throw std::runtime_error(Exception("holonomic mobile platform not yet implemented - sorry."));
00265 
00266     } else { // non-holonomic
00267 
00268       // add two drive wheels at the back and two steering wheels at the front
00269       ref<physics::Material> wMat(new physics::Material());
00270       wMat->setBaseColor(gfx::Color3(0.1,0.1,0.1));// dark grey
00271       //wMat->setSurfaceAppearance(PathName("images/basn2c16.png"));
00272       ref<Cylinder> wCyl(NewObj Cylinder(wheelWidth, wheelRadius));
00273 
00274       // create solids for each wheel
00275       platformSolids[LeftFrontWheel] = ref<Solid>(solidSystem->createSolid(wCyl, wMat)); 
00276       platformSolids[LeftFrontWheel]->setName(pd->getName()+":leftFrontWheel");
00277       solidSystem->addSolid(platformSolids[LeftFrontWheel]);
00278       platformSolids[LeftFrontWheel]->setEnabled(dynamic);
00279       spatialGroup->add(platformSolids[LeftFrontWheel]);
00280 
00281       platformSolids[RightFrontWheel] = ref<Solid>(solidSystem->createSolid(wCyl, wMat)); 
00282       platformSolids[RightFrontWheel]->setName(pd->getName()+":rightFrontWheel");
00283       solidSystem->addSolid(platformSolids[RightFrontWheel]);
00284       platformSolids[RightFrontWheel]->setEnabled(dynamic);
00285       spatialGroup->add(platformSolids[RightFrontWheel]);
00286       
00287       platformSolids[LeftBackWheel] = ref<Solid>(solidSystem->createSolid(wCyl, wMat)); 
00288       platformSolids[LeftBackWheel]->setName(pd->getName()+":leftBackWheel");
00289       solidSystem->addSolid(platformSolids[LeftBackWheel]);
00290       platformSolids[LeftBackWheel]->setEnabled(dynamic);
00291       spatialGroup->add(platformSolids[LeftBackWheel]);
00292       
00293       platformSolids[RightBackWheel] = ref<Solid>(solidSystem->createSolid(wCyl, wMat)); 
00294       platformSolids[RightBackWheel]->setName(pd->getName()+":rightBackWheel");
00295       solidSystem->addSolid(platformSolids[RightBackWheel]);
00296       platformSolids[RightBackWheel]->setEnabled(dynamic);
00297       spatialGroup->add(platformSolids[RightBackWheel]);
00298       
00299       // position them relative to the platform
00300       Point3 leftFrontWheelPos(initialPosition);
00301       Quat4 leftFrontWheelOrient(initialOrientation.getQuat4());
00302 
00303       Point3 rightFrontWheelPos(initialPosition);
00304       Quat4 rightFrontWheelOrient(initialOrientation.getQuat4());
00305 
00306       Point3 leftBackWheelPos(initialPosition);
00307       Quat4 leftBackWheelOrient(initialOrientation.getQuat4());
00308 
00309       Point3 rightBackWheelPos(initialPosition);
00310       Quat4 rightBackWheelOrient(initialOrientation.getQuat4());
00311 
00312       // rotate left wheels upright (Z points out of the side of platform)
00313       leftFrontWheelOrient *= Quat4(Vector3(1,0,0),-consts::Pi/2.0);
00314       leftBackWheelOrient *= Quat4(Vector3(1,0,0),-consts::Pi/2.0);
00315       // rotate right wheels upright (the other way)
00316       rightFrontWheelOrient *= Quat4(Vector3(1,0,0),consts::Pi/2.0);
00317       rightBackWheelOrient *= Quat4(Vector3(1,0,0),consts::Pi/2.0);
00318 
00319       // translate to platform sides
00320       Real yoffset = dim.y/2.0;
00321       leftFrontWheelPos += leftFrontWheelOrient.rotate(Vector3(0,0,yoffset));
00322       leftBackWheelPos += leftFrontWheelOrient.rotate(Vector3(0,0,yoffset));
00323       rightFrontWheelPos += rightFrontWheelOrient.rotate(Vector3(0,0,yoffset));
00324       rightBackWheelPos += rightFrontWheelOrient.rotate(Vector3(0,0,yoffset));
00325 
00326       // translate to front/back of platfom
00327       leftFrontWheelPos += leftFrontWheelOrient.rotate(Vector3(W-L,0,0));
00328       rightFrontWheelPos += rightFrontWheelOrient.rotate(Vector3(W-L,0,0));
00329       leftBackWheelPos += leftFrontWheelOrient.rotate(Vector3(-L,0,0));
00330       rightBackWheelPos += rightFrontWheelOrient.rotate(Vector3(-L,0,0));
00331 
00332       // translate down
00333       leftFrontWheelPos += leftFrontWheelOrient.rotate(Vector3(0,wheelOffsetDown,0));
00334       leftBackWheelPos += leftFrontWheelOrient.rotate(Vector3(0,wheelOffsetDown,0));
00335       rightFrontWheelPos += rightFrontWheelOrient.rotate(Vector3(0,-wheelOffsetDown,0));
00336       rightBackWheelPos += rightFrontWheelOrient.rotate(Vector3(0,-wheelOffsetDown,0));
00337       
00338 
00339       // set pos/orient
00340       platformSolids[LeftFrontWheel]->setPosition( leftFrontWheelPos );
00341       platformSolids[LeftFrontWheel]->setOrientation( leftFrontWheelOrient );
00342       platformSolids[RightFrontWheel]->setPosition( rightFrontWheelPos );
00343       platformSolids[RightFrontWheel]->setOrientation( rightFrontWheelOrient );
00344       platformSolids[LeftBackWheel]->setPosition( leftBackWheelPos );
00345       platformSolids[LeftBackWheel]->setOrientation( leftBackWheelOrient );
00346       platformSolids[RightBackWheel]->setPosition( rightBackWheelPos );
00347       platformSolids[RightBackWheel]->setOrientation( rightBackWheelOrient );
00348 
00349 
00350       // the front wheels need a crossbar steering system to connect them
00351       //  and keep them facing the same direction
00352       wheelConstraintGroup = solidSystem->createConstraintGroup();
00353 
00354       // first the wheel mounts
00355       ref<Box> mBox(NewObj Box(wheelMountLength,wheelMountLength/4.0,wheelMountLength/4.0));
00356       ref<physics::Material> mMat(new physics::Material());
00357       mMat->setBaseColor(gfx::Color3(0.7,0.7,0.7));
00358 
00359       platformSolids[LeftFrontWheelMount] = ref<Solid>(solidSystem->createSolid(mBox, mMat)); 
00360       platformSolids[LeftFrontWheelMount]->setName(pd->getName()+":leftFrontWheelMount");
00361       solidSystem->addSolid(platformSolids[LeftFrontWheelMount]);
00362       platformSolids[LeftFrontWheelMount]->setEnabled(dynamic);
00363       spatialGroup->add(platformSolids[LeftFrontWheelMount]);
00364       
00365       platformSolids[RightFrontWheelMount] = ref<Solid>(solidSystem->createSolid(mBox, mMat));
00366       platformSolids[RightFrontWheelMount]->setName(pd->getName()+":rightFrontWheelMount");
00367       solidSystem->addSolid(platformSolids[RightFrontWheelMount]);
00368       platformSolids[RightFrontWheelMount]->setEnabled(dynamic);
00369       spatialGroup->add(platformSolids[RightFrontWheelMount]);
00370       
00371       platformSolids[LeftFrontWheelMount]->setPosition( leftFrontWheelPos + leftFrontWheelOrient.rotate(Vector3(0,0,-wheelPivotOffset)) );
00372       platformSolids[LeftFrontWheelMount]->setPosition( platformSolids[LeftFrontWheelMount]->getPosition() + initialOrientation.getQuat4().rotate(Vector3(wheelMountLength/2.0,0,0)) );
00373       platformSolids[LeftFrontWheelMount]->setOrientation( initialOrientation.getQuat4() );
00374       platformSolids[RightFrontWheelMount]->setPosition( rightFrontWheelPos + rightFrontWheelOrient.rotate(Vector3(0,0,-wheelPivotOffset)) );
00375       platformSolids[RightFrontWheelMount]->setOrientation( initialOrientation.getQuat4() );
00376       platformSolids[RightFrontWheelMount]->setPosition( platformSolids[RightFrontWheelMount]->getPosition() + initialOrientation.getQuat4().rotate(Vector3(wheelMountLength/2.0,0,0)) );
00377 
00378       // create the steering crossbar to connect the right & left wheel mounts
00379       ref<Box> xBox(NewObj Box(0.1,dim.y - 2.0*wheelPivotOffset,0.1));
00380       platformSolids[Crossbar] = ref<Solid>(solidSystem->createSolid(xBox, mMat)); 
00381       platformSolids[Crossbar]->setName(pd->getName()+":steeringCrossbar");
00382       solidSystem->addSolid(platformSolids[Crossbar]);
00383       platformSolids[Crossbar]->setEnabled(dynamic);
00384       spatialGroup->add(platformSolids[Crossbar]);
00385       // position it
00386       Point3 crossbarPos( leftFrontWheelPos );
00387       Quat4  crossbarOrient( initialOrientation.getQuat4() );
00388       crossbarPos += crossbarOrient.rotate(Vector3(0,-dim.y/2.0,0));
00389       crossbarPos += crossbarOrient.rotate(Vector3(wheelMountLength,0,0));
00390       platformSolids[Crossbar]->setPosition( crossbarPos );
00391       platformSolids[Crossbar]->setOrientation( crossbarOrient );
00392       
00393       
00394       // only connect everything up with constraints & motors if we're doing dynamic simulation.
00395       //  That way, for static simulation the Solids can be explicitly positioned without
00396       //  worrying about maintaining constraints
00397       if (dynamic) { 
00398       
00399         // connect the mounts to the wheels
00400         ref<HingeJoint> leftMountHinge = solidSystem->createHingeJoint();
00401         wheelConstraintGroup->addConstraint(leftMountHinge);
00402         leftMountHinge->attach(platformSolids[LeftFrontWheelMount], platformSolids[LeftFrontWheel]);
00403         leftMountHinge->setAxis(Vector3(0,1,0));
00404         leftMountHinge->setAnchor(Point3(-wheelMountLength/2.0,0,0));
00405         
00406         ref<HingeJoint> rightMountHinge = solidSystem->createHingeJoint();
00407         wheelConstraintGroup->addConstraint(rightMountHinge);
00408         rightMountHinge->attach(platformSolids[RightFrontWheelMount], platformSolids[RightFrontWheel]);
00409         rightMountHinge->setAxis(Vector3(0,1,0));
00410         rightMountHinge->setAnchor(Point3(-wheelMountLength/2.0,0,0));
00411         
00412         // connect the mounts to the crossbar
00413         ref<HingeJoint> leftCrossbarHinge = solidSystem->createHingeJoint();
00414         wheelConstraintGroup->addConstraint(leftCrossbarHinge);
00415         leftCrossbarHinge->attach(platformSolids[LeftFrontWheelMount], platformSolids[Crossbar]);
00416         leftCrossbarHinge->setAxis(Vector3(0,0,1));
00417         leftCrossbarHinge->setAnchor(Point3(wheelMountLength/2.0,0,0));
00418         
00419         ref<HingeJoint> rightCrossbarHinge = solidSystem->createHingeJoint();
00420         wheelConstraintGroup->addConstraint(rightCrossbarHinge);
00421         rightCrossbarHinge->attach(platformSolids[RightFrontWheelMount], platformSolids[Crossbar]);
00422         rightCrossbarHinge->setAxis(Vector3(0,0,1));
00423         rightCrossbarHinge->setAnchor(Point3(wheelMountLength/2.0,0,0));
00424         
00425         
00426         // now connect the mounts to the platform
00427         ref<HingeJoint> leftSteeringHinge = solidSystem->createHingeJoint();
00428         wheelConstraintGroup->addConstraint(leftSteeringHinge);
00429         leftSteeringHinge->attach(platformSolids[LeftFrontWheelMount], platformSolids[Platform]);
00430         leftSteeringHinge->setAxis(Vector3(0,0,-1));
00431         leftSteeringHinge->setAnchor(Point3(-wheelMountLength/2.0,0,0));
00432         leftSteeringHinge->setLowStop(-Math::degToRad(35));
00433         leftSteeringHinge->setHighStop(Math::degToRad(35));
00434         
00435         ref<HingeJoint> rightSteeringHinge = solidSystem->createHingeJoint();
00436         wheelConstraintGroup->addConstraint(rightSteeringHinge);
00437         rightSteeringHinge->attach(platformSolids[RightFrontWheelMount], platformSolids[Platform]);
00438         rightSteeringHinge->setAxis(Vector3(0,0,-1));
00439         rightSteeringHinge->setAnchor(Point3(-wheelMountLength/2.0,0,0));
00440         
00441         
00442         
00443         // Back wheels with HingeJoints
00444         ref<HingeJoint> hingeLeft = solidSystem->createHingeJoint();
00445         wheelConstraintGroup->addConstraint(hingeLeft);
00446         hingeLeft->attach(platformSolids[Platform], platformSolids[LeftBackWheel]);
00447         hingeLeft->setAxis(Vector3(0,-1,0));
00448         hingeLeft->setAnchor( leftBackWheelPos - platformSolids[Platform]->getPosition() );
00449         
00450         ref<HingeJoint> hingeRight = solidSystem->createHingeJoint();
00451         wheelConstraintGroup->addConstraint(hingeRight);
00452         hingeRight->attach(platformSolids[Platform], platformSolids[RightBackWheel]);
00453         hingeRight->setAxis(Vector3(0,-1,0));
00454         hingeRight->setAnchor( rightBackWheelPos - platformSolids[Platform]->getPosition() );
00455 
00456 
00457         
00458         // now attach drive motors
00459         leftDriveMotor = solidSystem->createMotor();
00460         hingeLeft->attachMotor(1, leftDriveMotor);
00461         leftDriveMotor->setTargetVel(0);
00462         leftDriveMotor->setMaxForce(0);
00463         leftDriveHingeJoint = hingeLeft;
00464   
00465         rightDriveMotor = solidSystem->createMotor();
00466         hingeRight->attachMotor(1, rightDriveMotor);
00467         rightDriveMotor->setTargetVel(0);
00468         rightDriveMotor->setMaxForce(0.005);
00469         rightDriveHingeJoint = hingeRight;
00470   
00471   
00472         // and a steering motor on the left
00473         steeringMotor = solidSystem->createMotor();
00474         leftSteeringHinge->attachMotor(1, steeringMotor);
00475         steeringMotor->setTargetVel(0);
00476         steeringMotor->setMaxForce(0.005);
00477         steeringHingeJoint = leftSteeringHinge;
00478   
00479   
00480         // add some motors to the front wheels, just to provide some
00481         //  'friction-like' damping.
00482         ref<Motor> leftFrontWheelMotor = solidSystem->createMotor();
00483         leftMountHinge->attachMotor(1, leftFrontWheelMotor);
00484         leftFrontWheelMotor->setTargetVel(0);
00485         leftFrontWheelMotor->setMaxForce(0.02);
00486   
00487         ref<Motor> rightFrontWheelMotor = solidSystem->createMotor();
00488         rightMountHinge->attachMotor(1, rightFrontWheelMotor);
00489         rightFrontWheelMotor->setTargetVel(0);
00490         rightFrontWheelMotor->setMaxForce(0.02);
00491       }
00492 
00493     }
00494 
00495   }
00496 
00497 }
00498 
00499 
00500 
00501 ref<physics::Collidable> SimulatedPlatform::createCollidable(CollidableFlags flags)
00502 {
00503   Assert(solidSystem);
00504   Assert(platformSolids.size() > 0);
00505   
00506   ref<CollisionCuller> cc(solidSystem->getCollisionCuller());
00507   ref<const robot::PlatformDescription> pd(platformDescr);
00508 
00509   array<ref<Collidable> > collidables(platformSolids.size());
00510   collidables[Platform] = platformSolids[Platform]->createCollidable(flags);
00511   collidables[Platform]->setName("platformBody");
00512   
00513   if (pd->isMobile()) {
00514     ref<CollidableGroup> platformGroup = cc->createCollidableGroup();
00515 
00516     // Create a group with the platform and all the rest in a subgroup
00517     platformGroup->addCollidable( collidables[Platform] );
00518     
00519     ref<CollidableGroup> partsGroup = cc->createCollidableGroup();
00520     partsGroup->setChildIntercollisionEnabled(false);
00521     
00522     for(PlatformSolids p=PlatformSolids(Platform+1); p<PlatformSolids(platformSolids.size()); p = PlatformSolids(p+1)) {
00523       collidables[p] = platformSolids[p]->createCollidable(flags);
00524       partsGroup->addCollidable( collidables[p] );
00525     }
00526     
00527     platformGroup->addCollidable( partsGroup );
00528   
00529     disableCollisions(collidables);
00530     return platformGroup;
00531   }
00532   else {
00533     return collidables[Platform];
00534   }
00535   
00536 }
00537 
00538 
00539 
00540 void SimulatedPlatform::disableCollisions(const array<ref<Collidable> >& collidables)
00541 {
00542   ref<const robot::PlatformDescription> pd(platformDescr);
00543   if (!pd->isMobile()) return;
00544 
00545   // don't collide any of the wheels, mounts or crossbar with the platform
00546   //  !!! should relax this for the real wheels once the collision model
00547   //      uses a  cylinder instead of a capped cylinder (??)
00548 
00549   ref<CollisionCuller> cc(solidSystem->getCollisionCuller());
00550   cc->collisionEnable(false,collidables[LeftFrontWheel], collidables[Platform]);
00551   cc->collisionEnable(false,collidables[RightFrontWheel], collidables[Platform]);
00552   cc->collisionEnable(false,collidables[LeftFrontWheelMount], collidables[Platform]);
00553   cc->collisionEnable(false,collidables[LeftFrontWheelMount], collidables[LeftFrontWheel]);
00554   cc->collisionEnable(false,collidables[LeftFrontWheelMount], collidables[Crossbar]);
00555   cc->collisionEnable(false,collidables[RightFrontWheelMount], collidables[Platform]);
00556   cc->collisionEnable(false,collidables[RightFrontWheelMount], collidables[RightFrontWheel]);
00557   cc->collisionEnable(false,collidables[RightFrontWheelMount], collidables[Crossbar]);
00558   cc->collisionEnable(false,collidables[LeftBackWheel], collidables[Platform]);
00559   cc->collisionEnable(false,collidables[RightBackWheel], collidables[Platform]);
00560   cc->collisionEnable(false,collidables[Crossbar], collidables[Platform]);
00561   cc->collisionEnable(false,collidables[Crossbar], collidables[LeftFrontWheel]);
00562   cc->collisionEnable(false,collidables[Crossbar], collidables[RightFrontWheel]);
00563 
00564 }
00565 
00566 
00567 
00568 bool SimulatedPlatform::formatSupported(String format, Real version, ExternalizationType type) const
00569 {
00570   return false; // none supported (yet)
00571 }
00572 
00573 void SimulatedPlatform::externalize(base::Externalizer& e, String format, Real version)
00574 {
00575   //if (format=="") format = String("dh");
00576 
00577   if (!formatSupported(format,version))
00578     throw std::invalid_argument(Exception(String("format ")+format+" "+base::realToString(version)+" unsupported"));
00579 
00580 }

Generated on Thu Jul 29 15:56:41 2004 for OpenSim by doxygen 1.3.6