Skip to content

Commit 5cc9bba

Browse files
committed
refactored slack and dual initialization
1 parent 6a3d7ce commit 5cc9bba

File tree

5 files changed

+43
-66
lines changed

5 files changed

+43
-66
lines changed

ocs2_ipm/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ if(cmake_clang_tools_FOUND)
7373
TARGETS ${PROJECT_NAME}
7474
SOURCE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/test
7575
CT_HEADER_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include
76-
CF_WERROR
76+
CF_FIX
7777
)
7878
endif(cmake_clang_tools_FOUND)
7979

ocs2_ipm/include/ocs2_ipm/IpmHelpers.h

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -115,36 +115,20 @@ scalar_t fractionToBoundaryStepSize(const vector_t& v, const vector_t& dv, scala
115115
*
116116
* @param time: The time discretization.
117117
* @param constraintsSize: The constraint tems size.
118-
* @param slackStateIneq: The slack variable trajectory of the state inequality constraints.
119-
* @param dualStateIneq: The dual variable trajectory of the state inequality constraints.
120-
* @param slackStateInputIneq: The slack variable trajectory of the state-input inequality constraints.
121-
* @param dualStateInputIneq: The dual variable trajectory of the state-input inequality constraints.
118+
* @param stateIneq: The slack/dual variable trajectory of the state inequality constraints.
119+
* @param stateInputIneq: The slack/dual variable trajectory of the state-input inequality constraints.
122120
* @return A dual solution.
123121
*/
124122
DualSolution toDualSolution(const std::vector<AnnotatedTime>& time, const std::vector<multiple_shooting::ConstraintsSize>& constraintsSize,
125-
const vector_array_t& slackStateIneq, const vector_array_t& dualStateIneq,
126-
const vector_array_t& slackStateInputIneq, const vector_array_t& dualStateInputIneq);
123+
const vector_array_t& stateIneq, const vector_array_t& stateInputIneq);
127124

128125
/**
129-
* Extracts a slack variable of the state-only and state-input constraints from a MultiplierCollection
126+
* Extracts slack/dual variables of the state-only and state-input constraints from a MultiplierCollection
130127
*
131-
* @param[in] multiplierCollection: The MultiplierCollection.
132-
* @param[out] slackStateIneq: The slack variable of the state inequality constraints.
133-
* @param[out] dualStateIneq: The dual variable of the state inequality constraints.
134-
* @param[out] slackStateInputIneq: The slack variable of the state-input inequality constraints.
135-
* @param[out] dualStateInputIneq: The dual variable of the state-input inequality constraints.
128+
* @param multiplierCollection: The MultiplierCollection.
129+
* @return slack/dual variables of the state-only (first) and state-input constraints (second).
136130
*/
137-
void toSlackDual(const MultiplierCollection& multiplierCollection, vector_t& slackStateIneq, vector_t& dualStateIneq,
138-
vector_t& slackStateInputIneq, vector_t& dualStateInputIneq);
139-
140-
/**
141-
* Extracts a slack variable of the state-only constraints from a MultiplierCollection
142-
*
143-
* @param[in] multiplierCollection: The MultiplierCollection.
144-
* @param[out] slackStateIneq: The slack variable of the state inequality constraints.
145-
* @param[out] dualStateIneq: The dual variable of the state inequality constraints.
146-
*/
147-
void toSlackDual(const MultiplierCollection& multiplierCollection, vector_t& slackStateIneq, vector_t& dualStateIneq);
131+
std::pair<vector_t, vector_t> fromDualSolution(const MultiplierCollection& multiplierCollection);
148132

149133
} // namespace ipm
150134
} // namespace ocs2

ocs2_ipm/include/ocs2_ipm/IpmSolver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ class IpmSolver : public SolverBase {
202202
PrimalSolution primalSolution_;
203203
vector_array_t costateTrajectory_;
204204
vector_array_t projectionMultiplierTrajectory_;
205-
DualSolution slackDualTrajectory_;
205+
DualSolution slackIneqTrajectory_;
206+
DualSolution dualIneqTrajectory_;
206207

207208
// Value function in absolute state coordinates (without the constant value)
208209
std::vector<ScalarFunctionQuadraticApproximation> valueFunction_;

ocs2_ipm/src/IpmHelpers.cpp

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -114,26 +114,23 @@ scalar_t fractionToBoundaryStepSize(const vector_t& v, const vector_t& dv, scala
114114
}
115115

116116
namespace {
117-
MultiplierCollection toMultiplierCollection(const multiple_shooting::ConstraintsSize constraintsSize, const vector_t& slackStateIneq,
118-
const vector_t& dualStateIneq) {
117+
MultiplierCollection toMultiplierCollection(const multiple_shooting::ConstraintsSize constraintsSize, const vector_t& stateIneq) {
119118
MultiplierCollection multiplierCollection;
120119
size_t head = 0;
121120
for (const size_t size : constraintsSize.stateIneq) {
122-
multiplierCollection.stateIneq.emplace_back(0.0, slackStateIneq.segment(head, size));
123-
multiplierCollection.stateEq.emplace_back(0.0, dualStateIneq.segment(head, size));
121+
multiplierCollection.stateIneq.emplace_back(0.0, stateIneq.segment(head, size));
124122
head += size;
125123
}
126124
return multiplierCollection;
127125
}
128126

129-
MultiplierCollection toMultiplierCollection(const multiple_shooting::ConstraintsSize constraintsSize, const vector_t& slackStateIneq,
130-
const vector_t& dualStateIneq, const vector_t& slackStateInputIneq,
131-
const vector_t& dualStateInputIneq) {
132-
MultiplierCollection multiplierCollection = toMultiplierCollection(constraintsSize, slackStateIneq, dualStateIneq);
127+
MultiplierCollection toMultiplierCollection(const multiple_shooting::ConstraintsSize constraintsSize, const vector_t& stateIneq,
128+
const vector_t& stateInputIneq) {
129+
MultiplierCollection multiplierCollection = toMultiplierCollection(constraintsSize, stateIneq);
133130
size_t head = 0;
134131
for (const size_t size : constraintsSize.stateInputIneq) {
135-
multiplierCollection.stateInputIneq.emplace_back(0.0, slackStateInputIneq.segment(head, size));
136-
multiplierCollection.stateInputEq.emplace_back(0.0, dualStateInputIneq.segment(head, size));
132+
multiplierCollection.stateInputIneq.emplace_back(0.0, stateInputIneq.segment(head, size));
133+
head += size;
137134
}
138135
return multiplierCollection;
139136
}
@@ -153,22 +150,8 @@ vector_t extractLagrangian(const std::vector<Multiplier>& termsMultiplier) {
153150
}
154151
} // namespace
155152

156-
void toSlackDual(const MultiplierCollection& multiplierCollection, vector_t& slackStateIneq, vector_t& dualStateIneq,
157-
vector_t& slackStateInputIneq, vector_t& dualStateInputIneq) {
158-
slackStateIneq = extractLagrangian(multiplierCollection.stateIneq);
159-
dualStateIneq = extractLagrangian(multiplierCollection.stateEq);
160-
slackStateInputIneq = extractLagrangian(multiplierCollection.stateInputIneq);
161-
dualStateInputIneq = extractLagrangian(multiplierCollection.stateInputEq);
162-
}
163-
164-
void toSlackDual(const MultiplierCollection& multiplierCollection, vector_t& slackStateIneq, vector_t& dualStateIneq) {
165-
slackStateIneq = extractLagrangian(multiplierCollection.stateIneq);
166-
dualStateIneq = extractLagrangian(multiplierCollection.stateEq);
167-
}
168-
169153
DualSolution toDualSolution(const std::vector<AnnotatedTime>& time, const std::vector<multiple_shooting::ConstraintsSize>& constraintsSize,
170-
const vector_array_t& slackStateIneq, const vector_array_t& dualStateIneq,
171-
const vector_array_t& slackStateInputIneq, const vector_array_t& dualStateInputIneq) {
154+
const vector_array_t& stateIneq, const vector_array_t& stateInputIneq) {
172155
// Problem horizon
173156
const int N = static_cast<int>(time.size()) - 1;
174157

@@ -181,18 +164,21 @@ DualSolution toDualSolution(const std::vector<AnnotatedTime>& time, const std::v
181164

182165
for (int i = 0; i < N; ++i) {
183166
if (time[i].event == AnnotatedTime::Event::PreEvent) {
184-
dualSolution.preJumps.emplace_back(toMultiplierCollection(constraintsSize[i], slackStateIneq[i], dualStateIneq[i]));
167+
dualSolution.preJumps.emplace_back(toMultiplierCollection(constraintsSize[i], stateIneq[i]));
185168
dualSolution.intermediates.push_back(dualSolution.intermediates.back()); // no event at the initial node
186169
} else {
187-
dualSolution.intermediates.emplace_back(
188-
toMultiplierCollection(constraintsSize[i], slackStateIneq[i], dualStateIneq[i], slackStateInputIneq[i], dualStateInputIneq[i]));
170+
dualSolution.intermediates.emplace_back(toMultiplierCollection(constraintsSize[i], stateIneq[i], stateInputIneq[i]));
189171
}
190172
}
191-
dualSolution.final = toMultiplierCollection(constraintsSize[N], slackStateIneq[N], dualStateIneq[N]);
173+
dualSolution.final = toMultiplierCollection(constraintsSize[N], stateIneq[N]);
192174
dualSolution.intermediates.push_back(dualSolution.intermediates.back());
193175

194176
return dualSolution;
195177
}
196178

179+
std::pair<vector_t, vector_t> fromDualSolution(const MultiplierCollection& multiplierCollection) {
180+
return std::make_pair(extractLagrangian(multiplierCollection.stateIneq), extractLagrangian(multiplierCollection.stateInputIneq));
181+
}
182+
197183
} // namespace ipm
198184
} // namespace ocs2

ocs2_ipm/src/IpmSolver.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ void IpmSolver::reset() {
100100
primalSolution_ = PrimalSolution();
101101
costateTrajectory_.clear();
102102
projectionMultiplierTrajectory_.clear();
103-
slackDualTrajectory_.clear();
103+
slackIneqTrajectory_.clear();
104+
dualIneqTrajectory_.clear();
104105
valueFunction_.clear();
105106
performanceIndeces_.clear();
106107

@@ -215,8 +216,9 @@ void IpmSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
215216
multiple_shooting::initializeStateInputTrajectories(initState, timeDiscretization, primalSolution_, *initializerPtr_, x, u);
216217

217218
// Initialize the slack and dual variables of the interior point method
218-
if (!slackDualTrajectory_.timeTrajectory.empty()) {
219-
std::ignore = trajectorySpread(oldModeSchedule, newModeSchedule, slackDualTrajectory_);
219+
if (!slackIneqTrajectory_.timeTrajectory.empty()) {
220+
std::ignore = trajectorySpread(oldModeSchedule, newModeSchedule, slackIneqTrajectory_);
221+
std::ignore = trajectorySpread(oldModeSchedule, newModeSchedule, dualIneqTrajectory_);
220222
}
221223
scalar_t barrierParam = settings_.initialBarrierParameter;
222224
vector_array_t slackStateIneq, dualStateIneq, slackStateInputIneq, dualStateInputIneq;
@@ -281,8 +283,8 @@ void IpmSolver::runImpl(scalar_t initTime, const vector_t& initState, scalar_t f
281283
primalSolution_ = toPrimalSolution(timeDiscretization, std::move(x), std::move(u));
282284
costateTrajectory_ = std::move(lmd);
283285
projectionMultiplierTrajectory_ = std::move(nu);
284-
slackDualTrajectory_ =
285-
ipm::toDualSolution(timeDiscretization, constraintsSize_, slackStateIneq, dualStateIneq, slackStateInputIneq, dualStateInputIneq);
286+
slackIneqTrajectory_ = ipm::toDualSolution(timeDiscretization, constraintsSize_, slackStateIneq, slackStateInputIneq);
287+
dualIneqTrajectory_ = ipm::toDualSolution(timeDiscretization, constraintsSize_, dualStateIneq, dualStateInputIneq);
286288
problemMetrics_ = multiple_shooting::toProblemMetrics(timeDiscretization, std::move(metrics));
287289
computeControllerTimer_.endTimer();
288290

@@ -374,8 +376,8 @@ void IpmSolver::initializeSlackDualTrajectory(const std::vector<AnnotatedTime>&
374376
const vector_array_t& u, scalar_t barrierParam, vector_array_t& slackStateIneq,
375377
vector_array_t& dualStateIneq, vector_array_t& slackStateInputIneq,
376378
vector_array_t& dualStateInputIneq) {
377-
const auto& oldTimeTrajectory = slackDualTrajectory_.timeTrajectory;
378-
const auto& oldPostEventIndices = slackDualTrajectory_.postEventIndices;
379+
const auto& oldTimeTrajectory = slackIneqTrajectory_.timeTrajectory;
380+
const auto& oldPostEventIndices = slackIneqTrajectory_.postEventIndices;
379381
const auto newTimeTrajectory = toInterpolationTime(timeDiscretization);
380382
const auto newPostEventIndices = toPostEventIndices(timeDiscretization);
381383

@@ -404,8 +406,9 @@ void IpmSolver::initializeSlackDualTrajectory(const std::vector<AnnotatedTime>&
404406
for (size_t i = 0; i < N; i++) {
405407
if (timeDiscretization[i].event == AnnotatedTime::Event::PreEvent) {
406408
const auto cachedEventIndex = cacheEventIndexBias + eventIdx;
407-
if (cachedEventIndex < slackDualTrajectory_.preJumps.size()) {
408-
ipm::toSlackDual(std::move(slackDualTrajectory_.preJumps[cachedEventIndex]), slackStateIneq[i], dualStateIneq[i]);
409+
if (cachedEventIndex < slackIneqTrajectory_.preJumps.size()) {
410+
std::tie(slackStateIneq[i], std::ignore) = ipm::fromDualSolution(slackIneqTrajectory_.preJumps[cachedEventIndex]);
411+
std::tie(dualStateIneq[i], std::ignore) = ipm::fromDualSolution(dualIneqTrajectory_.preJumps[cachedEventIndex]);
409412
} else {
410413
const auto time = getIntervalStart(timeDiscretization[i]);
411414
const auto& state = x[i];
@@ -429,8 +432,10 @@ void IpmSolver::initializeSlackDualTrajectory(const std::vector<AnnotatedTime>&
429432
} else {
430433
const auto time = getIntervalStart(timeDiscretization[i]);
431434
if (interpolatableTimePeriod.first <= time && time <= interpolatableTimePeriod.second) {
432-
ipm::toSlackDual(getIntermediateDualSolutionAtTime(slackDualTrajectory_, time), slackStateIneq[i], dualStateIneq[i],
433-
slackStateInputIneq[i], dualStateInputIneq[i]);
435+
std::tie(slackStateIneq[i], slackStateInputIneq[i]) =
436+
ipm::fromDualSolution(getIntermediateDualSolutionAtTime(slackIneqTrajectory_, time));
437+
std::tie(dualStateIneq[i], dualStateInputIneq[i]) =
438+
ipm::fromDualSolution(getIntermediateDualSolutionAtTime(slackIneqTrajectory_, time));
434439
} else {
435440
constexpr auto request = Request::Constraint;
436441
const auto& state = x[i];
@@ -463,7 +468,8 @@ void IpmSolver::initializeSlackDualTrajectory(const std::vector<AnnotatedTime>&
463468
}
464469

465470
if (interpolateTillFinalTime) {
466-
ipm::toSlackDual(std::move(slackDualTrajectory_.final), slackStateIneq[N], dualStateIneq[N]);
471+
std::tie(slackStateIneq[N], std::ignore) = ipm::fromDualSolution(slackIneqTrajectory_.final);
472+
std::tie(dualStateIneq[N], std::ignore) = ipm::fromDualSolution(dualIneqTrajectory_.final);
467473
} else {
468474
const auto time = newTimeTrajectory[N];
469475
const auto& state = x[N];

0 commit comments

Comments
 (0)