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 #include <ompl/extensions/ode/ODESimpleSetup.h>
00038 #include <ompl/base/GoalRegion.h>
00039 #include <ompl/config.h>
00040 #include <iostream>
00041 #include <ode/ode.h>
00042
00043 namespace ob = ompl::base;
00044 namespace og = ompl::geometric;
00045 namespace oc = ompl::control;
00046
00048
00049 class RigidBodyEnvironment : public oc::ODEEnvironment
00050 {
00051 public:
00052
00053 RigidBodyEnvironment(void) : oc::ODEEnvironment()
00054 {
00055 createWorld();
00056 }
00057
00058 virtual ~RigidBodyEnvironment(void)
00059 {
00060 destroyWorld();
00061 }
00062
00063
00064
00065
00066
00067 virtual unsigned int getControlDimension(void) const
00068 {
00069 return 3;
00070 }
00071
00072 virtual void getControlBounds(std::vector<double> &lower, std::vector<double> &upper) const
00073 {
00074 static double maxForce = 0.2;
00075 lower.resize(3);
00076 lower[0] = -maxForce;
00077 lower[1] = -maxForce;
00078 lower[2] = -maxForce;
00079
00080 upper.resize(3);
00081 upper[0] = maxForce;
00082 upper[1] = maxForce;
00083 upper[2] = maxForce;
00084 }
00085
00086 virtual void applyControl(const double *control) const
00087 {
00088 dBodyAddForce(boxBody, control[0], control[1], control[2]);
00089 }
00090
00091 virtual bool isValidCollision(dGeomID geom1, dGeomID geom2, const dContact& contact) const
00092 {
00093 return false;
00094 }
00095
00096 virtual void setupContact(dGeomID geom1, dGeomID geom2, dContact &contact) const
00097 {
00098 contact.surface.mode = dContactSoftCFM | dContactApprox1;
00099 contact.surface.mu = 0.9;
00100 contact.surface.soft_cfm = 0.2;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 void createWorld(void);
00112
00113
00114 void destroyWorld(void);
00115
00116
00117
00118 void setPlanningParameters(void);
00119
00120
00121 dWorldID bodyWorld;
00122
00123
00124 dSpaceID space;
00125
00126
00127 dMass m;
00128
00129
00130 dGeomID boxGeom;
00131
00132
00133 dBodyID boxBody;
00134
00135 };
00136
00137
00138
00139 class RigidBodyGoal : public ob::GoalRegion
00140 {
00141 public:
00142
00143 RigidBodyGoal(const ob::SpaceInformationPtr &si) : ob::GoalRegion(si)
00144 {
00145 threshold_ = 0.5;
00146 }
00147
00148 virtual double distanceGoal(const ob::State *st) const
00149 {
00150 const double *pos = st->as<oc::ODEStateSpace::StateType>()->getBodyPosition(0);
00151 double dx = fabs(pos[0] - 30);
00152 double dy = fabs(pos[1] - 55);
00153 double dz = fabs(pos[2] - 35);
00154 return sqrt(dx * dx + dy * dy + dz * dz);
00155 }
00156
00157 };
00158
00159
00160
00161 class RigidBodyStateProjectionEvaluator : public ob::ProjectionEvaluator
00162 {
00163 public:
00164
00165 RigidBodyStateProjectionEvaluator(const ob::StateSpace *space) : ob::ProjectionEvaluator(space)
00166 {
00167 }
00168
00169 virtual unsigned int getDimension(void) const
00170 {
00171 return 3;
00172 }
00173
00174 virtual void defaultCellSizes(void)
00175 {
00176 cellSizes_.resize(3);
00177 cellSizes_[0] = 1;
00178 cellSizes_[1] = 1;
00179 cellSizes_[2] = 1;
00180 }
00181
00182 virtual void project(const ob::State *state, ob::EuclideanProjection &projection) const
00183 {
00184 const double *pos = state->as<oc::ODEStateSpace::StateType>()->getBodyPosition(0);
00185 projection[0] = pos[0];
00186 projection[1] = pos[1];
00187 projection[2] = pos[2];
00188 }
00189
00190 };
00191
00192
00193 class RigidBodyStateSpace : public oc::ODEStateSpace
00194 {
00195 public:
00196
00197 RigidBodyStateSpace(const oc::ODEEnvironmentPtr &env) : oc::ODEStateSpace(env)
00198 {
00199 }
00200
00201 virtual double distance(const ob::State *s1, const ob::State *s2) const
00202 {
00203 const double *p1 = s1->as<oc::ODEStateSpace::StateType>()->getBodyPosition(0);
00204 const double *p2 = s1->as<oc::ODEStateSpace::StateType>()->getBodyPosition(0);
00205 double dx = fabs(p1[0] - p2[0]);
00206 double dy = fabs(p1[1] - p2[1]);
00207 double dz = fabs(p1[2] - p2[2]);
00208 return sqrt(dx * dx + dy * dy + dz * dz);
00209 }
00210
00211 virtual void registerProjections(void)
00212 {
00213 registerDefaultProjection(ob::ProjectionEvaluatorPtr(new RigidBodyStateProjectionEvaluator(this)));
00214 }
00215
00216 };
00217
00219
00220 int main(int, char **)
00221 {
00222
00223 dInitODE2(0);
00224
00225
00226 oc::ODEEnvironmentPtr env(new RigidBodyEnvironment());
00227
00228
00229 RigidBodyStateSpace *stateSpace = new RigidBodyStateSpace(env);
00230 ob::StateSpacePtr stateSpacePtr = ob::StateSpacePtr(stateSpace);
00231
00232
00233 oc::ODESimpleSetup ss(stateSpacePtr);
00234
00235
00236 ss.setGoal(ob::GoalPtr(new RigidBodyGoal(ss.getSpaceInformation())));
00237
00238 ob::RealVectorBounds bounds(3);
00239 bounds.setLow(-200);
00240 bounds.setHigh(200);
00241 stateSpace->setVolumeBounds(bounds);
00242
00243 bounds.setLow(-20);
00244 bounds.setHigh(20);
00245 stateSpace->setLinearVelocityBounds(bounds);
00246 stateSpace->setAngularVelocityBounds(bounds);
00247
00248 ss.setup();
00249 ss.print();
00250
00251 if (ss.solve(10))
00252 {
00253 const og::PathGeometric &p = ss.getSolutionPath().asGeometric();
00254 const std::vector<ob::State*> &states = p.states;
00255 for (unsigned int i = 0 ; i < states.size() ; ++i)
00256 {
00257 const double *pos = states[i]->as<ob::CompoundState>()->as<ob::RealVectorStateSpace::StateType>(0)->values;
00258 std::cout << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;
00259 }
00260 }
00261
00262 dCloseODE();
00263
00264 return 0;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00275
00276
00277
00278
00279
00280 void RigidBodyEnvironment::createWorld(void)
00281 {
00282
00283
00284
00285 bodyWorld = dWorldCreate();
00286 space = dHashSpaceCreate(0);
00287
00288 dWorldSetGravity(bodyWorld, 0, 0, -0.981);
00289
00290 double lx = 0.2;
00291 double ly = 0.2;
00292 double lz = 0.1;
00293
00294 dMassSetBox(&m, 1, lx, ly, lz);
00295
00296 boxGeom = dCreateBox(space, lx, ly, lz);
00297 boxBody = dBodyCreate(bodyWorld);
00298 dBodySetMass(boxBody, &m);
00299 dGeomSetBody(boxGeom, boxBody);
00300
00301
00302
00303
00304 setPlanningParameters();
00305 }
00306
00307 void RigidBodyEnvironment::destroyWorld(void)
00308 {
00309 dSpaceDestroy(space);
00310 dWorldDestroy(bodyWorld);
00311 }
00312
00313 void RigidBodyEnvironment::setPlanningParameters(void)
00314 {
00315
00316 world_ = bodyWorld;
00317 collisionSpaces_.push_back(space);
00318 stateBodies_.push_back(boxBody);
00319 stepSize_ = 0.05;
00320 maxContacts_ = 3;
00321 minControlSteps_ = 10;
00322 maxControlSteps_ = 500;
00323 }