43 #include <ilqgames/constraint/single_dimension_constraint.h> 44 #include <ilqgames/cost/extreme_value_cost.h> 45 #include <ilqgames/cost/quadratic_cost.h> 46 #include <ilqgames/cost/signed_distance_cost.h> 47 #include <ilqgames/dynamics/concatenated_dynamical_system.h> 48 #include <ilqgames/dynamics/single_player_car_5d.h> 49 #include <ilqgames/examples/three_player_collision_avoidance_reachability_example.h> 50 #include <ilqgames/geometry/draw_shapes.h> 51 #include <ilqgames/geometry/polyline2.h> 52 #include <ilqgames/solver/ilq_solver.h> 53 #include <ilqgames/solver/problem.h> 54 #include <ilqgames/solver/solver_params.h> 55 #include <ilqgames/utils/types.h> 62 DEFINE_double(d0, 5.0,
"Initial distance from the origin (m).");
63 DEFINE_double(v0, 5.0,
"Initial speed (m/s).");
66 DEFINE_double(buffer, 3.0,
"Nominal signed distance cost (m).");
73 static constexpr
float kOmegaMax = 1.0;
74 static constexpr
float kAMax = 0.1;
75 static constexpr
float kControlCostWeight = 0.1;
78 using P1 = SinglePlayerCar5D;
79 using P2 = SinglePlayerCar5D;
80 using P3 = SinglePlayerCar5D;
81 static constexpr
float kInterAxleDistance = 4.0;
83 static const Dimension kP1XIdx = P1::kPxIdx;
84 static const Dimension kP1YIdx = P1::kPyIdx;
85 static const Dimension kP1HeadingIdx = P1::kThetaIdx;
86 static const Dimension kP1VIdx = P1::kVIdx;
88 static const Dimension kP2XIdx = P1::kNumXDims + P2::kPxIdx;
89 static const Dimension kP2YIdx = P1::kNumXDims + P2::kPyIdx;
90 static const Dimension kP2HeadingIdx = P1::kNumXDims + P2::kThetaIdx;
91 static const Dimension kP2VIdx = P1::kNumXDims + P2::kVIdx;
93 static const Dimension kP3XIdx = P1::kNumXDims + P2::kNumXDims + P3::kPxIdx;
94 static const Dimension kP3YIdx = P1::kNumXDims + P2::kNumXDims + P3::kPyIdx;
95 static const Dimension kP3HeadingIdx =
96 P1::kNumXDims + P2::kNumXDims + P3::kThetaIdx;
97 static const Dimension kP3VIdx = P1::kNumXDims + P2::kNumXDims + P3::kVIdx;
101 void ThreePlayerCollisionAvoidanceReachabilityExample::ConstructDynamics() {
102 dynamics_.reset(
new ConcatenatedDynamicalSystem(
103 {std::make_shared<P1>(kInterAxleDistance),
104 std::make_shared<P2>(kInterAxleDistance),
105 std::make_shared<P3>(kInterAxleDistance)}));
108 void ThreePlayerCollisionAvoidanceReachabilityExample::ConstructInitialState() {
110 constexpr
float kAnglePerturbation = 0.1;
111 x0_ = VectorXf::Zero(dynamics_->XDim());
112 x0_(kP1XIdx) = FLAGS_d0;
114 x0_(kP1HeadingIdx) = -M_PI + kAnglePerturbation;
115 x0_(kP1VIdx) = FLAGS_v0;
116 x0_(kP2XIdx) = -0.5 * FLAGS_d0;
117 x0_(kP2YIdx) = 0.5 * std::sqrt(3.0) * FLAGS_d0;
118 x0_(kP2HeadingIdx) = -M_PI / 3.0 + kAnglePerturbation;
119 x0_(kP2VIdx) = FLAGS_v0;
120 x0_(kP3XIdx) = -0.5 * FLAGS_d0;
121 x0_(kP3YIdx) = -0.5 * std::sqrt(3.0) * FLAGS_d0;
122 x0_(kP3HeadingIdx) = M_PI / 3.0 + kAnglePerturbation;
123 x0_(kP3VIdx) = FLAGS_v0;
126 void ThreePlayerCollisionAvoidanceReachabilityExample::ConstructPlayerCosts() {
128 player_costs_.emplace_back(
"P1");
129 player_costs_.emplace_back(
"P2");
130 player_costs_.emplace_back(
"P3");
131 auto& p1_cost = player_costs_[0];
132 auto& p2_cost = player_costs_[1];
133 auto& p3_cost = player_costs_[2];
136 const auto control_cost = std::make_shared<QuadraticCost>(
137 kControlCostWeight, -1, 0.0,
"ControlCost");
138 p1_cost.AddControlCost(0, control_cost);
139 p2_cost.AddControlCost(1, control_cost);
140 p3_cost.AddControlCost(2, control_cost);
143 const auto p1_omega_max_constraint =
144 std::make_shared<SingleDimensionConstraint>(
145 P1::kOmegaIdx, kOmegaMax,
true,
"Omega Constraint (Max)");
146 const auto p1_omega_min_constraint =
147 std::make_shared<SingleDimensionConstraint>(
148 P1::kOmegaIdx, -kOmegaMax,
false,
"Omega Constraint (Min)");
149 const auto p1_a_max_constraint = std::make_shared<SingleDimensionConstraint>(
150 P1::kAIdx, kAMax,
true,
"Acceleration Constraint (Max)");
151 const auto p1_a_min_constraint = std::make_shared<SingleDimensionConstraint>(
152 P1::kAIdx, -kAMax,
false,
"Acceleration Constraint (Min)");
153 p1_cost.AddControlConstraint(0, p1_omega_max_constraint);
154 p1_cost.AddControlConstraint(0, p1_omega_min_constraint);
155 p1_cost.AddControlConstraint(0, p1_a_max_constraint);
156 p1_cost.AddControlConstraint(0, p1_a_min_constraint);
158 const auto p2_omega_max_constraint =
159 std::make_shared<SingleDimensionConstraint>(
160 P2::kOmegaIdx, kOmegaMax,
true,
"Omega Constraint (Max)");
161 const auto p2_omega_min_constraint =
162 std::make_shared<SingleDimensionConstraint>(
163 P2::kOmegaIdx, -kOmegaMax,
false,
"Omega Constraint (Min)");
164 const auto p2_a_max_constraint = std::make_shared<SingleDimensionConstraint>(
165 P2::kAIdx, kAMax,
true,
"Acceleration Constraint (Max)");
166 const auto p2_a_min_constraint = std::make_shared<SingleDimensionConstraint>(
167 P2::kAIdx, -kAMax,
false,
"Acceleration Constraint (Min)");
168 p2_cost.AddControlConstraint(1, p2_omega_max_constraint);
169 p2_cost.AddControlConstraint(1, p2_omega_min_constraint);
170 p2_cost.AddControlConstraint(1, p2_a_max_constraint);
171 p2_cost.AddControlConstraint(1, p2_a_min_constraint);
173 const auto p3_omega_max_constraint =
174 std::make_shared<SingleDimensionConstraint>(
175 P3::kOmegaIdx, kOmegaMax,
true,
"Omega Constraint (Max)");
176 const auto p3_omega_min_constraint =
177 std::make_shared<SingleDimensionConstraint>(
178 P3::kOmegaIdx, -kOmegaMax,
false,
"Omega Constraint (Min)");
179 const auto p3_a_max_constraint = std::make_shared<SingleDimensionConstraint>(
180 P3::kAIdx, kAMax,
true,
"Acceleration Constraint (Max)");
181 const auto p3_a_min_constraint = std::make_shared<SingleDimensionConstraint>(
182 P3::kAIdx, -kAMax,
false,
"Acceleration Constraint (Min)");
183 p3_cost.AddControlConstraint(2, p3_omega_max_constraint);
184 p3_cost.AddControlConstraint(2, p3_omega_min_constraint);
185 p3_cost.AddControlConstraint(2, p3_a_max_constraint);
186 p3_cost.AddControlConstraint(2, p3_a_min_constraint);
189 const std::shared_ptr<SignedDistanceCost> p1_p2_collision_avoidance_cost(
190 new SignedDistanceCost({kP1XIdx, kP1YIdx}, {kP2XIdx, kP2YIdx},
192 const std::shared_ptr<SignedDistanceCost> p1_p3_collision_avoidance_cost(
193 new SignedDistanceCost({kP1XIdx, kP1YIdx}, {kP3XIdx, kP3YIdx},
195 const std::shared_ptr<SignedDistanceCost> p2_p3_collision_avoidance_cost(
196 new SignedDistanceCost({kP2XIdx, kP2YIdx}, {kP3XIdx, kP3YIdx},
199 constexpr
bool kTakeMin =
false;
200 const std::shared_ptr<ExtremeValueCost> p1_proximity_cost(
201 new ExtremeValueCost(
202 {p1_p2_collision_avoidance_cost, p1_p3_collision_avoidance_cost},
203 kTakeMin,
"Proximity"));
204 const std::shared_ptr<ExtremeValueCost> p2_proximity_cost(
205 new ExtremeValueCost(
206 {p1_p2_collision_avoidance_cost, p2_p3_collision_avoidance_cost},
207 kTakeMin,
"Proximity"));
208 const std::shared_ptr<ExtremeValueCost> p3_proximity_cost(
209 new ExtremeValueCost(
210 {p2_p3_collision_avoidance_cost, p1_p3_collision_avoidance_cost},
211 kTakeMin,
"Proximity"));
212 p1_cost.AddStateCost(p1_proximity_cost);
213 p2_cost.AddStateCost(p2_proximity_cost);
214 p3_cost.AddStateCost(p3_proximity_cost);
217 p1_cost.SetMaxOverTime();
218 p2_cost.SetMaxOverTime();
219 p3_cost.SetMaxOverTime();
222 inline std::vector<float> ThreePlayerCollisionAvoidanceReachabilityExample::Xs(
223 const VectorXf& x)
const {
224 return {x(kP1XIdx), x(kP2XIdx), x(kP3XIdx)};
227 inline std::vector<float> ThreePlayerCollisionAvoidanceReachabilityExample::Ys(
228 const VectorXf& x)
const {
229 return {x(kP1YIdx), x(kP2YIdx), x(kP3YIdx)};
232 inline std::vector<float>
233 ThreePlayerCollisionAvoidanceReachabilityExample::Thetas(
234 const VectorXf& x)
const {
235 return {x(kP1HeadingIdx), x(kP2HeadingIdx), x(kP3HeadingIdx)};