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/orientation_cost.h> 49 #include <ilqgames/cost/proximity_cost.h> 50 #include <ilqgames/cost/quadratic_cost.h> 51 #include <ilqgames/cost/quadratic_polyline2_cost.h> 52 #include <ilqgames/cost/semiquadratic_cost.h> 53 #include <ilqgames/cost/semiquadratic_polyline2_cost.h> 54 #include <ilqgames/cost/weighted_convex_proximity_cost.h> 55 #include <ilqgames/dynamics/concatenated_dynamical_system.h> 56 #include <ilqgames/dynamics/single_player_car_6d.h> 57 #include <ilqgames/dynamics/single_player_unicycle_4d.h> 58 #include <ilqgames/examples/two_player_collision_example.h> 59 #include <ilqgames/geometry/polyline2.h> 60 #include <ilqgames/solver/ilq_solver.h> 61 #include <ilqgames/solver/lq_feedback_solver.h> 62 #include <ilqgames/solver/problem.h> 63 #include <ilqgames/solver/solver_params.h> 64 #include <ilqgames/utils/solver_log.h> 65 #include <ilqgames/utils/strategy.h> 66 #include <ilqgames/utils/types.h> 77 static constexpr
float kInterAxleLength = 4.0;
80 static constexpr
float kOmegaCostWeight = 5000.0;
81 static constexpr
float kJerkCostWeight = 3250.0;
83 static constexpr
float kACostWeight = 50.0;
84 static constexpr
float kP1NominalVCostWeight = 10.0;
85 static constexpr
float kP2NominalVCostWeight = 1.0;
87 static constexpr
float kLaneCostWeight = 250.0;
88 static constexpr
float kLaneBoundaryCostWeight = 50000.0;
90 static constexpr
float kMinProximity = 7.5;
91 static constexpr
float kP1ProximityCostWeight = 5000.0;
92 static constexpr
float kP2ProximityCostWeight = 5000.0;
93 using ProxCost = ProximityCost;
96 static constexpr
float kNominalHeadingCostWeight = 150.0;
98 static constexpr
bool kOrientedRight =
true;
101 static constexpr
float kLaneHalfWidth = 2.5;
104 static constexpr
float kP1NominalV = 5.0;
105 static constexpr
float kP2NominalV = 5.0;
108 static constexpr
float kP1NominalHeading = M_PI_2;
111 static constexpr
float kP1InitialX = 2.5;
112 static constexpr
float kP1InitialY = -50.0;
114 static constexpr
float kP2InitialX = 2.5;
115 static constexpr
float kP2InitialY = 50.0;
117 static constexpr
float kP1InitialHeading = M_PI_2;
118 static constexpr
float kP2InitialHeading = -M_PI_2;
120 static constexpr
float kP1InitialSpeed = 10.0;
121 static constexpr
float kP2InitialSpeed = 2.0;
124 static constexpr
float kGoalCostWeight = 1000.0;
125 static constexpr
float kP1GoalX = 2.5;
126 static constexpr
float kP1GoalY = 50.0;
127 static constexpr
float kP2GoalX = 2.5;
128 static constexpr
float kP2GoalY = -50.0;
131 using P1 = SinglePlayerCar6D;
132 using P2 = SinglePlayerCar6D;
134 static const Dimension kP1XIdx = P1::kPxIdx;
135 static const Dimension kP1YIdx = P1::kPyIdx;
136 static const Dimension kP1HeadingIdx = P1::kThetaIdx;
137 static const Dimension kP1PhiIdx = P1::kPhiIdx;
138 static const Dimension kP1VIdx = P1::kVIdx;
139 static const Dimension kP1AIdx = P1::kAIdx;
141 static const Dimension kP2XIdx = P1::kNumXDims + P2::kPxIdx;
142 static const Dimension kP2YIdx = P1::kNumXDims + P2::kPyIdx;
143 static const Dimension kP2HeadingIdx = P1::kNumXDims + P2::kThetaIdx;
144 static const Dimension kP2PhiIdx = P1::kNumXDims + P2::kPhiIdx;
145 static const Dimension kP2VIdx = P1::kNumXDims + P2::kVIdx;
146 static const Dimension kP2AIdx = P1::kNumXDims + P2::kAIdx;
149 static const Dimension kP1OmegaIdx = 0;
150 static const Dimension kP1JerkIdx = 1;
151 static const Dimension kP2OmegaIdx = 0;
152 static const Dimension kP2JerkIdx = 1;
156 void TwoPlayerCollisionExample::ConstructDynamics() {
157 dynamics_.reset(
new ConcatenatedDynamicalSystem(
158 {std::make_shared<SinglePlayerCar6D>(kInterAxleLength),
159 std::make_shared<SinglePlayerCar6D>(kInterAxleLength)}));
162 void TwoPlayerCollisionExample::ConstructInitialState() {
163 x0_ = VectorXf::Zero(dynamics_->XDim());
164 x0_(kP1XIdx) = kP1InitialX;
165 x0_(kP1YIdx) = kP1InitialY;
166 x0_(kP1HeadingIdx) = kP1InitialHeading;
167 x0_(kP1VIdx) = kP1InitialSpeed;
168 x0_(kP2XIdx) = kP2InitialX;
169 x0_(kP2YIdx) = kP2InitialY;
170 x0_(kP2HeadingIdx) = kP2InitialHeading;
171 x0_(kP2VIdx) = kP2InitialSpeed;
174 void TwoPlayerCollisionExample::ConstructPlayerCosts() {
176 player_costs_.emplace_back(
"P1", 1.0, 0.0);
177 player_costs_.emplace_back(
"P2", 1.0, 0.0);
178 auto& p1_cost = player_costs_[0];
179 auto& p2_cost = player_costs_[1];
182 const Polyline2 lane1_p1p2({Point2(2.5, -50.0), Point2(2.5, 50.0)});
183 const std::shared_ptr<QuadraticPolyline2Cost> p1_lane1_cost(
184 new QuadraticPolyline2Cost(kLaneCostWeight, lane1_p1p2,
185 {kP1XIdx, kP1YIdx},
"LaneCenter"));
186 const std::shared_ptr<QuadraticPolyline2Cost> p2_lane1_cost(
187 new QuadraticPolyline2Cost(kLaneCostWeight * 10, lane1_p1p2,
188 {kP2XIdx, kP2YIdx},
"LaneCenter"));
189 p1_cost.AddStateCost(p1_lane1_cost);
190 p2_cost.AddStateCost(p2_lane1_cost);
193 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane1_l_cost(
194 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight * 1000, lane1_p1p2,
195 {kP1XIdx, kP1YIdx}, -kLaneHalfWidth,
196 !kOrientedRight,
"LaneLeftBoundary"));
197 const std::shared_ptr<SemiquadraticPolyline2Cost> p2_lane1_l_cost(
198 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight * 10, lane1_p1p2,
199 {kP2XIdx, kP2YIdx}, -kLaneHalfWidth,
200 !kOrientedRight,
"LaneLeftBoundary"));
201 p1_cost.AddStateCost(p1_lane1_l_cost);
202 p2_cost.AddStateCost(p2_lane1_l_cost);
205 const std::shared_ptr<SemiquadraticPolyline2Cost> p2_lane1_r_cost(
206 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane1_p1p2,
207 {kP2XIdx, kP2YIdx}, kLaneHalfWidth,
208 kOrientedRight,
"LaneRightBoundary"));
209 p2_cost.AddStateCost(p2_lane1_r_cost);
212 const Polyline2 lane1_p1({Point2(2.5 + kLaneHalfWidth, -50.0),
213 Point2(2.5 + kLaneHalfWidth, -5.0)});
214 const Polyline2 lane2_p1(
215 {Point2(2.5 + kLaneHalfWidth, 5.0), Point2(2.5 + kLaneHalfWidth, 50.0)});
216 const Polyline2 lane3_p1({Point2(10.0, -5.0), Point2(10.0, 5.0)});
217 const Polyline2 lane4_p1(
218 {Point2(2.5 + kLaneHalfWidth, 5.0), Point2(25.0, 5.0)});
219 const Polyline2 lane5_p1(
220 {Point2(2.5 + kLaneHalfWidth, -5.0), Point2(25, -5.0)});
221 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane2_r_cost(
222 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane1_p1,
223 {kP1XIdx, kP1YIdx}, 0.0, kOrientedRight,
224 "LaneRightBoundary_lane1_p1"));
225 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane3_r_cost(
226 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane2_p1,
227 {kP1XIdx, kP1YIdx}, 0.0, kOrientedRight,
228 "LaneRightBoundary_lane2_p1"));
229 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane4_r_cost(
230 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane3_p1,
231 {kP1XIdx, kP1YIdx}, 0.0, kOrientedRight,
232 "LaneRightBoundary_lane3_p1"));
233 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane5_l_cost(
234 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane4_p1,
235 {kP1XIdx, kP1YIdx}, 0.0, !kOrientedRight,
236 "LaneLeftBoundary_lane4_p1"));
237 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane6_r_cost(
238 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane5_p1,
239 {kP1XIdx, kP1YIdx}, 0.0, kOrientedRight,
240 "LaneRightBoundary_lane5_p1"));
241 p1_cost.AddStateCost(p1_lane2_r_cost);
242 p1_cost.AddStateCost(p1_lane3_r_cost);
243 p1_cost.AddStateCost(p1_lane4_r_cost);
244 p1_cost.AddStateCost(p1_lane5_l_cost);
245 p1_cost.AddStateCost(p1_lane6_r_cost);
252 const auto p1_nominal_v_cost = std::make_shared<QuadraticCost>(
253 kP1NominalVCostWeight, kP1VIdx, kP1NominalV,
"NominalV");
256 p1_cost.AddStateCost(p1_nominal_v_cost);
262 const auto p2_nominal_v_cost = std::make_shared<QuadraticCost>(
263 kP2NominalVCostWeight, kP2VIdx, kP2NominalV,
"NominalV");
266 p2_cost.AddStateCost(p2_nominal_v_cost);
269 const auto p1_omega_cost = std::make_shared<QuadraticCost>(
270 kOmegaCostWeight, kP1OmegaIdx, 0.0,
"Steering");
271 const auto p1_jerk_cost =
272 std::make_shared<QuadraticCost>(kJerkCostWeight, kP1JerkIdx, 0.0,
"Jerk");
273 p1_cost.AddControlCost(0, p1_omega_cost);
274 p1_cost.AddControlCost(0, p1_jerk_cost);
276 const auto p2_omega_cost = std::make_shared<QuadraticCost>(
277 kOmegaCostWeight, kP2OmegaIdx, 0.0,
"Steering");
278 const auto p2_jerk_cost =
279 std::make_shared<QuadraticCost>(kJerkCostWeight, kP2JerkIdx, 0.0,
"Jerk");
280 p2_cost.AddControlCost(1, p2_omega_cost);
281 p2_cost.AddControlCost(1, p2_jerk_cost);
284 constexpr
float kFinalTimeWindow = 0.5;
285 const auto p1_goalx_cost = std::make_shared<FinalTimeCost>(
286 std::make_shared<QuadraticCost>(kGoalCostWeight, kP1XIdx, kP1GoalX),
287 time::kTimeHorizon - kFinalTimeWindow,
"GoalX");
288 const auto p1_goaly_cost = std::make_shared<FinalTimeCost>(
289 std::make_shared<QuadraticCost>(kGoalCostWeight, kP1YIdx, kP1GoalY),
290 time::kTimeHorizon - kFinalTimeWindow,
"GoalY");
291 p1_cost.AddStateCost(p1_goalx_cost);
292 p1_cost.AddStateCost(p1_goaly_cost);
294 const auto p2_goalx_cost = std::make_shared<FinalTimeCost>(
295 std::make_shared<QuadraticCost>(kGoalCostWeight, kP2XIdx, kP2GoalX),
296 time::kTimeHorizon - kFinalTimeWindow,
"GoalX");
297 const auto p2_goaly_cost = std::make_shared<FinalTimeCost>(
298 std::make_shared<QuadraticCost>(kGoalCostWeight, kP2YIdx, kP2GoalY),
299 time::kTimeHorizon - kFinalTimeWindow,
"GoalY");
300 p2_cost.AddStateCost(p2_goalx_cost);
301 p2_cost.AddStateCost(p2_goaly_cost);
304 const std::shared_ptr<ProxCost> p1p2_proximity_cost(
305 new ProxCost(kP1ProximityCostWeight, {kP1XIdx, kP1YIdx},
306 {kP2XIdx, kP2YIdx}, kMinProximity,
"ProximityP2"));
307 p1_cost.AddStateCost(p1p2_proximity_cost);
309 const std::shared_ptr<ProxCost> p2p1_proximity_cost(
310 new ProxCost(kP2ProximityCostWeight, {kP2XIdx, kP2YIdx},
311 {kP1XIdx, kP1YIdx}, kMinProximity,
"ProximityP1"));
312 p2_cost.AddStateCost(p2p1_proximity_cost);
315 inline std::vector<float> TwoPlayerCollisionExample::Xs(
316 const VectorXf& x)
const {
317 return {x(kP1XIdx), x(kP2XIdx)};
320 inline std::vector<float> TwoPlayerCollisionExample::Ys(
321 const VectorXf& x)
const {
322 return {x(kP1YIdx), x(kP2YIdx)};
325 inline std::vector<float> TwoPlayerCollisionExample::Thetas(
326 const VectorXf& x)
const {
327 return {x(kP1HeadingIdx), x(kP2HeadingIdx)};