Skip to content

Commit 3825614

Browse files
committed
refactore Ipm
1 parent ec559e4 commit 3825614

File tree

2 files changed

+26
-25
lines changed

2 files changed

+26
-25
lines changed

ocs2_ipm/include/ocs2_ipm/IpmSolver.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,10 @@ class IpmSolver : public SolverBase {
139139

140140
/** Returns solution of the QP subproblem in delta coordinates: */
141141
struct OcpSubproblemSolution {
142-
vector_array_t deltaXSol; // delta_x(t)
143-
vector_array_t deltaUSol; // delta_u(t)
144-
vector_array_t deltaNuSol; // delta_nu(t)
142+
vector_array_t deltaXSol; // delta_x(t)
143+
vector_array_t deltaUSol; // delta_u(t)
144+
vector_array_t deltaLmdSol; // delta_lmd(t)
145+
vector_array_t deltaNuSol; // delta_nu(t)
145146
vector_array_t deltaSlackStateIneq;
146147
vector_array_t deltaSlackStateInputIneq;
147148
vector_array_t deltaDualStateIneq;
@@ -156,7 +157,7 @@ class IpmSolver : public SolverBase {
156157

157158
/** Extract the value function based on the last solved QP */
158159
void extractValueFunction(const std::vector<AnnotatedTime>& time, const vector_array_t& x, const vector_array_t& lmd,
159-
const vector_array_t& deltaXSol, vector_array_t& deltaLmdSol);
160+
const vector_array_t& deltaXSol);
160161

161162
/** Constructs the primal solution based on the optimized state and input trajectories */
162163
PrimalSolution toPrimalSolution(const std::vector<AnnotatedTime>& time, vector_array_t&& x, vector_array_t&& u);

ocs2_ipm/src/IpmSolver.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,7 @@ void IpmSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
230230
const vector_t delta_x0 = initState - x[0];
231231
const auto deltaSolution =
232232
getOCPSolution(delta_x0, barrierParam, slackStateIneq, slackStateInputIneq, dualStateIneq, dualStateInputIneq);
233-
vector_array_t deltaLmdSol;
234-
extractValueFunction(timeDiscretization, x, lmd, deltaSolution.deltaXSol, deltaLmdSol);
233+
extractValueFunction(timeDiscretization, x, lmd, deltaSolution.deltaXSol);
235234
solveQpTimer_.endTimer();
236235

237236
// Apply step
@@ -243,23 +242,16 @@ void IpmSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
243242
slackStateInputIneq, metrics);
244243
const scalar_t dualStepSize =
245244
settings_.usePrimalStepSizeForDual ? std::min(stepInfo.stepSize, deltaSolution.maxDualStepSize) : deltaSolution.maxDualStepSize;
246-
performanceIndeces_.push_back(stepInfo.performanceAfterStep);
247245
if (settings_.computeLagrangeMultipliers) {
248-
multiple_shooting::incrementTrajectory(lmd, deltaLmdSol, stepInfo.stepSize, lmd);
246+
multiple_shooting::incrementTrajectory(lmd, deltaSolution.deltaLmdSol, stepInfo.stepSize, lmd);
249247
if (settings_.projectStateInputEqualityConstraints) {
250-
// Remaining term that depends on the costate
251-
auto deltaNuSol = std::move(deltaSolution.deltaNuSol);
252-
for (int i = 0; i < nu.size(); i++) {
253-
if (nu[i].size() > 0) {
254-
deltaNuSol[i].noalias() += projectionMultiplierCoefficients_[i].dfdcostate * deltaLmdSol[i + 1];
255-
}
256-
}
257-
multiple_shooting::incrementTrajectory(nu, deltaNuSol, stepInfo.stepSize, nu);
248+
multiple_shooting::incrementTrajectory(nu, deltaSolution.deltaNuSol, stepInfo.stepSize, nu);
258249
}
259250
}
260251
multiple_shooting::incrementTrajectory(dualStateIneq, deltaSolution.deltaDualStateIneq, stepInfo.stepSize, dualStateIneq);
261252
multiple_shooting::incrementTrajectory(dualStateInputIneq, deltaSolution.deltaDualStateInputIneq, stepInfo.stepSize,
262253
dualStateInputIneq);
254+
performanceIndeces_.push_back(stepInfo.performanceAfterStep);
263255
linesearchTimer_.endTimer();
264256

265257
// Check convergence
@@ -393,6 +385,20 @@ IpmSolver::OcpSubproblemSolution IpmSolver::getOCPSolution(const vector_t& delta
393385
// to determine if the solution is a descent direction for the cost: compute gradient(cost)' * [dx; du]
394386
solution.armijoDescentMetric = armijoDescentMetric(lagrangian_, deltaXSol, deltaUSol);
395387

388+
// Extract value function
389+
auto& deltaLmdSol = solution.deltaLmdSol;
390+
if (settings_.createValueFunction) {
391+
valueFunction_ = hpipmInterface_.getRiccatiCostToGo(dynamics_[0], lagrangian_[0]);
392+
// Extract costate directions
393+
if (settings_.computeLagrangeMultipliers) {
394+
deltaLmdSol.resize(deltaXSol.size());
395+
for (int i = 0; i < deltaXSol.size(); ++i) {
396+
deltaLmdSol[i] = valueFunction_[i].dfdx;
397+
deltaLmdSol[i].noalias() += valueFunction_[i].dfdxx * deltaXSol[i];
398+
}
399+
}
400+
}
401+
396402
// Problem horizon
397403
const int N = static_cast<int>(deltaXSol.size()) - 1;
398404

@@ -436,6 +442,7 @@ IpmSolver::OcpSubproblemSolution IpmSolver::getOCPSolution(const vector_t& delta
436442
deltaNuSol[i] = projectionMultiplierCoefficients_[i].f;
437443
deltaNuSol[i].noalias() += projectionMultiplierCoefficients_[i].dfdx * deltaXSol[i];
438444
deltaNuSol[i].noalias() += projectionMultiplierCoefficients_[i].dfdu * deltaUSol[i];
445+
deltaNuSol[i].noalias() += projectionMultiplierCoefficients_[i].dfdcostate * deltaLmdSol[i + 1];
439446
}
440447
// Re-map the projected input back to the original space.
441448
tmp.noalias() = constraintsProjection_[i].dfdu * deltaUSol[i];
@@ -465,16 +472,9 @@ IpmSolver::OcpSubproblemSolution IpmSolver::getOCPSolution(const vector_t& delta
465472
}
466473

467474
void IpmSolver::extractValueFunction(const std::vector<AnnotatedTime>& time, const vector_array_t& x, const vector_array_t& lmd,
468-
const vector_array_t& deltaXSol, vector_array_t& deltaLmdSol) {
475+
const vector_array_t& deltaXSol) {
469476
if (settings_.createValueFunction) {
470-
valueFunction_ = hpipmInterface_.getRiccatiCostToGo(dynamics_[0], lagrangian_[0]);
471-
// Compute costate directions
472-
deltaLmdSol.resize(deltaXSol.size());
473-
for (int i = 0; i < time.size(); ++i) {
474-
deltaLmdSol[i] = valueFunction_[i].dfdx;
475-
deltaLmdSol[i].noalias() += valueFunction_[i].dfdxx * x[i];
476-
}
477-
// Correct for linearization state
477+
// Correct for linearization state. Naive value function of hpipm is already extracted and stored in valueFunction_ in getOCPSolution().
478478
for (int i = 0; i < time.size(); ++i) {
479479
valueFunction_[i].dfdx.noalias() -= valueFunction_[i].dfdxx * x[i];
480480
if (settings_.computeLagrangeMultipliers) {

0 commit comments

Comments
 (0)