@@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
35
36
36
#include < ocs2_oc/multiple_shooting/Helpers.h>
37
37
#include < ocs2_oc/multiple_shooting/Initialization.h>
38
+ #include < ocs2_oc/multiple_shooting/MetricsComputation.h>
38
39
#include < ocs2_oc/multiple_shooting/PerformanceIndexComputation.h>
39
40
#include < ocs2_oc/multiple_shooting/Transcription.h>
40
41
#include < ocs2_oc/precondition/Ruzi.h>
@@ -177,6 +178,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
177
178
178
179
// Bookkeeping
179
180
performanceIndeces_.clear ();
181
+ std::vector<Metrics> metrics;
180
182
181
183
int iter = 0 ;
182
184
slp::Convergence convergence = slp::Convergence::FALSE ;
@@ -186,7 +188,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
186
188
}
187
189
// Make QP approximation
188
190
linearQuadraticApproximationTimer_.startTimer ();
189
- const auto baselinePerformance = setupQuadraticSubproblem (timeDiscretization, initState, x, u);
191
+ const auto baselinePerformance = setupQuadraticSubproblem (timeDiscretization, initState, x, u, metrics );
190
192
linearQuadraticApproximationTimer_.endTimer ();
191
193
192
194
// Solve LP
@@ -197,7 +199,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
197
199
198
200
// Apply step
199
201
linesearchTimer_.startTimer ();
200
- const auto stepInfo = takeStep (baselinePerformance, timeDiscretization, initState, deltaSolution, x, u);
202
+ const auto stepInfo = takeStep (baselinePerformance, timeDiscretization, initState, deltaSolution, x, u, metrics );
201
203
performanceIndeces_.push_back (stepInfo.performanceAfterStep );
202
204
linesearchTimer_.endTimer ();
203
205
@@ -211,6 +213,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
211
213
212
214
computeControllerTimer_.startTimer ();
213
215
primalSolution_ = toPrimalSolution (timeDiscretization, std::move (x), std::move (u));
216
+ problemMetrics_ = multiple_shooting::toProblemMetrics (timeDiscretization, std::move (metrics));
214
217
computeControllerTimer_.endTimer ();
215
218
216
219
++numProblems_;
@@ -290,7 +293,7 @@ PrimalSolution SlpSolver::toPrimalSolution(const std::vector<AnnotatedTime>& tim
290
293
}
291
294
292
295
PerformanceIndex SlpSolver::setupQuadraticSubproblem (const std::vector<AnnotatedTime>& time, const vector_t & initState,
293
- const vector_array_t & x, const vector_array_t & u) {
296
+ const vector_array_t & x, const vector_array_t & u, std::vector<Metrics>& metrics ) {
294
297
// Problem horizon
295
298
const int N = static_cast <int >(time.size ()) - 1 ;
296
299
@@ -302,6 +305,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
302
305
stateInputIneqConstraints_.resize (N);
303
306
constraintsProjection_.resize (N);
304
307
projectionMultiplierCoefficients_.resize (N);
308
+ metrics.resize (N + 1 );
305
309
306
310
std::atomic_int timeIndex{0 };
307
311
auto parallelTask = [&](int workerId) {
@@ -314,6 +318,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
314
318
if (time[i].event == AnnotatedTime::Event::PreEvent) {
315
319
// Event node
316
320
auto result = multiple_shooting::setupEventNode (ocpDefinition, time[i].time , x[i], x[i + 1 ]);
321
+ metrics[i] = multiple_shooting::computeMetrics (result);
317
322
workerPerformance += multiple_shooting::computePerformanceIndex (result);
318
323
cost_[i] = std::move (result.cost );
319
324
dynamics_[i] = std::move (result.dynamics );
@@ -327,6 +332,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
327
332
const scalar_t ti = getIntervalStart (time[i]);
328
333
const scalar_t dt = getIntervalDuration (time[i], time[i + 1 ]);
329
334
auto result = multiple_shooting::setupIntermediateNode (ocpDefinition, sensitivityDiscretizer_, ti, dt, x[i], x[i + 1 ], u[i]);
335
+ metrics[i] = multiple_shooting::computeMetrics (result);
330
336
workerPerformance += multiple_shooting::computePerformanceIndex (result, dt);
331
337
multiple_shooting::projectTranscription (result, settings_.extractProjectionMultiplier );
332
338
cost_[i] = std::move (result.cost );
@@ -344,6 +350,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
344
350
if (i == N) { // Only one worker will execute this
345
351
const scalar_t tN = getIntervalStart (time[N]);
346
352
auto result = multiple_shooting::setupTerminalNode (ocpDefinition, tN, x[N]);
353
+ metrics[i] = multiple_shooting::computeMetrics (result);
347
354
workerPerformance += multiple_shooting::computePerformanceIndex (result);
348
355
cost_[i] = std::move (result.cost );
349
356
stateIneqConstraints_[i] = std::move (result.ineqConstraints );
@@ -365,44 +372,46 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
365
372
}
366
373
367
374
PerformanceIndex SlpSolver::computePerformance (const std::vector<AnnotatedTime>& time, const vector_t & initState, const vector_array_t & x,
368
- const vector_array_t & u) {
369
- // Problem horizon
375
+ const vector_array_t & u, std::vector<Metrics>& metrics ) {
376
+ // Problem size
370
377
const int N = static_cast <int >(time.size ()) - 1 ;
378
+ metrics.resize (N + 1 );
371
379
372
380
std::vector<PerformanceIndex> performance (settings_.nThreads , PerformanceIndex ());
373
381
std::atomic_int timeIndex{0 };
374
382
auto parallelTask = [&](int workerId) {
375
383
// Get worker specific resources
376
384
OptimalControlProblem& ocpDefinition = ocpDefinitions_[workerId];
377
- PerformanceIndex workerPerformance; // Accumulate performance in local variable
378
385
379
386
int i = timeIndex++;
380
387
while (i < N) {
381
388
if (time[i].event == AnnotatedTime::Event::PreEvent) {
382
389
// Event node
383
- workerPerformance += multiple_shooting::computeEventPerformance (ocpDefinition, time[i].time , x[i], x[i + 1 ]);
390
+ metrics[i] = multiple_shooting::computeEventMetrics (ocpDefinition, time[i].time , x[i], x[i + 1 ]);
391
+ performance[workerId] += toPerformanceIndex (metrics[i]);
384
392
} else {
385
393
// Normal, intermediate node
386
394
const scalar_t ti = getIntervalStart (time[i]);
387
395
const scalar_t dt = getIntervalDuration (time[i], time[i + 1 ]);
388
- workerPerformance += multiple_shooting::computeIntermediatePerformance (ocpDefinition, discretizer_, ti, dt, x[i], x[i + 1 ], u[i]);
396
+ metrics[i] = multiple_shooting::computeIntermediateMetrics (ocpDefinition, discretizer_, ti, dt, x[i], x[i + 1 ], u[i]);
397
+ performance[workerId] += toPerformanceIndex (metrics[i], dt);
389
398
}
390
399
391
400
i = timeIndex++;
392
401
}
393
402
394
403
if (i == N) { // Only one worker will execute this
395
404
const scalar_t tN = getIntervalStart (time[N]);
396
- workerPerformance += multiple_shooting::computeTerminalPerformance (ocpDefinition, tN, x[N]);
405
+ metrics[N] = multiple_shooting::computeTerminalMetrics (ocpDefinition, tN, x[N]);
406
+ performance[workerId] += toPerformanceIndex (metrics[N]);
397
407
}
398
-
399
- // Accumulate! Same worker might run multiple tasks
400
- performance[workerId] += workerPerformance;
401
408
};
402
409
runParallel (std::move (parallelTask));
403
410
404
- // Account for init state in performance
405
- performance.front ().dynamicsViolationSSE += (initState - x.front ()).squaredNorm ();
411
+ // Account for initial state in performance
412
+ const vector_t initDynamicsViolation = initState - x.front ();
413
+ metrics.front ().dynamicsViolation += initDynamicsViolation;
414
+ performance.front ().dynamicsViolationSSE += initDynamicsViolation.squaredNorm ();
406
415
407
416
// Sum performance of the threads
408
417
PerformanceIndex totalPerformance = std::accumulate (std::next (performance.begin ()), performance.end (), performance.front ());
@@ -412,7 +421,7 @@ PerformanceIndex SlpSolver::computePerformance(const std::vector<AnnotatedTime>&
412
421
413
422
slp::StepInfo SlpSolver::takeStep (const PerformanceIndex& baseline, const std::vector<AnnotatedTime>& timeDiscretization,
414
423
const vector_t & initState, const OcpSubproblemSolution& subproblemSolution, vector_array_t & x,
415
- vector_array_t & u) {
424
+ vector_array_t & u, std::vector<Metrics>& metrics ) {
416
425
using StepType = FilterLinesearch::StepType;
417
426
418
427
/*
@@ -438,13 +447,14 @@ slp::StepInfo SlpSolver::takeStep(const PerformanceIndex& baseline, const std::v
438
447
scalar_t alpha = 1.0 ;
439
448
vector_array_t xNew (x.size ());
440
449
vector_array_t uNew (u.size ());
450
+ std::vector<Metrics> metricsNew (metrics.size ());
441
451
do {
442
452
// Compute step
443
453
multiple_shooting::incrementTrajectory (u, du, alpha, uNew);
444
454
multiple_shooting::incrementTrajectory (x, dx, alpha, xNew);
445
455
446
456
// Compute cost and constraints
447
- const PerformanceIndex performanceNew = computePerformance (timeDiscretization, initState, xNew, uNew);
457
+ const PerformanceIndex performanceNew = computePerformance (timeDiscretization, initState, xNew, uNew, metricsNew );
448
458
449
459
// Step acceptance and record step type
450
460
bool stepAccepted;
@@ -462,6 +472,7 @@ slp::StepInfo SlpSolver::takeStep(const PerformanceIndex& baseline, const std::v
462
472
if (stepAccepted) { // Return if step accepted
463
473
x = std::move (xNew);
464
474
u = std::move (uNew);
475
+ metrics = std::move (metricsNew);
465
476
466
477
// Prepare step info
467
478
slp::StepInfo stepInfo;
0 commit comments