44 #include <ilqgames/constraint/polyline2_signed_distance_constraint.h> 45 #include <ilqgames/constraint/proximity_constraint.h> 46 #include <ilqgames/constraint/single_dimension_constraint.h> 47 #include <ilqgames/cost/curvature_cost.h> 48 #include <ilqgames/cost/final_time_cost.h> 49 #include <ilqgames/cost/locally_convex_proximity_cost.h> 50 #include <ilqgames/cost/nominal_path_length_cost.h> 51 #include <ilqgames/cost/proximity_cost.h> 52 #include <ilqgames/cost/quadratic_cost.h> 53 #include <ilqgames/cost/quadratic_polyline2_cost.h> 54 #include <ilqgames/cost/semiquadratic_cost.h> 55 #include <ilqgames/cost/semiquadratic_polyline2_cost.h> 56 #include <ilqgames/cost/weighted_convex_proximity_cost.h> 57 #include <ilqgames/dynamics/concatenated_dynamical_system.h> 58 #include <ilqgames/dynamics/single_player_car_5d.h> 59 #include <ilqgames/dynamics/single_player_car_6d.h> 60 #include <ilqgames/dynamics/single_player_unicycle_4d.h> 61 #include <ilqgames/examples/three_player_intersection_example.h> 62 #include <ilqgames/geometry/polyline2.h> 63 #include <ilqgames/solver/problem.h> 64 #include <ilqgames/solver/solver_params.h> 65 #include <ilqgames/utils/solver_log.h> 66 #include <ilqgames/utils/strategy.h> 67 #include <ilqgames/utils/types.h> 78 static constexpr
float kInterAxleLength = 4.0;
81 static constexpr
float kStateRegularization = 1.0;
82 static constexpr
float kControlRegularization = 5.0;
84 static constexpr
float kOmegaCostWeight = 0.1;
85 static constexpr
float kJerkCostWeight = 0.1;
86 static constexpr
float kMaxOmega = 1.0;
88 static constexpr
float kACostWeight = 0.1;
89 static constexpr
float kNominalVCostWeight = 100.0;
91 static constexpr
float kLaneCostWeight = 25.0;
93 static constexpr
float kMinProximity = 6.0;
94 using ProxCost = ProximityCost;
95 static constexpr
float kP1ProximityCostWeight = 10.0;
96 static constexpr
float kP2ProximityCostWeight = 10.0;
97 static constexpr
float kP3ProximityCostWeight = 10.0;
99 static constexpr
bool kOrientedRight =
true;
100 static constexpr
bool kBarrierOrientedInside =
false;
103 static constexpr
float kLaneHalfWidth = 2.5;
106 static constexpr
float kP1MaxV = 12.0;
107 static constexpr
float kP2MaxV = 12.0;
108 static constexpr
float kP3MaxV = 2.0;
109 static constexpr
float kMinV = 1.0;
111 static constexpr
float kP1NominalV = 8.0;
112 static constexpr
float kP2NominalV = 5.0;
113 static constexpr
float kP3NominalV = 1.5;
116 static constexpr
float kP1InitialX = -2.0;
117 static constexpr
float kP2InitialX = -10.0;
118 static constexpr
float kP3InitialX = -11.0;
120 static constexpr
float kP1InitialY = -30.0;
121 static constexpr
float kP2InitialY = 45.0;
122 static constexpr
float kP3InitialY = 16.0;
124 static constexpr
float kP1InitialHeading = M_PI_2;
125 static constexpr
float kP2InitialHeading = -M_PI_2;
126 static constexpr
float kP3InitialHeading = 0.0;
128 static constexpr
float kP1InitialSpeed = 4.0;
129 static constexpr
float kP2InitialSpeed = 3.0;
130 static constexpr
float kP3InitialSpeed = 1.25;
133 using P1 = SinglePlayerCar6D;
134 using P2 = SinglePlayerCar6D;
135 using P3 = SinglePlayerUnicycle4D;
137 static const Dimension kP1XIdx = P1::kPxIdx;
138 static const Dimension kP1YIdx = P1::kPyIdx;
139 static const Dimension kP1HeadingIdx = P1::kThetaIdx;
140 static const Dimension kP1PhiIdx = P1::kPhiIdx;
141 static const Dimension kP1VIdx = P1::kVIdx;
142 static const Dimension kP1AIdx = P1::kAIdx;
144 static const Dimension kP2XIdx = P1::kNumXDims + P2::kPxIdx;
145 static const Dimension kP2YIdx = P1::kNumXDims + P2::kPyIdx;
146 static const Dimension kP2HeadingIdx = P1::kNumXDims + P2::kThetaIdx;
147 static const Dimension kP2PhiIdx = P1::kNumXDims + P2::kPhiIdx;
148 static const Dimension kP2VIdx = P1::kNumXDims + P2::kVIdx;
149 static const Dimension kP2AIdx = P1::kNumXDims + P2::kAIdx;
151 static const Dimension kP3XIdx = P1::kNumXDims + P2::kNumXDims + P3::kPxIdx;
152 static const Dimension kP3YIdx = P1::kNumXDims + P2::kNumXDims + P3::kPyIdx;
153 static const Dimension kP3HeadingIdx =
154 P1::kNumXDims + P2::kNumXDims + P3::kThetaIdx;
155 static const Dimension kP3VIdx = P1::kNumXDims + P2::kNumXDims + P3::kVIdx;
158 static const Dimension kP1OmegaIdx = 0;
159 static const Dimension kP1JerkIdx = 1;
160 static const Dimension kP2OmegaIdx = 0;
161 static const Dimension kP2JerkIdx = 1;
162 static const Dimension kP3OmegaIdx = 0;
163 static const Dimension kP3AIdx = 1;
166 void ThreePlayerIntersectionExample::ConstructDynamics() {
167 dynamics_.reset(
new ConcatenatedDynamicalSystem(
168 {std::make_shared<P1>(kInterAxleLength),
169 std::make_shared<P2>(kInterAxleLength), std::make_shared<P3>()}));
172 void ThreePlayerIntersectionExample::ConstructInitialState() {
173 x0_ = VectorXf::Zero(dynamics_->XDim());
174 x0_(kP1XIdx) = kP1InitialX;
175 x0_(kP1YIdx) = kP1InitialY;
176 x0_(kP1HeadingIdx) = kP1InitialHeading;
177 x0_(kP1VIdx) = kP1InitialSpeed;
178 x0_(kP2XIdx) = kP2InitialX;
179 x0_(kP2YIdx) = kP2InitialY;
180 x0_(kP2HeadingIdx) = kP2InitialHeading;
181 x0_(kP2VIdx) = kP2InitialSpeed;
182 x0_(kP3XIdx) = kP3InitialX;
183 x0_(kP3YIdx) = kP3InitialY;
184 x0_(kP3HeadingIdx) = kP3InitialHeading;
185 x0_(kP3VIdx) = kP3InitialSpeed;
188 void ThreePlayerIntersectionExample::ConstructPlayerCosts() {
190 player_costs_.emplace_back(
"P1", kStateRegularization,
191 kControlRegularization);
192 player_costs_.emplace_back(
"P2", kStateRegularization,
193 kControlRegularization);
194 player_costs_.emplace_back(
"P3", kStateRegularization,
195 kControlRegularization);
196 auto& p1_cost = player_costs_[0];
197 auto& p2_cost = player_costs_[1];
198 auto& p3_cost = player_costs_[2];
201 const Polyline2 lane1(
202 {Point2(kP1InitialX, -1000.0), Point2(kP1InitialX, 1000.0)});
203 const Polyline2 lane2(
204 {Point2(kP2InitialX, 1000.0), Point2(kP2InitialX, 18.0),
205 Point2(kP2InitialX + 0.5, 15.0), Point2(kP2InitialX + 1.0, 14.0),
206 Point2(kP2InitialX + 3.0, 12.5), Point2(kP2InitialX + 6.0, 12.0),
207 Point2(1000.0, 12.0)});
208 const Polyline2 lane3(
209 {Point2(-1000.0, kP3InitialY), Point2(1000.0, kP3InitialY)});
211 const std::shared_ptr<QuadraticPolyline2Cost> p1_lane_cost(
212 new QuadraticPolyline2Cost(kLaneCostWeight, lane1, {kP1XIdx, kP1YIdx},
214 const std::shared_ptr<Polyline2SignedDistanceConstraint> p1_lane_r_constraint(
215 new Polyline2SignedDistanceConstraint(lane1, {kP1XIdx, kP1YIdx},
216 kLaneHalfWidth, !kOrientedRight,
217 "LaneRightBoundary"));
218 const std::shared_ptr<Polyline2SignedDistanceConstraint> p1_lane_l_constraint(
219 new Polyline2SignedDistanceConstraint(lane1, {kP1XIdx, kP1YIdx},
220 -kLaneHalfWidth, kOrientedRight,
221 "LaneLeftBoundary"));
222 p1_cost.AddStateCost(p1_lane_cost);
226 const std::shared_ptr<QuadraticPolyline2Cost> p2_lane_cost(
227 new QuadraticPolyline2Cost(kLaneCostWeight, lane2, {kP2XIdx, kP2YIdx},
229 const std::shared_ptr<Polyline2SignedDistanceConstraint> p2_lane_r_constraint(
230 new Polyline2SignedDistanceConstraint(lane2, {kP2XIdx, kP2YIdx},
231 kLaneHalfWidth, !kOrientedRight,
232 "LaneRightBoundary"));
233 const std::shared_ptr<Polyline2SignedDistanceConstraint> p2_lane_l_constraint(
234 new Polyline2SignedDistanceConstraint(lane2, {kP2XIdx, kP2YIdx},
235 -kLaneHalfWidth, kOrientedRight,
236 "LaneLeftBoundary"));
237 p2_cost.AddStateCost(p2_lane_cost);
241 const std::shared_ptr<QuadraticPolyline2Cost> p3_lane_cost(
242 new QuadraticPolyline2Cost(kLaneCostWeight, lane3, {kP3XIdx, kP3YIdx},
244 const std::shared_ptr<Polyline2SignedDistanceConstraint> p3_lane_r_constraint(
245 new Polyline2SignedDistanceConstraint(lane3, {kP3XIdx, kP3YIdx},
246 kLaneHalfWidth, !kOrientedRight,
247 "LaneRightBoundary"));
248 const std::shared_ptr<Polyline2SignedDistanceConstraint> p3_lane_l_constraint(
249 new Polyline2SignedDistanceConstraint(lane3, {kP3XIdx, kP3YIdx},
250 -kLaneHalfWidth, kOrientedRight,
251 "LaneLeftBoundary"));
252 p3_cost.AddStateCost(p3_lane_cost);
257 const auto p1_min_v_constraint = std::make_shared<SingleDimensionConstraint>(
258 kP1VIdx, kMinV, !kOrientedRight,
"MinV");
259 const auto p1_max_v_constraint = std::make_shared<SingleDimensionConstraint>(
260 kP1VIdx, kP1MaxV, kOrientedRight,
"MaxV");
261 const auto p1_nominal_v_cost = std::make_shared<QuadraticCost>(
262 kNominalVCostWeight, kP1VIdx, kP1NominalV,
"NominalV");
265 p1_cost.AddStateCost(p1_nominal_v_cost);
267 const auto p2_min_v_constraint = std::make_shared<SingleDimensionConstraint>(
268 kP2VIdx, kMinV, !kOrientedRight,
"MinV");
269 const auto p2_max_v_constraint = std::make_shared<SingleDimensionConstraint>(
270 kP2VIdx, kP2MaxV, kOrientedRight,
"MaxV");
271 const auto p2_nominal_v_cost = std::make_shared<QuadraticCost>(
272 kNominalVCostWeight, kP2VIdx, kP2NominalV,
"NominalV");
275 p2_cost.AddStateCost(p2_nominal_v_cost);
277 const auto p3_min_v_constraint = std::make_shared<SingleDimensionConstraint>(
278 kP3VIdx, kMinV, !kOrientedRight,
"MinV");
279 const auto p3_max_v_constraint = std::make_shared<SingleDimensionConstraint>(
280 kP3VIdx, kP3MaxV, kOrientedRight,
"MaxV");
281 const auto p3_nominal_v_cost = std::make_shared<QuadraticCost>(
282 kNominalVCostWeight, kP3VIdx, kP3NominalV,
"NominalV");
285 p3_cost.AddStateCost(p3_nominal_v_cost);
288 const auto p1_omega_max_constraint =
289 std::make_shared<SingleDimensionConstraint>(
290 kP1OmegaIdx, kMaxOmega, kOrientedRight,
"SteeringMax");
291 const auto p1_omega_min_constraint =
292 std::make_shared<SingleDimensionConstraint>(
293 kP1OmegaIdx, -kMaxOmega, !kOrientedRight,
"SteeringMin");
294 const auto p1_omega_cost = std::make_shared<QuadraticCost>(
295 kOmegaCostWeight, kP1OmegaIdx, 0.0,
"Steering");
296 const auto p1_jerk_cost =
297 std::make_shared<QuadraticCost>(kJerkCostWeight, kP1JerkIdx, 0.0,
"Jerk");
300 p1_cost.AddControlCost(0, p1_omega_cost);
301 p1_cost.AddControlCost(0, p1_jerk_cost);
303 const auto p2_omega_max_constraint =
304 std::make_shared<SingleDimensionConstraint>(
305 kP2OmegaIdx, kMaxOmega, !kOrientedRight,
"SteeringMax");
306 const auto p2_omega_min_constraint =
307 std::make_shared<SingleDimensionConstraint>(
308 kP2OmegaIdx, -kMaxOmega, kOrientedRight,
"SteeringMin");
309 const auto p2_omega_cost = std::make_shared<QuadraticCost>(
310 kOmegaCostWeight, kP2OmegaIdx, 0.0,
"Steering");
311 const auto p2_jerk_cost =
312 std::make_shared<QuadraticCost>(kJerkCostWeight, kP2JerkIdx, 0.0,
"Jerk");
315 p2_cost.AddControlCost(1, p2_omega_cost);
316 p2_cost.AddControlCost(1, p2_jerk_cost);
318 const auto p3_omega_max_constraint =
319 std::make_shared<SingleDimensionConstraint>(
320 kP3OmegaIdx, kMaxOmega, kOrientedRight,
"SteeringMax");
321 const auto p3_omega_min_constraint =
322 std::make_shared<SingleDimensionConstraint>(
323 kP3OmegaIdx, -kMaxOmega, !kOrientedRight,
"SteeringMin");
324 const auto p3_omega_cost = std::make_shared<QuadraticCost>(
325 kOmegaCostWeight, kP3OmegaIdx, 0.0,
"Steering");
326 const auto p3_a_cost = std::make_shared<QuadraticCost>(kACostWeight, kP3AIdx,
327 0.0,
"Acceleration");
330 p3_cost.AddControlCost(2, p3_omega_cost);
331 p3_cost.AddControlCost(2, p3_a_cost);
362 constexpr
bool kKeepClose =
true;
363 const std::shared_ptr<ProximityConstraint> p1p2_proximity_constraint(
364 new ProximityConstraint({kP1XIdx, kP1YIdx}, {kP2XIdx, kP2YIdx},
365 kMinProximity, !kKeepClose,
366 "ProximityConstraintP2"));
367 const std::shared_ptr<ProximityConstraint> p1p3_proximity_constraint(
368 new ProximityConstraint({kP1XIdx, kP1YIdx}, {kP3XIdx, kP3YIdx},
369 kMinProximity, !kKeepClose,
370 "ProximityConstraintP3"));
371 p1_cost.AddStateConstraint(p1p2_proximity_constraint);
372 p1_cost.AddStateConstraint(p1p3_proximity_constraint);
374 const std::shared_ptr<ProximityConstraint> p2p1_proximity_constraint(
375 new ProximityConstraint({kP2XIdx, kP2YIdx}, {kP1XIdx, kP1YIdx},
376 kMinProximity, !kKeepClose,
377 "ProximityConstraintP1"));
378 const std::shared_ptr<ProximityConstraint> p2p3_proximity_constraint(
379 new ProximityConstraint({kP2XIdx, kP2YIdx}, {kP3XIdx, kP3YIdx},
380 kMinProximity, !kKeepClose,
381 "ProximityConstraintP3"));
382 p2_cost.AddStateConstraint(p2p1_proximity_constraint);
383 p2_cost.AddStateConstraint(p2p3_proximity_constraint);
385 const std::shared_ptr<ProximityConstraint> p3p1_proximity_constraint(
386 new ProximityConstraint({kP3XIdx, kP3YIdx}, {kP1XIdx, kP1YIdx},
387 kMinProximity, !kKeepClose,
388 "ProximityConstraintP1"));
389 const std::shared_ptr<ProximityConstraint> p3p2_proximity_constraint(
390 new ProximityConstraint({kP3XIdx, kP3YIdx}, {kP2XIdx, kP2YIdx},
391 kMinProximity, !kKeepClose,
392 "ProximityConstraintP2"));
393 p3_cost.AddStateConstraint(p3p1_proximity_constraint);
394 p3_cost.AddStateConstraint(p3p2_proximity_constraint);
431 inline std::vector<float> ThreePlayerIntersectionExample::Xs(
432 const VectorXf& x)
const {
433 return {x(kP1XIdx), x(kP2XIdx), x(kP3XIdx)};
436 inline std::vector<float> ThreePlayerIntersectionExample::Ys(
437 const VectorXf& x)
const {
438 return {x(kP1YIdx), x(kP2YIdx), x(kP3YIdx)};
441 inline std::vector<float> ThreePlayerIntersectionExample::Thetas(
442 const VectorXf& x)
const {
443 return {x(kP1HeadingIdx), x(kP2HeadingIdx), x(kP3HeadingIdx)};