GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tests/tools-obstacle.hh Lines: 104 157 66.2 %
Date: 2024-02-02 12:21:48 Branches: 149 386 38.6 %

Line Branch Exec Source
1
2
// Copyright (C) 2018 LAAS-CNRS
3
// Author: Pierre Fernbach
4
//
5
// This file is part of the hpp-rbprm.
6
//
7
// hpp-rbprm is free software: you can redistribute it and/or modify
8
// it under the terms of the GNU Lesser General Public License as published by
9
// the Free Software Foundation, either version 3 of the License, or
10
// (at your option) any later version.
11
//
12
// test-hpp is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU Lesser General Public License for more details.
16
//
17
// You should have received a copy of the GNU Lesser General Public License
18
// along with hpp-core.  If not, see <http://www.gnu.org/licenses/>.
19
20
#ifndef TOOLSOBSTACLE_HH
21
#define TOOLSOBSTACLE_HH
22
23
#include <hpp/affordance/affordance-extraction.hh>
24
#include <hpp/affordance/operations.hh>
25
#include <hpp/core/config-validations.hh>
26
#include <hpp/core/problem-solver.hh>
27
#include <hpp/core/problem.hh>
28
#include <hpp/pinocchio/device.hh>
29
#include <hpp/pinocchio/fwd.hh>
30
#include <hpp/pinocchio/urdf/util.hh>
31
#include <hpp/rbprm/dynamic/dynamic-path-validation.hh>
32
#include <hpp/rbprm/planner/dynamic-planner.hh>
33
#include <hpp/rbprm/planner/oriented-path-optimizer.hh>
34
#include <hpp/rbprm/planner/random-shortcut-dynamic.hh>
35
#include <hpp/rbprm/planner/rbprm-steering-kinodynamic.hh>
36
#include <hpp/rbprm/rbprm-device.hh>
37
#include <hpp/rbprm/rbprm-path-validation.hh>
38
#include <hpp/rbprm/rbprm-shooter.hh>
39
#include <pinocchio/parsers/urdf.hpp>
40
41
#if BOOST_VERSION / 100 % 1000 >= 60
42
#include <boost/bind/bind.hpp>
43
using namespace boost::placeholders;
44
#else
45
#include <boost/bind.hpp>
46
#endif
47
48
using namespace hpp;
49
using namespace hpp::core;
50
51
13
void addAffObjects(hpp::core::ProblemSolver& problemSolver,
52
                   const affordance::OperationBases_t& ops,
53
                   const std::vector<affordance::CollisionObjects_t>& affObjs,
54
                   const std::string obstacleNameNonAff) {
55
26
  const std::string affSuffix = "aff";
56
26
  std::string obstacleName(obstacleNameNonAff);
57
13
  obstacleName += affSuffix;
58
52
  for (unsigned int opIdx = 0; opIdx < ops.size(); opIdx++) {
59
78
    AffordanceObjects_t objs;
60
39
    affordance::CollisionObjects_t affs = affObjs[opIdx];
61
209
    for (unsigned int objIdx = 0; objIdx < affs.size(); objIdx++) {
62
340
      std::stringstream ss;
63

170
      ss << opIdx << "_" << objIdx;
64

340
      std::string ig = obstacleName + ss.str();
65
170
      problemSolver.addObstacle(ig, *(affs[objIdx]), false, false);
66
170
      hpp::pinocchio::CollisionObjectPtr_t obj = problemSolver.obstacle(ig);
67

170
      objs.push_back(std::make_pair(ig, obj));
68
    }
69

39
    if (problemSolver.affordanceObjects.has(ops[opIdx]->affordance_)) {
70
      AffordanceObjects_t mapObjs =
71
          problemSolver.affordanceObjects.get(ops[opIdx]->affordance_);
72
      objs.insert(objs.begin() + objs.size(), mapObjs.begin(), mapObjs.end());
73
    }
74

39
    problemSolver.affordanceObjects.erase(ops[opIdx]->affordance_);
75

39
    problemSolver.affordanceObjects.add(ops[opIdx]->affordance_, objs);
76
  }
77
13
}
78
79
13
void affordanceAnalysis(ProblemSolver& problemSolver,
80
                        const std::string& obstacleName,
81
                        const affordance::OperationBases_t& operations,
82
                        std::vector<double> reduceSizes) {
83
26
  std::list<std::string> obstacles = problemSolver.obstacleNames(true, true);
84
  std::list<std::string>::iterator objIt =
85
13
      std::find(obstacles.begin(), obstacles.end(), obstacleName);
86

13
  while (reduceSizes.size() < operations.size()) reduceSizes.push_back(0.);
87
13
  if (objIt == obstacles.end())
88
    throw std::runtime_error(
89
        "No obstacle by given name found. Unable to analyse.");
90
  try {
91
    affordance::SemanticsDataPtr_t aff = affordance::affordanceAnalysis(
92

26
        (problemSolver.obstacle(obstacleName)->fcl()), operations);
93
    std::vector<std::vector<fcl::CollisionObjectPtr_t> > affObjs =
94

13
        affordance::getReducedAffordanceObjects(aff, reduceSizes);
95
    // add fcl::CollisionObstacles to problemSolver
96

13
    addAffObjects(problemSolver, operations, affObjs, obstacleName);
97
  } catch (const std::exception& exc) {
98
    throw std::runtime_error(exc.what());
99
  }
100
13
}
101
102
13
affordance::OperationBases_t createOperations(
103
    hpp::core::ProblemSolver& pSolver) {
104

13
  pSolver.affordanceConfigs.add("Support", vector3_t(0.3, 0.3, 0.05));
105

13
  pSolver.affordanceConfigs.add("Lean", vector3_t(0.1, 0.3, 0.05));
106

13
  pSolver.affordanceConfigs.add("Support45", vector3_t(0.1, 0.3, 0.05));
107

13
  if (!pSolver.affordanceConfigs.has("Support"))
108
    throw std::runtime_error(
109
        "No 'Support' affordance type found Afford::createOperations ()");
110
  const hpp::pinocchio::vector3_t& sconf =
111

13
      pSolver.affordanceConfigs.get("Support");
112

13
  if (!pSolver.affordanceConfigs.has("Lean"))
113
    throw std::runtime_error(
114
        "No 'Lean' affordance type found in Afford::createOperations ()");
115
  const hpp::pinocchio::vector3_t& lconf =
116

13
      pSolver.affordanceConfigs.get("Lean");
117

13
  if (!pSolver.affordanceConfigs.has("Support45"))
118
    throw std::runtime_error(
119
        "No 'Support45' affordance type found in Afford::createOperations ()");
120
  const hpp::pinocchio::vector3_t& s45conf =
121

13
      pSolver.affordanceConfigs.get("Support45");
122
  affordance::SupportOperationPtr_t support(
123



26
      new affordance::SupportOperation(sconf[0], sconf[1], sconf[2]));
124
  affordance::LeanOperationPtr_t lean(
125



26
      new affordance::LeanOperation(lconf[0], lconf[1], lconf[2]));
126
  affordance::Support45OperationPtr_t support45(
127



26
      new affordance::Support45Operation(s45conf[0], s45conf[1], s45conf[2]));
128
129
13
  affordance::OperationBases_t operations;
130
13
  operations.push_back(support);
131
13
  operations.push_back(lean);
132
13
  operations.push_back(support45);
133
134
26
  return operations;
135
}
136
137
13
void loadObstacleWithAffordance(hpp::core::ProblemSolver& pSolver,
138
                                std::string packagename, std::string filename,
139
                                std::string prefix,
140
                                const affordance::OperationBases_t& operations,
141
                                std::vector<double> reduceSizes) {
142
26
  DevicePtr_t device(hpp::pinocchio::Device::create(prefix));
143
13
  if (packagename.empty())
144
    hpp::pinocchio::urdf::loadModelFromString(device, 0, "", "anchor", filename,
145
                                              "");
146
  else
147

13
    hpp::pinocchio::urdf::loadUrdfModel(device, "anchor", packagename,
148
                                        filename);
149
13
  device->controlComputation(hpp::pinocchio::JOINT_POSITION);
150
13
  pSolver.addObstacle(device, true, true);
151
26
  std::list<std::string> obstacles = pSolver.obstacleNames(true, false);
152
26
  for (std::list<std::string>::const_iterator cit = obstacles.begin();
153
39
       cit != obstacles.end(); ++cit) {
154
13
    if ((*cit).find(prefix) == 0)
155

13
      affordanceAnalysis(pSolver, *cit, operations, reduceSizes);
156
  }
157
13
}
158
159
13
void loadObstacleWithAffordance(hpp::core::ProblemSolver& pSolver,
160
                                std::string packagename, std::string filename,
161
                                std::string prefix) {
162
26
  affordance::OperationBases_t operations = createOperations(pSolver);
163
26
  std::vector<double> reduceSizes;
164

52
  while (reduceSizes.size() < operations.size()) reduceSizes.push_back(0.);
165


13
  return loadObstacleWithAffordance(pSolver, packagename, filename, prefix,
166
26
                                    operations, reduceSizes);
167
}
168
169
void loadDarpa(hpp::core::ProblemSolver& pSolver) {
170
  loadObstacleWithAffordance(pSolver, std::string("hpp_environments"),
171
                             std::string("multicontact/darpa"),
172
                             std::string("planning"));
173
}
174
175
typedef hpp::core::Container<hpp::core::AffordanceObjects_t> affMap_t;
176
struct BindShooter {
177
13
  BindShooter(const std::size_t shootLimit = 10000,
178
              const std::size_t displacementLimit = 100)
179
13
      : shootLimit_(shootLimit), displacementLimit_(displacementLimit) {}
180
181
37
  hpp::rbprm::RbPrmShooterPtr_t create(
182
      /*const hpp::pinocchio::DevicePtr_t& robot,*/ core::ProblemConstPtr_t
183
          problem,
184
      const hpp::core::ProblemSolverPtr_t problemSolver) {
185
    hpp::core::Container<hpp::core::AffordanceObjects_t> affMap_ =
186
74
        problemSolver->affordanceObjects;
187
37
    affMap_ = problemSolver->affordanceObjects;
188
    hpp::pinocchio::RbPrmDevicePtr_t robotcast =
189
74
        static_pointer_cast<hpp::pinocchio::RbPrmDevice>(problem->robot());
190
37
    if (affMap_.map.empty()) {
191
      throw std::runtime_error(
192
          "No affordances found. Unable to create shooter object.");
193
    }
194
    rbprm::RbPrmShooterPtr_t shooter = hpp::rbprm::RbPrmShooter::create(
195
        robotcast, problemSolver->problem()->collisionObstacles(), affMap_,
196

37
        romFilter_, affFilter_, shootLimit_, displacementLimit_);
197

37
    if (!so3Bounds_.empty()) shooter->BoundSO3(so3Bounds_);
198
74
    return shooter;
199
  }
200
201
13
  hpp::core::PathValidationPtr_t createPathValidation(
202
      const hpp::pinocchio::DevicePtr_t& robot,
203
      const hpp::pinocchio::value_type& val,
204
      const hpp::core::ProblemSolverPtr_t problemSolver) {
205
    hpp::pinocchio::RbPrmDevicePtr_t robotcast =
206
26
        static_pointer_cast<hpp::pinocchio::RbPrmDevice>(robot);
207
    hpp::core::Container<hpp::core::AffordanceObjects_t> affMap_ =
208
26
        problemSolver->affordanceObjects;
209
13
    if (affMap_.map.empty()) {
210
      throw std::runtime_error(
211
          "No affordances found. Unable to create Path Validaton object.");
212
    }
213
    hpp::rbprm::RbPrmValidationPtr_t validation(
214
13
        hpp::rbprm::RbPrmValidation::create(robotcast, romFilter_, affFilter_,
215
26
                                            affMap_));
216
    hpp::rbprm::RbPrmPathValidationPtr_t collisionChecking =
217
26
        hpp::rbprm::RbPrmPathValidation::create(robot, val);
218
13
    collisionChecking->add(validation);
219
26
    problemSolver->problem()->configValidation(
220
26
        core::ConfigValidations::create());
221
13
    problemSolver->problem()->configValidations()->add(validation);
222
26
    return collisionChecking;
223
  }
224
225
  hpp::core::PathValidationPtr_t createDynamicPathValidation(
226
      const hpp::pinocchio::DevicePtr_t& robot,
227
      const hpp::pinocchio::value_type& val,
228
      const hpp::core::ProblemSolverPtr_t problemSolver) {
229
    hpp::pinocchio::RbPrmDevicePtr_t robotcast =
230
        static_pointer_cast<hpp::pinocchio::RbPrmDevice>(robot);
231
    hpp::core::Container<hpp::core::AffordanceObjects_t> affMap_ =
232
        problemSolver->affordanceObjects;
233
    if (affMap_.map.empty()) {
234
      throw std::runtime_error(
235
          "No affordances found. Unable to create Path Validaton object.");
236
    }
237
    hpp::rbprm::RbPrmValidationPtr_t validation(
238
        hpp::rbprm::RbPrmValidation::create(robotcast, romFilter_, affFilter_,
239
                                            affMap_));
240
    hpp::rbprm::DynamicPathValidationPtr_t collisionChecking =
241
        hpp::rbprm::DynamicPathValidation::create(robot, val);
242
    collisionChecking->add(validation);
243
    problemSolver->problem()->configValidation(
244
        core::ConfigValidations::create());
245
    problemSolver->problem()->configValidations()->add(validation);
246
    // build the dynamicValidation :
247
    double sizeFootX, sizeFootY, mass, mu;
248
    bool rectangularContact;
249
    sizeFootX = problemSolver->problem()
250
                    ->getParameter(std::string("DynamicPlanner/sizeFootX"))
251
                    .floatValue() /
252
                2.;
253
    sizeFootY = problemSolver->problem()
254
                    ->getParameter(std::string("DynamicPlanner/sizeFootY"))
255
                    .floatValue() /
256
                2.;
257
    if (sizeFootX > 0. && sizeFootY > 0.)
258
      rectangularContact = 1;
259
    else
260
      rectangularContact = 0;
261
    mass = robot->mass();
262
    mu = problemSolver->problem()
263
             ->getParameter(std::string("DynamicPlanner/friction"))
264
             .floatValue();
265
    hppDout(notice, "mu define in python : " << mu);
266
    DynamicValidationPtr_t dynamicVal = DynamicValidation::create(
267
        rectangularContact, sizeFootX, sizeFootY, mass, mu, robot);
268
    collisionChecking->addDynamicValidator(dynamicVal);
269
270
    return collisionChecking;
271
  }
272
273
  std::vector<std::string> romFilter_;
274
  std::map<std::string, std::vector<std::string> > affFilter_;
275
  std::size_t shootLimit_;
276
  std::size_t displacementLimit_;
277
  std::vector<double> so3Bounds_;
278
};
279
280
std::vector<double> addSo3LimitsHyQ() {
281
  std::vector<double> res;
282
  res.push_back(-0.4);
283
  res.push_back(0.4);
284
  res.push_back(-0.3);
285
  res.push_back(0.3);
286
  res.push_back(-0.3);
287
  res.push_back(0.3);
288
  return res;
289
}
290
291
13
hpp::core::ProblemSolverPtr_t configureRbprmProblemSolverForSupportLimbs(
292
    const DevicePtr_t& robot, BindShooter& bShooter) {
293
13
  hpp::core::ProblemSolverPtr_t ps = hpp::core::ProblemSolver::create();
294
295
  /*bind shooter init*/
296
  hpp::pinocchio::RbPrmDevicePtr_t robotcast =
297
26
      static_pointer_cast<hpp::pinocchio::RbPrmDevice>(robot);
298
13
  std::vector<std::string> affNames;
299

13
  affNames.push_back(std::string("Support"));
300
30
  for (std::map<std::string, DevicePtr_t>::const_iterator cit =
301
13
           robotcast->robotRoms_.begin();
302
73
       cit != robotcast->robotRoms_.end(); ++cit) {
303

30
    bShooter.affFilter_.insert(std::make_pair(cit->first, affNames));
304
30
    bShooter.romFilter_.push_back(cit->first);
305
  }
306
  /*END bind shoorther init*/
307
308
13
  ps->robot(robot);
309


26
  ps->configurationShooters.add(
310
      "RbprmShooter",
311
      boost::bind(&BindShooter::create, boost::ref(bShooter), _1, ps));
312


26
  ps->pathValidations.add("RbprmPathValidation",
313
                          boost::bind(&BindShooter::createPathValidation,
314
                                      boost::ref(bShooter), _1, _2, ps));
315


26
  ps->pathValidations.add("RbprmDynamicPathValidation",
316
                          boost::bind(&BindShooter::createDynamicPathValidation,
317
                                      boost::ref(bShooter), _1, _2, ps));
318

13
  ps->pathPlanners.add("DynamicPlanner", DynamicPlanner::createWithRoadmap);
319

13
  ps->steeringMethods.add("RBPRMKinodynamic",
320
                          SteeringMethodKinodynamic::create);
321

13
  ps->pathOptimizers.add("RandomShortcutDynamic",
322
                         RandomShortcutDynamic::create);
323

13
  ps->pathOptimizers.add("OrientedPathOptimizer",
324
                         OrientedPathOptimizer::create);
325
26
  return ps;
326
}
327
#endif  // TOOLSOBSTACLE_HH