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