GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/interpolation/effector-rrt.cc Lines: 0 451 0.0 %
Date: 2024-02-02 12:21:48 Branches: 0 860 0.0 %

Line Branch Exec Source
1
// Copyright (c) 2014, LAAS-CNRS
2
// Authors: Steve Tonneau (steve.tonneau@laas.fr)
3
//
4
// This file is part of hpp-rbprm.
5
// hpp-rbprm is free software: you can redistribute it
6
// and/or modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation, either version
8
// 3 of the License, or (at your option) any later version.
9
//
10
// hpp-rbprm is distributed in the hope that it will be
11
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
// General Lesser Public License for more details.  You should have
14
// received a copy of the GNU Lesser General Public License along with
15
// hpp-rbprm. If not, see <http://www.gnu.org/licenses/>.
16
17
#include <ndcurves/bezier_curve.h>
18
#include <ndcurves/helpers/effector_spline.h>
19
20
#include <hpp/bezier-com-traj/solve_end_effector.hh>
21
#include <hpp/constraints/generic-transformation.hh>
22
#include <hpp/core/bi-rrt-planner.hh>
23
#include <hpp/core/configuration-shooter/uniform.hh>
24
#include <hpp/core/problem-solver.hh>
25
#include <hpp/pinocchio/joint-collection.hh>
26
#include <hpp/pinocchio/joint.hh>
27
#include <hpp/rbprm/interpolation/com-rrt.hh>
28
#include <hpp/rbprm/interpolation/limb-rrt.hh>
29
#include <hpp/rbprm/interpolation/spline/effector-rrt.hh>
30
#include <hpp/rbprm/rbprm-fullbody.hh>
31
#include <hpp/rbprm/tools.hh>
32
#include <pinocchio/multibody/geometry.hpp>
33
34
namespace hpp {
35
using namespace core;
36
namespace rbprm {
37
namespace interpolation {
38
39
typedef std::pair<value_type, vector_t> Waypoint;
40
typedef std::vector<Waypoint, Eigen::aligned_allocator<Waypoint> > T_Waypoint;
41
typedef T_Waypoint::iterator IT_Waypoint;
42
typedef T_Waypoint::const_iterator CIT_Waypoint;
43
typedef Eigen::Matrix<value_type, 3, 1> Vector3;
44
const value_type epsilon = std::numeric_limits<value_type>::epsilon();
45
46
bool Is2d(const T_Waypoint& wayPoints) {
47
  const std::size_t dim = wayPoints.front().second.rows() - 1;
48
  const core::value_type ref = wayPoints.front().second[dim];
49
  value_type z_var = 0.;
50
  for (CIT_Waypoint cit = wayPoints.begin() + 1; cit != wayPoints.end();
51
       ++cit) {
52
    z_var = std::max(z_var, fabs(cit->second[dim] - ref));
53
  }
54
  return z_var < 0.02;
55
}
56
57
bool IsLine(const T_Waypoint& wayPoints) {
58
  // return true;
59
  const vector_t& init = wayPoints.front().second;
60
  // compute line between first and last
61
  vector_t dir = wayPoints.back().second - init;
62
  vector_t dir2;
63
  dir.normalize();
64
  for (CIT_Waypoint cit = wayPoints.begin() + 1; cit != wayPoints.end() - 1;
65
       ++cit) {
66
    dir2 = cit->second - init;
67
    if (dir.norm() > epsilon)
68
      dir2.normalize();
69
    else
70
      throw("todo waypoint distance nul in end efefctor interpolation");
71
    // if(dir.dot(dir2) < 0.9999)
72
    if (dir.dot(dir2) < 1 - epsilon * 4) return false;
73
    // return false || Is2d(wayPoints);
74
  }
75
  return true;
76
}
77
78
Transform3f getEffectorTransformAt(core::DevicePtr_t device,
79
                                   const pinocchio::Frame& effector,
80
                                   const core::PathPtr_t path,
81
                                   const value_type time) {
82
  Configuration_t result(path->outputSize());
83
  (*path)(result, time);
84
  hppDout(notice, "result in getEffectorTransform : "
85
                      << pinocchio::displayConfig(result));
86
  device->currentConfiguration(result);
87
  device->computeForwardKinematics();
88
  Transform3f transform = effector.currentTransformation();
89
  return transform;
90
}
91
92
vector_t GetEffectorPositionAt(core::PathPtr_t path,
93
                               constraints::PositionPtr_t position,
94
                               const value_type time) {
95
  bool success;
96
  return position->operator()(path->operator()(time, success)).vector();
97
}
98
99
void getEffectorConfigAt(core::DevicePtr_t device,
100
                         const pinocchio::Frame& effector,
101
                         const core::PathPtr_t path, const value_type time,
102
                         ConfigurationOut_t result) {
103
  Transform3f transform = getEffectorTransformAt(device, effector, path, time);
104
  result.head<3>() = transform.translation();
105
  result.segment<4>(3) = Transform3f::Quaternion(transform.rotation()).coeffs();
106
}
107
108
void getEffectorConfigForConfig(core::DevicePtr_t device,
109
                                const pinocchio::Frame& effector,
110
                                const Configuration_t fullBodyConfig,
111
                                ConfigurationOut_t result) {
112
  device->currentConfiguration(fullBodyConfig);
113
  device->computeForwardKinematics();
114
  Transform3f transform = effector.currentTransformation();
115
  result.head<3>() = transform.translation();
116
  result.segment<4>(3) = Transform3f::Quaternion(transform.rotation()).coeffs();
117
}
118
119
DevicePtr_t createFreeFlyerDevice() {
120
  DevicePtr_t endEffectorDevice = hpp::core::Device_t::create("endEffector");
121
  hpp::pinocchio::ModelPtr_t m =
122
      hpp::pinocchio::ModelPtr_t(new hpp::pinocchio::Model());
123
  hpp::pinocchio::GeomModelPtr_t gm =
124
      hpp::pinocchio::GeomModelPtr_t(new hpp::pinocchio::GeomModel);
125
  Transform3f mat;
126
  mat.setIdentity();
127
  endEffectorDevice->setModel(m);
128
  endEffectorDevice->setGeomModel(gm);
129
  endEffectorDevice->model().addJoint(0, ::pinocchio::JointModelFreeFlyer(),
130
                                      mat, "freeflyer");
131
  return endEffectorDevice;
132
}
133
134
fcl::Vec3f getNormal(const std::string& effector, const State& state,
135
                     bool& found) {
136
  std::map<std::string, fcl::Vec3f>::const_iterator cit =
137
      state.contactNormals_.find(effector);
138
  if (cit != state.contactNormals_.end()) {
139
    found = true;
140
    return cit->second;
141
  } else {
142
    found = false;
143
    return fcl::Vec3f(0., 0., 1.);
144
  }
145
}
146
147
T_Waypoint getWayPoints(pinocchio::DevicePtr_t device, core::PathPtr_t path,
148
                        const pinocchio::Frame effector,
149
                        const value_type effectorDistance, bool& isLine) {
150
  // create evaluation function
151
  constraints::PositionPtr_t position =
152
      createPositionMethod(device, fcl::Vec3f(), effector);
153
  // define arbitrary number of way points depending on length
154
  // std::size_t nbWayPoints = std::size_t(std::max(effectorDistance * 10, 3.));
155
  std::size_t nbWayPoints = 30;
156
  std::size_t dim = position->outputSize();
157
  if (!(nbWayPoints % 2)) nbWayPoints += 1;
158
  value_type pathIncrement = path->length() / (value_type)nbWayPoints;
159
  T_Waypoint res;
160
  value_type t = path->timeRange().first;
161
  res.push_back(std::make_pair(0, GetEffectorPositionAt(path, position, t)));
162
  for (std::size_t i = 1; i < nbWayPoints - 1; ++i) {
163
    t += pathIncrement;
164
    res.push_back(std::make_pair(i, GetEffectorPositionAt(path, position, t)));
165
  }
166
  res.push_back(std::make_pair(
167
      nbWayPoints - 1,
168
      GetEffectorPositionAt(path, position, path->timeRange().second)));
169
  if (IsLine(res) && effectorDistance > 0.03) {
170
    // value_type height = effectorDistance < 0.1 ? 0.01 : std::max(nbWayPoints*
171
    // 0.015, 0.02) ; std::cout << "is line " << std::endl;
172
    value_type height =
173
        effectorDistance < 0.1
174
            ? 0.03
175
            : std::min(0.07, std::max((value_type)nbWayPoints * 0.01, 0.02));
176
    isLine = true;
177
    T_Waypoint res2;
178
    res2.push_back(res.front());
179
    res2.push_back(
180
        std::make_pair(1, vector_t::Ones(position->outputSize()) * height +
181
                              res.front().second +
182
                              (res.back().second - res.front().second) / 2.));
183
    res2.push_back(std::make_pair(2, res.back().second));
184
    return res2;
185
  } else if (Is2d(res) && effectorDistance > 0.03) {
186
    std::cout << "is 2d " << std::endl;
187
    isLine = true;
188
    std::size_t apex = nbWayPoints / 2;
189
    // value_type max_height = effectorDistance < 0.1 ? 0.01 :
190
    // std::max(nbWayPoints* 0.015, 0.02);
191
    value_type max_height =
192
        effectorDistance < 0.1
193
            ? 0.03
194
            : std::min(0.07, std::max((value_type)nbWayPoints * 0.01, 0.02));
195
    value_type inc = max_height / (value_type)apex;
196
    std::size_t current = 0;
197
    std::size_t inc_fac = 0;
198
    for (IT_Waypoint it = res.begin(); it != res.end() - 1; ++it, ++current) {
199
      if (current > apex) {
200
        it->second[dim - 1] += (value_type)inc_fac * (inc);
201
        --inc_fac;
202
      } else {
203
        it->second[dim - 1] += (value_type)inc_fac * inc;
204
        if (current == apex)
205
          --inc_fac;
206
        else
207
          ++inc_fac;
208
      }
209
    }
210
  }
211
  return res;
212
}
213
214
value_type genHeight(const bool normalFound) {
215
  if (normalFound)
216
    return 0.01;
217
  else
218
    return 0.;
219
}
220
221
exact_cubic_Ptr splineFromEffectorTraj(RbPrmFullBodyPtr_t fullbody,
222
                                       const pinocchio::Frame effector,
223
                                       core::PathPtr_t path,
224
                                       const State& startState,
225
                                       const State& nextState, bool& isLine) {
226
  // estimate length of distance travelled
227
  value_type length = effectorDistance(startState, nextState);
228
  T_Waypoint wayPoints =
229
      getWayPoints(fullbody->device_, path, effector, length, isLine);
230
  std::string effLimb = getEffectorLimb(startState, nextState);
231
  bool found(false);
232
  fcl::Vec3f n1 = getNormal(effLimb, startState, found);
233
  value_type h1 = genHeight(found);
234
  fcl::Vec3f n2 = getNormal(effLimb, nextState, found);
235
  value_type h2 = genHeight(found);
236
  std::cout << "AM I CALLED " << n1 << "\n"
237
            << n2 << "\n h1 " << h1 << "\n h2 " << h2 << std::endl;
238
  /* exact_cubic_Ptr ptr = exact_cubic_Ptr(curves::helpers::effector_spline(
239
                                             wayPoints.begin(),
240
                                             wayPoints.end(),
241
                                             n1, n2,
242
                                             h1, h2,
243
                                             h1, h2));
244
                                             */
245
  // exact_cubic_Ptr ptr = exact_cubic_Ptr(new
246
  // curve_constraint_t(wayPoints.begin(), wayPoints.end()));
247
  exact_cubic_Ptr ptr =
248
      exact_cubic_Ptr(new exact_cubic_t(wayPoints.begin(), wayPoints.end()));
249
  isLine = true;
250
  // exact_cubic_Ptr ptr = exact_cubic_Ptr(new exact_cubic_t(wayPoints.begin(),
251
  // wayPoints.end()));
252
  return ptr;
253
}
254
255
std::vector<pinocchio::JointPtr_t> getJointsByName(
256
    RbPrmFullBodyPtr_t fullbody, const std::vector<std::string>& names) {
257
  std::vector<pinocchio::JointPtr_t> res;
258
  for (std::vector<std::string>::const_iterator cit = names.begin();
259
       cit != names.end(); ++cit) {
260
    res.push_back(fullbody->device_->getJointByName(*cit));
261
  }
262
  return res;
263
}
264
265
/**
266
 * @brief buildPredefinedPath
267
 * @param normal contact normal
268
 * @param config init or goal configuration (see init param)
269
 * @param posOffset
270
 * @param velOffset
271
 * @param init if true : c0 is initial position else, c0 is final position
272
 * @param offsetConfig return the goal or init configuration
273
 * @return the path
274
 */
275
BezierPathPtr_t buildPredefinedPath(
276
    const DevicePtr_t& endEffectorDevice, const Vector3& normal,
277
    const Configuration_t& config, value_type posOffset, value_type velOffset,
278
    value_type time, bool init, Configuration_t& offsetConfig,
279
    bezier_com_traj::ProblemData& pData, value_type aOffset = 0) {
280
  pData.constraints_.flag_ = INIT_POS | INIT_VEL | INIT_ACC | END_ACC |
281
                             END_VEL | END_POS | INIT_JERK | END_JERK;
282
  Vector3 c(config.head<3>());
283
  pData.c0_ = c;
284
  pData.c1_ = c;
285
  if (init)
286
    pData.c1_ += posOffset * normal;
287
  else
288
    pData.c0_ += posOffset * normal;
289
  if (init) {
290
    pData.dc0_ = Vector3::Zero();
291
    pData.dc1_ = normal * velOffset;
292
  } else {
293
    pData.dc1_ = Vector3::Zero();
294
    pData.dc0_ = normal * velOffset;
295
  }
296
  if (init) {
297
    pData.ddc0_ = Vector3::Zero();
298
    pData.ddc1_ = normal * aOffset;
299
  } else {
300
    pData.ddc1_ = Vector3::Zero();
301
    pData.ddc0_ = normal * aOffset;
302
  }
303
304
  offsetConfig.head<3>() = pData.c1_;
305
  hppDout(notice, "CREATE BEZIER for constraints : ");
306
  hppDout(notice, "normal : " << normal.transpose());
307
  hppDout(notice, "c0   = " << pData.c0_.transpose());
308
  hppDout(notice, "dc0  = " << pData.dc0_.transpose());
309
  hppDout(notice, "ddc0 = " << pData.ddc0_.transpose());
310
  hppDout(notice, "c1   = " << pData.c1_.transpose());
311
  hppDout(notice, "dc1  = " << pData.dc1_.transpose());
312
  hppDout(notice, "ddc1 = " << pData.ddc1_.transpose());
313
  hppDout(notice, "Compute waypoints for takeOff phase : ");
314
  std::vector<bezier_t::point_t> pts;
315
  BezierPathPtr_t refEffector;
316
  if (init) {
317
    pts = bezier_com_traj::computeConstantWaypointsInitPredef(pData, time);
318
    refEffector =
319
        BezierPath::create(endEffectorDevice, pts.begin(), pts.end(), config,
320
                           offsetConfig, core::interval_t(0., time));
321
    pData.j1_ = refEffector->getBezier()->derivate(time, 3);
322
    pData.ddc1_ = refEffector->getBezier()->derivate(time, 2);
323
    pData.dc1_ = refEffector->getBezier()->derivate(time, 1);
324
    hppDout(notice, "New final jerk : " << pData.j1_.transpose());
325
    hppDout(notice, "New final acc  : " << pData.ddc1_.transpose());
326
    hppDout(notice, "New final vel  : " << pData.dc1_.transpose());
327
  } else {
328
    pts = bezier_com_traj::computeConstantWaypointsGoalPredef(pData, time);
329
    refEffector =
330
        BezierPath::create(endEffectorDevice, pts.begin(), pts.end(),
331
                           offsetConfig, config, core::interval_t(0., time));
332
    pData.j0_ = refEffector->getBezier()->derivate(0., 3);
333
    pData.ddc0_ = refEffector->getBezier()->derivate(0., 2);
334
    pData.dc0_ = refEffector->getBezier()->derivate(0., 1);
335
    hppDout(notice, "New init jerk : " << pData.j0_.transpose());
336
    hppDout(notice, "New init acc  : " << pData.ddc0_.transpose());
337
    hppDout(notice, "New init vel  : " << pData.dc0_.transpose());
338
  }
339
340
  // get the final / initial jerk and set it in problemData :
341
342
  hppDout(notice, "Path Bezier created");
343
  /*
344
   bezier_t::t_point_t pts;
345
   bezier_com_traj::ResultDataCOMTraj res_takeoff =
346
  bezier_com_traj::solveEndEffector<EndEffectorPath>(pDataTakeoff,endEffPath,timeTakeoff,0.);
347
  if(!res_takeoff.success_){
348
      hppDout(warning,"[WARNING] qp solver failed to compute takeoff bezier
349
  curve !!"); return fullBodyComPath;
350
  }
351
  hppDout(notice,"Done.");
352
  bezier_Ptr refEffectorTakeoffBezier=bezier_Ptr(new
353
  bezier_t(res_takeoff.c_of_t_)); pts = refEffectorTakeoffBezier->waypoints();
354
   BezierPathPtr_t refEffectorTakeoff =
355
  BezierPath::create(endEffectorDevice,refEffectorTakeoffBezier,initConfig,takeoffConfig,core::interval_t(0.,timeTakeoff));
356
  hppDout(notice,"Path Bezier created");
357
  */
358
  std::ostringstream ss;
359
  ss << "[";
360
  for (std::vector<bezier_t::point_t>::const_iterator wpit = pts.begin();
361
       wpit != pts.end(); ++wpit) {
362
    ss << "[" << (*wpit)[0] << "," << (*wpit)[1] << "," << (*wpit)[2] << "],";
363
  }
364
  ss.seekp(-1, ss.cur);
365
  ss << ']';
366
  hppDout(notice,
367
          "Waypoint for reference end effector predefined path ( init = "
368
              << init << ") :");
369
  hppDout(notice, ss.str());
370
  return refEffector;
371
}
372
373
PathVectorPtr_t computeBezierPath(const DevicePtr_t& endEffectorDevice,
374
                                  const ProblemData& pDataMid,
375
                                  const EndEffectorPath& endEffPath,
376
                                  value_type timeMid, value_type weightRRT,
377
                                  const BezierPathPtr_t& refEffectorTakeoff,
378
                                  const BezierPathPtr_t& refEffectorLanding,
379
                                  bezier_Ptr& refEffectorMidBezier) {
380
  bezier_com_traj::ResultDataCOMTraj res =
381
      bezier_com_traj::solveEndEffector<EndEffectorPath>(pDataMid, endEffPath,
382
                                                         timeMid, weightRRT);
383
  if (!res.success_) {
384
    hppDout(warning, "[WARNING] qp solver failed to compute bezier curve !!");
385
    return PathVectorPtr_t();
386
  }
387
  refEffectorMidBezier = bezier_Ptr(new bezier_t(res.c_of_t_));
388
  bezier_t::t_point_t wps = refEffectorMidBezier->waypoints();
389
  std::ostringstream ss;
390
  ss << "[";
391
  for (bezier_t::cit_point_t wpit = wps.begin(); wpit != wps.end(); ++wpit) {
392
    ss << "[" << (*wpit)[0] << "," << (*wpit)[1] << "," << (*wpit)[2] << "],";
393
  }
394
  ss.seekp(-1, ss.cur);
395
  ss << ']';
396
  hppDout(notice, "Waypoint for reference end effector : ");
397
  hppDout(notice, ss.str());
398
399
  hppDout(notice, "configurations of the path : ");
400
  hppDout(notice, "init    : " << pinocchio::displayConfig(
401
                      refEffectorTakeoff->initial()));
402
  hppDout(notice,
403
          "takeoff : " << pinocchio::displayConfig(refEffectorTakeoff->end()));
404
  hppDout(notice, "landing : " << pinocchio::displayConfig(
405
                      refEffectorLanding->initial()));
406
  hppDout(notice,
407
          "end     : " << pinocchio::displayConfig(refEffectorLanding->end()));
408
409
  BezierPathPtr_t refEffectorMid = BezierPath::create(
410
      endEffectorDevice, refEffectorMidBezier, refEffectorTakeoff->end(),
411
      refEffectorLanding->initial(), core::interval_t(0., timeMid));
412
413
  // merge the 3 curves :
414
  PathVectorPtr_t refEffectorPath = PathVector::create(
415
      refEffectorMid->outputSize(), refEffectorMid->outputDerivativeSize());
416
  refEffectorPath->appendPath(refEffectorTakeoff);
417
  refEffectorPath->appendPath(refEffectorMid);
418
  refEffectorPath->appendPath(refEffectorLanding);
419
  return refEffectorPath;
420
}
421
422
void computePredefConstants(double /*dist_translation*/, double p_max,
423
                            double /*p_min*/, double t_total, double& t_predef,
424
                            double& posOffset, double& /*velOffset*/,
425
                            double& /*a_max_predefined*/) {
426
  double timeMid = (t_total - (2 * t_predef)) / 2.;
427
  posOffset = p_max / (1. + 4. * timeMid / t_predef +
428
                       6. * timeMid * timeMid / (t_predef * t_predef) -
429
                       (timeMid * timeMid * timeMid) /
430
                           (t_predef * t_predef * t_predef));
431
}
432
433
core::PathPtr_t generateEndEffectorBezier(
434
    RbPrmFullBodyPtr_t fullbody, core::ProblemSolverPtr_t problemSolver,
435
    const PathPtr_t comPath, const State& startState, const State& nextState) {
436
  pinocchio::Frame effector = getEffector(fullbody, startState, nextState);
437
  std::string effectorName = getEffectorLimb(startState, nextState);
438
  EndEffectorPath endEffPath(fullbody->device_, effector, comPath);
439
  // create a 'device' object for the end effector (freeflyer 6D). Needed for
440
  // the path and the orientation constraint
441
  DevicePtr_t endEffectorDevice = createFreeFlyerDevice();
442
  Configuration_t initConfig(endEffectorDevice->configSize()),
443
      endConfig(endEffectorDevice->configSize());
444
  getEffectorConfigForConfig(fullbody->device_, effector,
445
                             startState.configuration_, initConfig);
446
  hppDout(notice, "start state conf = "
447
                      << pinocchio::displayConfig(startState.configuration_));
448
  getEffectorConfigForConfig(fullbody->device_, effector,
449
                             nextState.configuration_, endConfig);
450
  Configuration_t takeoffConfig(initConfig), landingConfig(endConfig);
451
452
  // ## compute initial takeoff phase for the end effector :
453
454
  Vector3 c0(initConfig.head<3>());
455
  Vector3 c1(endConfig.head<3>());
456
  c0[2] = 0;  // replace with normal instead of z axis
457
  c1[2] = 0;
458
  const value_type dist_translation = (c1 - c0).norm();
459
  const value_type timeDelay =
460
      0.05;  // this is the time during the 'single support' phase where the
461
             // feet don't move. It is needed to allow a safe mass transfer
462
             // without exiting the flexibility.
463
  const value_type totalTime = comPath->length() - 2. * timeDelay;
464
  // const value_type ratioTimeTakeOff=0.1;// percentage of the total time //
465
  // was 0.1
466
467
  // const value_type timeTakeoff = totalTime*ratioTimeTakeOff; // percentage of
468
  // the total time
469
  value_type timeTakeoff;  // it's a minimum time, it can be increased
470
  value_type p_max;        // offset for the higher point in the curve
471
  value_type p_min;        // min offset at the end of the predefined trajectory
472
  value_type posOffset, velOffset, a_max_predefined;
473
  // a_max_predefined = 1.5;
474
  if (effectorName == "hrp2_rleg_rom" || effectorName == "hrp2_lleg_rom") {
475
    // timeTakeoff = 0.1;
476
    // p_max = 0.1;
477
    // p_min = 0.05;
478
    timeTakeoff = 0.3;
479
    p_max = 0.03;
480
    p_min = 0.01;
481
    posOffset = 0.003;  // was 0.004 (for 1.8second)
482
  } else {
483
    timeTakeoff = 0.3;
484
    p_max = 0.05;
485
    p_min = 0.01;
486
    posOffset = 0.004;
487
  }
488
489
  computePredefConstants(dist_translation, p_max, p_min, totalTime, timeTakeoff,
490
                         posOffset, velOffset, a_max_predefined);
491
  // velOffset = 0.;
492
  // a_max_predefined = 0.;
493
494
  const value_type timeLanding = timeTakeoff;
495
  const value_type timeMid = totalTime - 2 * timeTakeoff;
496
497
  hppDout(notice, "Effector-rrt, moving effector name : " << effectorName);
498
  hppDout(notice, "Time takeoff : " << timeTakeoff);
499
  hppDout(notice, "total time : " << totalTime);
500
  Vector3 startNormal, nextNormal;
501
  if (startState.contactNormals_.find(effectorName) ==
502
      startState.contactNormals_.end()) {
503
    startNormal = Vector3(0, 0, 1);
504
  } else {
505
    startNormal = startState.contactNormals_.at(effectorName);
506
    hppDout(notice, "previous normal : " << startNormal);
507
  }
508
  if (nextState.contactNormals_.find(effectorName) ==
509
      nextState.contactNormals_.end()) {
510
    nextNormal = Vector3(0, 0, 1);
511
  } else {
512
    nextNormal = nextState.contactNormals_.at(effectorName);
513
    hppDout(notice, "previous normal : " << nextNormal);
514
  }
515
516
  bezier_com_traj::ProblemData pDataLanding, pDataTakeoff;
517
  BezierPathPtr_t refEffectorTakeoff = buildPredefinedPath(
518
      endEffectorDevice, startNormal, initConfig, posOffset, velOffset,
519
      timeTakeoff, true, takeoffConfig, pDataTakeoff, a_max_predefined);
520
  BezierPathPtr_t refEffectorLanding = buildPredefinedPath(
521
      endEffectorDevice, nextNormal, endConfig, posOffset, -velOffset,
522
      timeLanding, false, landingConfig, pDataLanding, a_max_predefined);
523
524
  // ## compute bezier curve that follow the rrt path and that respect the
525
  // constraints :
526
  bezier_com_traj::ProblemData pDataMid;
527
  pDataMid.constraints_.flag_ = INIT_POS | INIT_VEL | INIT_ACC | END_ACC |
528
                                END_VEL | END_POS | INIT_JERK | END_JERK;
529
530
  pDataMid.c0_ = pDataTakeoff.c1_;
531
  pDataMid.c1_ = pDataLanding.c0_;
532
  pDataMid.dc0_ = pDataTakeoff.dc1_;
533
  pDataMid.dc1_ = pDataLanding.dc0_;
534
  pDataMid.ddc0_ = pDataTakeoff.ddc1_;
535
  pDataMid.ddc1_ = pDataLanding.ddc0_;
536
  pDataMid.j0_ = pDataTakeoff.j1_;
537
  pDataMid.j1_ = pDataLanding.j0_;
538
539
  hppDout(notice, "CREATE BEZIER for constraints : ");
540
  hppDout(notice, "c0   = " << pDataMid.c0_.transpose());
541
  hppDout(notice, "dc0  = " << pDataMid.dc0_.transpose());
542
  hppDout(notice, "ddc0 = " << pDataMid.ddc0_.transpose());
543
  hppDout(notice, "j0   = " << pDataMid.j0_.transpose());
544
  hppDout(notice, "c1   = " << pDataMid.c1_.transpose());
545
  hppDout(notice, "dc1  = " << pDataMid.dc1_.transpose());
546
  hppDout(notice, "ddc1 = " << pDataMid.ddc1_.transpose());
547
  hppDout(notice, "j1   = " << pDataMid.j1_.transpose());
548
549
  hppDout(notice, "Distance traveled by the end effector : "
550
                      << (pDataMid.c1_ - pDataMid.c0_).norm());
551
  hppDout(notice, "Distance : " << (pDataMid.c1_ - pDataMid.c0_).transpose());
552
  hppDout(notice, "Time = " << timeMid);
553
554
  // ## call solver :
555
  bezier_Ptr refEffectorMidBezier;
556
  PathVectorPtr_t refEffectorPath;
557
  refEffectorPath = computeBezierPath(endEffectorDevice, pDataMid, endEffPath,
558
                                      timeMid, 0., refEffectorTakeoff,
559
                                      refEffectorLanding, refEffectorMidBezier);
560
  if (!refEffectorPath) {
561
    hppDout(notice, "Error whil computing Bezier path");
562
    return PathPtr_t();
563
  } else {
564
    // ## save the path
565
    problemSolver->addPath(
566
        refEffectorPath);  // add end effector path to the problemSolver
567
568
    // save the endEffector trajectory in the map :
569
    {
570
      size_t pathId = problemSolver->paths().size() - 1;
571
      hppDout(notice, "Add trajectories for path = "
572
                          << pathId << " and effector = " << effector.name());
573
      std::vector<bezier_Ptr> allRefEffector;
574
      allRefEffector.push_back(refEffectorTakeoff->getBezier());
575
      allRefEffector.push_back(refEffectorMidBezier);
576
      allRefEffector.push_back(refEffectorLanding->getBezier());
577
      bool successMap = fullbody->addEffectorTrajectory(pathId, effector.name(),
578
                                                        allRefEffector);
579
#ifndef HPP_DEBUG
580
      (void)successMap;
581
#endif
582
      hppDout(notice, "success add bezier to map = " << successMap);
583
    }
584
    // FIXME : using pathId = problemSolver->paths().size()  this way assume
585
    // that the path returned by this method will be the next added in
586
    // problemSolver. As there is no access to problemSolver here, it's the best
587
    // workaround.
588
    return refEffectorPath;
589
  }
590
}
591
592
std::vector<core::PathVectorPtr_t> fitBeziersToPath(
593
    RbPrmFullBodyPtr_t fullbody, const pinocchio::Frame& effector,
594
    const value_type comPathLength, const PathPtr_t fullBodyComPath,
595
    const State& startState, const State& nextState) {
596
  core::PathVectorPtr_t fullBodyPathVector = core::PathVector::create(
597
      fullBodyComPath->outputSize(), fullBodyComPath->outputDerivativeSize());
598
  fullBodyPathVector->appendPath(fullBodyComPath);
599
  std::string effectorName = getEffectorLimb(startState, nextState);
600
  EndEffectorPath endEffPath(fullbody->device_, effector, fullBodyComPath);
601
  // create a 'device' object for the end effector (freeflyer 6D). Needed for
602
  // the path and the orientation constraint
603
  DevicePtr_t endEffectorDevice = createFreeFlyerDevice();
604
  Configuration_t initConfig(endEffectorDevice->configSize()),
605
      endConfig(endEffectorDevice->configSize());
606
  getEffectorConfigForConfig(fullbody->device_, effector,
607
                             startState.configuration_, initConfig);
608
#ifdef HPP_DEBUG
609
  bool success;
610
#endif
611
  hppDout(notice, "fb com path init = " << pinocchio::displayConfig(
612
                      (*fullBodyComPath)(0., success)));
613
  hppDout(notice, "start state conf = "
614
                      << pinocchio::displayConfig(startState.configuration_));
615
  getEffectorConfigForConfig(fullbody->device_, effector,
616
                             nextState.configuration_, endConfig);
617
  Configuration_t takeoffConfig(initConfig), landingConfig(endConfig);
618
619
  // ## compute initial takeoff phase for the end effector :
620
621
  Vector3 c0(initConfig.head<3>());
622
  Vector3 c1(endConfig.head<3>());
623
  c0[2] = 0;  // replace with normal instead of z axis
624
  c1[2] = 0;
625
  const value_type dist_translation = (c1 - c0).norm();
626
  const value_type timeDelay =
627
      0.05;  // this is the time during the 'single support' phase where the
628
             // feet don't move. It is needed to allow a safe mass transfer
629
             // without exiting the flexibility.
630
  const value_type totalTime = comPathLength - 2. * timeDelay;
631
  // const value_type ratioTimeTakeOff=0.1;// percentage of the total time //
632
  // was 0.1
633
634
  // const value_type timeTakeoff = totalTime*ratioTimeTakeOff; // percentage of
635
  // the total time
636
  value_type timeTakeoff = 0.3;   // it's a minimum time, it can be increased
637
  const value_type p_max = 0.03;  // offset for the higher point in the curve
638
  const value_type p_min =
639
      0.01;  // min offset at the end of the predefined trajectory
640
641
  // values for hrp2 :
642
  /*value_type timeTakeoff = 0.1; // it's a minimum time, it can be increased
643
  //HRP2 const value_type p_max = 0.03; // offset for the higher point in the
644
  curve const value_type p_min = 0.002; // min offset at the end of the
645
  predefined trajectory
646
  */
647
  value_type posOffset, velOffset, a_max_predefined;
648
  // a_max_predefined = 1.5;
649
650
  computePredefConstants(dist_translation, p_max, p_min, totalTime, timeTakeoff,
651
                         posOffset, velOffset, a_max_predefined);
652
  // posOffset = 0.004;
653
  // velOffset = 0.;
654
  // a_max_predefined = 0.;
655
656
  const value_type timeLanding = timeTakeoff;
657
  const value_type timeMid = totalTime - 2 * timeTakeoff;
658
659
  hppDout(notice, "Effector-rrt, moving effector name : " << effectorName);
660
  hppDout(notice,
661
          "previous normal : " << startState.contactNormals_.at(effectorName));
662
  hppDout(notice,
663
          "next normal : " << nextState.contactNormals_.at(effectorName));
664
665
  bezier_com_traj::ProblemData pDataLanding, pDataTakeoff;
666
  BezierPathPtr_t refEffectorTakeoff = buildPredefinedPath(
667
      endEffectorDevice, startState.contactNormals_.at(effectorName),
668
      initConfig, posOffset, velOffset, timeTakeoff, true, takeoffConfig,
669
      pDataTakeoff, a_max_predefined);
670
  BezierPathPtr_t refEffectorLanding = buildPredefinedPath(
671
      endEffectorDevice, nextState.contactNormals_.at(effectorName), endConfig,
672
      posOffset, -velOffset, timeLanding, false, landingConfig, pDataLanding,
673
      a_max_predefined);
674
675
  // ## compute bezier curve that follow the rrt path and that respect the
676
  // constraints :
677
  bezier_com_traj::ProblemData pDataMid;
678
  pDataMid.constraints_.flag_ = INIT_POS | INIT_VEL | INIT_ACC | END_ACC |
679
                                END_VEL | END_POS | INIT_JERK | END_JERK;
680
681
  pDataMid.c0_ = pDataTakeoff.c1_;
682
  pDataMid.c1_ = pDataLanding.c0_;
683
  pDataMid.dc0_ = pDataTakeoff.dc1_;
684
  pDataMid.dc1_ = pDataLanding.dc0_;
685
  pDataMid.ddc0_ = pDataTakeoff.ddc1_;
686
  pDataMid.ddc1_ = pDataLanding.ddc0_;
687
  pDataMid.j0_ = pDataTakeoff.j1_;
688
  pDataMid.j1_ = pDataLanding.j0_;
689
690
  hppDout(notice, "CREATE BEZIER for constraints : ");
691
  hppDout(notice, "c0   = " << pDataMid.c0_.transpose());
692
  hppDout(notice, "dc0  = " << pDataMid.dc0_.transpose());
693
  hppDout(notice, "ddc0 = " << pDataMid.ddc0_.transpose());
694
  hppDout(notice, "j0   = " << pDataMid.j0_.transpose());
695
  hppDout(notice, "c1   = " << pDataMid.c1_.transpose());
696
  hppDout(notice, "dc1  = " << pDataMid.dc1_.transpose());
697
  hppDout(notice, "ddc1 = " << pDataMid.ddc1_.transpose());
698
  hppDout(notice, "j1   = " << pDataMid.j1_.transpose());
699
  hppDout(notice, "Distance traveled by the end effector : "
700
                      << (pDataMid.c1_ - pDataMid.c0_).norm());
701
  hppDout(notice, "Distance : " << (pDataMid.c1_ - pDataMid.c0_).transpose());
702
  hppDout(notice, "Time = " << timeMid);
703
704
  //  endEffPath.setOffset(pDataMid.c0_ - endEffPath(0)); //FIXME : bug with
705
  //  com_path = bezier ???
706
707
  // ## call solver :
708
  std::vector<value_type> weightRRT;
709
  weightRRT.push_back(0);
710
  weightRRT.push_back(0.5);
711
  weightRRT.push_back(0.75);
712
  weightRRT.push_back(0.85);
713
  weightRRT.push_back(0.9);
714
  weightRRT.push_back(0.95);
715
  weightRRT.push_back(1.);
716
  /* weightRRT.push_back(0.);
717
   weightRRT.push_back(0.2);
718
   weightRRT.push_back(0.4);
719
   weightRRT.push_back(0.6);
720
   weightRRT.push_back(0.8);
721
   weightRRT.push_back(0.9);
722
   weightRRT.push_back(1.);*/
723
724
  std::vector<core::PathVectorPtr_t> res;
725
  core::PathVectorPtr_t bezierPath;
726
  bezier_Ptr refEffectorMidBezier;
727
  hppDout(notice, "Try to fit bezier to rrt path with 1 variables");
728
  for (std::vector<value_type>::const_iterator it_weight = weightRRT.begin();
729
       it_weight != weightRRT.end(); ++it_weight) {
730
    hppDout(notice, "Compute bezier path for weight : " << *it_weight);
731
    bezierPath = computeBezierPath(endEffectorDevice, pDataMid, endEffPath,
732
                                   timeMid, (*it_weight), refEffectorTakeoff,
733
                                   refEffectorLanding, refEffectorMidBezier);
734
    if (bezierPath) {
735
      res.push_back(bezierPath);
736
    } else {
737
      hppDout(notice,
738
              "Error while compute bezier path, with weight : " << *it_weight);
739
      res.push_back(fullBodyPathVector);
740
    }
741
  }
742
  // now use 3 waypoints variables :
743
  hppDout(notice, "Try to fit bezier to rrt path with 3 variables");
744
  pDataMid.constraints_.flag_ = INIT_POS | INIT_VEL | INIT_ACC | END_ACC |
745
                                END_VEL | END_POS | INIT_JERK | END_JERK |
746
                                THREE_FREE_VAR;
747
748
  for (std::vector<value_type>::const_iterator it_weight =
749
           weightRRT.begin() + 1;
750
       it_weight != weightRRT.end(); ++it_weight) {
751
    hppDout(notice, "Compute bezier path for weight : " << *it_weight);
752
    bezierPath = computeBezierPath(endEffectorDevice, pDataMid, endEffPath,
753
                                   timeMid, (*it_weight), refEffectorTakeoff,
754
                                   refEffectorLanding, refEffectorMidBezier);
755
    if (bezierPath) {
756
      res.push_back(bezierPath);
757
    } else {
758
      hppDout(notice,
759
              "Error while compute bezier path, with weight : " << *it_weight);
760
      res.push_back(fullBodyPathVector);
761
    }
762
  }
763
764
  hppDout(notice, "Try to fit bezier to rrt path with 5 variables");
765
  pDataMid.constraints_.flag_ = INIT_POS | INIT_VEL | INIT_ACC | END_ACC |
766
                                END_VEL | END_POS | INIT_JERK | END_JERK |
767
                                FIVE_FREE_VAR;
768
769
  for (std::vector<value_type>::const_iterator it_weight =
770
           weightRRT.begin() + 1;
771
       it_weight != weightRRT.end(); ++it_weight) {
772
    hppDout(notice, "Compute bezier path for weight : " << *it_weight);
773
    bezierPath = computeBezierPath(endEffectorDevice, pDataMid, endEffPath,
774
                                   timeMid, (*it_weight), refEffectorTakeoff,
775
                                   refEffectorLanding, refEffectorMidBezier);
776
    if (bezierPath) {
777
      res.push_back(bezierPath);
778
    } else {
779
      hppDout(notice,
780
              "Error while compute bezier path, with weight : " << *it_weight);
781
      res.push_back(fullBodyPathVector);
782
    }
783
  }
784
785
  return res;
786
}
787
788
core::PathPtr_t effectorRRTFromPath(
789
    RbPrmFullBodyPtr_t fullbody, core::ProblemSolverPtr_t problemSolver,
790
    const PathPtr_t comPath, const PathPtr_t fullBodyComPath,
791
    const State& startState, const State& nextState,
792
    const std::size_t /*numOptimizations*/, const bool keepExtraDof,
793
    const PathPtr_t refPath,
794
    const std::vector<std::string>& constrainedJointPos,
795
    const std::vector<std::string>& constrainedLockedJoints) {
796
  hppDout(notice, "Begin effectorRRT with fullBodyComPath");
797
  // removing extra dof
798
  core::segment_t interval(0, fullBodyComPath->initial().rows() - 1);
799
  core::segments_t intervals;
800
  intervals.push_back(interval);
801
  core::segments_t velIntervals(
802
      1, core::segment_t(0, fullbody->device_->numberDof() - 1));
803
  core::PathPtr_t reducedComPath =
804
      core::SubchainPath::create(fullBodyComPath, intervals, velIntervals);
805
  const pinocchio::Frame effector =
806
      getEffector(fullbody, startState, nextState);
807
  DevicePtr_t endEffectorDevice = createFreeFlyerDevice();
808
809
  std::vector<PathVectorPtr_t> listPathBezier =
810
      fitBeziersToPath(fullbody, effector, comPath->length(), fullBodyComPath,
811
                       startState, nextState);
812
  // iterate over all bezier path and try to find a whole body motion that can
813
  // follow it :
814
  const size_t maxIterationRRT =
815
      500;  // FIXME : adjust value for more complexe environnement
816
  std::vector<value_type> weightRRT;  // only required for debug
817
  weightRRT.push_back(0);
818
  weightRRT.push_back(0.5);
819
  weightRRT.push_back(0.75);
820
  weightRRT.push_back(0.85);
821
  weightRRT.push_back(0.9);
822
  weightRRT.push_back(0.95);
823
  weightRRT.push_back(1.);
824
  size_t it = 0;
825
  bool success_rrt = false;
826
827
  core::PathPtr_t interpolatedPath;
828
  core::PathVectorPtr_t solutionPath;
829
  for (std::vector<PathVectorPtr_t>::const_iterator it_path =
830
           listPathBezier.begin();
831
       it_path != listPathBezier.end() && !success_rrt; ++it_path, ++it) {
832
    // ## compute whole body motion that follow the reference
833
    EffectorRRTShooterFactory shooterFactory(reducedComPath);
834
    std::vector<pinocchio::JointPtr_t> constrainedJoint =
835
        getJointsByName(fullbody, constrainedJointPos);
836
    std::vector<pinocchio::JointPtr_t> constrainedLocked =
837
        getJointsByName(fullbody, constrainedLockedJoints);
838
    hppDout(notice, "effectorRRT, contrained joint pose size : "
839
                        << constrainedJointPos.size());
840
    hppDout(notice, "effectorRRT, contrained locked joint  size : "
841
                        << constrainedLockedJoints.size());
842
843
    SetEffectorRRTConstraints constraintFactory(
844
        comPath, *it_path, refPath, effector, endEffectorDevice,
845
        constrainedJoint, constrainedLocked);
846
    T_StateFrame stateFrames;
847
    stateFrames.push_back(
848
        std::make_pair(comPath->timeRange().first, startState));
849
    stateFrames.push_back(
850
        std::make_pair(comPath->timeRange().second, nextState));
851
852
    try {
853
      interpolatedPath = interpolateStatesFromPath<EffectorRRTHelper,
854
                                                   EffectorRRTShooterFactory,
855
                                                   SetEffectorRRTConstraints>(
856
          fullbody, problemSolver->problem(), shooterFactory, constraintFactory,
857
          comPath,
858
          // stateFrames.begin(), stateFrames.begin()+1, numOptimizations % 10,
859
          // keepExtraDof);
860
          stateFrames.begin(), stateFrames.begin() + 1,
861
          /*numOptimizations this should be different from the numOptimization
862
             used by comRRT*/
863
          1, keepExtraDof, 0.001, maxIterationRRT);
864
      if (interpolatedPath) {
865
        success_rrt = true;
866
        hppDout(notice, "InterpolateStateFromPath success for weightDistance = "
867
                            << weightRRT[it]);
868
        solutionPath = *it_path;
869
      }
870
    } catch (std::runtime_error e) {
871
      hppDout(notice, "InterpolateStateFromPath failed for weightDistance = "
872
                          << weightRRT[it]);
873
      hppDout(notice, "Error = " << e.what());
874
    }
875
    /*
876
    success_rrt = true; //FIXME for testing purpose : always return the first
877
    path computed if(!interpolatedPath)//FIXME for testing purpose : always
878
    return the first path computed interpolatedPath = refEffectorPath; //FIXME
879
    for testing purpose : always return the first path computed
880
    */
881
  }
882
883
  if (success_rrt) {
884
    // ## save the path
885
    problemSolver->addPath(
886
        solutionPath);  // add end effector path to the problemSolver
887
888
    // save the endEffector trajectory in the map :
889
    {
890
      size_t pathId = problemSolver->paths().size();
891
      hppDout(notice, "Add trajectories for path = "
892
                          << pathId << " and effector = " << effector.name());
893
      assert(solutionPath->numberPaths() == 3 &&
894
             "Solution pathVector should have 3 paths (takeoff, mid, landing)");
895
      BezierPathPtr_t takeoffPath =
896
          dynamic_pointer_cast<BezierPath>(solutionPath->pathAtRank(0));
897
      BezierPathPtr_t midPath =
898
          dynamic_pointer_cast<BezierPath>(solutionPath->pathAtRank(1));
899
      BezierPathPtr_t landingPath =
900
          dynamic_pointer_cast<BezierPath>(solutionPath->pathAtRank(2));
901
      std::vector<bezier_Ptr> allRefEffector;
902
      allRefEffector.push_back(takeoffPath->getBezier());
903
      allRefEffector.push_back(midPath->getBezier());
904
      allRefEffector.push_back(landingPath->getBezier());
905
      bool successMap = fullbody->addEffectorTrajectory(pathId, effector.name(),
906
                                                        allRefEffector);
907
#ifndef HPP_DEBUG
908
      (void)successMap;
909
#endif
910
      hppDout(notice, "success = " << successMap);
911
    }
912
    // FIXME : using pathId = problemSolver->paths().size()  this way assume
913
    // that the path returned by this method will be the next added in
914
    // problemSolver. As there is no access to problemSolver here, it's the best
915
    // workaround.
916
    return interpolatedPath;
917
  } else {
918
    hppDout(notice,
919
            "Effector RRT failed to produce a bezier curve, return rrt path.");
920
    return fullBodyComPath;
921
  }
922
}
923
924
core::PathPtr_t effectorRRTFromPath(
925
    RbPrmFullBodyPtr_t fullbody, core::ProblemSolverPtr_t problemSolver,
926
    const PathPtr_t comPath, const State& startState, const State& nextState,
927
    const std::size_t numOptimizations, const bool keepExtraDof,
928
    const PathPtr_t refPath,
929
    const std::vector<std::string>& constrainedJointPos,
930
    const std::vector<std::string>& constrainedLockedJoints) {
931
  hppDout(notice, "Begin effectorRRTFromPath, start comRRT : ");
932
  core::PathPtr_t fullBodyComPath =
933
      comRRT(fullbody, problemSolver, comPath, startState, nextState,
934
             numOptimizations, true);
935
  core::PathVectorPtr_t fullBodyPathVector = core::PathVector::create(
936
      fullBodyComPath->outputSize(), fullBodyComPath->outputDerivativeSize());
937
  fullBodyPathVector->appendPath(fullBodyComPath);
938
  problemSolver->addPath(fullBodyPathVector);
939
  hppDout(notice, "add fullBodyCom path at id : "
940
                      << (problemSolver->paths().size() - 1));
941
  hppDout(notice, "comRRT done.");
942
  if (effectorDistance(startState, nextState) <
943
      0.03) {  // end effectors does not move, return the comRRT path
944
    hppDout(notice, "Effector doesn't move, return comRRT path.");
945
    return fullBodyComPath;
946
  }
947
948
  return effectorRRTFromPath(fullbody, problemSolver, comPath, fullBodyComPath,
949
                             startState, nextState, numOptimizations,
950
                             keepExtraDof, refPath, constrainedJointPos,
951
                             constrainedLockedJoints);
952
}
953
954
core::PathPtr_t effectorRRT(RbPrmFullBodyPtr_t fullbody,
955
                            ProblemSolverPtr_t problemSolver,
956
                            const PathPtr_t comPath, const State& startState,
957
                            const State& nextState,
958
                            const std::size_t numOptimizations,
959
                            const bool keepExtraDof) {
960
  const std::vector<std::string> dum, dum2;
961
  return effectorRRTFromPath(fullbody, problemSolver, comPath, startState,
962
                             nextState, numOptimizations, keepExtraDof,
963
                             core::PathPtr_t(), dum, dum2);
964
}
965
966
core::PathPtr_t effectorRRT(
967
    RbPrmFullBodyPtr_t fullbody, core::ProblemSolverPtr_t problemSolver,
968
    const PathPtr_t comPath, const State& startState, const State& nextState,
969
    const std::size_t numOptimizations, const bool keepExtraDof,
970
    const std::vector<std::string>& constrainedJointPos,
971
    const std::vector<std::string>& constrainedLockedJoints) {
972
  return effectorRRTFromPath(fullbody, problemSolver, comPath, startState,
973
                             nextState, numOptimizations, keepExtraDof,
974
                             core::PathPtr_t(), constrainedJointPos,
975
                             constrainedLockedJoints);
976
}
977
978
void SetEffectorRRTConstraints::operator()(EffectorRRTHelper& helper,
979
                                           const State& from,
980
                                           const State& to) const {
981
  CreateContactConstraints<EffectorRRTHelper>(helper, from, to);
982
  CreateComConstraint<EffectorRRTHelper, core::PathPtr_t>(helper, refCom_);
983
  CreateEffectorConstraint<EffectorRRTHelper, core::PathPtr_t>(helper, refEff_,
984
                                                               effector_);
985
986
  if (refFullbody_) {
987
    hppDout(notice, "Ref fullBody provided, create 6D effector constraint : ");
988
    for (std::vector<pinocchio::JointPtr_t>::const_iterator cit =
989
             constrainedJointPos_.begin();
990
         cit != constrainedJointPos_.end(); ++cit) {
991
      hppDout(notice, "Constrained joint pose : " << (*cit)->name());
992
      Create6DEffectorConstraint<EffectorRRTHelper, core::PathPtr_t>(
993
          helper, refFullbody_,
994
          helper.fullBodyDevice_->getFrameByName((*cit)->name()));
995
    }
996
  }
997
  if (endEffectorDevice_ &&
998
      false) {  // TEST disable orientation constraint for test
999
    hppDout(notice,
1000
            "EndEffectorDevice provided, add orientation constraint for the "
1001
            "end effector ");
1002
    CreateOrientationConstraint<EffectorRRTHelper, core::PathPtr_t>(
1003
        helper, refEff_, effector_, endEffectorDevice_);
1004
  }
1005
1006
  /*    Configuration_t refConfig = helper.fullbody_->referenceConfig();
1007
      CreatePosturalTaskConstraint<EffectorRRTHelper,Configuration_t>(helper,
1008
     refConfig); helper.proj_->lastIsOptional(true);
1009
      helper.proj_->numOptimize(500);
1010
      helper.proj_->lastAsCost(true);
1011
      helper.proj_->errorThreshold(1e-3);*/
1012
}
1013
1014
vector_t EndEffectorPath::operator()(value_type u) const {
1015
  assert(u >= 0 && u <= 1 && "u must be normalized");
1016
  size_t tId = fullBodyPath_->outputSize() - 1;
1017
  value_type t = u * fullBodyPath_->end()[tId];  // u is between 0 and 1
1018
  hppDout(notice, "EndEffectorPath called, last time in fullBodyPath : "
1019
                      << fullBodyPath_->end()[tId]);
1020
  hppDout(notice, "Indexed size : " << fullBodyPath_->length());
1021
  value_type cId = 0;
1022
  bool found(false);
1023
  value_type index = 0;
1024
  hppDout(notice, "Looking for time : " << t);
1025
  bool success;
1026
  while (cId < fullBodyPath_->length() && !found) {
1027
    if (fullBodyPath_->operator()(cId, success)[tId] >= t) {
1028
      index = cId;
1029
      found = true;
1030
    }
1031
    cId += 0.01;
1032
  }
1033
  if (found)
1034
    hppDout(notice, "found at index : " << index);
1035
  else
1036
    index = fullBodyPath_
1037
                ->length();  // should never happen ?? should throw an error
1038
1039
  // the path "fullBodyPath" is not indexed by the time, the time value is the
1040
  // last value of each extraConfig we need to look for the time corresponding
1041
  // to t :
1042
  vector_t res =
1043
      GetEffectorPositionAt(fullBodyPath_, positionConstraint_, index);
1044
  return Vector3(res + offset_);
1045
}
1046
1047
}  // namespace interpolation
1048
}  // namespace rbprm
1049
}  // namespace hpp