44 #include <ilqgames/cost/curvature_cost.h> 45 #include <ilqgames/cost/final_time_cost.h> 46 #include <ilqgames/cost/locally_convex_proximity_cost.h> 47 #include <ilqgames/cost/nominal_path_length_cost.h> 48 #include <ilqgames/cost/proximity_cost.h> 49 #include <ilqgames/cost/quadratic_cost.h> 50 #include <ilqgames/cost/quadratic_norm_cost.h> 51 #include <ilqgames/cost/quadratic_polyline2_cost.h> 52 #include <ilqgames/cost/semiquadratic_cost.h> 53 #include <ilqgames/cost/semiquadratic_norm_cost.h> 54 #include <ilqgames/cost/semiquadratic_polyline2_cost.h> 55 #include <ilqgames/dynamics/concatenated_flat_system.h> 56 #include <ilqgames/dynamics/single_player_flat_car_6d.h> 57 #include <ilqgames/dynamics/single_player_flat_unicycle_4d.h> 58 #include <ilqgames/examples/three_player_flat_intersection_example.h> 59 #include <ilqgames/geometry/polyline2.h> 60 #include <ilqgames/solver/problem.h> 61 #include <ilqgames/utils/initialize_along_route.h> 62 #include <ilqgames/utils/solver_log.h> 63 #include <ilqgames/utils/strategy.h> 64 #include <ilqgames/utils/types.h> 75 static constexpr
float kInterAxleLength = 4.0;
78 static constexpr
float kUnicycleAuxCostWeight = 500.0;
79 static constexpr
float kCarAuxCostWeight = 500.0;
80 static constexpr
float kOmegaCostWeight = 50.0;
81 static constexpr
float kJerkCostWeight = 50.0;
83 static constexpr
float kACostWeight = 5.0;
84 static constexpr
float kCurvatureCostWeight = 1.0;
85 static constexpr
float kMaxVCostWeight = 10.0;
86 static constexpr
float kNominalVCostWeight = 10.0;
88 static constexpr
float kGoalCostWeight = 0.1;
89 static constexpr
float kLaneCostWeight = 25.0;
90 static constexpr
float kLaneBoundaryCostWeight = 100.0;
92 static constexpr
float kMinProximity = 6.0;
93 static constexpr
float kP1ProximityCostWeight = 100.0;
94 static constexpr
float kP2ProximityCostWeight = 100.0;
95 static constexpr
float kP3ProximityCostWeight = 10.0;
96 using ProxCost = ProximityCost;
98 static constexpr
bool kOrientedRight =
true;
101 static constexpr
float kLaneHalfWidth = 2.5;
104 static constexpr
float kP1GoalX = -6.0;
105 static constexpr
float kP1GoalY = 600.0;
107 static constexpr
float kP2GoalX = 500.0;
108 static constexpr
float kP2GoalY = 12.0;
110 static constexpr
float kP3GoalX = 100.0;
111 static constexpr
float kP3GoalY = 16.0;
114 static constexpr
float kP1MaxV = 12.0;
115 static constexpr
float kP2MaxV = 12.0;
116 static constexpr
float kP3MaxV = 2.0;
117 static constexpr
float kMinV = 1.0;
119 static constexpr
float kP1NominalV = 8.0;
120 static constexpr
float kP2NominalV = 5.0;
121 static constexpr
float kP3NominalV = 1.5;
124 static constexpr
float kP1InitialX = -2.0;
125 static constexpr
float kP2InitialX = -10.0;
126 static constexpr
float kP3InitialX = -11.0;
128 static constexpr
float kP1InitialY = -30.0;
129 static constexpr
float kP2InitialY = 45.0;
130 static constexpr
float kP3InitialY = 16.0;
132 static constexpr
float kP1InitialHeading = M_PI_2;
133 static constexpr
float kP2InitialHeading = -M_PI_2;
134 static constexpr
float kP3InitialHeading = 0.0;
136 static constexpr
float kP1InitialSpeed = 5.0;
137 static constexpr
float kP2InitialSpeed = 5.0;
138 static constexpr
float kP3InitialSpeed = 1.25;
141 using P1 = SinglePlayerFlatCar6D;
142 using P2 = SinglePlayerFlatCar6D;
143 using P3 = SinglePlayerFlatUnicycle4D;
145 static const Dimension kP1XIdx = P1::kPxIdx;
146 static const Dimension kP1YIdx = P1::kPyIdx;
147 static const Dimension kP1HeadingIdx = P1::kThetaIdx;
148 static const Dimension kP1PhiIdx = P1::kPhiIdx;
149 static const Dimension kP1VIdx = P1::kVIdx;
150 static const Dimension kP1AIdx = P1::kAIdx;
151 static const Dimension kP1VxIdx = P1::kVxIdx;
152 static const Dimension kP1VyIdx = P1::kVyIdx;
153 static const Dimension kP1AxIdx = P1::kAxIdx;
154 static const Dimension kP1AyIdx = P1::kAyIdx;
156 static const Dimension kP2XIdx = P1::kNumXDims + P2::kPxIdx;
157 static const Dimension kP2YIdx = P1::kNumXDims + P2::kPyIdx;
158 static const Dimension kP2HeadingIdx = P1::kNumXDims + P2::kThetaIdx;
159 static const Dimension kP2PhiIdx = P1::kNumXDims + P2::kPhiIdx;
160 static const Dimension kP2VIdx = P1::kNumXDims + P2::kVIdx;
161 static const Dimension kP2AIdx = P1::kNumXDims + P2::kAIdx;
162 static const Dimension kP2VxIdx = P1::kNumXDims + P2::kVxIdx;
163 static const Dimension kP2VyIdx = P1::kNumXDims + P2::kVyIdx;
164 static const Dimension kP2AxIdx = P1::kNumXDims + P2::kAxIdx;
165 static const Dimension kP2AyIdx = P1::kNumXDims + P2::kAyIdx;
167 static const Dimension kP3XIdx = P1::kNumXDims + P2::kNumXDims + P3::kPxIdx;
168 static const Dimension kP3YIdx = P1::kNumXDims + P2::kNumXDims + P3::kPyIdx;
169 static const Dimension kP3HeadingIdx =
170 P1::kNumXDims + P2::kNumXDims + P3::kThetaIdx;
171 static const Dimension kP3VIdx = P1::kNumXDims + P2::kNumXDims + P3::kVIdx;
172 static const Dimension kP3VxIdx = P1::kNumXDims + P2::kNumXDims + P3::kVxIdx;
173 static const Dimension kP3VyIdx = P1::kNumXDims + P2::kNumXDims + P3::kVyIdx;
176 static const Dimension kP1OmegaIdx = 0;
177 static const Dimension kP1JerkIdx = 1;
178 static const Dimension kP2OmegaIdx = 0;
179 static const Dimension kP2JerkIdx = 1;
180 static const Dimension kP3OmegaIdx = 0;
181 static const Dimension kP3AIdx = 1;
185 void ThreePlayerFlatIntersectionExample::ConstructDynamics() {
186 dynamics_.reset(
new ConcatenatedFlatSystem(
187 {std::make_shared<P1>(kInterAxleLength),
188 std::make_shared<P2>(kInterAxleLength), std::make_shared<P3>()}));
191 void ThreePlayerFlatIntersectionExample::ConstructInitialState() {
192 VectorXf x0 = VectorXf::Zero(dynamics_->XDim());
193 x0(kP1XIdx) = kP1InitialX;
194 x0(kP1YIdx) = kP1InitialY;
195 x0(kP1HeadingIdx) = kP1InitialHeading;
196 x0(kP1VIdx) = kP1InitialSpeed;
197 x0(kP2XIdx) = kP2InitialX;
198 x0(kP2YIdx) = kP2InitialY;
199 x0(kP2HeadingIdx) = kP2InitialHeading;
200 x0(kP2VIdx) = kP2InitialSpeed;
201 x0(kP3XIdx) = kP3InitialX;
202 x0(kP3YIdx) = kP3InitialY;
203 x0(kP3HeadingIdx) = kP3InitialHeading;
204 x0(kP3VIdx) = kP3InitialSpeed;
206 x0_ = dynamics_->ToLinearSystemState(x0);
209 void ThreePlayerFlatIntersectionExample::ConstructPlayerCosts() {
211 player_costs_.emplace_back(
"P1");
212 player_costs_.emplace_back(
"P2");
213 player_costs_.emplace_back(
"P3");
214 auto& p1_cost = player_costs_[0];
215 auto& p2_cost = player_costs_[1];
216 auto& p3_cost = player_costs_[2];
219 const Polyline2 lane1(
220 {Point2(kP1InitialX, -1000.0), Point2(kP1InitialX, 1000.0)});
221 const Polyline2 lane2(
222 {Point2(kP2InitialX, 1000.0), Point2(kP2InitialX, 18.0),
223 Point2(kP2InitialX + 0.5, 15.0), Point2(kP2InitialX + 1.0, 14.0),
224 Point2(kP2InitialX + 3.0, 12.5), Point2(kP2InitialX + 6.0, 12.0),
225 Point2(1000.0, 12.0)});
226 const Polyline2 lane3(
227 {Point2(-1000.0, kP3InitialY), Point2(1000.0, kP3InitialY)});
229 const std::shared_ptr<QuadraticPolyline2Cost> p1_lane_cost(
230 new QuadraticPolyline2Cost(kLaneCostWeight, lane1, {kP1XIdx, kP1YIdx},
232 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane_r_cost(
233 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane1,
234 {kP1XIdx, kP1YIdx}, kLaneHalfWidth,
235 kOrientedRight,
"LaneRightBoundary"));
236 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane_l_cost(
237 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane1,
238 {kP1XIdx, kP1YIdx}, -kLaneHalfWidth,
239 !kOrientedRight,
"LaneLeftBoundary"));
240 p1_cost.AddStateCost(p1_lane_cost);
241 p1_cost.AddStateCost(p1_lane_r_cost);
242 p1_cost.AddStateCost(p1_lane_l_cost);
244 const std::shared_ptr<QuadraticPolyline2Cost> p2_lane_cost(
245 new QuadraticPolyline2Cost(kLaneCostWeight, lane2, {kP2XIdx, kP2YIdx},
247 const std::shared_ptr<SemiquadraticPolyline2Cost> p2_lane_r_cost(
248 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane2,
249 {kP2XIdx, kP2YIdx}, kLaneHalfWidth,
250 kOrientedRight,
"LaneRightBoundary"));
251 const std::shared_ptr<SemiquadraticPolyline2Cost> p2_lane_l_cost(
252 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane2,
253 {kP2XIdx, kP2YIdx}, -kLaneHalfWidth,
254 !kOrientedRight,
"LaneLeftBoundary"));
255 p2_cost.AddStateCost(p2_lane_cost);
256 p2_cost.AddStateCost(p2_lane_r_cost);
257 p2_cost.AddStateCost(p2_lane_l_cost);
259 const std::shared_ptr<QuadraticPolyline2Cost> p3_lane_cost(
260 new QuadraticPolyline2Cost(kLaneCostWeight, lane3, {kP3XIdx, kP3YIdx},
262 const std::shared_ptr<SemiquadraticPolyline2Cost> p3_lane_r_cost(
263 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane3,
264 {kP3XIdx, kP3YIdx}, kLaneHalfWidth,
265 kOrientedRight,
"LaneRightBoundary"));
266 const std::shared_ptr<SemiquadraticPolyline2Cost> p3_lane_l_cost(
267 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane3,
268 {kP3XIdx, kP3YIdx}, -kLaneHalfWidth,
269 !kOrientedRight,
"LaneLeftBoundary"));
270 p3_cost.AddStateCost(p3_lane_cost);
271 p3_cost.AddStateCost(p3_lane_r_cost);
272 p3_cost.AddStateCost(p3_lane_l_cost);
275 const std::shared_ptr<SemiquadraticNormCost> p1_min_v_cost(
276 new SemiquadraticNormCost(kMaxVCostWeight, {kP1VxIdx, kP1VyIdx}, kMinV,
277 !kOrientedRight,
"MinV"));
278 const std::shared_ptr<SemiquadraticNormCost> p1_max_v_cost(
279 new SemiquadraticNormCost(kMaxVCostWeight, {kP1VxIdx, kP1VyIdx}, kP1MaxV,
280 kOrientedRight,
"MaxV"));
281 const std::shared_ptr<QuadraticNormCost> p1_nominal_v_cost(
282 new QuadraticNormCost(kNominalVCostWeight, {kP1VxIdx, kP1VyIdx},
283 kP1NominalV,
"NominalV"));
284 p1_cost.AddStateCost(p1_min_v_cost);
285 p1_cost.AddStateCost(p1_max_v_cost);
286 p1_cost.AddStateCost(p1_nominal_v_cost);
288 const std::shared_ptr<SemiquadraticNormCost> p2_min_v_cost(
289 new SemiquadraticNormCost(kMaxVCostWeight, {kP2VxIdx, kP2VyIdx}, kMinV,
290 !kOrientedRight,
"MinV"));
291 const std::shared_ptr<SemiquadraticNormCost> p2_max_v_cost(
292 new SemiquadraticNormCost(kMaxVCostWeight, {kP2VxIdx, kP2VyIdx}, kP2MaxV,
293 kOrientedRight,
"MaxV"));
294 const std::shared_ptr<QuadraticNormCost> p2_nominal_v_cost(
295 new QuadraticNormCost(kNominalVCostWeight, {kP2VxIdx, kP2VyIdx},
296 kP2NominalV,
"NominalV"));
297 p2_cost.AddStateCost(p2_min_v_cost);
298 p2_cost.AddStateCost(p2_max_v_cost);
299 p2_cost.AddStateCost(p2_nominal_v_cost);
301 const std::shared_ptr<SemiquadraticNormCost> p3_min_v_cost(
302 new SemiquadraticNormCost(kMaxVCostWeight, {kP3VxIdx, kP3VyIdx}, kMinV,
303 !kOrientedRight,
"MinV"));
304 const std::shared_ptr<SemiquadraticNormCost> p3_max_v_cost(
305 new SemiquadraticNormCost(kMaxVCostWeight, {kP3VxIdx, kP3VyIdx}, kP3MaxV,
306 kOrientedRight,
"MaxV"));
307 const std::shared_ptr<QuadraticNormCost> p3_nominal_v_cost(
308 new QuadraticNormCost(kNominalVCostWeight, {kP3VxIdx, kP3VyIdx},
309 kP3NominalV,
"NominalV"));
310 p3_cost.AddStateCost(p3_min_v_cost);
311 p3_cost.AddStateCost(p3_max_v_cost);
312 p3_cost.AddStateCost(p3_nominal_v_cost);
315 constexpr Dimension kApplyInAllDimensions = -1;
316 const auto unicycle_aux_cost = std::make_shared<QuadraticCost>(
317 kUnicycleAuxCostWeight, kApplyInAllDimensions, 0.0,
"Auxiliary Input");
318 const auto car_aux_cost = std::make_shared<QuadraticCost>(
319 kCarAuxCostWeight, kApplyInAllDimensions, 0.0,
"Auxiliary Input");
320 p1_cost.AddControlCost(0, car_aux_cost);
321 p2_cost.AddControlCost(1, car_aux_cost);
322 p3_cost.AddControlCost(2, unicycle_aux_cost);
325 const std::shared_ptr<ProxCost> p1p2_proximity_cost(
326 new ProxCost(kP1ProximityCostWeight, {kP1XIdx, kP1YIdx},
327 {kP2XIdx, kP2YIdx}, kMinProximity,
"ProximityP2"));
328 const std::shared_ptr<ProxCost> p1p3_proximity_cost(
329 new ProxCost(kP1ProximityCostWeight, {kP1XIdx, kP1YIdx},
330 {kP3XIdx, kP3YIdx}, kMinProximity,
"ProximityP3"));
331 p1_cost.AddStateCost(p1p2_proximity_cost);
332 p1_cost.AddStateCost(p1p3_proximity_cost);
334 const std::shared_ptr<ProxCost> p2p1_proximity_cost(
335 new ProxCost(kP2ProximityCostWeight, {kP2XIdx, kP2YIdx},
336 {kP1XIdx, kP1YIdx}, kMinProximity,
"ProximityP1"));
337 const std::shared_ptr<ProxCost> p2p3_proximity_cost(
338 new ProxCost(kP2ProximityCostWeight, {kP2XIdx, kP2YIdx},
339 {kP3XIdx, kP3YIdx}, kMinProximity,
"ProximityP3"));
340 p2_cost.AddStateCost(p2p1_proximity_cost);
341 p2_cost.AddStateCost(p2p3_proximity_cost);
343 const std::shared_ptr<ProxCost> p3p1_proximity_cost(
344 new ProxCost(kP3ProximityCostWeight, {kP3XIdx, kP3YIdx},
345 {kP1XIdx, kP1YIdx}, kMinProximity,
"ProximityP1"));
346 const std::shared_ptr<ProxCost> p3p2_proximity_cost(
347 new ProxCost(kP3ProximityCostWeight, {kP3XIdx, kP3YIdx},
348 {kP2XIdx, kP2YIdx}, kMinProximity,
"ProximityP2"));
349 p3_cost.AddStateCost(p3p1_proximity_cost);
350 p3_cost.AddStateCost(p3p2_proximity_cost);
353 inline std::vector<float> ThreePlayerFlatIntersectionExample::Xs(
354 const VectorXf& xi)
const {
355 return {xi(kP1XIdx), xi(kP2XIdx), xi(kP3XIdx)};
358 inline std::vector<float> ThreePlayerFlatIntersectionExample::Ys(
359 const VectorXf& xi)
const {
360 return {xi(kP1YIdx), xi(kP2YIdx), xi(kP3YIdx)};
363 inline std::vector<float> ThreePlayerFlatIntersectionExample::Thetas(
364 const VectorXf& xi)
const {
365 const VectorXf x = dynamics_->FromLinearSystemState(xi);
366 return {x(kP1HeadingIdx), x(kP2HeadingIdx), x(kP3HeadingIdx)};