GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/ZMPRefTrajectoryGeneration/AnalyticalMorisawaCompact.cpp Lines: 63 1331 4.7 %
Date: 2023-09-06 16:16:35 Branches: 58 1259 4.6 %

Line Branch Exec Source
1
/*
2
 * Copyright 2008, 2009, 2010, 2014, 2015
3
 *
4
 * Torea Foissotte
5
 * Olivier Stasse
6
 *
7
 * JRL, CNRS/AIST
8
 *
9
 * This file is part of jrl-walkgen.
10
 * jrl-walkgen is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Lesser General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * jrl-walkgen is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Lesser Public License for more details.
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with jrl-walkgen. If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 * Research carried out within the scope of the
23
 * Joint Japanese-French Robotics Laboratory (JRL)
24
 */
25
/* This object generates the reference value for the
26
   ZMP based on a polynomail representation
27
   of the ZMP following
28
   "Experimentation of Humanoid Walking Allowing Immediate
29
   Modification of Foot Place Based on Analytical Solution"
30
   Morisawa, Harada, Kajita, Nakaoka, Fujiwara, Kanehiro, Hirukawa,
31
   ICRA 2007, 3989--39994
32
*/
33
34
#include <Debug.hh>
35
#include <ZMPRefTrajectoryGeneration/AnalyticalMorisawaCompact.hh>
36
#include <boost/version.hpp>
37
#include <fstream>
38
#include <iomanip>
39
40
typedef double doublereal;
41
typedef int integer;
42
43
extern "C" {
44
extern int dgesvx_(char *, char *,          /* 0 FACT TRANS */
45
                   integer *, integer *,    /* 2 N NHRS */
46
                   doublereal *, integer *, /* 4 A LDA */
47
                   doublereal *, integer *, /* 6 AF LDAF */
48
                   integer *,               /* 7 IPIV */
49
                   char *,                  /* 8 EQUED */
50
                   doublereal *,            /* 9 R */
51
                   doublereal *,            /* 10 C */
52
                   doublereal *,            /* 11 B */
53
                   integer *,               /* 12 LDB */
54
                   doublereal *,            /* 13 X */
55
                   integer *,               /* 14 LDX */
56
                   doublereal *,            /* 15 RCOND */
57
                   doublereal *,            /* 16 FERR */
58
                   doublereal *,            /* 17 BERR */
59
                   doublereal *,            /* 18 WORK */
60
                   integer *,               /* 19 IWORK */
61
                   integer *                /* 20 INFO */
62
);
63
64
#if BOOST_VERSION >= 104000
65
extern void dgetrf_(integer *m,    /* M */
66
                    integer *n,    /* N */
67
                    doublereal *A, /* A */
68
                    integer *lda,  /* LDA */
69
                    integer *ipiv, /* IPIV */
70
                    integer *info  /* info */
71
);
72
#endif
73
}
74
75
namespace PatternGeneratorJRL {
76
77
5
AnalyticalMorisawaCompact::AnalyticalMorisawaCompact(SimplePluginManager *lSPM,
78
5
                                                     PinocchioRobot *aPR)
79








5
    : AnalyticalMorisawaAbstract(lSPM) {
80
5
  RegisterMethods();
81
5
  m_OnLineMode = false;
82
5
  m_EndPhase = false;
83
84
5
  memset(&m_CTIPX, 0, sizeof(m_CTIPX));
85
5
  memset(&m_CTIPY, 0, sizeof(m_CTIPY));
86
87
5
  m_OnLineChangeStepMode = ABSOLUTE_FRAME;
88
5
  m_PR = aPR;
89
5
  m_FeetTrajectoryGenerator = m_BackUpm_FeetTrajectoryGenerator = 0;
90
91
5
  m_NeedToReset = true;
92
5
  m_AbsoluteTimeReference = 0.0;
93
94
5
  m_PreviewControl = new PreviewControl(
95

5
      lSPM, OptimalControllerSolver::MODE_WITH_INITIALPOS, true);
96
97
  /*! Dynamic allocation of the analytical trajectories for the ZMP
98
    and the COG */
99

5
  m_AnalyticalZMPCoGTrajectoryX = new AnalyticalZMPCOGTrajectory(7);
100

5
  m_AnalyticalZMPCoGTrajectoryY = new AnalyticalZMPCOGTrajectory(7);
101
  // m_AnalyticalZMPCoGTrajectoryZ = new AnalyticalZMPCOGTrajectory(7);
102
103
  /*! Dynamic allocation of the filters. */
104
5
  m_FilterXaxisByPC = new FilteringAnalyticalTrajectoryByPreviewControl(
105

5
      lSPM, m_AnalyticalZMPCoGTrajectoryX, m_PreviewControl);
106
107
5
  m_FilterYaxisByPC = new FilteringAnalyticalTrajectoryByPreviewControl(
108

5
      lSPM, m_AnalyticalZMPCoGTrajectoryY, m_PreviewControl);
109
110

5
  m_kajitaDynamicFilter = new DynamicFilter(lSPM, m_PR);
111
112
5
  m_VerboseLevel = 0;
113
114
5
  m_NewStepInTheStackOfAbsolutePosition = false;
115
116
5
  m_FilteringActivate = true;
117
118

5
  m_CoMbsplinesZ = new BSplinesFoot();
119

5
  m_ZMPpolynomeZ = new Polynome3(0.0, 0.0);
120
5
  DFpreviewWindowSize_ = 0.0;
121
122
  RESETDEBUG4("Test.dat");
123
5
}
124
125
20
AnalyticalMorisawaCompact::~AnalyticalMorisawaCompact() {
126
10
  if (m_VerboseLevel > 2) {
127
    // Display the clock for some part of the code.
128
    cout << "Part of the foot position computation + queue handling." << endl;
129
    m_Clock1.Display();
130
    cout << "Part of the foot change landing position" << endl;
131
    m_Clock2.Display();
132
    cout << "Part on the analytical ZMP COG trajectories and "
133
         << "foot polynomial computation" << endl;
134
    m_Clock3.Display();
135
  }
136
137
20
  string Filename("Clock1.dat");
138
10
  m_Clock1.RecordDataBuffer(Filename);
139
10
  Filename = "Clock2.dat";
140
10
  m_Clock2.RecordDataBuffer(Filename);
141
10
  Filename = "Clock3.dat";
142
10
  m_Clock3.RecordDataBuffer(Filename);
143
144

10
  if (m_AnalyticalZMPCoGTrajectoryX != 0) delete m_AnalyticalZMPCoGTrajectoryX;
145
  ODEBUG4("Destructor: did AnalyticalZMPCoGTrajectoryX", "DebugPGI.txt");
146
147

10
  if (m_AnalyticalZMPCoGTrajectoryY != 0) delete m_AnalyticalZMPCoGTrajectoryY;
148
  ODEBUG4("Destructor: did AnalyticalZMPCoGTrajectoryY", "DebugPGI.txt");
149
150

10
  if (m_FilterXaxisByPC != 0) delete m_FilterXaxisByPC;
151
152
  ODEBUG4("Destructor: did FilterXaxisByPC", "DebugPGI.txt");
153
154

10
  if (m_FilterYaxisByPC != 0) delete m_FilterYaxisByPC;
155
156
  ODEBUG4("Destructor: did FilterYaxisByPC", "DebugPGI.txt");
157
158

10
  if (m_PreviewControl != 0) delete m_PreviewControl;
159
160
10
  if (m_BackUpm_FeetTrajectoryGenerator != 0)
161
10
    delete m_BackUpm_FeetTrajectoryGenerator;
162
  ODEBUG4("Destructor: did PreviewControl", "DebugPGI.txt");
163
20
}
164
165
bool AnalyticalMorisawaCompact::InitializeBasicVariables() {
166
  m_NumberOfIntervals = 2 * m_NumberOfStepsInAdvance + 1;
167
168
  // Compute the temporal intervals.
169
  m_DeltaTj.resize(m_NumberOfIntervals);
170
  m_Omegaj.resize(m_NumberOfIntervals);
171
  m_StepTypes.resize(m_NumberOfIntervals);
172
173
  m_DeltaTj[0] = m_Tsingle * 3.0;
174
175
  m_StepTypes[0] = DOUBLE_SUPPORT;
176
  for (int i = 1; i < m_NumberOfIntervals; i++) {
177
    if (i % 2 == 0) {
178
      m_DeltaTj[i] = m_Tsingle;
179
      m_StepTypes[i] = SINGLE_SUPPORT;
180
    } else {
181
      m_DeltaTj[i] = m_Tdble;
182
      m_StepTypes[i] = DOUBLE_SUPPORT;
183
    }
184
  }
185
  m_DeltaTj[m_NumberOfIntervals - 1] = m_Tsingle * 3.0;
186
  m_StepTypes[m_NumberOfIntervals - 1] = DOUBLE_SUPPORT;
187
  ComputePreviewControlTimeWindow();
188
189
  if (m_VerboseLevel >= 2) {
190
    double total = 0;
191
    for (int i = 0; i < m_NumberOfIntervals; i++) {
192
      cout << setprecision(12) << m_DeltaTj[i] << " ";
193
      total += m_DeltaTj[i];
194
    }
195
    cout << " total: " << total << endl;
196
  }
197
198
  // Specify the degrees corresponding to the given interval.
199
  m_PolynomialDegrees.resize(m_NumberOfIntervals);
200
  m_PolynomialDegrees[0] = 4;
201
  m_PolynomialDegrees[m_NumberOfIntervals - 1] = 4;
202
  for (int i = 1; i < m_NumberOfIntervals - 1; i++) m_PolynomialDegrees[i] = 3;
203
204
  /*! Dynamic allocation for the foot trajectory. */
205
  if (m_FeetTrajectoryGenerator != 0) {
206
    m_FeetTrajectoryGenerator->SetDeltaTj(m_DeltaTj);
207
  }
208
  return true;
209
}
210
211
void AnalyticalMorisawaCompact::ComputePolynomialWeights() {
212
  Eigen::MatrixXd iZ;
213
  iZ = m_Z.inverse();
214
215
  // Compute the weights.
216
  m_y = iZ + m_w;
217
218
  if (m_VerboseLevel >= 2) {
219
    std::ofstream ofs;
220
    ofs.open("YMatrix.dat", ofstream::out);
221
    ofs.precision(10);
222
223
    for (unsigned int i = 0; i < m_y.size(); i++) {
224
      ofs << m_y[i] << " ";
225
    }
226
    ofs << endl;
227
    ofs.close();
228
  }
229
}
230
231
void AnalyticalMorisawaCompact::ResetTheResolutionOfThePolynomial() {
232
  long int SizeOfZ = m_Z.rows();
233
234
  m_AF.resize(SizeOfZ, 2 * SizeOfZ);
235
  m_IPIV.resize(SizeOfZ);
236
  m_AF.setZero();
237
  m_IPIV.setZero();
238
239
  m_NeedToReset = true;
240
}
241
242
void AnalyticalMorisawaCompact::ComputePolynomialWeights2() {
243
  int SizeOfZ = (int)m_Z.rows(), LDA, LDAF, LDB;
244
  int NRHS = 1;
245
246
  char EQUED = 'N';
247
248
  Eigen::MatrixXd tZ;
249
  tZ = m_Z.transpose();
250
251
  Eigen::VectorXd lR;
252
  lR.resize(SizeOfZ);
253
  Eigen::VectorXd lC;
254
  lC.resize(SizeOfZ);
255
256
  m_y.resize(SizeOfZ);
257
  // Eigen::VectorXd m_X;
258
  // b m_X.resize(SizeOfZ);
259
  LDA = SizeOfZ;
260
  LDAF = SizeOfZ;
261
  LDB = SizeOfZ;
262
263
  double lRCOND;
264
265
  Eigen::VectorXd lFERR, lBERR;
266
  lFERR.resize(SizeOfZ);
267
  lBERR.resize(SizeOfZ);
268
269
  int lwork = 4 * SizeOfZ;
270
  double *work = new double[lwork];
271
  int *iwork = new int[SizeOfZ];
272
  int lsizeofx = SizeOfZ;
273
  int info = 0;
274
275
  if (m_NeedToReset) {
276
    m_AF = m_Z.transpose();
277
    dgetrf_(&SizeOfZ,   /* M */
278
            &SizeOfZ,   /* N here M=N=SizeOfZ */
279
            &m_AF(0),   /* A */
280
            &SizeOfZ,   /* Leading dimension cf before */
281
            &m_IPIV(0), /* IPIV */
282
            &info       /* info */
283
    );
284
    m_NeedToReset = false;
285
  }
286
287
  char lF[2] = "F";
288
  char lN[2] = "N";
289
  dgesvx_(lF,       /* Specify that AF and IPIV should be used. */
290
          lN,       /* A * X = B */
291
          &SizeOfZ, /* Size of A */
292
          &NRHS,    /*Nb of columns for X et B */
293
          &tZ(0),   /* Access to A */
294
          &LDA,     /* Leading size of A */
295
          &m_AF(0), &LDAF, &m_IPIV(0), &EQUED, &lR(0), &lC(0), &m_w(0), &LDB,
296
          &m_y(0), &lsizeofx, &lRCOND, &lFERR(0), &lBERR(0), work, iwork,
297
          &info);
298
299
  // Compute the weights.
300
  // m_y=iZ+m_w;
301
302
  if (m_VerboseLevel >= 2) {
303
    std::ofstream ofs;
304
    ofs.open("YMatrix.dat", ofstream::out);
305
    ofs.precision(10);
306
307
    for (unsigned int i = 0; i < m_y.size(); i++) {
308
      ofs << m_y[i] << " ";
309
    }
310
    ofs << endl;
311
    ofs.close();
312
  }
313
314
  delete[] work;
315
  delete[] iwork;
316
}
317
318
int AnalyticalMorisawaCompact::BuildAndSolveCOMZMPForASetOfSteps(
319
    Eigen::Matrix3d &lStartingCOMState,
320
    FootAbsolutePosition &LeftFootInitialPosition,
321
    FootAbsolutePosition &RightFootInitialPosition,
322
    bool IgnoreFirstRelativeFoot, bool DoNotPrepareLastFoot) {
323
  if (m_RelativeFootPositions.size() == 0) return -2;
324
325
  int NbSteps = (int)m_RelativeFootPositions.size();
326
  int NbOfIntervals = 2 * NbSteps + 1;
327
328
  SetNumberOfStepsInAdvance(NbSteps);
329
  InitializeBasicVariables();
330
331
  vector<double> *lCoMZ;
332
  vector<double> *lZMPZ;
333
334
  lCoMZ = &m_CTIPX.CoMZ;
335
  lZMPZ = &m_CTIPX.ZMPZ;
336
337
  lCoMZ->resize(NbOfIntervals);
338
  lZMPZ->resize(NbOfIntervals);
339
  for (int i = 0; i < NbOfIntervals; i++) {
340
    (*lCoMZ)[i] = lStartingCOMState(2, 0);
341
    (*lZMPZ)[i] = 0.0;
342
  }
343
344
  /*! Build the Z Matrix. */
345
  BuildingTheZMatrix(*lCoMZ, *lZMPZ);
346
347
  ResetTheResolutionOfThePolynomial();
348
349
  /*! Initialize correctly the analytical trajectories. */
350
  m_AnalyticalZMPCoGTrajectoryX->SetNumberOfIntervals(NbOfIntervals);
351
  m_AnalyticalZMPCoGTrajectoryY->SetNumberOfIntervals(NbOfIntervals);
352
353
  m_AnalyticalZMPCoGTrajectoryX->SetPolynomialDegrees(m_PolynomialDegrees);
354
  m_AnalyticalZMPCoGTrajectoryY->SetPolynomialDegrees(m_PolynomialDegrees);
355
356
  m_AnalyticalZMPCoGTrajectoryX->SetStartingTimeIntervalsAndHeightVariation(
357
      m_DeltaTj, m_Omegaj);
358
  m_AnalyticalZMPCoGTrajectoryY->SetStartingTimeIntervalsAndHeightVariation(
359
      m_DeltaTj, m_Omegaj);
360
361
  /* Build the profil for the X and Y axis. */
362
  double InitialCoMX = 0.0;
363
  double InitialCoMSpeedX = 0.0;
364
  double FinalCoMPosX = 0.6;
365
  vector<double> *lZMPX = 0;
366
  lZMPX = &m_CTIPX.ZMPProfil;
367
368
  lZMPX->resize(NbOfIntervals);
369
370
  double InitialCoMY = 0.0;
371
  double InitialCoMSpeedY = 0.0;
372
  double FinalCoMPosY = 0.0;
373
  vector<double> *lZMPY = 0;
374
  lZMPY = &m_CTIPY.ZMPProfil;
375
376
  lZMPY->resize(NbOfIntervals);
377
378
  (*lZMPX)[0] = lStartingCOMState(0, 0);
379
  (*lZMPY)[0] = lStartingCOMState(1, 0);
380
381
  /*! Extract the set of initial conditions relevant for
382
    computing the analytical trajectories. */
383
  InitialCoMX = (*lZMPX)[0];
384
  InitialCoMSpeedX = lStartingCOMState(0, 1);
385
  InitialCoMY = (*lZMPY)[0];
386
  InitialCoMSpeedY = lStartingCOMState(1, 1);
387
388
  /*! Extract the set of absolute coordinates for the foot position. */
389
  if (m_FeetTrajectoryGenerator != 0) {
390
    m_FeetTrajectoryGenerator->SetDeltaTj(m_DeltaTj);
391
    m_FeetTrajectoryGenerator->InitializeFromRelativeSteps(
392
        m_RelativeFootPositions, LeftFootInitialPosition,
393
        RightFootInitialPosition, m_AbsoluteSupportFootPositions,
394
        IgnoreFirstRelativeFoot, false);
395
    unsigned int i = 0, j = 1;
396
397
    for (i = 0, j = 1; i < m_AbsoluteSupportFootPositions.size(); i++, j += 2) {
398
      (*lZMPX)[j] = m_AbsoluteSupportFootPositions[i].x;
399
      (*lZMPX)[j + 1] = m_AbsoluteSupportFootPositions[i].x;
400
401
      (*lZMPY)[j] = m_AbsoluteSupportFootPositions[i].y;
402
      (*lZMPY)[j + 1] = m_AbsoluteSupportFootPositions[i].y;
403
    }
404
405
    // Strategy for the final CoM pos: middle of the segment
406
    // between the two final steps, in order to be statically stable.
407
    unsigned int lindex =
408
        (unsigned int)(m_AbsoluteSupportFootPositions.size() - 1);
409
410
    if (DoNotPrepareLastFoot)
411
      FinalCoMPosX = m_AbsoluteSupportFootPositions[lindex].x;
412
    else
413
      FinalCoMPosX = 0.5 * (m_AbsoluteSupportFootPositions[lindex - 1].x +
414
                            m_AbsoluteSupportFootPositions[lindex].x);
415
    if (DoNotPrepareLastFoot)
416
      (*lZMPX)[j - 2] = (*lZMPX)[j - 1] =
417
          m_AbsoluteSupportFootPositions[lindex].x;
418
    else
419
      (*lZMPX)[j - 2] = (*lZMPX)[j - 1] = FinalCoMPosX;
420
421
    if (DoNotPrepareLastFoot)
422
      FinalCoMPosY = m_AbsoluteSupportFootPositions[lindex].y;
423
    else
424
      FinalCoMPosY = 0.5 * (m_AbsoluteSupportFootPositions[lindex - 1].y +
425
                            m_AbsoluteSupportFootPositions[lindex].y);
426
427
    if (DoNotPrepareLastFoot)
428
      (*lZMPY)[j - 2] = (*lZMPY)[j - 1] =
429
          m_AbsoluteSupportFootPositions[lindex].y;
430
    else
431
      (*lZMPY)[j - 2] = (*lZMPY)[j - 1] = FinalCoMPosY;
432
  } else {
433
    std::cerr << " Feet Trajectory Generator NOT INITIALIZED" << std::endl;
434
    return -1;
435
  }
436
437
  /*! Build 3rd order polynomials. */
438
  for (int i = 1; i < NbOfIntervals - 1; i++) {
439
    m_AnalyticalZMPCoGTrajectoryX->Building3rdOrderPolynomial(
440
        i, (*lZMPX)[i - 1], (*lZMPX)[i]);
441
    m_AnalyticalZMPCoGTrajectoryY->Building3rdOrderPolynomial(
442
        i, (*lZMPY)[i - 1], (*lZMPY)[i]);
443
  }
444
445
  // Block for X trajectory
446
  m_CTIPX.InitialCoM = InitialCoMX;
447
  m_CTIPX.InitialCoMSpeed = InitialCoMSpeedX;
448
  m_CTIPX.FinalCoMPos = FinalCoMPosX;
449
  // m_CTIPX.ZMPProfil = lZMPX;
450
  // m_CTIPX.ZMPZ = lZMPZ;
451
  // m_CTIPX.CoMZ = lCoMZ;
452
  ComputeTrajectory(m_CTIPX, *m_AnalyticalZMPCoGTrajectoryX);
453
454
  // Block for Y trajectory.
455
  m_CTIPY.InitialCoM = InitialCoMY;
456
  m_CTIPY.InitialCoMSpeed = InitialCoMSpeedY;
457
  m_CTIPY.FinalCoMPos = FinalCoMPosY;
458
  // m_CTIPY.ZMPProfil = lZMPY;
459
  m_CTIPY.ZMPZ = *lZMPZ;
460
  m_CTIPY.CoMZ = *lCoMZ;
461
  ComputeTrajectory(m_CTIPY, *m_AnalyticalZMPCoGTrajectoryY);
462
463
  return 0;
464
}
465
466
void AnalyticalMorisawaCompact::GetZMPDiscretization(
467
    deque<ZMPPosition> &ZMPPositions, deque<COMState> &COMStates,
468
    deque<RelativeFootPosition> &RelativeFootPositions,
469
    deque<FootAbsolutePosition> &LeftFootAbsolutePositions,
470
    deque<FootAbsolutePosition> &RightFootAbsolutePositions, double,
471
    COMState &lStartingCOMState, Eigen::Vector3d &,
472
    FootAbsolutePosition &InitLeftFootAbsolutePosition,
473
    FootAbsolutePosition &InitRightFootAbsolutePosition) {
474
  // INITIALIZE FEET POSITIONS:
475
  // --------------------------
476
  Eigen::Vector3d lAnklePositionRight, lAnklePositionLeft;
477
  PRFoot *LeftFoot, *RightFoot;
478
  LeftFoot = m_PR->leftFoot();
479
  if (LeftFoot == 0) LTHROW("No left foot");
480
481
  RightFoot = m_PR->rightFoot();
482
  if (RightFoot == 0) LTHROW("No right foot");
483
484
  lAnklePositionLeft = LeftFoot->anklePosition;
485
  lAnklePositionRight = RightFoot->anklePosition;
486
487
  Eigen::Matrix4d CurPosWICF_homogeneous;
488
  CurPosWICF_homogeneous = m_kajitaDynamicFilter->getComAndFootRealization()
489
                               ->GetCurrentPositionofWaistInCOMFrame();
490
491
  m_RelativeFootPositions = RelativeFootPositions;
492
  /* This part computes the CoM and ZMP trajectory giving
493
     the foot position information.
494
     It also creates the analytical feet trajectories.
495
  */
496
  Eigen::Matrix3d lMStartingCOMState;
497
498
  lMStartingCOMState(0, 0) = lStartingCOMState.x[0];
499
  lMStartingCOMState(1, 0) = lStartingCOMState.y[0];
500
  lMStartingCOMState(2, 0) = lStartingCOMState.z[0];
501
502
  m_InitialPoseCoMHeight = lMStartingCOMState(2, 0);
503
504
  for (unsigned int i = 0; i < 3; i++) {
505
    for (unsigned int j = 1; j < 3; j++) lMStartingCOMState(i, j) = 0.0;
506
  }
507
508
  int r = 0;
509
  if ((r = BuildAndSolveCOMZMPForASetOfSteps(
510
           lMStartingCOMState, InitLeftFootAbsolutePosition,
511
           InitRightFootAbsolutePosition, true, false)) < 0) {
512
    switch (r) {
513
      case (-1):
514
        LTHROW("Error: Humanoid Specificities not initialized. ");
515
        break;
516
      case (-2):
517
        LTHROW("Error: Relative Foot Size");
518
        break;
519
    }
520
    return;
521
  }
522
523
  /*! Set the current time reference for the analytical trajectory. */
524
  double TimeShift = m_Tsingle * 2;
525
  m_AbsoluteTimeReference = m_CurrentTime - TimeShift;
526
  m_AnalyticalZMPCoGTrajectoryX->SetAbsoluteTimeReference(
527
      m_AbsoluteTimeReference);
528
  m_AnalyticalZMPCoGTrajectoryY->SetAbsoluteTimeReference(
529
      m_AbsoluteTimeReference);
530
  m_FeetTrajectoryGenerator->SetAbsoluteTimeReference(m_AbsoluteTimeReference);
531
532
  /*! Compute the total size of the array related to the steps. */
533
  FillQueues(m_CurrentTime, m_CurrentTime + m_PreviewControlTime - TimeShift,
534
             ZMPPositions, COMStates, LeftFootAbsolutePositions,
535
             RightFootAbsolutePositions);
536
537
  bool filterOn_ = true;
538
  if (filterOn_) {
539
    /*! initialize the dynamic filter */
540
    unsigned int n = (unsigned int)COMStates.size();
541
    double KajitaPCpreviewWindow = 1.6;
542
    m_kajitaDynamicFilter->init(
543
        m_SamplingPeriod, m_SamplingPeriod, n * m_SamplingPeriod,
544
        m_PreviewControlTime - TimeShift + KajitaPCpreviewWindow,
545
        KajitaPCpreviewWindow, lStartingCOMState);
546
    /*! Set the upper body trajectory */
547
    Eigen::VectorXd UpperConfig = m_PR->currentRPYConfiguration();
548
    Eigen::VectorXd UpperVel = m_PR->currentRPYVelocity();
549
    Eigen::VectorXd UpperAcc = m_PR->currentRPYAcceleration();
550
    // carry the weight in front of him
551
    //        UpperConfig(18)= 0.0 ;            // CHEST_JOINT0
552
    //        UpperConfig(19)= 0.015 ;          // CHEST_JOINT1
553
    //        UpperConfig(20)= 0.0 ;            // HEAD_JOINT0
554
    //        UpperConfig(21)= 0.0 ;            // HEAD_JOINT1
555
    //        UpperConfig(22)= -0.108210414 ;   // RARM_JOINT0
556
    //        UpperConfig(23)= 0.0383972435 ;   // RARM_JOINT1
557
    //        UpperConfig(24)= 0.474729557 ;    // RARM_JOINT2
558
    //        UpperConfig(25)= -1.41720735 ;    // RARM_JOINT3
559
    //        UpperConfig(26)= 1.45385927 ;     // RARM_JOINT4
560
    //        UpperConfig(27)= 0.509636142 ;    // RARM_JOINT5
561
    //        UpperConfig(28)= 0.174532925 ;    // RARM_JOINT6
562
    //        UpperConfig(29)= -0.108210414 ;   // LARM_JOINT0
563
    //        UpperConfig(30)= -0.129154365 ;   // LARM_JOINT1
564
    //        UpperConfig(31)= -0.333357887 ;   // LARM_JOINT2
565
    //        UpperConfig(32)= -1.41720735 ;    // LARM_JOINT3
566
    //        UpperConfig(33)= 1.45385927 ;     // LARM_JOINT4
567
    //        UpperConfig(34)= -0.193731547 ;   // LARM_JOINT5
568
    //        UpperConfig(35)= 0.174532925 ;    // LARM_JOINT6
569
570
    //    // carry the weight over the head
571
    //    UpperConfig(18)= 0.0 ;            // CHEST_JOINT0
572
    //    UpperConfig(19)= 0.015 ;          // CHEST_JOINT1
573
    //    UpperConfig(20)= 0.0 ;            // HEAD_JOINT0
574
    //    UpperConfig(21)= 0.0 ;            // HEAD_JOINT1
575
    //    UpperConfig(22)= -1.4678219 ;     // RARM_JOINT0
576
    //    UpperConfig(23)= 0.0366519143 ;   // RARM_JOINT1
577
    //    UpperConfig(24)= 0.541052068 ;    // RARM_JOINT2
578
    //    UpperConfig(25)= -1.69296937 ;    // RARM_JOINT3
579
    //    UpperConfig(26)= 1.56556034 ;     // RARM_JOINT4
580
    //    UpperConfig(27)= 0.584685299 ;    // RARM_JOINT5
581
    //    UpperConfig(28)= 0.174532925 ;    // RARM_JOINT6
582
    //    UpperConfig(29)= -1.4678219 ;     // LARM_JOINT0
583
    //    UpperConfig(30)= -0.0366519143 ;  // LARM_JOINT1
584
    //    UpperConfig(31)= -0.541052068 ;   // LARM_JOINT2
585
    //    UpperConfig(32)= -1.69296937 ;    // LARM_JOINT3
586
    //    UpperConfig(33)= -1.56556034 ;     // LARM_JOINT4
587
    //    UpperConfig(34)= 0.584685299 ;    // LARM_JOINT5
588
    //    UpperConfig(35)= 0.174532925 ;    // LARM_JOINT6
589
590
    for (unsigned int i = 18; i < 35; ++i) {
591
      UpperConfig(i) = m_PR->currentRPYConfiguration()(i);
592
      UpperVel(i) = 0.0;
593
      UpperAcc(i) = 0.0;
594
    }
595
596
    m_kajitaDynamicFilter->setRobotUpperPart(UpperConfig, UpperVel, UpperAcc);
597
598
    /*! Add "KajitaPCpreviewWindow" second to the buffers for fitering */
599
    ZMPPosition lastZMP = ZMPPositions.back();
600
    COMState lastCoM = COMStates.back();
601
    FootAbsolutePosition lastLF = LeftFootAbsolutePositions.back();
602
    FootAbsolutePosition lastRF = RightFootAbsolutePositions.back();
603
    for (unsigned int i = 0; i < KajitaPCpreviewWindow / m_SamplingPeriod;
604
         ++i) {
605
      ZMPPositions.push_back(lastZMP);
606
      COMStates.push_back(lastCoM);
607
      LeftFootAbsolutePositions.push_back(lastLF);
608
      RightFootAbsolutePositions.push_back(lastRF);
609
    }
610
611
    for (unsigned int i = 0; i < COMStates.size(); ++i) {
612
      COMStates[i].roll[0] = 180 / M_PI * COMStates[i].roll[0];
613
      COMStates[i].pitch[0] = 180 / M_PI * COMStates[i].pitch[0];
614
      COMStates[i].yaw[0] = 180 / M_PI * COMStates[i].yaw[0];
615
    }
616
617
    // Filter the trajectory
618
    deque<COMState> outputDeltaCOMTraj_deq(n);
619
    m_kajitaDynamicFilter->OffLinefilter(
620
        COMStates, ZMPPositions, LeftFootAbsolutePositions,
621
        RightFootAbsolutePositions, vector<Eigen::VectorXd>(1, UpperConfig),
622
        vector<Eigen::VectorXd>(1, UpperVel),
623
        vector<Eigen::VectorXd>(1, UpperAcc), outputDeltaCOMTraj_deq);
624
625
#ifdef DEBUG
626
    m_kajitaDynamicFilter->Debug(
627
        COMStates, LeftFootAbsolutePositions, RightFootAbsolutePositions,
628
        COMStates, ZMPPositions, LeftFootAbsolutePositions,
629
        RightFootAbsolutePositions, outputDeltaCOMTraj_deq);
630
#endif
631
    vector<vector<double> > filteredZMPMB(n, vector<double>(2, 0.0));
632
    for (unsigned int i = 0; i < n; ++i) {
633
      for (int j = 0; j < 3; j++) {
634
        COMStates[i].x[j] += outputDeltaCOMTraj_deq[i].x[j];
635
        COMStates[i].y[j] += outputDeltaCOMTraj_deq[i].y[j];
636
      }
637
    }
638
639
    for (unsigned int i = 0; i < KajitaPCpreviewWindow / m_SamplingPeriod;
640
         ++i) {
641
      ZMPPositions.pop_back();
642
      COMStates.pop_back();
643
      LeftFootAbsolutePositions.pop_back();
644
      RightFootAbsolutePositions.pop_back();
645
    }
646
  }
647
  // End the Filtering
648
649
  m_UpperTimeLimitToUpdateStacks = m_CurrentTime;
650
  for (int i = 0; i < m_NumberOfIntervals; i++) {
651
    m_UpperTimeLimitToUpdateStacks += m_DeltaTj[i];
652
  }
653
}
654
655
std::size_t AnalyticalMorisawaCompact::InitOnLine(
656
    deque<ZMPPosition> &FinalZMPPositions, deque<COMState> &FinalCoMPositions,
657
    deque<FootAbsolutePosition> &FinalLeftFootAbsolutePositions,
658
    deque<FootAbsolutePosition> &FinalRightFootAbsolutePositions,
659
    FootAbsolutePosition &InitLeftFootAbsolutePosition,
660
    FootAbsolutePosition &InitRightFootAbsolutePosition,
661
    deque<RelativeFootPosition> &RelativeFootPositions,
662
    COMState &lStartingCOMState, Eigen::Vector3d &) {
663
  m_OnLineMode = true;
664
  m_RelativeFootPositions.clear();
665
666
  unsigned int r = (unsigned int)RelativeFootPositions.size();
667
  unsigned int maxrelsteps = r < 3 ? r : 3;
668
669
  // INITIALIZE FEET POSITIONS:
670
  // --------------------------
671
  Eigen::Vector3d lAnklePositionRight, lAnklePositionLeft;
672
  PRFoot *LeftFoot, *RightFoot;
673
  LeftFoot = m_PR->leftFoot();
674
  if (LeftFoot == 0) LTHROW("No left foot");
675
676
  RightFoot = m_PR->rightFoot();
677
  if (RightFoot == 0) LTHROW("No right foot");
678
679
  lAnklePositionLeft = LeftFoot->anklePosition;
680
  lAnklePositionRight = RightFoot->anklePosition;
681
682
  Eigen::Matrix4d CurPosWICF_homogeneous;
683
  CurPosWICF_homogeneous = m_kajitaDynamicFilter->getComAndFootRealization()
684
                               ->GetCurrentPositionofWaistInCOMFrame();
685
686
  InitLeftFootAbsolutePosition.x += lAnklePositionLeft(0);
687
  InitLeftFootAbsolutePosition.y += lAnklePositionLeft(1);
688
  InitLeftFootAbsolutePosition.z += lAnklePositionLeft(2);
689
  InitRightFootAbsolutePosition.x += lAnklePositionRight(0);
690
  InitRightFootAbsolutePosition.y += lAnklePositionRight(1);
691
  InitRightFootAbsolutePosition.z += lAnklePositionRight(2);
692
693
  // INITIALIZE THE COM
694
  // ------------------
695
  Eigen::Matrix3d lMStartingCOMState;
696
697
  lMStartingCOMState(0, 0) = lStartingCOMState.x[0];
698
  lMStartingCOMState(1, 0) = lStartingCOMState.y[0];
699
  lMStartingCOMState(2, 0) = lStartingCOMState.z[0];
700
701
  m_InitialPoseCoMHeight = lStartingCOMState.z[0];
702
703
  for (unsigned int i = 0; i < 3; i++) {
704
    for (unsigned int j = 1; j < 3; j++) lMStartingCOMState(i, j) = 0.0;
705
  }
706
707
  for (unsigned int i = 0; i < maxrelsteps; i++)
708
    m_RelativeFootPositions.push_back(RelativeFootPositions[i]);
709
710
  if (m_RelativeFootPositions[0].sy < 0)
711
    m_AbsoluteCurrentSupportFootPosition = InitRightFootAbsolutePosition;
712
  else
713
    m_AbsoluteCurrentSupportFootPosition = InitLeftFootAbsolutePosition;
714
715
  /* This part computes the CoM and ZMP trajectory
716
     giving the foot position information.
717
     It also creates the analytical feet trajectories.
718
  */
719
  if (BuildAndSolveCOMZMPForASetOfSteps(
720
          lMStartingCOMState, InitLeftFootAbsolutePosition,
721
          InitRightFootAbsolutePosition, true, true) < 0) {
722
    LTHROW("Error: Humanoid Specificities not initialized. ");
723
  }
724
725
  m_AbsoluteTimeReference = m_CurrentTime - m_Tsingle * 2;
726
  m_AnalyticalZMPCoGTrajectoryX->SetAbsoluteTimeReference(
727
      m_AbsoluteTimeReference);
728
  m_AnalyticalZMPCoGTrajectoryY->SetAbsoluteTimeReference(
729
      m_AbsoluteTimeReference);
730
  m_FeetTrajectoryGenerator->SetAbsoluteTimeReference(m_AbsoluteTimeReference);
731
732
  /* Current strategy : add 2 values, and update at each iteration the stack.
733
     When the limit is reached, and the stack exhausted this method is called
734
     again.  */
735
  FillQueues(m_CurrentTime, m_CurrentTime + 2 * m_SamplingPeriod,
736
             FinalZMPPositions, FinalCoMPositions,
737
             FinalLeftFootAbsolutePositions, FinalRightFootAbsolutePositions);
738
739
  for (unsigned i = 0; i < FinalCoMPositions.size(); ++i) {
740
    FinalCoMPositions[i].z[0] = lStartingCOMState.z[0];
741
    FinalCoMPositions[i].z[1] = lStartingCOMState.z[1];
742
    FinalCoMPositions[i].z[2] = lStartingCOMState.z[2];
743
  }
744
745
  /*! Recompute time when a new step should be added. */
746
  m_UpperTimeLimitToUpdateStacks =
747
      m_AbsoluteTimeReference + m_DeltaTj[0] + m_Tdble + 0.45 * m_Tsingle;
748
749
  double previewWindowSize = 0.8;
750
  double controlWindowSize = 0.005;
751
  double interpolationPeriod = 0.05;
752
  DFpreviewWindowSize_ = previewWindowSize - interpolationPeriod;  // second
753
  m_kajitaDynamicFilter->getComAndFootRealization()->ShiftFoot(false);
754
  m_kajitaDynamicFilter->init(m_SamplingPeriod, interpolationPeriod,
755
                              controlWindowSize, previewWindowSize,
756
                              DFpreviewWindowSize_, lStartingCOMState);
757
758
  return (int)m_RelativeFootPositions.size();
759
}
760
761
void AnalyticalMorisawaCompact::OnLine(
762
    double time, deque<ZMPPosition> &FinalZMPPositions,
763
    deque<COMState> &FinalCOMStates,
764
    deque<FootAbsolutePosition> &FinalLeftFootAbsolutePositions,
765
    deque<FootAbsolutePosition> &FinalRightFootAbsolutePositions) {
766
  unsigned int lIndexInterval;
767
  if (time < m_UpperTimeLimitToUpdateStacks) {
768
    if (m_AnalyticalZMPCoGTrajectoryX->GetIntervalIndexFromTime(
769
            time, lIndexInterval)) {
770
      ZMPPosition aZMPPos;
771
      memset(&aZMPPos, 0, sizeof(aZMPPos));
772
      COMState aCOMPos;
773
      memset(&aCOMPos, 0, sizeof(aCOMPos));
774
775
      if (m_FilteringActivate) {
776
        double FZmpX = 0, FComX = 0, FComdX = 0;
777
778
        // Should we filter ?
779
        bool r = m_FilterXaxisByPC->UpdateOneStep(time, FZmpX, FComX, FComdX);
780
        if (r) {
781
          double FZmpY = 0, FComY = 0, FComdY = 0;
782
          // Yes we should.
783
          m_FilterYaxisByPC->UpdateOneStep(time, FZmpY, FComY, FComdY);
784
785
          /*! Feed the ZMPPositions. */
786
          aZMPPos.px = FZmpX;
787
          aZMPPos.py = FZmpY;
788
789
          /*! Feed the COMStates. */
790
          aCOMPos.x[0] = FComX;
791
          aCOMPos.x[1] = FComdX;
792
          aCOMPos.y[0] = FComY;
793
          aCOMPos.y[1] = FComdY;
794
        }
795
      }
796
797
      /*! Feed the ZMPPositions. */
798
      double lZMPPosx = 0.0, lZMPPosy = 0.0;
799
      m_AnalyticalZMPCoGTrajectoryX->ComputeZMP(time, lZMPPosx, lIndexInterval);
800
      aZMPPos.px += lZMPPosx;
801
      m_AnalyticalZMPCoGTrajectoryY->ComputeZMP(time, lZMPPosy, lIndexInterval);
802
      aZMPPos.py += lZMPPosy;
803
      FinalZMPPositions.push_back(aZMPPos);
804
805
      /*! Feed the COMStates. */
806
      double lCOMPosx = 0.0, lCOMPosdx = 0.0;
807
      double lCOMPosy = 0.0, lCOMPosdy = 0.0;
808
      m_AnalyticalZMPCoGTrajectoryX->ComputeCOM(time, lCOMPosx, lIndexInterval);
809
      m_AnalyticalZMPCoGTrajectoryX->ComputeCOMSpeed(time, lCOMPosdx,
810
                                                     lIndexInterval);
811
      m_AnalyticalZMPCoGTrajectoryY->ComputeCOM(time, lCOMPosy, lIndexInterval);
812
      m_AnalyticalZMPCoGTrajectoryY->ComputeCOMSpeed(time, lCOMPosdy,
813
                                                     lIndexInterval);
814
      aCOMPos.x[0] += lCOMPosx;
815
      aCOMPos.x[1] += lCOMPosdx;
816
      aCOMPos.y[0] += lCOMPosy;
817
      aCOMPos.y[1] += lCOMPosdy;
818
      aCOMPos.z[0] = m_InitialPoseCoMHeight;
819
      FinalCOMStates.push_back(aCOMPos);
820
      /*! Feed the FootPositions. */
821
822
      /*! Left */
823
      FootAbsolutePosition LeftFootAbsPos;
824
      memset(&LeftFootAbsPos, 0, sizeof(LeftFootAbsPos));
825
      m_FeetTrajectoryGenerator->ComputeAnAbsoluteFootPosition(
826
          1, time, LeftFootAbsPos, lIndexInterval);
827
      FinalLeftFootAbsolutePositions.push_back(LeftFootAbsPos);
828
829
      /*! Right */
830
      FootAbsolutePosition RightFootAbsPos;
831
      memset(&RightFootAbsPos, 0, sizeof(RightFootAbsPos));
832
      m_FeetTrajectoryGenerator->ComputeAnAbsoluteFootPosition(
833
          -1, time, RightFootAbsPos, lIndexInterval);
834
      FinalRightFootAbsolutePositions.push_back(RightFootAbsPos);
835
    }
836
  } else {
837
    /*! We reached the end of the trajectory generated
838
      and no foot steps have been added. */
839
    m_OnLineMode = false;
840
  }
841
}
842
843
void AnalyticalMorisawaCompact::OnLineAddFoot(
844
    RelativeFootPosition &NewRelativeFootPosition,
845
    deque<ZMPPosition> &FinalZMPPositions, deque<COMState> &FinalCoMPositions,
846
    deque<FootAbsolutePosition> &FinalLeftFootAbsolutePositions,
847
    deque<FootAbsolutePosition> &FinalRightFootAbsolutePositions, bool) {
848
  ODEBUG("****************** Begin OnLineAddFoot **************************");
849
  unsigned int StartingIndexInterval;
850
  m_AnalyticalZMPCoGTrajectoryX->GetIntervalIndexFromTime(
851
      m_CurrentTime, StartingIndexInterval);
852
853
  unsigned int IndexInterval = (unsigned int)(m_CTIPX.ZMPProfil.size() - 1);
854
855
  /* If the interval detected is not a double support interval,
856
     a shift is done to chose the earliest double support interval. */
857
  vector<unsigned int> IndexLastZMPProfil;
858
  IndexLastZMPProfil.resize(1);
859
  IndexLastZMPProfil[0] = IndexInterval;
860
861
  // The strategy is simple: we trigger a false modification of the last
862
  // step and call change landing position, just after updating the stack
863
  // of relative foot positions.
864
865
  m_Clock1.StartTiming();
866
867
  // Update the stack of relative foot positions.
868
  m_RelativeFootPositions.pop_front();
869
  m_RelativeFootPositions.push_back(NewRelativeFootPosition);
870
871
  deque<FootAbsolutePosition> aQAFP;
872
873
  m_FeetTrajectoryGenerator->ComputeAbsoluteStepsFromRelativeSteps(
874
      m_RelativeFootPositions, FinalLeftFootAbsolutePositions[0],
875
      FinalRightFootAbsolutePositions[0], aQAFP);
876
877
  vector<FootAbsolutePosition> aNewFootAbsPos;
878
  aNewFootAbsPos.resize(1);
879
  aNewFootAbsPos[0] = aQAFP.back();
880
881
  if (FinalLeftFootAbsolutePositions[0].z == 0.0)
882
    m_AbsoluteCurrentSupportFootPosition = FinalLeftFootAbsolutePositions[0];
883
  else
884
    m_AbsoluteCurrentSupportFootPosition = FinalRightFootAbsolutePositions[0];
885
886
  m_AbsoluteSupportFootPositions.pop_front();
887
  m_AbsoluteSupportFootPositions.push_back(aNewFootAbsPos[0]);
888
889
  /* Indicates that the step has to be taken into account appropriatly
890
     to compute the trajectory. */
891
  m_NewStepInTheStackOfAbsolutePosition = true;
892
893
  m_Clock1.StopTiming();
894
  m_Clock1.IncIteration(1);
895
896
  m_Clock2.StartTiming();
897
898
  /* Realize the foot changing position during the last interval */
899
  bool lResetFilters = false;
900
  bool lTemporalShift = false;
901
  bool lAddingAFootStep = true;
902
  ChangeFootLandingPosition(m_CurrentTime, IndexLastZMPProfil, aNewFootAbsPos,
903
                            *m_AnalyticalZMPCoGTrajectoryX, m_CTIPX,
904
                            *m_AnalyticalZMPCoGTrajectoryY, m_CTIPY,
905
                            lTemporalShift, lResetFilters, 0, lAddingAFootStep);
906
907
  /* Indicates that the step has been taken into account appropriatly
908
     in computing the trajectory. */
909
  m_NewStepInTheStackOfAbsolutePosition = false;
910
911
  m_Clock2.StopTiming();
912
  m_Clock2.IncIteration(1);
913
914
  m_Clock3.StartTiming();
915
916
  /* Current strategy : add 2 values, and update at each iteration the stack.
917
     When the limit is reached, and the stack exhausted this method is called
918
     again. */
919
  FillQueues(m_AbsoluteTimeReference,
920
             m_AbsoluteTimeReference + 2 * m_SamplingPeriod, FinalZMPPositions,
921
             FinalCoMPositions, FinalLeftFootAbsolutePositions,
922
             FinalRightFootAbsolutePositions);
923
924
  for (unsigned i = 0; i < FinalCoMPositions.size(); ++i) {
925
    FinalCoMPositions[i].z[0] = m_InitialPoseCoMHeight;
926
    FinalCoMPositions[i].z[1] = 0.0;
927
    FinalCoMPositions[i].z[2] = 0.0;
928
  }
929
930
  m_Clock3.StopTiming();
931
  m_Clock3.IncIteration();
932
933
  /* Update the time at which the stack should not be updated anymore */
934
  m_UpperTimeLimitToUpdateStacks =
935
      m_AbsoluteTimeReference + m_DeltaTj[0] + m_Tdble + 0.45 * m_Tsingle;
936
  ODEBUG("****************** End OnLineAddFoot **************************");
937
}
938
939
void AnalyticalMorisawaCompact::ComputeW(double InitialCoMPos,
940
                                         double InitialCoMSpeed,
941
                                         vector<double> &ZMPPosSequence,
942
                                         double FinalCoMPos,
943
                                         AnalyticalZMPCOGTrajectory &aAZCT) {
944
  unsigned int lindex = 0;
945
946
  // Again assuming that the number of unknowns
947
  // is based on a 4- (m-2) 3 -4 th order polynomials.
948
  m_w.resize(2 * m_NumberOfIntervals + 6);
949
950
  // Initial CoM Position
951
  m_w(lindex) = InitialCoMPos - ZMPPosSequence[0];
952
  lindex++;
953
  // Initial CoM Speed
954
  m_w(lindex) = InitialCoMSpeed;
955
  lindex++;
956
957
  // Just be carefull:
958
  // at iteration j, we still build m_w for the
959
  // interval j-1.
960
  for (int j = 1; j < m_NumberOfIntervals; j++) {
961
    // Takes back the polynomial needed to compute m_w.
962
    Polynome *aPolynomeNext, *aPolynome;
963
    aAZCT.GetFromListOfCOGPolynomials(j, aPolynomeNext);
964
    vector<double> NextCoeffsFromCOG, CoeffsFromCOG;
965
    aPolynomeNext->GetCoefficients(NextCoeffsFromCOG);
966
    if (j == 1) {
967
      m_w[lindex] = NextCoeffsFromCOG[0] - ZMPPosSequence[0];
968
      lindex++;
969
      m_w[lindex] = NextCoeffsFromCOG[1];
970
      lindex++;
971
      m_w[lindex] = 0;  // ZMPPosSequence[0] - ZMPPosSequence[0];
972
      lindex++;
973
      m_w[lindex] = 0;
974
      lindex++;
975
    } else {
976
      aAZCT.GetFromListOfCOGPolynomials(j - 1, aPolynome);
977
      aPolynome->GetCoefficients(CoeffsFromCOG);
978
      double r1 = 0.0, r2 = 0.0;
979
      double deltat1 = 1.0, deltat2 = 1.0;
980
      for (unsigned int k = 0; k < CoeffsFromCOG.size(); k++) {
981
        r1 += CoeffsFromCOG[k] * deltat1;
982
        deltat1 *= m_DeltaTj[j - 1];
983
        if (k > 0) {
984
          r2 += k * CoeffsFromCOG[k] * deltat2;
985
          deltat2 *= m_DeltaTj[j - 1];
986
        }
987
      }
988
      if (j != m_NumberOfIntervals - 1) {
989
        m_w[lindex] = NextCoeffsFromCOG[0] - r1;
990
      } else {
991
        m_w[lindex] = ZMPPosSequence[j - 1] - r1;
992
      }
993
      lindex++;
994
      if (j != m_NumberOfIntervals - 1) {
995
        m_w[lindex] = NextCoeffsFromCOG[1] - r2;
996
      } else {
997
        m_w[lindex] = -r2;
998
      }
999
1000
      lindex++;
1001
    }
1002
  }
1003
1004
  // Compute the last part of w for the last interval.
1005
1006
  // Constraints on the final value of the CoM position
1007
  if (m_NumberOfIntervals > 1) {
1008
    m_w[lindex] = FinalCoMPos - ZMPPosSequence[m_NumberOfIntervals - 2];
1009
    lindex++;
1010
    // and the CoM speed.
1011
    m_w[lindex] = 0;
1012
    lindex++;
1013
1014
    // Position of the ZMP.
1015
    m_w[lindex] = FinalCoMPos - ZMPPosSequence[m_NumberOfIntervals - 2];
1016
    lindex++;
1017
    // and the ZMP speed.
1018
    m_w[lindex] = 0.0;
1019
    lindex++;
1020
  }
1021
1022
  if (m_VerboseLevel >= 2) {
1023
    std::ofstream ofs;
1024
    ofs.open("WCompactMatrix.dat", ofstream::out);
1025
    ofs.precision(10);
1026
1027
    for (unsigned int i = 0; i < m_w.size(); i++) {
1028
      ofs << m_w[i] << " ";
1029
    }
1030
    ofs << endl;
1031
    ofs.close();
1032
  }
1033
}
1034
1035
void AnalyticalMorisawaCompact::ComputeZ1(unsigned int &rowindex) {
1036
  double SquareOmega0 = m_Omegaj[0] * m_Omegaj[0];
1037
1038
  // First Row: Connection of the position of the CoM
1039
  double c0, s0;
1040
  double Deltat = m_DeltaTj[0] * m_DeltaTj[0];
1041
1042
  // A_2^(0) coefficient + A_1^(0) express as a function of A_2^(0)
1043
  m_Z(rowindex, 0) = Deltat + 2.0 / SquareOmega0;
1044
  // A3^(0) coefficient
1045
  Deltat *= m_DeltaTj[0];
1046
  m_Z(rowindex, 1) = Deltat + m_DeltaTj[0] * 6.0 / SquareOmega0;
1047
  // A4^(0) coefficient
1048
  Deltat *= m_DeltaTj[0];
1049
  m_Z(rowindex, 2) = Deltat;
1050
  m_Z(rowindex, 3) = c0 = cosh(m_Omegaj[0] * m_DeltaTj[0]);
1051
  m_Z(rowindex, 4) = s0 = sinh(m_Omegaj[0] * m_DeltaTj[0]);
1052
  m_Z(rowindex, 5) = -1.0;
1053
  rowindex++;
1054
1055
  // Second Row : Connection of the velocity of the CoM
1056
  Deltat = m_DeltaTj[0];
1057
  m_Z(rowindex, 0) = 2 * Deltat;
1058
  Deltat *= m_DeltaTj[0];
1059
  m_Z(rowindex, 1) = 3 * Deltat + 6.0 / SquareOmega0;
1060
  Deltat *= m_DeltaTj[0];
1061
  m_Z(rowindex, 2) = 4 * Deltat;
1062
  m_Z(rowindex, 3) = m_Omegaj[0] * s0;
1063
  m_Z(rowindex, 4) = m_Omegaj[0] * c0;
1064
  m_Z(rowindex, 6) = -m_Omegaj[0];
1065
  rowindex++;
1066
1067
  // Third Row : Terminal condition for the ZMP position
1068
  Deltat = m_DeltaTj[0] * m_DeltaTj[0];
1069
  m_Z(rowindex, 0) = Deltat;
1070
  Deltat *= m_DeltaTj[0];
1071
  m_Z(rowindex, 1) = Deltat;
1072
  Deltat *= m_DeltaTj[0];
1073
  m_Z(rowindex, 2) = Deltat - 12 * m_DeltaTj[0] * m_DeltaTj[0] / SquareOmega0;
1074
  rowindex++;
1075
1076
  // Fourth Row : Terminal velocity for the ZMP position
1077
  Deltat = m_DeltaTj[0];
1078
  m_Z(rowindex, 0) = 2.0 * Deltat;
1079
  Deltat *= m_DeltaTj[0];
1080
  m_Z(rowindex, 1) = 3.0 * Deltat;
1081
  Deltat *= m_DeltaTj[0];
1082
  m_Z(rowindex, 2) = 4 * Deltat - 24.0 * m_DeltaTj[0] / SquareOmega0;
1083
  rowindex++;
1084
}
1085
1086
void AnalyticalMorisawaCompact::ComputeZj(unsigned int intervalindex,
1087
                                          unsigned int &colindex,
1088
                                          unsigned int &rowindex) {
1089
  // First row : Connection of the position of the CoM
1090
  double Omegaj = m_Omegaj[intervalindex];
1091
  double Omegam = m_Omegaj[m_NumberOfIntervals - 1];
1092
1093
  double c0 = 0.0, s0 = 0.0;
1094
  m_Z(rowindex, colindex) = c0 = cosh(Omegaj * m_DeltaTj[intervalindex]);
1095
  m_Z(rowindex, colindex + 1) = s0 = sinh(Omegaj * m_DeltaTj[intervalindex]);
1096
1097
  if ((int)intervalindex != m_NumberOfIntervals - 2) {
1098
    m_Z(rowindex, colindex + 2) = -1.0;
1099
  } else {
1100
    m_Z(rowindex, colindex + 2) = -2.0 / (Omegam * Omegam);
1101
    m_Z(rowindex, colindex + 5) = -1.0;
1102
  }
1103
  rowindex++;
1104
1105
  // Second row : Connection of the velocity of the CoM
1106
  m_Z(rowindex, colindex) = Omegaj * s0;
1107
  m_Z(rowindex, colindex + 1) = Omegaj * c0;
1108
  if ((int)intervalindex != m_NumberOfIntervals - 2)
1109
    m_Z(rowindex, colindex + 3) = -Omegaj;
1110
  else {
1111
    m_Z(rowindex, colindex + 3) = -6.0 / (Omegam * Omegam);
1112
    m_Z(rowindex, colindex + 6) = -Omegam;
1113
  }
1114
  rowindex++;
1115
}
1116
1117
void AnalyticalMorisawaCompact::ComputeZm(unsigned intervalindex,
1118
                                          unsigned int &colindex,
1119
                                          unsigned int &rowindex) {
1120
  double Omegam = m_Omegaj[m_NumberOfIntervals - 1];
1121
  double SquareOmegam = Omegam * Omegam;
1122
1123
  // First row : Connection of the position of the CoM
1124
  double Deltat = m_DeltaTj[intervalindex];
1125
  Deltat *= m_DeltaTj[intervalindex];
1126
  m_Z(rowindex, colindex) = Deltat + 2.0 / SquareOmegam;
1127
1128
  Deltat *= m_DeltaTj[intervalindex];
1129
  m_Z(rowindex, colindex + 1) =
1130
      Deltat + m_DeltaTj[intervalindex] * 6.0 / SquareOmegam;
1131
1132
  Deltat *= m_DeltaTj[intervalindex];
1133
  m_Z(rowindex, colindex + 2) = Deltat;
1134
1135
  double c0 = 0.0, s0 = 0.0;
1136
  m_Z(rowindex, colindex + 3) = c0 = cosh(Omegam * m_DeltaTj[intervalindex]);
1137
  m_Z(rowindex, colindex + 4) = s0 = sinh(Omegam * m_DeltaTj[intervalindex]);
1138
  rowindex++;
1139
1140
  // Second row : Connection of the velocity of the CoM
1141
  Deltat = m_DeltaTj[intervalindex];
1142
  m_Z(rowindex, colindex) = 2 * Deltat;
1143
1144
  Deltat *= m_DeltaTj[intervalindex];
1145
  m_Z(rowindex, colindex + 1) = 3 * Deltat + 6.0 / SquareOmegam;
1146
1147
  Deltat *= m_DeltaTj[intervalindex];
1148
  m_Z(rowindex, colindex + 2) = 4 * Deltat;
1149
1150
  m_Z(rowindex, colindex + 3) = Omegam * s0;
1151
  m_Z(rowindex, colindex + 4) = Omegam * c0;
1152
  rowindex++;
1153
1154
  // Third row: Terminal condition for the ZMP position
1155
  Deltat = m_DeltaTj[intervalindex] * m_DeltaTj[intervalindex];
1156
  m_Z(rowindex, colindex) = Deltat;
1157
1158
  Deltat *= m_DeltaTj[intervalindex];
1159
  m_Z(rowindex, colindex + 1) = Deltat;
1160
1161
  Deltat *= m_DeltaTj[intervalindex];
1162
  m_Z(rowindex, colindex + 2) = Deltat - 12 * m_DeltaTj[intervalindex] *
1163
                                             m_DeltaTj[intervalindex] /
1164
                                             SquareOmegam;
1165
1166
  rowindex++;
1167
1168
  // Fourth row: Terminal velocity for the ZMP position
1169
  Deltat = m_DeltaTj[intervalindex];
1170
  m_Z(rowindex, colindex) = 2 * Deltat;
1171
1172
  Deltat *= m_DeltaTj[intervalindex];
1173
  m_Z(rowindex, colindex + 1) = 3 * Deltat;
1174
1175
  Deltat *= m_DeltaTj[intervalindex];
1176
  m_Z(rowindex, colindex + 2) =
1177
      4 * Deltat - 24.0 * m_DeltaTj[intervalindex] / SquareOmegam;
1178
1179
  rowindex++;
1180
}
1181
void AnalyticalMorisawaCompact::BuildingTheZMatrix(vector<double> &lCoM,
1182
                                                   vector<double> &lZMP) {
1183
  if (((int)lCoM.size() != m_NumberOfIntervals) ||
1184
      ((int)lZMP.size() != m_NumberOfIntervals))
1185
    return;
1186
1187
  for (unsigned int i = 0; i < lCoM.size(); i++) {
1188
    m_Omegaj[i] = sqrt(9.86 / (lCoM[i] - lZMP[i]));
1189
  }
1190
  BuildingTheZMatrix();
1191
}
1192
1193
void AnalyticalMorisawaCompact::BuildingTheZMatrix() {
1194
  unsigned NbRows, NbCols;
1195
  unsigned int rowindex = 0;
1196
  unsigned int colindex = 0;
1197
1198
  NbRows = 2 + 4 + 2 * (m_NumberOfIntervals - 2) + 4;
1199
  NbCols = 2 * m_NumberOfIntervals + 6;
1200
  m_Z.resize(NbRows, NbCols);
1201
1202
  // Initial condition for the COG position and the velocity
1203
  double SquareOmega0 = m_Omegaj[0] * m_Omegaj[0];
1204
1205
  {
1206
    for (unsigned int i = 0; i < m_Z.rows(); i++)
1207
      for (unsigned int j = 0; j < m_Z.cols(); j++) m_Z(i, j) = 0.0;
1208
  };
1209
  m_Z(0, 0) = 2.0 / SquareOmega0;
1210
  m_Z(0, 3) = 1.0;
1211
  rowindex++;
1212
  m_Z(1, 1) = 6.0 / SquareOmega0;
1213
  m_Z(1, 4) = m_Omegaj[0];
1214
  rowindex++;
1215
1216
  // Compute Z1
1217
  ComputeZ1(rowindex);
1218
  colindex += m_PolynomialDegrees[0] + 1;
1219
1220
  // Computing Zj.
1221
  for (int i = 1; i < m_NumberOfIntervals - 1; ++i) {
1222
    ComputeZj(i, colindex, rowindex);
1223
    colindex += 2;
1224
  }
1225
1226
  // Computing Zm
1227
  ComputeZm(m_NumberOfIntervals - 1, colindex, rowindex);
1228
1229
  if (m_VerboseLevel >= 2) {
1230
    std::ofstream ofs;
1231
    ofs.open("ZCompactMatrix.dat", ofstream::out);
1232
    ofs.precision(10);
1233
    for (unsigned int i = 0; i < m_Z.rows(); i++) {
1234
      for (unsigned int j = 0; j < m_Z.cols(); j++) {
1235
        ofs << m_Z(i, j) << " ";
1236
      }
1237
      ofs << endl;
1238
    }
1239
    ofs.close();
1240
  }
1241
}
1242
1243
void AnalyticalMorisawaCompact::TransfertTheCoefficientsToTrajectories(
1244
    AnalyticalZMPCOGTrajectory &aAZCT, vector<double> &lCoMZ,
1245
    vector<double> &lZMPZ, double &lZMPInit, double &lZMPEnd, bool) {
1246
  vector<double> lV;
1247
  vector<double> lW;
1248
1249
  // Set the starting point and the height variation.
1250
  aAZCT.SetStartingTimeIntervalsAndHeightVariation(m_DeltaTj, m_Omegaj);
1251
1252
  unsigned int lindex = 0;
1253
1254
  // Weights.
1255
  lV.resize(m_NumberOfIntervals);
1256
1257
  Polynome *aPolynome = 0;
1258
  aAZCT.GetFromListOfCOGPolynomials(0, aPolynome);
1259
  vector<double> coeff;
1260
  coeff.resize(m_PolynomialDegrees[0] + 1);
1261
1262
  for (unsigned int k = 2; k <= m_PolynomialDegrees[0]; k++) {
1263
    coeff[k] = m_y[lindex++];
1264
  }
1265
  coeff[1] = coeff[3] * 6.0 / (m_Omegaj[0] * m_Omegaj[0]);
1266
  coeff[0] = lZMPInit + coeff[2] * 2.0 / (m_Omegaj[0] * m_Omegaj[0]);
1267
1268
  aPolynome->SetCoefficients(coeff);
1269
1270
  lW.resize(m_NumberOfIntervals);
1271
1272
  for (int i = 0; i < m_NumberOfIntervals - 1; i++) {
1273
    lV[i] = m_y[lindex++];
1274
    lW[i] = m_y[lindex++];
1275
  }
1276
1277
  for (unsigned int k = 2; k <= m_PolynomialDegrees[m_NumberOfIntervals - 1];
1278
       k++) {
1279
    coeff[k] = m_y[lindex++];
1280
  }
1281
  coeff[1] =
1282
      coeff[3] * 6.0 /
1283
      (m_Omegaj[m_NumberOfIntervals - 1] * m_Omegaj[m_NumberOfIntervals - 1]);
1284
  coeff[0] = lZMPEnd + coeff[2] * 2.0 /
1285
                           (m_Omegaj[m_NumberOfIntervals - 1] *
1286
                            m_Omegaj[m_NumberOfIntervals - 1]);
1287
1288
  aAZCT.GetFromListOfCOGPolynomials(m_NumberOfIntervals - 1, aPolynome);
1289
  aPolynome->SetCoefficients(coeff);
1290
1291
  lV[m_NumberOfIntervals - 1] = m_y[lindex++];
1292
  lW[m_NumberOfIntervals - 1] = m_y[lindex++];
1293
1294
  // Set the hyperbolic weights.
1295
  aAZCT.SetCoGHyperbolicCoefficients(lV, lW);
1296
1297
  // Compute the ZMP weights from the CoG's ones:
1298
1299
  // for the first interval
1300
  aAZCT.TransfertOneIntervalCoefficientsFromCOGTrajectoryToZMPOne(0, lCoMZ[0],
1301
                                                                  lZMPZ[0]);
1302
1303
  // and the last interval
1304
  aAZCT.TransfertOneIntervalCoefficientsFromCOGTrajectoryToZMPOne(
1305
      m_NumberOfIntervals - 1, lCoMZ[m_NumberOfIntervals - 1],
1306
      lZMPZ[m_NumberOfIntervals - 1]);
1307
}
1308
1309
void AnalyticalMorisawaCompact::ComputeTrajectory(
1310
    CompactTrajectoryInstanceParameters &aCTIP,
1311
    AnalyticalZMPCOGTrajectory &aAZCT) {
1312
  ComputeW(aCTIP.InitialCoM, aCTIP.InitialCoMSpeed, aCTIP.ZMPProfil,
1313
           aCTIP.FinalCoMPos, aAZCT);
1314
  ComputePolynomialWeights2();
1315
  TransfertTheCoefficientsToTrajectories(
1316
      aAZCT, aCTIP.CoMZ, aCTIP.ZMPZ, aCTIP.ZMPProfil[0],
1317
      aCTIP.ZMPProfil[m_NumberOfIntervals - 1], false);
1318
}
1319
1320
int AnalyticalMorisawaCompact::TimeChange(double LocalTime,
1321
                                          unsigned int IndexStep,
1322
                                          unsigned int &IndexStartingInterval,
1323
                                          double &FinalTime, double &NewTj) {
1324
  // The Index Step can be equal to m_NumberOfIntervals.
1325
  if ((int)IndexStep < m_NumberOfIntervals)
1326
1327
    if (m_StepTypes[IndexStep] != DOUBLE_SUPPORT) {
1328
      LTHROW("ERROR WRONG FOOT TYPE. ");
1329
    }
1330
1331
  FinalTime = 0.0;
1332
  for (unsigned int j = 0; j < m_DeltaTj.size(); j++) FinalTime += m_DeltaTj[j];
1333
1334
  /* Find from which interval we are starting. */
1335
  m_AnalyticalZMPCoGTrajectoryX->GetIntervalIndexFromTime(
1336
      LocalTime + m_AbsoluteTimeReference, IndexStartingInterval);
1337
1338
  double reftime = 0.0;
1339
  for (unsigned int j = 0; j < IndexStartingInterval; j++)
1340
    reftime += m_DeltaTj[j];
1341
1342
  NewTj = m_DeltaTj[IndexStartingInterval] - LocalTime + reftime;
1343
1344
  /* Not enough time to change foot localisation
1345
     if this is the next step which should be changed
1346
     and we went over half the current interval.
1347
  */
1348
  if ((NewTj < m_Tsingle * 0.5) && (IndexStep == IndexStartingInterval + 1)) {
1349
    return ERROR_TOO_LATE_FOR_MODIFICATION;
1350
  }
1351
1352
  return 0;
1353
}
1354
1355
void AnalyticalMorisawaCompact::NewTimeIntervals(
1356
    unsigned int IndexStartingInterval, double NewTime) {
1357
  /* Build the new time interval. */
1358
  m_DeltaTj[0] = NewTime;
1359
  m_StepTypes[0] = m_StepTypes[IndexStartingInterval];
1360
  for (int i = 1; i < m_NumberOfIntervals; i++) {
1361
    if (m_StepTypes[i - 1] == DOUBLE_SUPPORT) {
1362
      m_DeltaTj[i] = m_Tsingle;
1363
      m_StepTypes[i] = SINGLE_SUPPORT;
1364
    } else {
1365
      m_DeltaTj[i] = m_Tdble;
1366
      m_StepTypes[i] = DOUBLE_SUPPORT;
1367
    }
1368
  }
1369
1370
  m_DeltaTj[m_NumberOfIntervals - 1] = m_Tsingle * 3.0;
1371
  m_StepTypes[m_NumberOfIntervals - 1] = DOUBLE_SUPPORT;
1372
  ComputePreviewControlTimeWindow();
1373
}
1374
1375
void AnalyticalMorisawaCompact::ConstraintsChange(
1376
    double, FluctuationParameters FPX, FluctuationParameters FPY,
1377
    CompactTrajectoryInstanceParameters &aCTIPX,
1378
    CompactTrajectoryInstanceParameters &aCTIPY,
1379
    unsigned int IndexStartingInterval, StepStackHandler *aStepStackHandler) {
1380
  if (IndexStartingInterval != 0) {
1381
    /* Shift the current value of the profil. */
1382
    int i;
1383
    unsigned int j;
1384
    for (i = IndexStartingInterval, j = 0; i < m_NumberOfIntervals; i++, j++) {
1385
      /* Shift the ZMP profil */
1386
      aCTIPX.ZMPProfil[j] = aCTIPX.ZMPProfil[i];
1387
      aCTIPY.ZMPProfil[j] = aCTIPY.ZMPProfil[i];
1388
    }
1389
1390
    /* Add value from the provided steps stack.
1391
       BE CAREFUL: There is a modification on the initial value
1392
       depending if a m_AbsoluteSupportFootPositions has been updated
1393
       or not.
1394
       If m_AbsoluteFootPositions has not been updated then
1395
       a demand for a new step will be triggered.
1396
    */
1397
1398
    unsigned int k = 0;
1399
    if (m_NewStepInTheStackOfAbsolutePosition)
1400
      k = (i - 3) / 2;
1401
    else
1402
      k = (i - 1) / 2;
1403
1404
    for (; (k < m_AbsoluteSupportFootPositions.size()) &&
1405
           (j < m_CTIPX.ZMPProfil.size());
1406
         k++, j += 2) {
1407
      aCTIPX.ZMPProfil[j] = m_AbsoluteSupportFootPositions[k].x;
1408
      aCTIPY.ZMPProfil[j] = m_AbsoluteSupportFootPositions[k].y;
1409
1410
      if ((j + 1) < m_CTIPX.ZMPProfil.size()) {
1411
        aCTIPX.ZMPProfil[j + 1] = m_AbsoluteSupportFootPositions[k].x;
1412
        aCTIPY.ZMPProfil[j + 1] = m_AbsoluteSupportFootPositions[k].y;
1413
      }
1414
    }
1415
    /* Complete the ZMP profil when no other step is available,
1416
       and if there is a StepStack Handler available.
1417
    */
1418
    if (aStepStackHandler != 0) {
1419
      /* Compute the number of steps needed. */
1420
      int NeededSteps = (int)((aCTIPX.ZMPProfil.size() - j + 1) / 2);
1421
      long int r;
1422
1423
      /* Test if there is enough step in the stack of.
1424
         We have to remove one, because there is
1425
         still the last foot added.
1426
      */
1427
      if ((r = (long int)aStepStackHandler->ReturnStackSize() - 1 -
1428
               (long int)NeededSteps) < 0) {
1429
        bool lNewStep = false;
1430
        double NewStepX = 0.0, NewStepY = 0.0, NewStepTheta = 0.0;
1431
        for (int li = 0; li < -r; li++) {
1432
          aStepStackHandler->AddStandardOnLineStep(lNewStep, NewStepX, NewStepY,
1433
                                                   NewStepTheta);
1434
        }
1435
      }
1436
1437
      /* Takes the number of Relative Foot Positions needed. */
1438
      deque<RelativeFootPosition> lRelativeFootPositions;
1439
      aStepStackHandler->CopyRelativeFootPosition(lRelativeFootPositions,
1440
                                                  false);
1441
1442
      /*! Remove the first step still in the stack. */
1443
      lRelativeFootPositions.pop_front();
1444
1445
      deque<FootAbsolutePosition> lAbsoluteSupportFootPositions;
1446
      int lLastIndex = (int)(m_AbsoluteSupportFootPositions.size() - 1);
1447
      m_FeetTrajectoryGenerator->ComputeAbsoluteStepsFromRelativeSteps(
1448
          lRelativeFootPositions, m_AbsoluteSupportFootPositions[lLastIndex],
1449
          lAbsoluteSupportFootPositions);
1450
1451
      /* Add the necessary absolute support foot positions. */
1452
      for (int li = 0; (li < NeededSteps) && (j < m_CTIPX.ZMPProfil.size());
1453
           li++, j += 2) {
1454
        aCTIPX.ZMPProfil[j] = lAbsoluteSupportFootPositions[li].x;
1455
        aCTIPY.ZMPProfil[j] = lAbsoluteSupportFootPositions[li].y;
1456
1457
        if ((j + 1) < m_CTIPX.ZMPProfil.size()) {
1458
          aCTIPX.ZMPProfil[j + 1] = lAbsoluteSupportFootPositions[li].x;
1459
          aCTIPY.ZMPProfil[j + 1] = lAbsoluteSupportFootPositions[li].y;
1460
        }
1461
      }
1462
1463
      /* Add the relative foot position inside the internal
1464
         stack as well as
1465
         the absolute foot position. It also removes the steps
1466
         inside the StepStackHandler object taken into account.*/
1467
      for (int li = 0; li < NeededSteps; li++) {
1468
        m_RelativeFootPositions.push_back(lRelativeFootPositions[li]);
1469
        m_AbsoluteSupportFootPositions.push_back(
1470
            lAbsoluteSupportFootPositions[li]);
1471
        aStepStackHandler->RemoveFirstStepInTheStack();
1472
      }
1473
      /*! Remove the corresponding step from the stack of
1474
        relative and absolute foot positions. */
1475
      for (unsigned int li = 0; li < IndexStartingInterval / 2; li++) {
1476
        m_RelativeFootPositions.pop_front();
1477
        m_AbsoluteSupportFootPositions.pop_front();
1478
      }
1479
    }
1480
  }
1481
1482
  /* Compute the current value of the initial
1483
     and final CoM to be feed to the new system. */
1484
  aCTIPX.InitialCoM = FPX.CoMInit;
1485
  aCTIPX.InitialCoMSpeed = FPX.CoMSpeedInit;
1486
  aCTIPX.FinalCoMPos = aCTIPX.ZMPProfil[m_NumberOfIntervals - 1];
1487
1488
  aCTIPY.InitialCoM = FPY.CoMInit;
1489
  aCTIPY.InitialCoMSpeed = FPY.CoMSpeedInit;
1490
  aCTIPY.FinalCoMPos = aCTIPY.ZMPProfil[m_NumberOfIntervals - 1];
1491
}
1492
1493
double AnalyticalMorisawaCompact::TimeCompensationForZMPFluctuation(
1494
    FluctuationParameters &aFP, double DeltaTInit) {
1495
  double r = 0.0;
1496
  double DeltaTNew = 0.0;
1497
  if (fabs(aFP.CoMSpeedNew) < 1e-7) aFP.CoMSpeedNew = 0.0;
1498
  if (fabs(aFP.ZMPSpeedNew) < 1e-7) aFP.ZMPSpeedNew = 0.0;
1499
  if (fabs(aFP.CoMSpeedInit) < 1e-7) aFP.CoMSpeedInit = 0.0;
1500
  if (fabs(aFP.ZMPSpeedInit) < 1e-7) aFP.ZMPSpeedInit = 0.0;
1501
  if (fabs(aFP.CoMInit) < 1e-7) aFP.CoMInit = 0.0;
1502
  if (fabs(aFP.ZMPInit) < 1e-7) aFP.ZMPInit = 0.0;
1503
  if (fabs(aFP.CoMNew) < 1e-7) aFP.CoMNew = 0.0;
1504
  if (fabs(aFP.ZMPNew) < 1e-7) aFP.ZMPNew = 0.0;
1505
1506
  double rden = (m_Omegaj[0] * (aFP.CoMInit - aFP.ZMPInit) +
1507
                 (aFP.CoMSpeedInit - aFP.ZMPSpeedInit));
1508
  if (fabs(rden) < 1e-5) rden = 0.0;
1509
1510
  double rnum = (m_Omegaj[0] * (aFP.CoMNew - aFP.ZMPNew) +
1511
                 (aFP.CoMSpeedNew - aFP.ZMPSpeedNew));
1512
1513
  if (rden == 0.0)
1514
    r = 0.0;
1515
  else
1516
    r = rnum / rden;
1517
1518
  ;
1519
  /*    r2 = ( m_Omegaj[0]*(aFP.CoMInit - aFP.ZMPInit)
1520
        + (aFP.CoMSpeedInit - aFP.ZMPSpeedInit) )/
1521
        (m_Omegaj[0] * ( aFP.CoMNew - aFP.ZMPNew) +
1522
        (aFP.CoMSpeedNew - aFP.ZMPSpeedNew)); */
1523
1524
  if (r < 0.0)
1525
    DeltaTNew = DeltaTInit + m_Tsingle * 0.5;
1526
  else if (r > 0)
1527
    DeltaTNew = DeltaTInit + log(r) / m_Omegaj[0];
1528
  else if (r == 0.0)
1529
    DeltaTNew = DeltaTInit;
1530
1531
  return DeltaTNew;
1532
}
1533
1534
void AnalyticalMorisawaCompact::ChangeZMPProfil(
1535
    vector<unsigned int> &IndexStep,
1536
    vector<FootAbsolutePosition> &NewFootAbsPos,
1537
    CompactTrajectoryInstanceParameters &aCTIPX,
1538
    CompactTrajectoryInstanceParameters &aCTIPY) {
1539
  /* Change in the constraints, i.e. modify
1540
     aCTIPX and aCTIPY appropriatly . */
1541
  for (unsigned int i = 0; i < IndexStep.size(); i++) {
1542
    unsigned int lIndexStep = IndexStep[i];
1543
    unsigned int lIndexForFootPrintInterval = 0;
1544
1545
    if (IndexStep.size() == NewFootAbsPos.size() * 2)
1546
      lIndexForFootPrintInterval = i / 2;
1547
    else {
1548
      lIndexForFootPrintInterval = i / 2;
1549
      if (lIndexForFootPrintInterval >= NewFootAbsPos.size())
1550
        lIndexForFootPrintInterval = (unsigned int)(NewFootAbsPos.size() - 1);
1551
    }
1552
1553
    if (lIndexStep < aCTIPX.ZMPProfil.size()) {
1554
      aCTIPX.ZMPProfil[lIndexStep] =
1555
          NewFootAbsPos[lIndexForFootPrintInterval].x;
1556
      aCTIPY.ZMPProfil[lIndexStep] =
1557
          NewFootAbsPos[lIndexForFootPrintInterval].y;
1558
    }
1559
    if (lIndexStep < aCTIPX.ZMPProfil.size() - 1) {
1560
      aCTIPX.ZMPProfil[lIndexStep + 1] =
1561
          NewFootAbsPos[lIndexForFootPrintInterval].x;
1562
      aCTIPY.ZMPProfil[lIndexStep + 1] =
1563
          NewFootAbsPos[lIndexForFootPrintInterval].y;
1564
    }
1565
1566
    /* If the end condition has been changed... */
1567
    if ((int)lIndexStep + 1 == m_NumberOfIntervals - 1) {
1568
      aCTIPX.FinalCoMPos = NewFootAbsPos[lIndexForFootPrintInterval].x;
1569
      aCTIPY.FinalCoMPos = NewFootAbsPos[lIndexForFootPrintInterval].y;
1570
    }
1571
  }
1572
}
1573
1574
int AnalyticalMorisawaCompact::ChangeFootLandingPosition(
1575
    double t, vector<unsigned int> &IndexStep,
1576
    vector<FootAbsolutePosition> &NewFootAbsPos) {
1577
  int r = 0;
1578
  r = ChangeFootLandingPosition(
1579
      t, IndexStep, NewFootAbsPos, *m_AnalyticalZMPCoGTrajectoryX, m_CTIPX,
1580
      *m_AnalyticalZMPCoGTrajectoryY, m_CTIPY, true, true, 0, false);
1581
  return r;
1582
}
1583
1584
int AnalyticalMorisawaCompact::ChangeFootLandingPosition(
1585
    double t, vector<unsigned int> &IndexStep,
1586
    vector<FootAbsolutePosition> &NewFootAbsPos,
1587
    AnalyticalZMPCOGTrajectory &aAZCTX,
1588
    CompactTrajectoryInstanceParameters &aCTIPX,
1589
    AnalyticalZMPCOGTrajectory &aAZCTY,
1590
    CompactTrajectoryInstanceParameters &aCTIPY, bool TemporalShift,
1591
    bool ResetFilters, StepStackHandler *aStepStackHandler,
1592
    bool AddingAFootStep) {
1593
  double LocalTime = t - m_AbsoluteTimeReference;
1594
  double FinalTime = 0.0;
1595
  unsigned int IndexStartingInterval = 0;
1596
  int RetourTC = 0;
1597
1598
  double NewTj = 0.0;
1599
  FluctuationParameters aFPX, aFPY;
1600
  double TCX = 0.0, TCY = 0.0, TCMax = 0.0;
1601
1602
  /* Perform First Time Change i.e. recomputing the proper Tj */
1603
  if ((RetourTC = TimeChange(LocalTime, IndexStep[0], IndexStartingInterval,
1604
                             FinalTime, NewTj)) < 0) {
1605
    LTHROW("Time Change not possible");
1606
    // return RetourTC;
1607
  }
1608
1609
  // displayDeltaTj(cerr);
1610
1611
  /* Store the current position and speed of each foot. */
1612
  FootAbsolutePosition InitAbsLeftFootPos, InitAbsRightFootPos;
1613
1614
  m_FeetTrajectoryGenerator->ComputeAnAbsoluteFootPosition(1, t,
1615
                                                           InitAbsLeftFootPos);
1616
  m_FeetTrajectoryGenerator->ComputeAnAbsoluteFootPosition(-1, t,
1617
                                                           InitAbsRightFootPos);
1618
1619
  /* ! This part of the code is not used if we are just trying to add
1620
     a foot step. */
1621
  // if ((int)IndexStep[0]<m_NumberOfIntervals)
1622
  if (!AddingAFootStep) {
1623
    /* Compute the time of maximal fluctuation
1624
       for the initial solution along the X axis.*/
1625
    aAZCTX.FluctuationMaximal();
1626
    aAZCTX.ComputeCOM(t, aFPX.CoMInit, IndexStartingInterval);
1627
1628
    aAZCTX.ComputeCOMSpeed(t, aFPX.CoMSpeedInit);
1629
    aAZCTX.ComputeZMP(t, aFPX.ZMPInit, IndexStartingInterval);
1630
1631
    aAZCTX.ComputeZMPSpeed(t, aFPX.ZMPSpeedInit);
1632
1633
    /* Compute the time of maximal fluctuation
1634
       for the initial solution along the Y axis.*/
1635
    aAZCTY.ComputeCOM(t, aFPY.CoMInit, IndexStartingInterval);
1636
    aAZCTY.ComputeCOMSpeed(t, aFPY.CoMSpeedInit);
1637
    aAZCTY.ComputeZMP(t, aFPY.ZMPInit, IndexStartingInterval);
1638
1639
    aAZCTY.ComputeZMPSpeed(t, aFPY.ZMPSpeedInit);
1640
1641
    /* Adapt the ZMP profil of aCTPIX and aCTPIY
1642
       according to IndexStep */
1643
    ChangeZMPProfil(IndexStep, NewFootAbsPos, aCTIPX, aCTIPY);
1644
1645
    /* Recompute the coefficient of the ZMP/COG trajectories objects. */
1646
    for (int i = 1; i < m_NumberOfIntervals - 1; i++) {
1647
      aAZCTX.Building3rdOrderPolynomial(i, aCTIPX.ZMPProfil[i - 1],
1648
                                        aCTIPX.ZMPProfil[i]);
1649
      aAZCTY.Building3rdOrderPolynomial(i, aCTIPY.ZMPProfil[i - 1],
1650
                                        aCTIPY.ZMPProfil[i]);
1651
    }
1652
1653
    /* Compute the trajectories */
1654
    ComputeTrajectory(aCTIPY, aAZCTY);
1655
    ComputeTrajectory(aCTIPX, aAZCTX);
1656
1657
    aAZCTX.ComputeCOM(t, aFPX.CoMNew);
1658
1659
    aAZCTX.ComputeCOMSpeed(t, aFPX.CoMSpeedNew);
1660
    aAZCTX.ComputeZMP(t, aFPX.ZMPNew);
1661
    aAZCTX.ComputeZMPSpeed(t, aFPX.ZMPSpeedNew);
1662
1663
    aAZCTY.ComputeCOM(t, aFPY.CoMNew);
1664
    aAZCTY.ComputeCOMSpeed(t, aFPY.CoMSpeedNew);
1665
    aAZCTY.ComputeZMP(t, aFPY.ZMPNew);
1666
    aAZCTY.ComputeZMPSpeed(t, aFPY.ZMPSpeedNew);
1667
1668
    TCX = TimeCompensationForZMPFluctuation(aFPX, NewTj);
1669
    TCY = TimeCompensationForZMPFluctuation(aFPY, NewTj);
1670
1671
    TCMax = TCX < TCY ? TCY : TCX;
1672
  } else {
1673
    // For a proper initialization of the analytical trajectories
1674
    // through constraint changes,
1675
    // the Fluctuation structure has to be changed
1676
    // approriatly.
1677
    aAZCTX.ComputeCOM(t, aFPX.CoMInit);
1678
    aAZCTX.ComputeCOMSpeed(t, aFPX.CoMSpeedInit);
1679
    aAZCTX.ComputeZMP(t, aFPX.ZMPInit, IndexStartingInterval);
1680
    aAZCTX.ComputeZMPSpeed(t, aFPX.ZMPSpeedInit);
1681
1682
    aAZCTY.ComputeCOM(t, aFPY.CoMInit);
1683
    aAZCTY.ComputeCOMSpeed(t, aFPY.CoMSpeedInit);
1684
    aAZCTY.ComputeZMP(t, aFPY.ZMPInit, IndexStartingInterval);
1685
    aAZCTY.ComputeZMPSpeed(t, aFPY.ZMPSpeedInit);
1686
1687
    aAZCTX.ComputeCOM(t, aFPX.CoMNew);
1688
1689
    aAZCTX.ComputeCOMSpeed(t, aFPX.CoMSpeedNew);
1690
    aAZCTX.ComputeZMP(t, aFPX.ZMPNew);
1691
    aAZCTX.ComputeZMPSpeed(t, aFPX.ZMPSpeedNew);
1692
1693
    aAZCTY.ComputeCOM(t, aFPY.CoMNew);
1694
    aAZCTY.ComputeCOMSpeed(t, aFPY.CoMSpeedNew);
1695
    aAZCTY.ComputeZMP(t, aFPY.ZMPNew);
1696
    aAZCTY.ComputeZMPSpeed(t, aFPY.ZMPSpeedNew);
1697
1698
    if (m_StepTypes[IndexStartingInterval] == SINGLE_SUPPORT)
1699
      TCMax = m_Tsingle - m_SamplingPeriod;
1700
    else
1701
      TCMax = m_Tdble - m_SamplingPeriod;
1702
  }
1703
1704
  /************ PERFORM THE TIME INTERVAL MODIFICATION ****************/
1705
1706
  if (TemporalShift) {
1707
    NewTimeIntervals(IndexStartingInterval, TCMax);  // TCMax
1708
  } else {
1709
    NewTimeIntervals(IndexStartingInterval, NewTj);
1710
  }
1711
1712
  /*! Extract the set of absolute coordinates for the foot position,
1713
    and recompute the feet trajectory accordingly. */
1714
  if (m_FeetTrajectoryGenerator != 0) {
1715
    m_FeetTrajectoryGenerator->SetDeltaTj(m_DeltaTj);
1716
1717
    /* Modify the feet trajectory */
1718
    ODEBUG("***** Begin Change Foot Landing Position **************");
1719
    m_FeetTrajectoryGenerator->ComputeAbsoluteStepsFromRelativeSteps(
1720
        m_RelativeFootPositions, InitAbsLeftFootPos, InitAbsRightFootPos,
1721
        m_AbsoluteSupportFootPositions);
1722
1723
    ODEBUG("***** End of Change Foot Landing Position *************");
1724
  }
1725
1726
  /* Shift the ZMP profil, the initial
1727
     and final condition, and update the queue of foot prints. */
1728
  ConstraintsChange(LocalTime, aFPX, aFPY, aCTIPX, aCTIPY,
1729
                    IndexStartingInterval, aStepStackHandler);
1730
1731
  m_FeetTrajectoryGenerator->InitializeFromRelativeSteps(
1732
      m_RelativeFootPositions, InitAbsLeftFootPos, InitAbsRightFootPos,
1733
      m_AbsoluteSupportFootPositions, false, true);
1734
1735
  // Initialize and modify the aAZCT trajectories' Tj and Omegaj.
1736
  aAZCTX.SetStartingTimeIntervalsAndHeightVariation(m_DeltaTj, m_Omegaj);
1737
  aAZCTY.SetStartingTimeIntervalsAndHeightVariation(m_DeltaTj, m_Omegaj);
1738
1739
  /* Recompute the coefficient of the ZMP/COG trajectories objects. */
1740
  for (int i = 1; i < m_NumberOfIntervals - 1; i++) {
1741
    aAZCTX.Building3rdOrderPolynomial(i, aCTIPX.ZMPProfil[i - 1],
1742
                                      aCTIPX.ZMPProfil[i]);
1743
    aAZCTY.Building3rdOrderPolynomial(i, aCTIPY.ZMPProfil[i - 1],
1744
                                      aCTIPY.ZMPProfil[i]);
1745
  }
1746
1747
  aAZCTX.SetAbsoluteTimeReference(t);
1748
  aAZCTY.SetAbsoluteTimeReference(t);
1749
1750
  /* Build the Z matrix */
1751
  BuildingTheZMatrix();
1752
  ResetTheResolutionOfThePolynomial();
1753
1754
  /* Compute the trajectories for ZMP and CoM */
1755
  ComputeTrajectory(aCTIPY, aAZCTY);
1756
  ComputeTrajectory(aCTIPX, aAZCTX);
1757
1758
  m_FeetTrajectoryGenerator->SetAbsoluteTimeReference(t);
1759
  m_AbsoluteTimeReference = t;
1760
1761
  /* Reset the filters */
1762
  // Preparing the filtering out of the feet.
1763
  if (m_FilteringActivate && ResetFilters) {
1764
    m_FilterXaxisByPC->FillInWholeBuffer(aFPX.ZMPInit, m_DeltaTj[0]);
1765
    m_FilterYaxisByPC->FillInWholeBuffer(aFPY.ZMPInit, m_DeltaTj[0]);
1766
  }
1767
  return 0;
1768
}
1769
1770
void AnalyticalMorisawaCompact::StringErrorMessage(int ErrorIndex,
1771
                                                   string &ErrorMessage) {
1772
  switch (ErrorIndex) {
1773
    case (0):
1774
      ErrorMessage = "No error";
1775
      break;
1776
    case (-1):
1777
      ErrorMessage = "Wrong foot type";
1778
      break;
1779
    case (-2):
1780
      ErrorMessage = "Modification is asked after the time limit";
1781
      break;
1782
    default:
1783
      ErrorMessage = "Unknown error";
1784
      break;
1785
  }
1786
}
1787
1788
int AnalyticalMorisawaCompact::SetPreviewControl(
1789
    PreviewControl *aPreviewControl) {
1790
  m_PreviewControl = aPreviewControl;
1791
  m_FilterXaxisByPC->SetPreviewControl(aPreviewControl);
1792
  m_FilterYaxisByPC->SetPreviewControl(aPreviewControl);
1793
1794
  return 0;
1795
}
1796
1797
PreviewControl *AnalyticalMorisawaCompact::GetPreviewControl() {
1798
  return m_PreviewControl;
1799
}
1800
1801
void AnalyticalMorisawaCompact::FilterOutOrthogonalDirection(
1802
    AnalyticalZMPCOGTrajectory &aAZCT,
1803
    CompactTrajectoryInstanceParameters &aCTIP, deque<double> &ZMPTrajectory,
1804
    deque<double> &CoGTrajectory) {
1805
  /* Initiliazing the Preview Control according to the trajectory
1806
     to filter. */
1807
  double lAbsoluteTimeReference = aAZCT.GetAbsoluteTimeReference();
1808
  Eigen::MatrixXd x(3, 1);
1809
1810
  /*! Initialize the state vector used by the preview controller */
1811
  x(0, 0) = 0.0;  // aAZCT.ComputeCOM(lAbsoluteTimeReference,x(0,0));
1812
  x(1, 0) = 0.0;  // aAZCT.ComputeCOMSpeed(lAbsoluteTimeReference,x(1,0));
1813
  x(2, 0) = 0.0;
1814
1815
  /*! Initializing variables needed to compute the state vector */
1816
  double lsxzmp = 0.0;
1817
  double lxzmp = 0.0;
1818
1819
  /*! Preview window of the ZMP ref positions */
1820
  double PreviewWindowTime = m_PreviewControl->PreviewControlTime();
1821
  deque<double> FIFOZMPRefPositions;
1822
  RESETDEBUG4("ProfilZMPError.dat");
1823
  for (double lx = 0; lx < m_DeltaTj[0] + 2 * PreviewWindowTime;
1824
       lx += m_SamplingPeriod) {
1825
    double r = 0.0;
1826
    if (lx < m_DeltaTj[0]) {
1827
      double lZMP;
1828
      aAZCT.ComputeZMP(lAbsoluteTimeReference + lx, lZMP);
1829
      r = aCTIP.ZMPProfil[0] - lZMP;
1830
    }
1831
1832
    FIFOZMPRefPositions.push_back(r);
1833
    ODEBUG4(r, "ProfilZMPError.dat");
1834
  }
1835
1836
  unsigned int lindex = 0;
1837
  lsxzmp = 0.0;
1838
  for (double lx = 0; lx < m_DeltaTj[0] + PreviewWindowTime;
1839
       lx += m_SamplingPeriod) {
1840
    m_PreviewControl->OneIterationOfPreview1D(x, lsxzmp, FIFOZMPRefPositions,
1841
                                              lindex, lxzmp, false);
1842
    ZMPTrajectory.push_back(lxzmp);
1843
    CoGTrajectory.push_back(x(0, 0));
1844
    lindex++;
1845
    lsxzmp = 0.0;
1846
  }
1847
}
1848
1849
5
void AnalyticalMorisawaCompact::SetFeetTrajectoryGenerator(
1850
    LeftAndRightFootTrajectoryGenerationMultiple *aFeetTrajectoryGenerator) {
1851
5
  m_FeetTrajectoryGenerator = aFeetTrajectoryGenerator;
1852
5
  if (m_BackUpm_FeetTrajectoryGenerator == 0)
1853
5
    m_BackUpm_FeetTrajectoryGenerator =
1854
        new LeftAndRightFootTrajectoryGenerationMultiple(
1855
5
            m_FeetTrajectoryGenerator->getSimplePluginManager(),
1856
5
            m_FeetTrajectoryGenerator->getFoot());
1857
5
}
1858
1859
LeftAndRightFootTrajectoryGenerationMultiple *
1860
AnalyticalMorisawaCompact::GetFeetTrajectoryGenerator() {
1861
  return m_FeetTrajectoryGenerator;
1862
}
1863
1864
int AnalyticalMorisawaCompact::OnLineFootChange(
1865
    double time, FootAbsolutePosition &aFootAbsolutePosition,
1866
    deque<ZMPPosition> &ZMPPositions, deque<COMState> &CoMPositions,
1867
    deque<FootAbsolutePosition> &LeftFootAbsolutePositions,
1868
    deque<FootAbsolutePosition> &RightFootAbsolutePositions,
1869
    StepStackHandler *aStepStackHandler) {
1870
  deque<FootAbsolutePosition> NewFeetAbsolutePosition;
1871
  NewFeetAbsolutePosition.push_back(aFootAbsolutePosition);
1872
  return OnLineFootChanges(time, NewFeetAbsolutePosition, ZMPPositions,
1873
                           CoMPositions, LeftFootAbsolutePositions,
1874
                           RightFootAbsolutePositions, aStepStackHandler);
1875
}
1876
1877
int AnalyticalMorisawaCompact::OnLineFootChanges(
1878
    double time, deque<FootAbsolutePosition> &aFootAbsolutePosition,
1879
    deque<ZMPPosition> &ZMPPositions, deque<COMState> &CoMPositions,
1880
    deque<FootAbsolutePosition> &LeftFootAbsolutePositions,
1881
    deque<FootAbsolutePosition> &RightFootAbsolutePositions,
1882
    StepStackHandler *aStepStackHandler) {
1883
  ODEBUG("***** Begin OnLineFootChange *****");
1884
  int IndexInterval = -1;
1885
1886
  /* Trying to find the index interval where the change should operate. */
1887
  double TimeReference = m_AbsoluteTimeReference;
1888
  if (time > m_AbsoluteTimeReference) {
1889
    for (unsigned int i = 0; i < m_DeltaTj.size(); i++) {
1890
      if (time < TimeReference + m_DeltaTj[i]) {
1891
        IndexInterval = (int)i;
1892
        break;
1893
      }
1894
      TimeReference += m_DeltaTj[i];
1895
    }
1896
  }
1897
1898
  if (IndexInterval == -1) {
1899
    cerr << "time :" << time << endl
1900
         << "m_AbsoluteTimeReference : " << m_AbsoluteTimeReference << endl
1901
         << "m_AbsoluteTimeReference + sum of DTj: " << TimeReference;
1902
    LTHROW("The time reference is not in the preview window ");
1903
    return -1;
1904
  }
1905
1906
  /* If the interval detected is not a double support interval,
1907
     a shift is done to chose the earliest double support interval. */
1908
  if (m_StepTypes[IndexInterval] != DOUBLE_SUPPORT) {
1909
    if (IndexInterval != 0)
1910
      IndexInterval -= 1;
1911
    else
1912
      IndexInterval += 1;
1913
  } else {
1914
    ODEBUG("Already on a DOUBLE_SUPPORT PHASE:" << IndexInterval);
1915
  }
1916
1917
  if (IndexInterval == -1) {
1918
    LTHROW("No feasible double support interval found.");
1919
    return -1;
1920
  }
1921
1922
  /* Backup data structures */
1923
  FootAbsolutePosition BackUpm_AbsoluteCurrentSupportFootPosition =
1924
      m_AbsoluteCurrentSupportFootPosition;
1925
  deque<FootAbsolutePosition> BackUpm_AbsoluteSupportFootPositions =
1926
      m_AbsoluteSupportFootPositions;
1927
  deque<RelativeFootPosition> BackUpm_RelativeFootPositions =
1928
      m_RelativeFootPositions;
1929
  *m_BackUpm_FeetTrajectoryGenerator = *m_FeetTrajectoryGenerator;
1930
1931
  /* Find the corresponding interval in the stack of foot steps*/
1932
  unsigned int lChangedIntervalFoot = (IndexInterval - 1) / 2;
1933
1934
  /* Which foot is the support one ? */
1935
  if (LeftFootAbsolutePositions[0].stepType < 0)
1936
    m_AbsoluteCurrentSupportFootPosition = LeftFootAbsolutePositions[0];
1937
  else
1938
    m_AbsoluteCurrentSupportFootPosition = RightFootAbsolutePositions[0];
1939
1940
  vector<unsigned int> IndexIntervals;
1941
  vector<FootAbsolutePosition> NewRelFootAbsolutePositions;
1942
1943
  /*! Recompute relative or absolute foot-steps positions
1944
    depending on the mode. */
1945
  if (m_OnLineChangeStepMode == ABSOLUTE_FRAME) {
1946
    IndexIntervals.resize(1);
1947
    IndexIntervals[0] = IndexInterval;
1948
1949
    for (unsigned int i = 0; i < aFootAbsolutePosition.size(); i++)
1950
      m_AbsoluteSupportFootPositions[i + lChangedIntervalFoot] =
1951
          aFootAbsolutePosition[i];
1952
1953
    /* From the new foot landing position computes the new relative set of
1954
       positions. */
1955
    m_FeetTrajectoryGenerator->ChangeRelStepsFromAbsSteps(
1956
        m_RelativeFootPositions, m_AbsoluteCurrentSupportFootPosition,
1957
        m_AbsoluteSupportFootPositions, lChangedIntervalFoot);
1958
1959
    NewRelFootAbsolutePositions.resize(aFootAbsolutePosition.size());
1960
    for (unsigned int i = 0; i < aFootAbsolutePosition.size(); i++)
1961
      NewRelFootAbsolutePositions[i] = aFootAbsolutePosition[i];
1962
  } else if (m_OnLineChangeStepMode == RELATIVE_FRAME) {
1963
    IndexIntervals.resize(m_NumberOfIntervals - IndexInterval);
1964
1965
    NewRelFootAbsolutePositions.resize(m_RelativeFootPositions.size() -
1966
                                       lChangedIntervalFoot);
1967
1968
    for (int j = IndexInterval, k = 0; k < (int)IndexIntervals.size();
1969
         j++, k++) {
1970
      IndexIntervals[k] = j;
1971
    }
1972
1973
    // In this mode the frame is relative to previous local modification...
1974
    for (unsigned int i = 0; i < aFootAbsolutePosition.size(); i++) {
1975
      m_RelativeFootPositions[lChangedIntervalFoot + i].sx +=
1976
          aFootAbsolutePosition[i].x;
1977
      m_RelativeFootPositions[lChangedIntervalFoot + i].sy +=
1978
          aFootAbsolutePosition[i].y;
1979
      m_RelativeFootPositions[lChangedIntervalFoot + i].sz +=
1980
          aFootAbsolutePosition[i].z;
1981
      m_RelativeFootPositions[lChangedIntervalFoot + i].theta +=
1982
          aFootAbsolutePosition[i].theta;
1983
    }
1984
1985
    deque<FootAbsolutePosition> lAbsoluteSupportFootPositions;
1986
    m_FeetTrajectoryGenerator->ComputeAbsoluteStepsFromRelativeSteps(
1987
        m_RelativeFootPositions, LeftFootAbsolutePositions[0],
1988
        RightFootAbsolutePositions[0], lAbsoluteSupportFootPositions);
1989
1990
    for (unsigned int j = 0, k = lChangedIntervalFoot;
1991
         j < NewRelFootAbsolutePositions.size(); j++, k++) {
1992
      NewRelFootAbsolutePositions[j] = lAbsoluteSupportFootPositions[k];
1993
    }
1994
    for (unsigned int k = lChangedIntervalFoot;
1995
         k < m_AbsoluteSupportFootPositions.size(); k++) {
1996
      m_AbsoluteSupportFootPositions[k] = lAbsoluteSupportFootPositions[k];
1997
    }
1998
  }
1999
2000
  ODEBUG("*** End Change foot position *** ");
2001
  /* Change the foot landing position. */
2002
  try {
2003
    ChangeFootLandingPosition(
2004
        m_CurrentTime, IndexIntervals, NewRelFootAbsolutePositions,
2005
        *m_AnalyticalZMPCoGTrajectoryX, m_CTIPX, *m_AnalyticalZMPCoGTrajectoryY,
2006
        m_CTIPY, true, true, aStepStackHandler, false);
2007
  } catch (exception &e) {
2008
    /*! Put back the foot steps to their original states */
2009
    m_AbsoluteCurrentSupportFootPosition =
2010
        BackUpm_AbsoluteCurrentSupportFootPosition;
2011
    m_AbsoluteSupportFootPositions = BackUpm_AbsoluteSupportFootPositions;
2012
    m_RelativeFootPositions = BackUpm_RelativeFootPositions;
2013
2014
    /*! Same for the feet trajectories */
2015
    *m_FeetTrajectoryGenerator = *m_BackUpm_FeetTrajectoryGenerator;
2016
2017
    std::cerr << "Unable to change the step ( " << aFootAbsolutePosition[0].x
2018
              << " , " << aFootAbsolutePosition[0].y << " , "
2019
              << aFootAbsolutePosition[0].theta << " ) " << std::endl;
2020
    throw e;
2021
  }
2022
2023
  // *** Very important:
2024
  // we assume that on the on-line mode we have two values ahead inside
2025
  // the stack. As the change will operate from the current time
2026
  // the stacks are cleared.
2027
  // ***
2028
  ZMPPositions.clear();
2029
  CoMPositions.clear();
2030
  LeftFootAbsolutePositions.clear();
2031
  RightFootAbsolutePositions.clear();
2032
2033
  /*! Compute next time where a foot-step should be added. */
2034
  m_UpperTimeLimitToUpdateStacks =
2035
      m_AbsoluteTimeReference + m_DeltaTj[0] + m_Tdble + 0.45 * m_Tsingle;
2036
2037
  /*! Put 2 iterations of the new trajectories in the queues */
2038
  FillQueues(m_AbsoluteTimeReference,
2039
             m_AbsoluteTimeReference + 2 * m_SamplingPeriod, ZMPPositions,
2040
             CoMPositions, LeftFootAbsolutePositions,
2041
             RightFootAbsolutePositions);
2042
  ODEBUG("***** End OnLineFootChange *****");
2043
  return 0;
2044
}
2045
2046
/*! \brief Return the time at which it is optimal to
2047
  regenerate a step in online mode.
2048
  This time is given in the size of the Left Foot Positions
2049
  queue under which such
2050
  new step has to be generate.
2051
*/
2052
int AnalyticalMorisawaCompact::ReturnOptimalTimeToRegenerateAStep() {
2053
  int r = 1;
2054
  return r;
2055
}
2056
2057
void AnalyticalMorisawaCompact::EndPhaseOfTheWalking(
2058
    deque<ZMPPosition> &FinalZMPPositions, deque<COMState> &FinalCoMPositions,
2059
    deque<FootAbsolutePosition> &FinalLeftFootAbsolutePositions,
2060
    deque<FootAbsolutePosition> &FinalRightFootAbsolutePositions) {
2061
  m_OnLineMode = true;
2062
  bool DoNotPrepareLastFoot = false;
2063
  int NbSteps = (int)m_RelativeFootPositions.size();
2064
  int NbOfIntervals = 2 * NbSteps + 1;
2065
2066
  /* Update the relative and absolute foot positions. */
2067
  m_RelativeFootPositions.pop_front();
2068
2069
  ODEBUG("***** Begin EndPhaseOfTheWalking *****");
2070
  // Strategy for the final CoM pos: middle of the segment
2071
  // between the two final steps, in order to be statically stable.
2072
  unsigned int lindex =
2073
      (unsigned int)(m_AbsoluteSupportFootPositions.size() - 1);
2074
  vector<double> *lZMPX = 0;
2075
  double FinalCoMPosX = 0.6;
2076
2077
  vector<double> *lZMPY = 0;
2078
  double FinalCoMPosY = 0.0;
2079
2080
  /*! Prepare end condition for CoM along X axis */
2081
  if (DoNotPrepareLastFoot)
2082
    FinalCoMPosX = m_AbsoluteSupportFootPositions[lindex].x;
2083
  else
2084
    FinalCoMPosX = 0.5 * (m_AbsoluteSupportFootPositions[lindex - 1].x +
2085
                          m_AbsoluteSupportFootPositions[lindex].x);
2086
  m_CTIPX.FinalCoMPos = FinalCoMPosX;
2087
2088
  /*! Prepare end condition for ZMP along X axis */
2089
  lZMPX = &m_CTIPX.ZMPProfil;
2090
  unsigned int j = (unsigned int)lZMPX->size();
2091
  if (DoNotPrepareLastFoot)
2092
    (*lZMPX)[j - 2] = (*lZMPX)[j - 1] =
2093
        m_AbsoluteSupportFootPositions[lindex].x;
2094
  else
2095
    (*lZMPX)[j - 2] = (*lZMPX)[j - 1] = FinalCoMPosX;
2096
2097
  /*! Build 3rd order polynomials. */
2098
  for (int i = 1; i < NbOfIntervals - 1; i++) {
2099
    m_AnalyticalZMPCoGTrajectoryX->Building3rdOrderPolynomial(
2100
        i, (*lZMPX)[i - 1], (*lZMPX)[i]);
2101
  }
2102
2103
  /*! Compute trajectory for CoM along X axis. */
2104
  ComputeTrajectory(m_CTIPX, *m_AnalyticalZMPCoGTrajectoryX);
2105
2106
  /*! Prepare end condition for CoM along Y axis */
2107
  if (DoNotPrepareLastFoot)
2108
    FinalCoMPosY = m_AbsoluteSupportFootPositions[lindex].y;
2109
  else
2110
    FinalCoMPosY = 0.5 * (m_AbsoluteSupportFootPositions[lindex - 1].y +
2111
                          m_AbsoluteSupportFootPositions[lindex].y);
2112
  m_CTIPY.FinalCoMPos = FinalCoMPosY;
2113
2114
  /*! Prepare end condition for ZMP along Y axis */
2115
  lZMPY = &m_CTIPY.ZMPProfil;
2116
  if (DoNotPrepareLastFoot)
2117
    (*lZMPY)[j - 2] = (*lZMPY)[j - 1] =
2118
        m_AbsoluteSupportFootPositions[lindex].y;
2119
  else
2120
    (*lZMPY)[j - 2] = (*lZMPY)[j - 1] = FinalCoMPosY;
2121
2122
  /*! Build 3rd order polynomials. */
2123
  for (int i = 1; i < NbOfIntervals - 1; i++) {
2124
    m_AnalyticalZMPCoGTrajectoryY->Building3rdOrderPolynomial(
2125
        i, (*lZMPY)[i - 1], (*lZMPY)[i]);
2126
  }
2127
2128
  /*! Compute the analytical trajectory*/
2129
  ComputeTrajectory(m_CTIPY, *m_AnalyticalZMPCoGTrajectoryY);
2130
2131
  /* Specify when a new step should be asked for. */
2132
  m_UpperTimeLimitToUpdateStacks =
2133
      m_AbsoluteTimeReference + m_PreviewControlTime;
2134
2135
  /* Put two positions from the new polynomials in the queues. */
2136
  FillQueues(m_CurrentTime, m_CurrentTime + 2 * m_SamplingPeriod,
2137
             FinalZMPPositions, FinalCoMPositions,
2138
             FinalLeftFootAbsolutePositions, FinalRightFootAbsolutePositions);
2139
2140
  m_EndPhase = true;
2141
  ODEBUG("**** End of EndPhaseOfTheWalking *******");
2142
}
2143
2144
5
void AnalyticalMorisawaCompact::RegisterMethods() {
2145


20
  std::string aMethodName[2] = {":onlinechangestepframe", ":setRobotUpperPart"};
2146
2147
10
  for (int i = 0; i < 1; i++) {
2148

5
    if (!RegisterMethod(aMethodName[i])) {
2149
      std::cerr << "Unable to register " << aMethodName[i] << std::endl;
2150
    } else {
2151
      ODEBUG("Succeed in registering " << aMethodName[i]);
2152
    }
2153
  }
2154
5
}
2155
2156
43
void AnalyticalMorisawaCompact::CallMethod(std::string &Method,
2157
                                           std::istringstream &strm) {
2158
43
  if (Method == ":onlinechangestepframe") {
2159
    std::string aws;
2160
    if (strm.good()) {
2161
      strm >> aws;
2162
      if (aws == "absolute")
2163
        m_OnLineChangeStepMode = ABSOLUTE_FRAME;
2164
      else if (aws == "relative")
2165
        m_OnLineChangeStepMode = RELATIVE_FRAME;
2166
    }
2167
43
  } else if (Method == ":filtering") {
2168
    std::string aws;
2169
    if (strm.good()) {
2170
      strm >> aws;
2171
      if (aws == "activate")
2172
        m_FilteringActivate = true;
2173
      else if (aws == "deactivate")
2174
        m_FilteringActivate = false;
2175
    }
2176
43
  } else if (Method == ":setRobotUpperPart") {
2177
    //      Eigen::VectorXd configuration ;
2178
    //      if (strm.good())
2179
    //      {
2180
    //        strm >> configuration;
2181
    //        m_kajitaDynamicFilter->setRobotUpperPart(configuration);
2182
    //      }
2183
  }
2184
2185
43
  ZMPRefTrajectoryGeneration::CallMethod(Method, strm);
2186
43
}
2187
2188
void AnalyticalMorisawaCompact::PropagateAbsoluteReferenceTime(double x) {
2189
  m_AbsoluteTimeReference = x;
2190
  m_AnalyticalZMPCoGTrajectoryX->SetAbsoluteTimeReference(x);
2191
  m_AnalyticalZMPCoGTrajectoryY->SetAbsoluteTimeReference(x);
2192
  m_FeetTrajectoryGenerator->SetAbsoluteTimeReference(x);
2193
}
2194
2195
void AnalyticalMorisawaCompact::FillQueues(
2196
    double samplingPeriod, double StartingTime, double EndTime,
2197
    deque<ZMPPosition> &FinalZMPPositions, deque<COMState> &FinalCoMPositions,
2198
    deque<FootAbsolutePosition> &FinalLeftFootAbsolutePositions,
2199
    deque<FootAbsolutePosition> &FinalRightFootAbsolutePositions) {
2200
  unsigned int lIndexInterval, lPrevIndexInterval;
2201
  m_AnalyticalZMPCoGTrajectoryX->GetIntervalIndexFromTime(
2202
      m_AbsoluteTimeReference, lIndexInterval);
2203
  lPrevIndexInterval = lIndexInterval;
2204
2205
  /*! Fill in the stacks: minimal strategy only 1 reference. */
2206
  for (double t = StartingTime; t <= EndTime; t += samplingPeriod) {
2207
    m_AnalyticalZMPCoGTrajectoryX->GetIntervalIndexFromTime(t, lIndexInterval,
2208
                                                            lPrevIndexInterval);
2209
2210
    /*! Feed the ZMPPositions. */
2211
    ZMPPosition aZMPPos;
2212
    if (!m_AnalyticalZMPCoGTrajectoryX->ComputeZMP(t, aZMPPos.px,
2213
                                                   lIndexInterval))
2214
      LTHROW("Unable to compute ZMP along X-Axis in EndPhaseOfWalking");
2215
2216
    if (!m_AnalyticalZMPCoGTrajectoryY->ComputeZMP(t, aZMPPos.py,
2217
                                                   lIndexInterval))
2218
      LTHROW("Unable to compute ZMP along Y-Axis in EndPhaseOfWalking");
2219
2220
    ComputeZMPz(t, aZMPPos, lIndexInterval);
2221
2222
    FinalZMPPositions.push_back(aZMPPos);
2223
2224
    /*! Feed the FootPositions. */
2225
2226
    /*! Left */
2227
    FootAbsolutePosition LeftFootAbsPos;
2228
    memset(&LeftFootAbsPos, 0, sizeof(LeftFootAbsPos));
2229
    if (!m_FeetTrajectoryGenerator->ComputeAnAbsoluteFootPosition(
2230
            1, t, LeftFootAbsPos, lIndexInterval)) {
2231
      LTHROW("Unable to compute left foot position in EndPhaseOfWalking");
2232
    }
2233
    FinalLeftFootAbsolutePositions.push_back(LeftFootAbsPos);
2234
2235
    /*! Right */
2236
    FootAbsolutePosition RightFootAbsPos;
2237
    memset(&RightFootAbsPos, 0, sizeof(RightFootAbsPos));
2238
    if (!m_FeetTrajectoryGenerator->ComputeAnAbsoluteFootPosition(
2239
            -1, t, RightFootAbsPos, lIndexInterval)) {
2240
      LTHROW(
2241
          "Unable to compute right foot"
2242
          " position in EndPhaseOfWalking");
2243
    }
2244
    FinalRightFootAbsolutePositions.push_back(RightFootAbsPos);
2245
2246
    /*! Feed the COMStates. */
2247
    COMState aCOMPos;
2248
    memset(&aCOMPos, 0, sizeof(aCOMPos));
2249
    if (!m_AnalyticalZMPCoGTrajectoryX->ComputeCOM(t, aCOMPos.x[0],
2250
                                                   lIndexInterval)) {
2251
      LTHROW("COM out of bound along X axis.");
2252
    }
2253
    m_AnalyticalZMPCoGTrajectoryX->ComputeCOMSpeed(t, aCOMPos.x[1],
2254
                                                   lIndexInterval);
2255
    m_AnalyticalZMPCoGTrajectoryX->ComputeCOMAcceleration(t, aCOMPos.x[2],
2256
                                                          lIndexInterval);
2257
2258
    if (!m_AnalyticalZMPCoGTrajectoryY->ComputeCOM(t, aCOMPos.y[0],
2259
                                                   lIndexInterval)) {
2260
      LTHROW("COM out of bound along Y axis.");
2261
    }
2262
    m_AnalyticalZMPCoGTrajectoryY->ComputeCOMSpeed(t, aCOMPos.y[1],
2263
                                                   lIndexInterval);
2264
    m_AnalyticalZMPCoGTrajectoryY->ComputeCOMAcceleration(t, aCOMPos.y[2],
2265
                                                          lIndexInterval);
2266
2267
    ComputeCoMz(t, lIndexInterval, aCOMPos, FinalCoMPositions);
2268
2269
    aCOMPos.yaw[0] = 0.5 * (LeftFootAbsPos.theta + RightFootAbsPos.theta);
2270
    aCOMPos.yaw[1] = 0.5 * (LeftFootAbsPos.dtheta + RightFootAbsPos.dtheta);
2271
    aCOMPos.yaw[2] = 0.5 * (LeftFootAbsPos.ddtheta + RightFootAbsPos.ddtheta);
2272
2273
    FinalCoMPositions.push_back(aCOMPos);
2274
2275
    ODEBUG4(aZMPPos.px << " " << aZMPPos.py << " " << aCOMPos.x[0] << " "
2276
                       << aCOMPos.y[0] << " " << aCOMPos.z[0] << " "
2277
                       << LeftFootAbsPos.x << " " << LeftFootAbsPos.y << " "
2278
                       << LeftFootAbsPos.z << " " << RightFootAbsPos.x << " "
2279
                       << RightFootAbsPos.y << " " << RightFootAbsPos.z << " "
2280
                       << samplingPeriod,
2281
            "Test.dat");
2282
  }
2283
}
2284
2285
void AnalyticalMorisawaCompact::ComputeCoMz(COMState &CoM,
2286
                                            FootAbsolutePosition &LeftFoot,
2287
                                            FootAbsolutePosition &) {
2288
  CoM.z[0] = ((LeftFoot.z + 0.7) + (LeftFoot.z + 0.85) + (LeftFoot.z + 0.7) +
2289
              (LeftFoot.z + 0.85)) *
2290
             0.25;
2291
  CoM.z[0] = ((LeftFoot.dz + 0.7) + (LeftFoot.dz + 0.85) + (LeftFoot.dz + 0.7) +
2292
              (LeftFoot.dz + 0.85)) *
2293
             0.25;
2294
  CoM.z[0] = ((LeftFoot.ddz + 0.7) + (LeftFoot.ddz + 0.85) +
2295
              (LeftFoot.ddz + 0.7) + (LeftFoot.ddz + 0.85)) *
2296
             0.25;
2297
}
2298
2299
void AnalyticalMorisawaCompact::ComputeCoMz(
2300
    double t, unsigned int lIndexInterval, COMState &CoM,
2301
    deque<COMState> &FinalCoMPositions) {
2302
  double *CoMz = CoM.z;
2303
  double moving_time =
2304
      m_RelativeFootPositions[0].SStime + m_RelativeFootPositions[0].DStime;
2305
  unsigned int Index = lIndexInterval / 2;
2306
2307
  // absFootz_0, the z axis is expressed in the waist frame
2308
  // we choose the left one by default, the foot are supposed to be symetrical
2309
  // we use it pass the ankle position to the fot position
2310
  PRFoot *aFoot = m_PR->leftFoot();
2311
  if (aFoot == 0) LTHROW("No foot");
2312
  Eigen::Vector3d corrZ;
2313
  corrZ = aFoot->anklePosition;
2314
  corrZ(2) = 0;  // foot height no more equal to ankle height; TODO :
2315
  // remove corrZ
2316
2317
  // after the final step we keep the same position for a while
2318
  if (Index >= m_AbsoluteSupportFootPositions.size()) {
2319
    if (FinalCoMPositions.size() == 0) {
2320
      CoMz[0] = m_InitialPoseCoMHeight +
2321
                m_AbsoluteSupportFootPositions[Index].z - corrZ(2);
2322
      CoMz[1] = 0.0;
2323
      CoMz[2] = 0.0;
2324
      return;
2325
    }
2326
2327
    COMState LastCoM = FinalCoMPositions.back();
2328
    double higherPoseCoMz = m_InitialPoseCoMHeight +
2329
                            m_AbsoluteSupportFootPositions.back().z - corrZ(2);
2330
    double ft =
2331
        m_RelativeFootPositions.back().SStime - (t - Index * moving_time);
2332
2333
    m_CoMbsplinesZ->SetParameters(ft, LastCoM.z[0], higherPoseCoMz,
2334
                                  vector<double>(), vector<double>(),
2335
                                  LastCoM.z[1], LastCoM.z[2]);
2336
    m_CoMbsplinesZ->Compute(m_SamplingPeriod, CoMz[0], CoMz[1], CoMz[2]);
2337
    return;
2338
  }
2339
  //    cout << "INDEX = " << Index << endl ;
2340
  //    cout << "lIndexInterval = " << lIndexInterval << endl ;
2341
2342
  double sx = m_RelativeFootPositions[Index].sx;
2343
  double sy = m_RelativeFootPositions[Index].sy;
2344
  double sz = m_RelativeFootPositions[Index].sz;
2345
  double SStime = m_RelativeFootPositions[Index].SStime;
2346
  double DStime = m_RelativeFootPositions[Index].DStime;
2347
  double initCoMheight = m_InitialPoseCoMHeight +
2348
                         m_AbsoluteSupportFootPositions[Index].z - corrZ(2);
2349
  double lowerCoMheight = 0.95 * m_InitialPoseCoMHeight +
2350
                          m_AbsoluteSupportFootPositions[Index].z - corrZ(2);
2351
  double FinalTime(0.0), InitPos(0.0), InitSpeed(0.0), InitAcc(0.0),
2352
      FinalPos(0.0), interpolationTime(0.0);
2353
  vector<double> MP;
2354
  MP.clear();
2355
  vector<double> ToMP;
2356
  ToMP.clear();
2357
2358
  COMState LastCoM;
2359
  if (FinalCoMPositions.size() != 0)
2360
    LastCoM = FinalCoMPositions.back();
2361
  else {
2362
    LastCoM.z[0] = initCoMheight;
2363
    LastCoM.z[1] = 0.0;
2364
    LastCoM.z[2] = 0.0;
2365
  }
2366
2367
  // we start analyze since 2nd step
2368
  if (Index == 0) {
2369
    sx = m_RelativeFootPositions[Index + 1].sx;
2370
    sy = m_RelativeFootPositions[Index + 1].sy;
2371
    sz = m_RelativeFootPositions[Index + 1].sz;
2372
    FinalTime = moving_time;
2373
    interpolationTime = t - Index * moving_time;
2374
    FinalPos = initCoMheight;
2375
    FinalTime = SStime - interpolationTime;
2376
    if (sx * sx + sy * sy > 0.22 * 0.22 && sz * sz + sz * sz < 0.00001 &&
2377
        sx * sx + sx * sx > 0.00001) {
2378
      FinalPos = lowerCoMheight;
2379
    }
2380
    InitPos = LastCoM.z[0];
2381
    InitSpeed = LastCoM.z[1];
2382
    InitAcc = LastCoM.z[2];
2383
    m_CoMbsplinesZ->SetParameters(FinalTime, InitPos, FinalPos, ToMP, MP,
2384
                                  InitSpeed, InitAcc);
2385
    m_CoMbsplinesZ->Compute(m_SamplingPeriod, CoMz[0], CoMz[1], CoMz[2]);
2386
    return;
2387
  }
2388
2389
  // variables that parameterize the trajectory of the CoM in z
2390
  double deltaZ;
2391
  // double static CoMzpre = CoMz;
2392
  double up = 0.20, upRight = 0.9, upLeft = 0.0;
2393
  double down = 0.4, downRight = 0.90, downLeft = 0.1;
2394
2395
  // some variables renaming which improve the readibility
2396
  double absFootz_0 = m_AbsoluteSupportFootPositions[Index].z - corrZ(2);
2397
  double absFootz_1 = m_AbsoluteSupportFootPositions[Index - 1].z - corrZ(2);
2398
  double absFootz_2 = 0.0;
2399
  if (Index > 1) {
2400
    absFootz_2 = m_AbsoluteSupportFootPositions[Index - 2].z - corrZ(2);
2401
  }
2402
2403
  // climbing
2404
  // put first leg on the stairs with decrease of CoM //up// of stair height
2405
  // the CoM line will decrease between an //upLeft to upRight
2406
  // interval of SStime.
2407
  // the CoM line will go up between an //upLeft1 to upRight1//
2408
  // interval of SStime while 2nd leg moving up on the stairs.
2409
  if (absFootz_0 > absFootz_1)  // first leg
2410
  {
2411
    deltaZ = absFootz_0 - absFootz_1;
2412
    if (Index > 1)
2413
      InitPos =
2414
          m_InitialPoseCoMHeight + absFootz_2 - up * (absFootz_1 - absFootz_2);
2415
    else  // Special case: starting the motion.
2416
      InitPos = m_InitialPoseCoMHeight;
2417
2418
    InitSpeed = 0.0;
2419
    FinalPos = m_InitialPoseCoMHeight + absFootz_1 - up * deltaZ;
2420
2421
    interpolationTime = t - Index * moving_time - upLeft * SStime;
2422
    FinalTime = (upRight - upLeft) * SStime - interpolationTime;
2423
  } else if (absFootz_0 == absFootz_1 &&
2424
             m_RelativeFootPositions[Index - 1].sz > 0)  // 2nd leg
2425
  {
2426
    deltaZ = (absFootz_0 - absFootz_2);
2427
    InitPos = m_InitialPoseCoMHeight + absFootz_2 - up * deltaZ;
2428
    InitSpeed = 0.0;
2429
    FinalPos = m_InitialPoseCoMHeight + absFootz_0;
2430
2431
    interpolationTime = t - Index * moving_time - upLeft * SStime;
2432
    FinalTime = (upRight - upLeft) * SStime - interpolationTime;
2433
  }
2434
  // going down
2435
  // the CoM line will decrease an //1+down// stair height
2436
  // between an //downLeft to downRight// interval of SStime while
2437
  // moving first leg down
2438
  // put the 2nd leg down while standing up the CoM.
2439
  else if (absFootz_0 < absFootz_1) {
2440
    deltaZ = absFootz_1 - absFootz_0;
2441
    if (Index > 1)
2442
      InitPos = m_InitialPoseCoMHeight + absFootz_1 -
2443
                down * (absFootz_2 - absFootz_1);
2444
    else  // Special case: starting the motion.
2445
      InitPos = m_InitialPoseCoMHeight;
2446
2447
    InitSpeed = 0.0;
2448
    FinalPos = m_InitialPoseCoMHeight + absFootz_0 - down * deltaZ;
2449
2450
    interpolationTime = t - Index * moving_time - downLeft * SStime;
2451
    FinalTime = (downRight - downLeft) * SStime - interpolationTime;
2452
  } else if (absFootz_0 == absFootz_1 &&
2453
             m_RelativeFootPositions[Index - 1].sz < 0)  // second leg
2454
  {
2455
    deltaZ = absFootz_2 - absFootz_0;
2456
    InitPos = m_InitialPoseCoMHeight + absFootz_0 - down * deltaZ;
2457
    InitSpeed = 0.0;
2458
    FinalPos = m_InitialPoseCoMHeight + absFootz_0;
2459
    interpolationTime = t - Index * moving_time - downLeft * SStime;
2460
    FinalTime = (downRight - downLeft) * SStime - interpolationTime;
2461
  }
2462
  // normal walking
2463
  // the com stay on the horizotal plane at the initial com altitude
2464
  else {
2465
    InitSpeed = 0.0;
2466
    interpolationTime = t - Index * moving_time - SStime;
2467
    FinalTime = moving_time - interpolationTime;
2468
    InitPos = initCoMheight;
2469
    FinalPos = initCoMheight;
2470
2471
    if (sx * sx + sy * sy > 0.22 * 0.22 && sz * sz + sz * sz < 0.00001 &&
2472
        sx * sx + sx * sx > 0.00001) {
2473
      if (LastCoM.z[0] >= lowerCoMheight + 0.00001 ||
2474
          LastCoM.z[0] <= lowerCoMheight - 0.00001) {
2475
        FinalTime = DStime - interpolationTime;
2476
        FinalPos = lowerCoMheight;
2477
      } else {
2478
        InitPos = lowerCoMheight;
2479
        FinalPos = lowerCoMheight;
2480
      }
2481
    } else if (LastCoM.z[0] >= initCoMheight + 0.00001 ||
2482
               LastCoM.z[0] <= initCoMheight - 0.00001) {
2483
      FinalTime = SStime - interpolationTime;
2484
      InitPos = lowerCoMheight;
2485
      FinalPos = initCoMheight;
2486
    } else {
2487
      InitPos = initCoMheight;
2488
      FinalPos = initCoMheight;
2489
    }
2490
  }
2491
2492
  //    cout << "relative position : "
2493
  //         << sx << " "
2494
  //         << sy << " "
2495
  //         << dx << " "
2496
  //         << dy << " "
2497
  //         << SStime << " "
2498
  //         << m_AbsoluteSupportFootPositions[Index].time << " "
2499
  //         << m_AbsoluteSupportFootPositions[Index-1].time << " " << endl ;
2500
  InitPos = LastCoM.z[0];
2501
  InitSpeed = LastCoM.z[1];
2502
  InitAcc = LastCoM.z[2];
2503
  m_CoMbsplinesZ->SetParameters(FinalTime, InitPos, FinalPos, ToMP, MP,
2504
                                InitSpeed, InitAcc);
2505
  m_CoMbsplinesZ->Compute(m_SamplingPeriod, CoMz[0], CoMz[1], CoMz[2]);
2506
}
2507
2508
void AnalyticalMorisawaCompact::ComputeZMPz(double t, ZMPPosition &ZMPz,
2509
                                            unsigned int IndexInterval) {
2510
  // absFootz_0, the z axis is expressed in the waist frame
2511
  // we choose the left one by default, the foot are supposed to be symetrical
2512
  // we use it pass the ankle position to the fot position
2513
  PRFoot *aFoot = m_PR->leftFoot();
2514
  if (aFoot == 0) LTHROW("No foot");
2515
  Eigen::Vector3d corrZ;
2516
  corrZ = aFoot->anklePosition;
2517
  corrZ(2) = 0.0;
2518
  bool sinple_support = (IndexInterval % 2) == 0;
2519
  double moving_time =
2520
      m_RelativeFootPositions[0].SStime + m_RelativeFootPositions[0].DStime;
2521
  unsigned int stepNumber = int(t / moving_time);
2522
2523
  // we start analyze since 2nd step
2524
  // after the final step we keep the same position for a while
2525
  // when a foot fly the zmp.pz is the supportFoot.z
2526
  if (stepNumber >= m_AbsoluteSupportFootPositions.size()) {
2527
    ZMPz.pz = m_AbsoluteSupportFootPositions.back().z - corrZ(2);
2528
    return;
2529
  } else if (stepNumber < 1) {
2530
    ZMPz.pz = m_AbsoluteSupportFootPositions.front().z - corrZ(2);
2531
  } else if (t <= moving_time || sinple_support) {
2532
    ZMPz.pz = m_AbsoluteSupportFootPositions[stepNumber - 1].z - corrZ(2);
2533
    return;
2534
  } else {
2535
    double absFootz_0 = m_AbsoluteSupportFootPositions[stepNumber].z - corrZ(2);
2536
    double absFootz_1 =
2537
        m_AbsoluteSupportFootPositions[stepNumber - 1].z - corrZ(2);
2538
    m_ZMPpolynomeZ->SetParametersWithInitPosInitSpeed(
2539
        m_RelativeFootPositions[0].DStime, absFootz_0, absFootz_1, 0.0);
2540
    ZMPz.pz = m_ZMPpolynomeZ->Compute(t - stepNumber * moving_time -
2541
                                      m_RelativeFootPositions[0].SStime);
2542
  }
2543
  return;
2544
}
2545
2546
void AnalyticalMorisawaCompact::FillQueues(
2547
    double StartingTime, double EndTime, deque<ZMPPosition> &FinalZMPPositions,
2548
    deque<COMState> &FinalCoMPositions,
2549
    deque<FootAbsolutePosition> &FinalLeftFootAbsolutePositions,
2550
    deque<FootAbsolutePosition> &FinalRightFootAbsolutePositions) {
2551
  FillQueues(m_SamplingPeriod, StartingTime, EndTime, FinalZMPPositions,
2552
             FinalCoMPositions, FinalLeftFootAbsolutePositions,
2553
             FinalRightFootAbsolutePositions);
2554
}
2555
}  // namespace PatternGeneratorJRL