GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/planner/dynamic-planner.cc Lines: 137 232 59.1 %
Date: 2024-02-02 12:21:48 Branches: 187 566 33.0 %

Line Branch Exec Source
1
//
2
// Copyright (c) 2014 CNRS
3
// Authors: Florent Lamiraux
4
//
5
// This file is part of hpp-core
6
// hpp-core is free software: you can redistribute it
7
// and/or modify it under the terms of the GNU Lesser General Public
8
// License as published by the Free Software Foundation, either version
9
// 3 of the License, or (at your option) any later version.
10
//
11
// hpp-core is distributed in the hope that it will be
12
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Lesser Public License for more details.  You should have
15
// received a copy of the GNU Lesser General Public License along with
16
// hpp-core  If not, see
17
// <http://www.gnu.org/licenses/>.
18
19
#include <hpp/fcl/collision_data.h>
20
21
#include <boost/tuple/tuple.hpp>
22
#include <hpp/centroidal-dynamics/centroidal_dynamics.hh>
23
#include <hpp/core/config-projector.hh>
24
#include <hpp/core/config-validations.hh>
25
#include <hpp/core/configuration-shooter/uniform.hh>
26
#include <hpp/core/edge.hh>
27
#include <hpp/core/kinodynamic-distance.hh>
28
#include <hpp/core/node.hh>
29
#include <hpp/core/path-projector.hh>
30
#include <hpp/core/path-validation-report.hh>
31
#include <hpp/core/path-validation.hh>
32
#include <hpp/core/path.hh>
33
#include <hpp/core/problem.hh>
34
#include <hpp/core/roadmap.hh>
35
#include <hpp/core/steering-method.hh>
36
#include <hpp/pinocchio/configuration.hh>
37
#include <hpp/pinocchio/device.hh>
38
#include <hpp/rbprm/planner/dynamic-planner.hh>
39
#include <hpp/rbprm/planner/parabola-path.hh>
40
#include <hpp/rbprm/planner/rbprm-roadmap.hh>
41
#include <hpp/rbprm/planner/rbprm-steering-kinodynamic.hh>
42
#include <hpp/rbprm/rbprm-device.hh>
43
#include <hpp/rbprm/rbprm-path-validation.hh>
44
#include <hpp/rbprm/rbprm-validation-report.hh>
45
#include <hpp/util/debug.hh>
46
#include <hpp/util/timer.hh>
47
48
#include "hpp/rbprm/utils/algorithms.h"
49
50
namespace hpp {
51
namespace rbprm {
52
using core::BiRRTPlanner;
53
using core::Configuration_t;
54
using core::ConfigurationPtr_t;
55
using core::Path;
56
using core::PathPtr_t;
57
using core::Problem;
58
using core::Roadmap;
59
using core::RoadmapPtr_t;
60
using core::size_type;
61
using pinocchio::displayConfig;
62
using pinocchio::value_type;
63
64
typedef centroidal_dynamics::MatrixXX MatrixXX;
65
typedef centroidal_dynamics::Matrix6X Matrix6X;
66
typedef centroidal_dynamics::Vector3 Vector3;
67
typedef centroidal_dynamics::Matrix3 Matrix3;
68
typedef centroidal_dynamics::Matrix63 Matrix63;
69
typedef centroidal_dynamics::Vector6 Vector6;
70
typedef centroidal_dynamics::VectorX VectorX;
71
72
24
DynamicPlannerPtr_t DynamicPlanner::createWithRoadmap(
73
    core::ProblemConstPtr_t problem, const RoadmapPtr_t& roadmap) {
74

24
  DynamicPlanner* ptr = new DynamicPlanner(problem, roadmap);
75
24
  return DynamicPlannerPtr_t(ptr);
76
}
77
78
DynamicPlannerPtr_t DynamicPlanner::create(core::ProblemConstPtr_t problem) {
79
  DynamicPlanner* ptr = new DynamicPlanner(problem);
80
  return DynamicPlannerPtr_t(ptr);
81
}
82
83
DynamicPlanner::DynamicPlanner(core::ProblemConstPtr_t problem)
84
    : BiRRTPlanner(problem),
85
      qProj_(new core::Configuration_t(problem->robot()->configSize())),
86
      roadmap_(dynamic_pointer_cast<core::Roadmap>(
87
          core::RbprmRoadmap::create(problem->distance(), problem->robot()))),
88
      sm_(dynamic_pointer_cast<SteeringMethodKinodynamic>(
89
          problem->steeringMethod())),
90
      smParabola_(rbprm::SteeringMethodParabola::create(problem)),
91
      rbprmPathValidation_(dynamic_pointer_cast<RbPrmPathValidation>(
92
          problem->pathValidation())) {
93
  assert(sm_ &&
94
         "steering method should be a kinodynamic steering method for this "
95
         "solver");
96
  assert(
97
      rbprmPathValidation_ &&
98
      "Path validation should be a RbPrmPathValidation class for this solver");
99
  assert(problem->robot()->mass() > 0. &&
100
         "When using dynamic planner, the robot mass should be correctly "
101
         "defined.");
102
  hppDout(notice, "number of affordances objects : "
103
                      << problem->collisionObstacles().size());
104
105
  sizeFootX_ = problem->getParameter(std::string("DynamicPlanner/sizeFootX"))
106
                   .floatValue() /
107
               2.;
108
  sizeFootY_ = problem->getParameter(std::string("DynamicPlanner/sizeFootY"))
109
                   .floatValue() /
110
               2.;
111
  if (sizeFootX_ > 0. && sizeFootY_ > 0.)
112
    rectangularContact_ = 1;
113
  else
114
    rectangularContact_ = 0;
115
116
  tryJump_ =
117
      problem->getParameter(std::string("DynamicPlanner/tryJump")).boolValue();
118
  hppDout(notice, "tryJump in dynamic planner = " << tryJump_);
119
  mu_ = problem->getParameter(std::string("DynamicPlanner/friction"))
120
            .floatValue();
121
  hppDout(notice, "mu define in python : " << mu_);
122
}
123
124
24
DynamicPlanner::DynamicPlanner(core::ProblemConstPtr_t problem,
125
24
                               const RoadmapPtr_t& roadmap)
126
    : BiRRTPlanner(problem, roadmap),
127

24
      qProj_(new core::Configuration_t(problem->robot()->configSize())),
128
      roadmap_(dynamic_pointer_cast<core::Roadmap>(
129
48
          core::RbprmRoadmap::create(problem->distance(), problem->robot()))),
130
      sm_(dynamic_pointer_cast<SteeringMethodKinodynamic>(
131
48
          problem->steeringMethod())),
132
      smParabola_(rbprm::SteeringMethodParabola::create(problem)),
133
      rbprmPathValidation_(dynamic_pointer_cast<RbPrmPathValidation>(
134

120
          problem->pathValidation())) {
135
24
  assert(sm_ &&
136
         "steering method should be a kinodynamic steering method for this "
137
         "solver");
138
24
  assert(
139
      rbprmPathValidation_ &&
140
      "Path validation should be a RbPrmPathValidation class for this solver");
141

24
  assert(problem->robot()->mass() > 0. &&
142
         "When using dynamic planner, the robot mass should be correctly "
143
         "defined.");
144
145
  hppDout(notice, "number of affordances objects : "
146
                      << problem->collisionObstacles().size());
147

48
  sizeFootX_ = problem->getParameter(std::string("DynamicPlanner/sizeFootX"))
148
24
                   .floatValue() /
149
               2.;
150

48
  sizeFootY_ = problem->getParameter(std::string("DynamicPlanner/sizeFootY"))
151
24
                   .floatValue() /
152
               2.;
153

24
  if (sizeFootX_ > 0. && sizeFootY_ > 0.)
154
24
    rectangularContact_ = 1;
155
  else
156
    rectangularContact_ = 0;
157
158
24
  tryJump_ =
159

24
      problem->getParameter(std::string("DynamicPlanner/tryJump")).boolValue();
160
  hppDout(notice, "tryJump in dynamic planner = " << tryJump_);
161

48
  mu_ = problem->getParameter(std::string("DynamicPlanner/friction"))
162
24
            .floatValue();
163
  hppDout(notice, "mu define in python : " << mu_);
164
24
}
165
166
void DynamicPlanner::init(const DynamicPlannerWkPtr_t& weak) {
167
  BiRRTPlanner::init(weak);
168
  weakPtr_ = weak;
169
}
170
171
1038
core::PathPtr_t DynamicPlanner::extendInternal(
172
    core::ConfigurationPtr_t& qProj_, const core::NodePtr_t& near,
173
    const core::ConfigurationPtr_t& target, bool reverse) {
174
1038
  const core::ConstraintSetPtr_t& constraints(sm_->constraints());
175
1038
  if (constraints) {
176
2076
    core::ConfigProjectorPtr_t configProjector(constraints->configProjector());
177
1038
    if (configProjector) {
178
      configProjector->projectOnKernel(*(near->configuration()), *target,
179
                                       *qProj_);
180
    } else {
181
1038
      *qProj_ = *target;
182
    }
183
184

1038
    if (constraints->apply(*qProj_)) {
185




1038
      return reverse ? (*sm_)(*qProj_, near) : (*sm_)(near, *qProj_);
186
    } else {
187
      return PathPtr_t();
188
    }
189
  }
190
  return reverse ? (*sm_)(*target, near) : (*sm_)(near, *target);
191
}
192
193
core::PathPtr_t DynamicPlanner::extendParabola(
194
    const core::ConfigurationPtr_t& from,
195
    const core::ConfigurationPtr_t& target, bool reverse) {
196
  const core::SteeringMethodPtr_t& sm(problem()->steeringMethod());
197
  const core::ConstraintSetPtr_t& constraints(sm->constraints());
198
  core::PathPtr_t path;
199
  if (constraints) {
200
    core::ConfigProjectorPtr_t configProjector(constraints->configProjector());
201
    if (configProjector) {
202
      configProjector->projectOnKernel(*from, *target, *qProj_);
203
    } else {
204
      *qProj_ = *target;
205
    }
206
    if (constraints->apply(*qProj_)) {
207
      if (reverse)
208
        path = (*smParabola_)(*qProj_, *from);
209
      else
210
        path = (*smParabola_)(*from, *qProj_);
211
    } else {
212
      return core::PathPtr_t();
213
    }
214
  } else {
215
    if (reverse)
216
      path = (*smParabola_)(*target, *from);
217
    else
218
      path = (*smParabola_)(*from, *target);
219
  }
220
  return path;
221
}
222
223
bool DynamicPlanner::tryParabolaPath(const core::NodePtr_t& x_near,
224
                                     core::ConfigurationPtr_t q_last,
225
                                     const core::ConfigurationPtr_t& target,
226
                                     bool reverse, core::NodePtr_t& x_jump,
227
                                     core::NodePtr_t& x_new,
228
                                     core::PathPtr_t& kinoPath,
229
                                     core::PathPtr_t& paraPath) {
230
  bool success(false);
231
  core::PathValidationPtr_t pathValidation(problem()->pathValidation());
232
  core::PathPtr_t validPath;
233
  core::PathValidationReportPtr_t report;
234
  const size_type indexECS =
235
      problem()->robot()->configSize() -
236
      problem()->robot()->extraConfigSpace().dimension();  // ecs index
237
  bool kinoPathValid(false);
238
  hppDout(notice, "!! begin tryParabolaPath");
239
240
  // 1. compute a parabola between last configuration valid in contact, and
241
  // qrand (target)
242
  paraPath = extendParabola(q_last, target, reverse);
243
  if (paraPath) {
244
    hppDout(notice, "!! ParaPath computed");
245
    if (paraPath->length() >
246
        0) {  // only add if the full path is valid (because we can't extract a
247
              // subpath of a parabola path)
248
      hppDout(notice, "!! parabola path valid !");
249
      ParabolaPathPtr_t parabolaPath =
250
          dynamic_pointer_cast<ParabolaPath>(paraPath);
251
      core::ConfigurationPtr_t q_new(
252
          new core::Configuration_t(parabolaPath->end()));
253
      core::ConfigurationPtr_t q_jump(
254
          new core::Configuration_t(parabolaPath->initial()));
255
      // 2. update q_jump with the correct initial velocity needed for the
256
      // computed parabola
257
      // TODO : update q_jump with the right velocity from parabola
258
      for (size_t i = 0; i < 3; ++i) {
259
        (*q_jump)[indexECS + i] = parabolaPath->V0_[i];
260
        (*q_new)[indexECS + i] = parabolaPath->Vimp_[i];
261
      }
262
263
      hppDout(notice, "q_last = " << displayConfig(*q_last));
264
      hppDout(notice, "q_jump = " << displayConfig(*q_jump));
265
      hppDout(notice, "q_target = " << displayConfig(*target));
266
      hppDout(notice, "q_new = " << displayConfig(*q_new));
267
268
      // 3. compute a kinodynamic path between near and q_jump
269
      hppStartBenchmark(EXTEND);
270
      kinoPath = extendInternal(qProj_, x_near, q_jump, reverse);
271
      hppStopBenchmark(EXTEND);
272
      hppDisplayBenchmark(EXTEND);
273
      if (kinoPath) {
274
        hppDout(notice, "!! Kino path computed");
275
        kinoPathValid =
276
            pathValidation->validate(kinoPath, false, validPath, report);
277
        if (kinoPathValid) {
278
          hppDout(notice, "!! Kino path valid !");
279
          value_type t_final = validPath->timeRange().second;
280
          if (t_final != kinoPath->timeRange().first &&
281
              validPath->end() == *(q_jump)) {
282
            // 4. add both nodes and edges to the roadmap
283
            success = true;
284
            hppDout(notice, "add both nodes and edges to the roadmap");
285
            x_jump = roadmap()->addNodeAndEdge(x_near, q_jump, kinoPath);
286
            computeGIWC(x_jump);
287
            x_new = roadmap()->addNodeAndEdge(x_jump, q_new, paraPath);
288
            computeGIWC(x_new);
289
          } else {
290
            hppDout(notice, "!! lenght of Kino path incorrect.");
291
          }
292
        } else {
293
          hppDout(notice, "!! Kino path not valid.");
294
        }
295
      } else {
296
        hppDout(notice, "!! Kino path doesn't exist.");
297
      }
298
    } else {
299
      hppDout(notice, "!! Parabola path not valid.");
300
    }
301
  } else {
302
    hppDout(notice, "!! parabola path doesn't exist.");
303
  }
304
305
  return success;
306
}
307
308
431
void DynamicPlanner::oneStep() {
309
  hppDout(info,
310
          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new Step "
311
          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
312
  PathPtr_t validPath, path;
313
431
  core::PathValidationPtr_t pathValidation(problem()->pathValidation());
314
  value_type distance;
315
  core::NodePtr_t near, reachedNodeFromStart;
316
431
  bool startComponentConnected(false), pathValidFromStart(false),
317
431
      pathValidFromEnd(false);
318
  ConfigurationPtr_t q_new;
319
  hppStartBenchmark(SHOOT);
320
431
  ConfigurationPtr_t q_rand = configurationShooter_->shoot();
321
  hppDout(info, "Random configuration : " << displayConfig(*q_rand));
322
  hppStopBenchmark(SHOOT);
323
  hppDisplayBenchmark(SHOOT);
324
325
  // ######################## first , try to connect to start component
326
  // #################### //
327
  hppStartBenchmark(NEAREST);
328

431
  near = roadmap()->nearestNode(q_rand, startComponent_, distance);
329
  hppStopBenchmark(NEAREST);
330
  hppDisplayBenchmark(NEAREST);
331
332
431
  core::RbprmNodePtr_t castNode = static_cast<core::RbprmNodePtr_t>(near);
333
  if (castNode)
334
    hppDout(notice, "Node casted correctly");
335
  else
336
    hppDout(notice, "Impossible to cast node to rbprmNode");
337
338
  hppStartBenchmark(EXTEND);
339
431
  path = extendInternal(qProj_, near, q_rand);
340
  hppStopBenchmark(EXTEND);
341
  hppDisplayBenchmark(EXTEND);
342
431
  if (path) {
343
431
    core::PathValidationReportPtr_t report;
344
    pathValidFromStart =
345
431
        pathValidation->validate(path, false, validPath, report);
346
347
    // Insert new path to q_near in roadmap
348
431
    if (validPath) {
349
299
      if (validPath->timeRange().second != path->timeRange().first) {
350
221
        pathValidFromStart =
351



221
            pathValidFromStart && (validPath->end() == *q_rand);
352
221
        startComponentConnected = true;
353

221
        q_new = ConfigurationPtr_t(new Configuration_t(validPath->end()));
354
221
        reachedNodeFromStart =
355

221
            roadmap()->addNodeAndEdge(near, q_new, validPath);
356
221
        computeGIWC(reachedNodeFromStart);
357
        hppDout(info,
358
                "~~~~~~~~~~~~~~~~~~~~ New node added to start component : "
359
                    << displayConfig(*q_new));
360
      } else {
361
78
        pathValidFromStart = false;
362
      }
363
    }
364
  }
365
366
  hppDout(info,
367
          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Try to connect end component "
368
          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
369
370
  // ######################## now try to connect qrand to end components (in
371
  // reverse )######################## //
372
860
  for (auto& itcc : endComponents_) {
373
    hppStartBenchmark(NEAREST);
374

431
    near = roadmap()->nearestNode(q_rand, itcc, distance, true);
375
    hppStopBenchmark(NEAREST);
376
    hppDisplayBenchmark(NEAREST);
377
378
    hppStartBenchmark(EXTEND);
379
431
    path = extendInternal(qProj_, near, q_rand, true);
380
    hppStopBenchmark(EXTEND);
381
    hppDisplayBenchmark(EXTEND);
382
431
    if (path) {
383
      core::PathValidationReportPtr_t report;
384
      pathValidFromEnd =
385
431
          pathValidation->validate(path, true, validPath, report);
386

431
      if (pathValidFromStart && validPath) {
387



30
        pathValidFromEnd = pathValidFromEnd && (validPath->initial() == *q_new);
388
      }
389

431
      if (pathValidFromStart &&
390
          pathValidFromEnd)  // qrand was successfully connected to both trees
391
      {
392
        // we won, a path is found
393

1
        roadmap()->addEdge(reachedNodeFromStart, near, validPath);
394
        hppDout(
395
            info,
396
            "~~~~~~~~~~~~~~~~~~~~ Start and goal component connected !!!!!! "
397
                << displayConfig(*q_new));
398
        hppDout(notice, "#### end of planning phase #### ");
399
1
        return;
400
430
      } else if (validPath) {
401
376
        value_type t_final = validPath->timeRange().second;
402
376
        if (t_final != path->timeRange().first) {
403
          ConfigurationPtr_t q_newEnd =
404

277
              ConfigurationPtr_t(new Configuration_t(validPath->initial()));
405
          core::NodePtr_t newNode =
406

277
              roadmap()->addNodeAndEdge(q_newEnd, near, validPath);
407
277
          computeGIWC(newNode);
408
          hppDout(info,
409
                  "~~~~~~~~~~~~~~~~~~~~~~ New node added to end component : "
410
                      << displayConfig(*q_newEnd));
411
412
277
          if (startComponentConnected) {  // now try to connect both nodes (qnew
413
                                          // -> qnewEnd)
414
            hppStartBenchmark(EXTEND);
415
            path =
416
152
                extendInternal(qProj_, reachedNodeFromStart, q_newEnd, false);
417
            hppStopBenchmark(EXTEND);
418
            hppDisplayBenchmark(EXTEND);
419

243
            if (path &&
420

243
                pathValidation->validate(path, false, validPath, report)) {
421

1
              if (validPath->end() == *q_newEnd) {
422

1
                roadmap()->addEdge(reachedNodeFromStart, newNode, path);
423
                hppDout(info,
424
                        "~~~~~~~~ both new nodes connected together !!!!!! "
425
                            << displayConfig(*q_new));
426
1
                return;
427
              }
428
            }
429
          }
430
        }
431
      }
432
    }
433
  }
434
}
435
436
548
void DynamicPlanner::computeGIWC(const core::NodePtr_t x, bool use_bestReport) {
437
  core::ValidationReportPtr_t report;
438
  // randomnize the collision pair, in order to get a different surface of
439
  // contact each time (because only the first one in collision is considered by
440
  // fcl and put in the report)
441
1096
  rbprmPathValidation_->getValidator()
442
548
      ->randomnizeCollisionPairs();  // FIXME : remove if we compute all
443
                                     // collision pairs
444
548
  rbprmPathValidation_->getValidator()->computeAllContacts(true);
445
  hppDout(notice, "Compute GIWC, call validate for configuration : "
446
                      << pinocchio::displayConfig(*(x->configuration())));
447

548
  problem()->configValidations()->validate(*(x->configuration()), report);
448
548
  rbprmPathValidation_->getValidator()->computeAllContacts(false);
449
548
  if (use_bestReport) {
450
548
    core::RbprmNodePtr_t node = static_cast<core::RbprmNodePtr_t>(x);
451
548
    node->chooseBestContactSurface(
452
        report,
453
1096
        dynamic_pointer_cast<pinocchio::RbPrmDevice>(problem()->robot()));
454
  }
455
548
  computeGIWC(x, report);
456
548
}
457
458
548
void DynamicPlanner::computeGIWC(const core::NodePtr_t xNode,
459
                                 core::ValidationReportPtr_t report) {
460
548
  core::RbprmNodePtr_t node = static_cast<core::RbprmNodePtr_t>(xNode);
461
  hppDout(notice, "## compute GIWC");
462
548
  core::ConfigurationPtr_t q = node->configuration();
463
  // fil normal information in node
464
548
  if (node) {
465
    hppDout(info, "~~ NODE cast correctly");
466
  } else {
467
    hppDout(error, "~~ NODE cannot be cast");
468
    return;
469
  }
470
471
  hppDout(info, "~~ q = " << displayConfig(*q));
472
548
  node->fillNodeMatrices(
473
548
      report, rectangularContact_, sizeFootX_, sizeFootY_,
474

1096
      problem()->robot()->mass(), mu_,
475
1096
      dynamic_pointer_cast<pinocchio::RbPrmDevice>(problem()->robot()));
476
}  // computeGIWC
477
478
// re implement virtual method, same as base class but without the symetric edge
479
// (goal -> start)
480
24
void DynamicPlanner::tryConnectInitAndGoals() {
481
  // call steering method here to build a direct conexion
482
48
  core::PathValidationPtr_t pathValidation(problem()->pathValidation());
483
48
  core::PathProjectorPtr_t pathProjector(problem()->pathProjector());
484
24
  core::PathPtr_t validPath, projPath, path, kinoPath, paraPath;
485
24
  core::NodePtr_t initNode = roadmap()->initNode();
486
  core::NodePtr_t x_jump;
487
24
  computeGIWC(initNode, true);
488

48
  for (auto& itn : roadmap()->goalNodes()) {
489
24
    computeGIWC(itn, true);
490
24
    core::ConfigurationPtr_t q1((initNode)->configuration());
491
24
    core::ConfigurationPtr_t q2(itn->configuration());
492

24
    assert(*q1 != *q2);
493
    hppStartBenchmark(EXTEND);
494
24
    path = extendInternal(qProj_, initNode, q2);
495
    hppStopBenchmark(EXTEND);
496
    hppDisplayBenchmark(EXTEND);
497
    hppDout(notice, "try direction path, after extendInternal");
498
24
    if (!path) continue;
499
    hppDout(notice, "try direction path, after continue");
500
501
24
    if (pathProjector) {
502
      if (!pathProjector->apply(path, projPath)) continue;
503
    } else {
504
24
      projPath = path;
505
    }
506
24
    if (projPath) {
507
24
      core::PathValidationReportPtr_t report;
508
      // roadmap ()->addEdge (initNode, itn, projPath);  // (TODO a
509
      // supprimer)display the path no matter if it's successful or not
510
511
      bool pathValid =
512
24
          pathValidation->validate(projPath, false, validPath, report);
513
514
      // roadmap ()->addEdge (initNode, itn, validPath);  // (TODO a
515
      // supprimer)display the path no matter if it's successful or not
516
517

46
      if (pathValid &&
518
22
          validPath->timeRange().second !=
519
22
              path->timeRange().first) {  // connection to goal config
520
                                          // successfull, add the edge
521

22
        roadmap()->addEdge(initNode, itn, projPath);
522
2
      } else if (validPath) {
523
2
        if (tryJump_) {
524
          std::vector<std::string> filter;
525
          core::ValidationReportPtr_t valReport;
526
          // check if the validation fail because of the ROM or because of the
527
          // trunk
528
          RbPrmPathValidationPtr_t rbprmPathValidation =
529
              dynamic_pointer_cast<RbPrmPathValidation>(pathValidation);
530
          bool successPathOperator;
531
          bool trunkValid = rbprmPathValidation->getValidator()->validate(
532
              (*projPath)(report->parameter, successPathOperator), valReport,
533
              filter);
534
          if (trunkValid &&
535
              successPathOperator) {  // if it failed because of the ROM, we can
536
                                      // try a parabola
537
            core::ConfigurationPtr_t q_jump(
538
                new core::Configuration_t(validPath->end()));
539
            core::NodePtr_t x_goal;
540
            bool parabolaSuccess =
541
                tryParabolaPath(initNode, q_jump, q2, false, x_jump, x_goal,
542
                                kinoPath, paraPath);
543
            hppDout(notice, "parabola success = " << parabolaSuccess);
544
            if (parabolaSuccess) {
545
              hppDout(notice, "x_goal conf = "
546
                                  << displayConfig(*(x_goal->configuration())));
547
              roadmap()->addEdge(x_jump, itn, paraPath);
548
            }
549
          } else {
550
            hppDout(notice, "trunk in collision");
551
          }
552
2
        } else if (validPath->timeRange().second !=
553
2
                   path->timeRange().first) {  // add the last valid configu
554
                                               // reached to the roadmap
555
          core::ConfigurationPtr_t q_new(
556

4
              new core::Configuration_t(validPath->end()));
557
          core::NodePtr_t x_new =
558

2
              roadmap()->addNodeAndEdge(initNode, q_new, validPath);
559
2
          computeGIWC(x_new);
560
        }
561
      }
562
    }
563
  }
564
24
}
565
566
24
core::PathVectorPtr_t DynamicPlanner::finishSolve(
567
    const core::PathVectorPtr_t& path) {
568
  /*std::cout<<"total_path_computed = "<<sm_->totalTimeComputed_<<std::endl;
569
  std::cout<<"total_path_validated = "<<sm_->totalTimeValidated_<<std::endl;
570
  std::cout<<"percentage validated path
571
  ="<<((sm_->totalTimeValidated_)/(sm_->totalTimeComputed_))*100.<<std::endl;
572
  std::cout<<"rejected_paths = "<<sm_->rejectedPath_<<std::endl;
573
  */
574
  /*
575
  std::ofstream myfile;
576
  myfile.open ("/local/dev_hpp/benchs/benchHyq_darpa.txt", std::ios::out |
577
  std::ios::app ); myfile<<"total_path_computed =
578
  "<<sm_->totalTimeComputed_<<std::endl; myfile<<"total_path_validated =
579
  "<<sm_->totalTimeValidated_<<std::endl; myfile<<"percentage_validated_path
580
  ="<<(double)sm_->totalTimeValidated_/sm_->totalTimeValidated_<<std::endl;
581
  myfile<<"total_direction_computed = "<<sm_->dirTotal_<<std::endl;
582
  myfile<<"total_direction_valid = "<<sm_->dirValid_<<std::endl;
583
  myfile<<"percentage_valide_direction
584
  ="<<(double)(((double)sm_->dirValid_)/((double)sm_->dirTotal_))<<std::endl;
585
  myfile<<"rejected_paths = "<<sm_->rejectedPath_<<std::endl;
586
  myfile<<"num_nodes = "<<roadmap()->nodes().size()<<std::endl;
587
588
  myfile.close();
589
  */
590
24
  return path;
591
}
592
593
3
HPP_START_PARAMETER_DECLARATION(Kinodynamic)
594


3
Problem::declareParameter(core::ParameterDescription(
595
    core::Parameter::FLOAT, "DynamicPlanner/sizeFootX",
596
    "The lenght of the feet along X axis (assuming rectangular feet).",
597
6
    core::Parameter(0.)));
598


3
Problem::declareParameter(core::ParameterDescription(
599
    core::Parameter::FLOAT, "DynamicPlanner/sizeFootY",
600
    "The lenght of the feet along Y axis (assuming rectangular feet).",
601
6
    core::Parameter(0.)));
602


3
Problem::declareParameter(core::ParameterDescription(
603
    core::Parameter::FLOAT, "DynamicPlanner/friction",
604
    "Value of the friction coefficient between the feet of the robot and the "
605
    "ground.",
606
6
    core::Parameter(0.5)));
607


3
Problem::declareParameter(core::ParameterDescription(
608
    core::Parameter::BOOL, "DynamicPlanner/tryJump",
609
    "If True, when a trajectory is invalid because all the rom leave "
610
    "the contact, a ballistic motion is tried to connect both states",
611
6
    core::Parameter(false)));
612
3
HPP_END_PARAMETER_DECLARATION(Kinodynamic)
613
614
}  // namespace rbprm
615
}  // namespace hpp