Skip to content

Commit 41b9a6a

Browse files
Extract shared CDDP and interior-point helpers
Move duplicated line-search, constraint bookkeeping, and filter logic into dedicated utility files used by the core and interior-point solvers. Add a regression test covering stale warm-start trajectory dimensions so solve() rebuilds incompatible state and control trajectories before use.
1 parent e430d00 commit 41b9a6a

9 files changed

Lines changed: 454 additions & 376 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ set(cddp_core_srcs
127127
src/cddp_core/dynamical_system.cpp
128128
src/cddp_core/objective.cpp
129129
src/cddp_core/constraint.cpp
130+
src/cddp_core/cddp_context_utils.cpp
130131
src/cddp_core/helper.cpp
132+
src/cddp_core/interior_point_utils.cpp
131133
src/cddp_core/boxqp.cpp
132134
src/cddp_core/qp_solver.cpp
133135
src/cddp_core/cddp_core.cpp
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
Copyright 2026 Tomo Sasaki
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "cddp_context_utils.hpp"
18+
19+
#include <algorithm>
20+
#include <stdexcept>
21+
22+
namespace cddp::detail {
23+
24+
namespace {
25+
26+
bool hasCompatibleVectorLayout(const std::vector<Eigen::VectorXd> &trajectory,
27+
int expected_size, int vector_dim) {
28+
return static_cast<int>(trajectory.size()) == expected_size &&
29+
std::all_of(trajectory.begin(), trajectory.end(),
30+
[vector_dim](const Eigen::VectorXd &value) {
31+
return value.size() == vector_dim;
32+
});
33+
}
34+
35+
} // namespace
36+
37+
std::vector<double> buildLineSearchAlphas(const LineSearchOptions &options) {
38+
std::vector<double> alphas;
39+
alphas.reserve(static_cast<size_t>(std::max(1, options.max_iterations)));
40+
41+
double current_alpha = options.initial_step_size;
42+
for (int i = 0; i < options.max_iterations; ++i) {
43+
alphas.push_back(current_alpha);
44+
current_alpha *= options.step_reduction_factor;
45+
if (current_alpha < options.min_step_size &&
46+
i < options.max_iterations - 1) {
47+
alphas.push_back(options.min_step_size);
48+
break;
49+
}
50+
}
51+
52+
if (alphas.empty()) {
53+
alphas.push_back(options.initial_step_size);
54+
}
55+
56+
return alphas;
57+
}
58+
59+
bool hasCompatibleWarmStartTrajectories(
60+
const CDDPOptions &options, const std::vector<Eigen::VectorXd> &states,
61+
const std::vector<Eigen::VectorXd> &controls, int horizon, int state_dim,
62+
int control_dim) {
63+
return options.warm_start &&
64+
hasCompatibleVectorLayout(states, horizon + 1, state_dim) &&
65+
hasCompatibleVectorLayout(controls, horizon, control_dim);
66+
}
67+
68+
void ensureTrajectoryShape(std::vector<Eigen::VectorXd> &trajectory,
69+
int expected_size, int vector_dim) {
70+
if (hasCompatibleVectorLayout(trajectory, expected_size, vector_dim)) {
71+
return;
72+
}
73+
74+
trajectory.assign(static_cast<size_t>(expected_size),
75+
Eigen::VectorXd::Zero(vector_dim));
76+
}
77+
78+
void addOrReplaceConstraint(
79+
std::map<std::string, std::unique_ptr<Constraint>> &constraint_set,
80+
std::string constraint_name, std::unique_ptr<Constraint> constraint,
81+
int &total_dual_dim) {
82+
if (!constraint) {
83+
throw std::runtime_error("Cannot add null constraint.");
84+
}
85+
86+
const int dual_dim = constraint->getDualDim();
87+
auto existing_constraint = constraint_set.find(constraint_name);
88+
if (existing_constraint != constraint_set.end()) {
89+
total_dual_dim -= existing_constraint->second->getDualDim();
90+
}
91+
92+
constraint_set[constraint_name] = std::move(constraint);
93+
total_dual_dim += dual_dim;
94+
}
95+
96+
bool removeConstraint(
97+
std::map<std::string, std::unique_ptr<Constraint>> &constraint_set,
98+
const std::string &constraint_name, int &total_dual_dim) {
99+
auto it = constraint_set.find(constraint_name);
100+
if (it == constraint_set.end()) {
101+
return false;
102+
}
103+
104+
total_dual_dim -= it->second->getDualDim();
105+
constraint_set.erase(it);
106+
return true;
107+
}
108+
109+
} // namespace cddp::detail
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright 2026 Tomo Sasaki
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#ifndef CDDP_CONTEXT_UTILS_HPP
18+
#define CDDP_CONTEXT_UTILS_HPP
19+
20+
#include <map>
21+
#include <memory>
22+
#include <string>
23+
#include <vector>
24+
25+
#include <Eigen/Dense>
26+
27+
#include "cddp_core/constraint.hpp"
28+
#include "cddp_core/options.hpp"
29+
30+
namespace cddp::detail {
31+
32+
std::vector<double> buildLineSearchAlphas(const LineSearchOptions &options);
33+
34+
bool hasCompatibleWarmStartTrajectories(
35+
const CDDPOptions &options, const std::vector<Eigen::VectorXd> &states,
36+
const std::vector<Eigen::VectorXd> &controls, int horizon, int state_dim,
37+
int control_dim);
38+
39+
void ensureTrajectoryShape(std::vector<Eigen::VectorXd> &trajectory,
40+
int expected_size, int vector_dim);
41+
42+
void addOrReplaceConstraint(
43+
std::map<std::string, std::unique_ptr<Constraint>> &constraint_set,
44+
std::string constraint_name, std::unique_ptr<Constraint> constraint,
45+
int &total_dual_dim);
46+
47+
bool removeConstraint(
48+
std::map<std::string, std::unique_ptr<Constraint>> &constraint_set,
49+
const std::string &constraint_name, int &total_dual_dim);
50+
51+
} // namespace cddp::detail
52+
53+
#endif // CDDP_CONTEXT_UTILS_HPP

0 commit comments

Comments
 (0)