Skip to content

Commit 5af9553

Browse files
Add additional case study of IPDDP
1 parent 91936bd commit 5af9553

4 files changed

+150
-1
lines changed

examples/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ target_link_libraries(cddp_unicycle_safe cddp)
3737
add_executable(cddp_unicycle_safe_ipddp cddp_unicycle_safe_ipddp.cpp)
3838
target_link_libraries(cddp_unicycle_safe_ipddp cddp)
3939

40+
add_executable(cddp_unicycle_safe_ipddp_v2 cddp_unicycle_safe_ipddp_v2.cpp)
41+
target_link_libraries(cddp_unicycle_safe_ipddp_v2 cddp)
42+
4043
add_executable(cddp_manipulator cddp_manipulator.cpp)
4144
target_link_libraries(cddp_manipulator cddp)
4245

examples/cddp_unicycle_safe_ipddp.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ int main() {
187187

188188
plt::xlabel("x");
189189
plt::ylabel("y");
190-
plt::title("Trajectory Compariso");
190+
plt::title("Trajectory Comparison");
191191
plt::legend();
192192

193193
// Save the comparison plot
+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
Copyright 2024 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 <iostream>
18+
#include <vector>
19+
#include <cmath>
20+
#include <filesystem>
21+
#include <memory>
22+
#include <cstdlib>
23+
24+
#include "cddp.hpp"
25+
26+
namespace plt = matplotlibcpp;
27+
namespace fs = std::filesystem;
28+
29+
int main() {
30+
// Problem parameters
31+
int state_dim = 3;
32+
int control_dim = 2;
33+
int horizon = 300;
34+
double timestep = 0.03;
35+
std::string integration_type = "euler";
36+
37+
// Create a unicycle dynamical system instance
38+
std::unique_ptr<cddp::DynamicalSystem> dyn_system = std::make_unique<cddp::Unicycle>(timestep, integration_type);
39+
40+
// Create objective function
41+
Eigen::MatrixXd Q = Eigen::MatrixXd::Zero(state_dim, state_dim);
42+
Eigen::MatrixXd R = 0.05 * Eigen::MatrixXd::Identity(control_dim, control_dim);
43+
Eigen::MatrixXd Qf = Eigen::MatrixXd::Identity(state_dim, state_dim);
44+
Qf << 100.0, 0.0, 0.0,
45+
0.0, 100.0, 0.0,
46+
0.0, 0.0, 100.0;
47+
Eigen::VectorXd goal_state(state_dim);
48+
goal_state << 3.0, 3.0, M_PI/2.0;
49+
50+
// Create an empty vector for reference states
51+
std::vector<Eigen::VectorXd> empty_reference_states;
52+
auto objective = std::make_unique<cddp::QuadraticObjective>(Q, R, Qf, goal_state, empty_reference_states, timestep);
53+
54+
// Define initial state
55+
Eigen::VectorXd initial_state(state_dim);
56+
initial_state << 0.0, 0.0, M_PI/4.0;
57+
58+
// Set up common CDDP options
59+
cddp::CDDPOptions options;
60+
options.max_iterations = 1000;
61+
options.verbose = true;
62+
options.debug = false;
63+
options.use_parallel = false;
64+
options.num_threads = 1;
65+
options.cost_tolerance = 1e-5;
66+
options.grad_tolerance = 1e-4;
67+
options.regularization_type = "both";
68+
options.regularization_control = 1e-2;
69+
options.regularization_state = 1e-3;
70+
options.barrier_coeff = 1e-1;
71+
72+
// Define control box constraint bounds
73+
Eigen::VectorXd control_upper_bound(control_dim);
74+
control_upper_bound << 1.1, M_PI;
75+
76+
// --------------------------
77+
cddp::CDDP cddp_solver(
78+
initial_state,
79+
goal_state,
80+
horizon,
81+
timestep,
82+
std::make_unique<cddp::Unicycle>(timestep, integration_type),
83+
std::make_unique<cddp::QuadraticObjective>(Q, R, Qf, goal_state, empty_reference_states, timestep),
84+
options
85+
);
86+
cddp_solver.setDynamicalSystem(std::make_unique<cddp::Unicycle>(timestep, integration_type));
87+
cddp_solver.setObjective(std::make_unique<cddp::QuadraticObjective>(Q, R, Qf, goal_state, empty_reference_states, timestep));
88+
cddp_solver.addConstraint("ControlConstraint", std::make_unique<cddp::ControlConstraint>(control_upper_bound));
89+
double radius1 = 0.4;
90+
Eigen::Vector2d center1(1.0, 1.0);
91+
cddp_solver.addConstraint("BallConstraint", std::make_unique<cddp::BallConstraint>(radius1, center1));
92+
double radius2 = 0.4;
93+
Eigen::Vector2d center2(1.5, 2.5);
94+
cddp_solver.addConstraint("BallConstraint2", std::make_unique<cddp::BallConstraint>(radius2, center2));
95+
96+
std::vector<Eigen::VectorXd> X_sol(horizon + 1, Eigen::VectorXd::Zero(state_dim));
97+
std::vector<Eigen::VectorXd> U_sol(horizon, Eigen::VectorXd::Zero(control_dim));
98+
for (int i = 0; i < horizon + 1; ++i) {
99+
X_sol[i] = initial_state;
100+
}
101+
cddp_solver.setInitialTrajectory(X_sol, U_sol);
102+
103+
cddp::CDDPSolution solution = cddp_solver.solve("IPDDP");
104+
X_sol = solution.state_sequence;
105+
U_sol = solution.control_sequence;
106+
107+
// --------------------------
108+
// Plot the trajectories for comparison
109+
std::vector<double> x_sol_plot, y_sol_plot;
110+
111+
for (const auto &state : X_sol) {
112+
x_sol_plot.push_back(state(0));
113+
y_sol_plot.push_back(state(1));
114+
}
115+
116+
plt::figure();
117+
plt::plot(x_sol_plot, y_sol_plot, {{"color", "b"}, {"linestyle", "-"}, {"label", "IPDDP"}});
118+
119+
// Also plot the ball for reference
120+
std::vector<double> t_ball, x_ball_circle, y_ball_circle;
121+
std::vector<double> t_ball2, x_ball_circle2, y_ball_circle2;
122+
for (double t = 0.0; t < 2 * M_PI; t += 0.01) {
123+
t_ball.push_back(t);
124+
x_ball_circle.push_back(center1(0) + radius1 * cos(t));
125+
y_ball_circle.push_back(center1(1) + radius1 * sin(t));
126+
x_ball_circle2.push_back(center2(0) + radius2 * cos(t));
127+
y_ball_circle2.push_back(center2(1) + radius2 * sin(t));
128+
}
129+
plt::plot(x_ball_circle, y_ball_circle, {{"color", "g"}, {"linestyle", "--"}, {"label", "Ball Constraint"}});
130+
plt::plot(x_ball_circle2, y_ball_circle2, {{"color", "g"}, {"linestyle", "--"}});
131+
plt::grid(true);
132+
plt::xlabel("x");
133+
plt::ylabel("y");
134+
plt::title("IPDDP safe trajectory");
135+
plt::legend();
136+
137+
// Save the comparison plot
138+
std::string plotDirectory = "../results/tests";
139+
if (!fs::exists(plotDirectory)) {
140+
fs::create_directory(plotDirectory);
141+
}
142+
plt::save(plotDirectory + "/trajectory_comparison_ipddp_v2.png");
143+
std::cout << "Trajectory comparison saved to " << plotDirectory + "/trajectory_comparison_ipddp_v2.png" << std::endl;
144+
145+
return 0;
146+
}
31.5 KB
Loading

0 commit comments

Comments
 (0)