GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/planner/parabola-path.cc Lines: 0 85 0.0 %
Date: 2024-02-02 12:21:48 Branches: 0 182 0.0 %

Line Branch Exec Source
1
//
2
// Copyright (c) 2014 CNRS
3
// Authors: Mylene Campana
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/core/config-projector.hh>
20
#include <hpp/core/straight-path.hh>
21
#include <hpp/pinocchio/configuration.hh>
22
#include <hpp/pinocchio/device.hh>
23
#include <hpp/pinocchio/joint.hh>
24
#include <hpp/rbprm/planner/parabola-path.hh>
25
#include <hpp/util/debug.hh>
26
27
namespace hpp {
28
namespace rbprm {
29
using core::interval_t;
30
using core::size_type;
31
using core::value_type;
32
using core::vector_t;
33
using pinocchio::displayConfig;
34
35
ParabolaPath::ParabolaPath(const core::DevicePtr_t& device,
36
                           core::ConfigurationIn_t init,
37
                           core::ConfigurationIn_t end, value_type length,
38
                           vector_t coefs)
39
    : parent_t(interval_t(0, length), device->configSize(),
40
               device->numberDof()),
41
      V0_(vector_t(3)),
42
      Vimp_(vector_t(3)),
43
      device_(device),
44
      initial_(init),
45
      end_(end),
46
      coefficients_(vector_t(coefs.size())),
47
      length_(length)
48
49
{
50
  assert(device);
51
  coefficients(coefs);
52
  initialROMnames_.reserve(10);
53
  endROMnames_.reserve(10);
54
}
55
56
ParabolaPath::ParabolaPath(const core::DevicePtr_t& device,
57
                           core::ConfigurationIn_t init,
58
                           core::ConfigurationIn_t end, value_type length,
59
                           vector_t coefs, vector_t V0, vector_t Vimp,
60
                           std::vector<std::string> initialROMnames,
61
                           std::vector<std::string> endROMnames)
62
    : parent_t(interval_t(0, length), device->configSize(),
63
               device->numberDof()),
64
      V0_(V0),
65
      Vimp_(Vimp),
66
      initialROMnames_(initialROMnames),
67
      endROMnames_(endROMnames),
68
      device_(device),
69
      initial_(init),
70
      end_(end),
71
      coefficients_(vector_t(coefs.size())),
72
      length_(length) {
73
  assert(device);
74
  coefficients(coefs);
75
  hppDout(info, "V0_= " << V0_.transpose() << " Vimp_= " << Vimp_.transpose());
76
  hppDout(info, "initialROMnames size= " << initialROMnames_.size());
77
}
78
79
ParabolaPath::ParabolaPath(const ParabolaPath& path)
80
    : parent_t(path),
81
      V0_(path.V0_),
82
      Vimp_(path.Vimp_),
83
      initialROMnames_(path.initialROMnames_),
84
      endROMnames_(path.endROMnames_),
85
      device_(path.device_),
86
      initial_(path.initial_),
87
      end_(path.end_),
88
      coefficients_(path.coefficients_),
89
      length_(path.length_) {
90
  hppDout(info, "V0_= " << V0_.transpose() << " Vimp_= " << Vimp_.transpose());
91
  hppDout(info, "initialROMnames size= " << initialROMnames_.size());
92
}
93
94
bool ParabolaPath::impl_compute(core::ConfigurationOut_t result,
95
                                value_type param) const {
96
  if (param == 0 || initial_(0) == end_(0)) {
97
    result = initial_;
98
    return true;
99
  }
100
  if (param >= length_) {
101
    result = end_;
102
    return true;
103
  }
104
105
  const size_type nbConfig = device_->configSize();
106
  const size_type ecsDim = device_->extraConfigSpace().dimension();
107
  // param = x_theta
108
  const value_type u = param / length_;
109
  const value_type theta = coefficients_(3);
110
  /* const value_type x_theta_max = - 0.5 *
111
       coefficients_ (1) / coefficients_ (0);
112
   const value_type x_theta_initial = cos(theta)*initial_ (0) +
113
       sin(theta)*initial_ (1);
114
   const value_type x_theta_end = cos(theta)*end_ (0) +
115
       sin(theta)*end_ (1);
116
   const bool tanThetaNotDefined = (theta < M_PI/2 + 1e-2 && theta > M_PI/2 -
117
   1e-2) || (theta > -M_PI/2 - 1e-2 && theta < -M_PI/2 + 1e-2);
118
*/
119
  result(0) = initial_(0) + u * length_ * cos(theta);
120
  result(1) = initial_(1) + u * length_ * sin(theta);
121
  const value_type x_theta = cos(theta) * result(0) + sin(theta) * result(1);
122
  result(2) = coefficients_(0) * x_theta * x_theta +
123
              coefficients_(1) * x_theta + coefficients_(2);
124
125
  pinocchio::interpolate(device_, initial_, end_, u, result);
126
  /* Quaternions interpolation */
127
  /*const core::JointPtr_t SO3joint = device_->getJointByName
128
  ("base_joint_SO3"); const std::size_t rank = SO3joint->rankInConfiguration ();
129
  const core::size_type dimSO3 = SO3joint->configSize ();
130
  SO3joint->configuration ()->interpolate
131
      (initial_, end_, u, rank, result);
132
133
  // if robot-trunk has internal DoF (except freeflyer ones)
134
  // then linear interpolation on them
135
  const std::size_t freeflyerDim = 3 + dimSO3;
136
  const bool hasInternalDof = nbConfig > ecsDim + freeflyerDim;
137
  if (hasInternalDof) {
138
    for (core::size_type i = freeflyerDim; i<nbConfig-ecsDim; i++) {
139
      result (i) = (1 - u) * initial_ (i) + u * end_ (i);
140
    }
141
  }*/
142
143
  /* Set to zero extra-configs (only on path, not on extremities */
144
  const std::size_t indexECS = nbConfig - ecsDim;
145
  for (size_type i = 0; i < ecsDim; i++) result(indexECS + i) = 0;
146
  return true;
147
}
148
149
core::PathPtr_t ParabolaPath::extract(const interval_t& subInterval) const {
150
  hppDout(error, "path extract is not recommended on parabola path");
151
  bool success;
152
  core::Configuration_t q1((*this)(subInterval.first, success));   // straight
153
  core::Configuration_t q2((*this)(subInterval.second, success));  // straight
154
  ParabolaPathPtr_t result = rbprm::ParabolaPath::create(
155
      device_, q1, q2, computeLength(q1, q2), coefficients_, V0_, Vimp_,
156
      initialROMnames_, endROMnames_);
157
  hppDout(info, "initialROMnames size= " << (*result).initialROMnames_.size());
158
  return result;
159
}
160
161
core::PathPtr_t ParabolaPath::reverse() const {
162
  hppDout(notice, " ~ reverse path parabola !!!!!!!!!!!!!!!!!!!!!!");
163
  bool success;
164
  core::Configuration_t q1((*this)(length_, success));
165
  core::Configuration_t q2((*this)(0, success));
166
  ParabolaPathPtr_t result =
167
      ParabolaPath::create(device_, q1, q2, length_, coefficients_, Vimp_, V0_,
168
                           endROMnames_, initialROMnames_);
169
  hppDout(info, "V0_= " << V0_.transpose() << " Vimp_= " << Vimp_.transpose());
170
  hppDout(info, "result V0_= " << (*result).V0_.transpose() << " result Vimp_= "
171
                               << (*result).Vimp_.transpose());
172
  hppDout(info,
173
          "path->initialROMnames size= " << (*result).initialROMnames_.size());
174
  hppDout(info,
175
          "this->initialROMnames size= " << (*this).initialROMnames_.size());
176
  hppDout(info, "result->initialROMnames size= "
177
                    << (*result).initialROMnames_.size());
178
  return result;
179
}
180
181
core::DevicePtr_t ParabolaPath::device() const { return device_; }
182
183
/*  value_type ParabolaPath::computeLength
184
  (const core::ConfigurationIn_t q1, const core::ConfigurationIn_t q2) const {
185
    const int N = 6; // number -1 of interval sub-divisions
186
    // for N = 4, computation error ~= 1e-5.
187
    // for N = 20, computation error ~= 1e-11.
188
    value_type length = 0;
189
    const value_type theta = coefficients_ (3);
190
    value_type x1 = cos(theta) * q1 (0)  + sin(theta) * q1 (1); // x_theta_0
191
    value_type x2 = cos(theta) * q2 (0) + sin(theta) * q2 (1); // x_theta_imp
192
    hppDout(notice,"xTheta0 = "<<x1 << " , "<<coefficients_[6]<<"   xThetaImp =
193
  "<<x2);
194
195
    // Define integration bounds
196
    if (x1 > x2) { // re-order integration bounds
197
      const value_type xtmp = x1;
198
      x1 = x2;
199
      x2 = xtmp;
200
    }
201
202
    const value_type dx = (x2 - x1) / N; // integration step size
203
    for (int i=0; i<N; i++) {
204
      length += dx*( 0.166666667*lengthFunction (x1 + i*dx)
205
                     + 0.666666667*lengthFunction (x1 + (i+0.5)*dx )
206
                     + 0.166666667*lengthFunction (x1 + (i+1)*dx ));
207
      // apparently, 1/6 and 2/3 are not recognized as floats ...
208
    }
209
    hppDout (notice, "length = " << length);
210
    return length;
211
  }*/
212
213
// test (pierre) :
214
value_type ParabolaPath::computeLength(const core::ConfigurationIn_t q1,
215
                                       const core::ConfigurationIn_t q2) const {
216
  const value_type theta = coefficients_(3);
217
  const value_type X = q2[0] - q1[0];
218
  const value_type Y = q2[1] - q1[1];
219
  ;
220
  // theta = coef[3]
221
  const value_type X_theta = X * cos(theta) + Y * sin(theta);
222
  return X_theta;
223
}
224
225
// Function equivalent to sqrt( 1 + f'(x)^2 )
226
value_type ParabolaPath::lengthFunction(const value_type x) const {
227
  const value_type y =
228
      sqrt(1 + (2 * coefficients_(0) * x + coefficients_(1)) *
229
                   (2 * coefficients_(0) * x + coefficients_(1)));
230
  return y;
231
}
232
233
vector_t ParabolaPath::evaluateVelocity(const value_type t) const {
234
  vector_t vel(3);
235
  bool success;
236
  const value_type theta = coefficients_(3);
237
  const value_type alpha = coefficients_(4);
238
  const value_type x_theta_0_dot = coefficients_(5);
239
  const value_type inv_x_theta_0_dot_sq = 1 / (x_theta_0_dot * x_theta_0_dot);
240
  const value_type x_theta_0 = coefficients_(6);
241
  const core::Configuration_t q = (*this)(t, success);
242
  const value_type x_theta = q[0] * cos(theta) + q[1] * sin(theta);
243
  vel[0] = x_theta_0_dot * cos(theta);
244
  vel[1] = x_theta_0_dot * sin(theta);
245
  vel[2] = x_theta_0_dot *
246
           (-9.81 * (x_theta - x_theta_0) * inv_x_theta_0_dot_sq + tan(alpha));
247
  return vel;
248
}
249
250
}  //   namespace rbprm
251
}  // namespace hpp