Skip to content

Commit 6b43b13

Browse files
Extracting problemMetrics for SLP
1 parent 25942ba commit 6b43b13

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

ocs2_slp/include/ocs2_slp/SlpSolver.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ class SlpSolver : public SolverBase {
6565

6666
void getPrimalSolution(scalar_t finalTime, PrimalSolution* primalSolutionPtr) const override { *primalSolutionPtr = primalSolution_; }
6767

68-
const ProblemMetrics& getSolutionMetrics() const override {
69-
throw std::runtime_error("[SlpSolver] getSolutionMetrics() not available yet.");
70-
}
68+
const ProblemMetrics& getSolutionMetrics() const override { return problemMetrics_; }
7169

7270
size_t getNumIterations() const override { return totalNumIterations_; }
7371

@@ -124,11 +122,11 @@ class SlpSolver : public SolverBase {
124122

125123
/** Creates QP around t, x(t), u(t). Returns performance metrics at the current {t, x(t), u(t)} */
126124
PerformanceIndex setupQuadraticSubproblem(const std::vector<AnnotatedTime>& time, const vector_t& initState, const vector_array_t& x,
127-
const vector_array_t& u);
125+
const vector_array_t& u, std::vector<Metrics>& metrics);
128126

129127
/** Computes only the performance metrics at the current {t, x(t), u(t)} */
130128
PerformanceIndex computePerformance(const std::vector<AnnotatedTime>& time, const vector_t& initState, const vector_array_t& x,
131-
const vector_array_t& u);
129+
const vector_array_t& u, std::vector<Metrics>& metrics);
132130

133131
/** Returns solution of the QP subproblem in delta coordinates: */
134132
struct OcpSubproblemSolution {
@@ -143,7 +141,8 @@ class SlpSolver : public SolverBase {
143141

144142
/** Decides on the step to take and overrides given trajectories {x(t), u(t)} <- {x(t) + a*dx(t), u(t) + a*du(t)} */
145143
slp::StepInfo takeStep(const PerformanceIndex& baseline, const std::vector<AnnotatedTime>& timeDiscretization, const vector_t& initState,
146-
const OcpSubproblemSolution& subproblemSolution, vector_array_t& x, vector_array_t& u);
144+
const OcpSubproblemSolution& subproblemSolution, vector_array_t& x, vector_array_t& u,
145+
std::vector<Metrics>& metrics);
147146

148147
/** Determine convergence after a step */
149148
slp::Convergence checkConvergence(int iteration, const PerformanceIndex& baseline, const slp::StepInfo& stepInfo) const;
@@ -179,6 +178,9 @@ class SlpSolver : public SolverBase {
179178
// Iteration performance log
180179
std::vector<PerformanceIndex> performanceIndeces_;
181180

181+
// The ProblemMetrics associated to primalSolution_
182+
ProblemMetrics problemMetrics_;
183+
182184
// Benchmarking
183185
size_t numProblems_{0};
184186
size_t totalNumIterations_{0};

ocs2_slp/src/SlpSolver.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3535

3636
#include <ocs2_oc/multiple_shooting/Helpers.h>
3737
#include <ocs2_oc/multiple_shooting/Initialization.h>
38+
#include <ocs2_oc/multiple_shooting/MetricsComputation.h>
3839
#include <ocs2_oc/multiple_shooting/PerformanceIndexComputation.h>
3940
#include <ocs2_oc/multiple_shooting/Transcription.h>
4041
#include <ocs2_oc/precondition/Ruzi.h>
@@ -177,6 +178,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
177178

178179
// Bookkeeping
179180
performanceIndeces_.clear();
181+
std::vector<Metrics> metrics;
180182

181183
int iter = 0;
182184
slp::Convergence convergence = slp::Convergence::FALSE;
@@ -186,7 +188,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
186188
}
187189
// Make QP approximation
188190
linearQuadraticApproximationTimer_.startTimer();
189-
const auto baselinePerformance = setupQuadraticSubproblem(timeDiscretization, initState, x, u);
191+
const auto baselinePerformance = setupQuadraticSubproblem(timeDiscretization, initState, x, u, metrics);
190192
linearQuadraticApproximationTimer_.endTimer();
191193

192194
// Solve LP
@@ -197,7 +199,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
197199

198200
// Apply step
199201
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);
201203
performanceIndeces_.push_back(stepInfo.performanceAfterStep);
202204
linesearchTimer_.endTimer();
203205

@@ -211,6 +213,7 @@ void SlpSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
211213

212214
computeControllerTimer_.startTimer();
213215
primalSolution_ = toPrimalSolution(timeDiscretization, std::move(x), std::move(u));
216+
problemMetrics_ = multiple_shooting::toProblemMetrics(timeDiscretization, std::move(metrics));
214217
computeControllerTimer_.endTimer();
215218

216219
++numProblems_;
@@ -290,7 +293,7 @@ PrimalSolution SlpSolver::toPrimalSolution(const std::vector<AnnotatedTime>& tim
290293
}
291294

292295
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) {
294297
// Problem horizon
295298
const int N = static_cast<int>(time.size()) - 1;
296299

@@ -302,6 +305,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
302305
stateInputIneqConstraints_.resize(N);
303306
constraintsProjection_.resize(N);
304307
projectionMultiplierCoefficients_.resize(N);
308+
metrics.resize(N + 1);
305309

306310
std::atomic_int timeIndex{0};
307311
auto parallelTask = [&](int workerId) {
@@ -314,6 +318,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
314318
if (time[i].event == AnnotatedTime::Event::PreEvent) {
315319
// Event node
316320
auto result = multiple_shooting::setupEventNode(ocpDefinition, time[i].time, x[i], x[i + 1]);
321+
metrics[i] = multiple_shooting::computeMetrics(result);
317322
workerPerformance += multiple_shooting::computePerformanceIndex(result);
318323
cost_[i] = std::move(result.cost);
319324
dynamics_[i] = std::move(result.dynamics);
@@ -327,6 +332,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
327332
const scalar_t ti = getIntervalStart(time[i]);
328333
const scalar_t dt = getIntervalDuration(time[i], time[i + 1]);
329334
auto result = multiple_shooting::setupIntermediateNode(ocpDefinition, sensitivityDiscretizer_, ti, dt, x[i], x[i + 1], u[i]);
335+
metrics[i] = multiple_shooting::computeMetrics(result);
330336
workerPerformance += multiple_shooting::computePerformanceIndex(result, dt);
331337
multiple_shooting::projectTranscription(result, settings_.extractProjectionMultiplier);
332338
cost_[i] = std::move(result.cost);
@@ -344,6 +350,7 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
344350
if (i == N) { // Only one worker will execute this
345351
const scalar_t tN = getIntervalStart(time[N]);
346352
auto result = multiple_shooting::setupTerminalNode(ocpDefinition, tN, x[N]);
353+
metrics[i] = multiple_shooting::computeMetrics(result);
347354
workerPerformance += multiple_shooting::computePerformanceIndex(result);
348355
cost_[i] = std::move(result.cost);
349356
stateIneqConstraints_[i] = std::move(result.ineqConstraints);
@@ -365,44 +372,46 @@ PerformanceIndex SlpSolver::setupQuadraticSubproblem(const std::vector<Annotated
365372
}
366373

367374
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
370377
const int N = static_cast<int>(time.size()) - 1;
378+
metrics.resize(N + 1);
371379

372380
std::vector<PerformanceIndex> performance(settings_.nThreads, PerformanceIndex());
373381
std::atomic_int timeIndex{0};
374382
auto parallelTask = [&](int workerId) {
375383
// Get worker specific resources
376384
OptimalControlProblem& ocpDefinition = ocpDefinitions_[workerId];
377-
PerformanceIndex workerPerformance; // Accumulate performance in local variable
378385

379386
int i = timeIndex++;
380387
while (i < N) {
381388
if (time[i].event == AnnotatedTime::Event::PreEvent) {
382389
// 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]);
384392
} else {
385393
// Normal, intermediate node
386394
const scalar_t ti = getIntervalStart(time[i]);
387395
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);
389398
}
390399

391400
i = timeIndex++;
392401
}
393402

394403
if (i == N) { // Only one worker will execute this
395404
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]);
397407
}
398-
399-
// Accumulate! Same worker might run multiple tasks
400-
performance[workerId] += workerPerformance;
401408
};
402409
runParallel(std::move(parallelTask));
403410

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();
406415

407416
// Sum performance of the threads
408417
PerformanceIndex totalPerformance = std::accumulate(std::next(performance.begin()), performance.end(), performance.front());
@@ -412,7 +421,7 @@ PerformanceIndex SlpSolver::computePerformance(const std::vector<AnnotatedTime>&
412421

413422
slp::StepInfo SlpSolver::takeStep(const PerformanceIndex& baseline, const std::vector<AnnotatedTime>& timeDiscretization,
414423
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) {
416425
using StepType = FilterLinesearch::StepType;
417426

418427
/*
@@ -438,13 +447,14 @@ slp::StepInfo SlpSolver::takeStep(const PerformanceIndex& baseline, const std::v
438447
scalar_t alpha = 1.0;
439448
vector_array_t xNew(x.size());
440449
vector_array_t uNew(u.size());
450+
std::vector<Metrics> metricsNew(metrics.size());
441451
do {
442452
// Compute step
443453
multiple_shooting::incrementTrajectory(u, du, alpha, uNew);
444454
multiple_shooting::incrementTrajectory(x, dx, alpha, xNew);
445455

446456
// Compute cost and constraints
447-
const PerformanceIndex performanceNew = computePerformance(timeDiscretization, initState, xNew, uNew);
457+
const PerformanceIndex performanceNew = computePerformance(timeDiscretization, initState, xNew, uNew, metricsNew);
448458

449459
// Step acceptance and record step type
450460
bool stepAccepted;
@@ -462,6 +472,7 @@ slp::StepInfo SlpSolver::takeStep(const PerformanceIndex& baseline, const std::v
462472
if (stepAccepted) { // Return if step accepted
463473
x = std::move(xNew);
464474
u = std::move(uNew);
475+
metrics = std::move(metricsNew);
465476

466477
// Prepare step info
467478
slp::StepInfo stepInfo;

ocs2_sqp/ocs2_sqp/src/SqpSolver.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ PerformanceIndex SqpSolver::computePerformance(const std::vector<AnnotatedTime>&
372372
const vector_array_t& u, std::vector<Metrics>& metrics) {
373373
// Problem size
374374
const int N = static_cast<int>(time.size()) - 1;
375-
metrics.clear();
376375
metrics.resize(N + 1);
377376

378377
std::vector<PerformanceIndex> performance(settings_.nThreads, PerformanceIndex());

0 commit comments

Comments
 (0)