GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
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 |
Generated by: GCOVR (Version 4.2) |