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_polyline2_cost.h> 51 #include <ilqgames/cost/semiquadratic_cost.h> 52 #include <ilqgames/cost/semiquadratic_polyline2_cost.h> 53 #include <ilqgames/cost/weighted_convex_proximity_cost.h> 54 #include <ilqgames/dynamics/concatenated_dynamical_system.h> 55 #include <ilqgames/dynamics/single_player_car_5d.h> 56 #include <ilqgames/dynamics/single_player_car_6d.h> 57 #include <ilqgames/dynamics/single_player_unicycle_4d.h> 58 #include <ilqgames/examples/modified_three_player_intersection_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 kStateRegularization = 10.0;
81 static constexpr
float kControlRegularization = 10.0;
83 static constexpr
float kOmegaCostWeight = 0.1;
84 static constexpr
float kACostWeight = 0.1;
86 static constexpr
float kLaneCostWeight = 25.0;
87 static constexpr
float kLaneBoundaryCostWeight = 100.0;
89 static constexpr
float kProximityCostWeight = 0.0;
90 static constexpr
float kMinProximity = 6.0;
91 using ProxCost = ProximityCost;
93 static constexpr
bool kOrientedRight =
true;
96 static constexpr
float kLaneHalfWidth = 2.5;
99 static constexpr
float kMaxVCostWeight = 100.0;
100 static constexpr
float kP1MaxV = 12.0;
101 static constexpr
float kP2MaxV = 12.0;
102 static constexpr
float kP3MaxV = 2.0;
103 static constexpr
float kMinV = 1.0;
105 static constexpr
float kNominalVCostWeight = 10.0;
106 static constexpr
float kP1NominalV = 8.0;
107 static constexpr
float kP2NominalV = 6.0;
108 static constexpr
float kP3NominalV = 1.5;
111 static constexpr
float kP1InitialX = -2.0;
112 static constexpr
float kP2InitialX = -10.0;
113 static constexpr
float kP3InitialX = -11.0;
115 static constexpr
float kP1InitialY = -30.0;
116 static constexpr
float kP2InitialY = 45.0;
117 static constexpr
float kP3InitialY = 16.0;
119 static constexpr
float kP1InitialHeading = M_PI_2;
120 static constexpr
float kP2InitialHeading = -M_PI_2;
121 static constexpr
float kP3InitialHeading = 0.0;
123 static constexpr
float kP1InitialSpeed = 4.0;
124 static constexpr
float kP2InitialSpeed = 3.0;
125 static constexpr
float kP3InitialSpeed = 1.25;
128 using P1 = SinglePlayerCar5D;
129 using P2 = SinglePlayerCar5D;
130 using P3 = SinglePlayerUnicycle4D;
132 static const Dimension kP1XIdx = P1::kPxIdx;
133 static const Dimension kP1YIdx = P1::kPyIdx;
134 static const Dimension kP1HeadingIdx = P1::kThetaIdx;
135 static const Dimension kP1PhiIdx = P1::kPhiIdx;
136 static const Dimension kP1VIdx = P1::kVIdx;
138 static const Dimension kP2XIdx = P1::kNumXDims + P2::kPxIdx;
139 static const Dimension kP2YIdx = P1::kNumXDims + P2::kPyIdx;
140 static const Dimension kP2HeadingIdx = P1::kNumXDims + P2::kThetaIdx;
141 static const Dimension kP2PhiIdx = P1::kNumXDims + P2::kPhiIdx;
142 static const Dimension kP2VIdx = P1::kNumXDims + P2::kVIdx;
144 static const Dimension kP3XIdx = P1::kNumXDims + P2::kNumXDims + P3::kPxIdx;
145 static const Dimension kP3YIdx = P1::kNumXDims + P2::kNumXDims + P3::kPyIdx;
146 static const Dimension kP3HeadingIdx =
147 P1::kNumXDims + P2::kNumXDims + P3::kThetaIdx;
148 static const Dimension kP3VIdx = P1::kNumXDims + P2::kNumXDims + P3::kVIdx;
151 static const Dimension kP1OmegaIdx = 0;
152 static const Dimension kP1AIdx = 1;
153 static const Dimension kP2OmegaIdx = 0;
154 static const Dimension kP2AIdx = 1;
155 static const Dimension kP3OmegaIdx = 0;
156 static const Dimension kP3AIdx = 1;
160 void ModifiedThreePlayerIntersectionExample::ConstructDynamics() {
161 dynamics_.reset(
new ConcatenatedDynamicalSystem(
162 {std::make_shared<P1>(kInterAxleLength),
163 std::make_shared<P2>(kInterAxleLength), std::make_shared<P3>()}));
166 void ModifiedThreePlayerIntersectionExample::ConstructInitialState() {
167 x0_ = VectorXf::Zero(dynamics_->XDim());
168 x0_(kP1XIdx) = kP1InitialX;
169 x0_(kP1YIdx) = kP1InitialY;
170 x0_(kP1HeadingIdx) = kP1InitialHeading;
171 x0_(kP1VIdx) = kP1InitialSpeed;
172 x0_(kP2XIdx) = kP2InitialX;
173 x0_(kP2YIdx) = kP2InitialY;
174 x0_(kP2HeadingIdx) = kP2InitialHeading;
175 x0_(kP2VIdx) = kP2InitialSpeed;
176 x0_(kP3XIdx) = kP3InitialX;
177 x0_(kP3YIdx) = kP3InitialY;
178 x0_(kP3HeadingIdx) = kP3InitialHeading;
179 x0_(kP3VIdx) = kP3InitialSpeed;
182 void ModifiedThreePlayerIntersectionExample::ConstructPlayerCosts() {
184 player_costs_.emplace_back(
"P1", kStateRegularization,
185 kControlRegularization);
186 player_costs_.emplace_back(
"P2", kStateRegularization,
187 kControlRegularization);
188 player_costs_.emplace_back(
"P3", kStateRegularization,
189 kControlRegularization);
190 auto& p1_cost = player_costs_[0];
191 auto& p2_cost = player_costs_[1];
192 auto& p3_cost = player_costs_[2];
195 const Polyline2 lane1(
196 {Point2(kP1InitialX, -1000.0), Point2(kP1InitialX, 1000.0)});
197 const Polyline2 lane2(
198 {Point2(kP2InitialX, 1000.0), Point2(kP2InitialX, 28.0),
199 Point2(kP2InitialX + 0.5, 25.0), Point2(kP2InitialX + 1.0, 24.0),
200 Point2(kP2InitialX + 3.0, 22.5), Point2(kP2InitialX + 6.0, 22.0),
201 Point2(1000.0, 22.0)});
202 const Polyline2 lane3(
203 {Point2(-1000.0, kP3InitialY), Point2(1000.0, kP3InitialY)});
205 const std::shared_ptr<QuadraticPolyline2Cost> p1_lane_cost(
206 new QuadraticPolyline2Cost(kLaneCostWeight, lane1, {kP1XIdx, kP1YIdx},
208 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane_r_cost(
209 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane1,
210 {kP1XIdx, kP1YIdx}, kLaneHalfWidth,
211 kOrientedRight,
"LaneRightBoundary"));
212 const std::shared_ptr<SemiquadraticPolyline2Cost> p1_lane_l_cost(
213 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane1,
214 {kP1XIdx, kP1YIdx}, -kLaneHalfWidth,
215 !kOrientedRight,
"LaneLeftBoundary"));
216 p1_cost.AddStateCost(p1_lane_cost);
217 p1_cost.AddStateCost(p1_lane_r_cost);
218 p1_cost.AddStateCost(p1_lane_l_cost);
220 const std::shared_ptr<QuadraticPolyline2Cost> p2_lane_cost(
221 new QuadraticPolyline2Cost(kLaneCostWeight, lane2, {kP2XIdx, kP2YIdx},
223 const std::shared_ptr<SemiquadraticPolyline2Cost> p2_lane_r_cost(
224 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane2,
225 {kP2XIdx, kP2YIdx}, kLaneHalfWidth,
226 kOrientedRight,
"LaneRightBoundary"));
227 const std::shared_ptr<SemiquadraticPolyline2Cost> p2_lane_l_cost(
228 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane2,
229 {kP2XIdx, kP2YIdx}, -kLaneHalfWidth,
230 !kOrientedRight,
"LaneLeftBoundary"));
231 p2_cost.AddStateCost(p2_lane_cost);
232 p2_cost.AddStateCost(p2_lane_r_cost);
233 p2_cost.AddStateCost(p2_lane_l_cost);
235 const std::shared_ptr<QuadraticPolyline2Cost> p3_lane_cost(
236 new QuadraticPolyline2Cost(kLaneCostWeight, lane3, {kP3XIdx, kP3YIdx},
238 const std::shared_ptr<SemiquadraticPolyline2Cost> p3_lane_r_cost(
239 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane3,
240 {kP3XIdx, kP3YIdx}, kLaneHalfWidth,
241 kOrientedRight,
"LaneRightBoundary"));
242 const std::shared_ptr<SemiquadraticPolyline2Cost> p3_lane_l_cost(
243 new SemiquadraticPolyline2Cost(kLaneBoundaryCostWeight, lane3,
244 {kP3XIdx, kP3YIdx}, -kLaneHalfWidth,
245 !kOrientedRight,
"LaneLeftBoundary"));
246 p3_cost.AddStateCost(p3_lane_cost);
247 p3_cost.AddStateCost(p3_lane_r_cost);
248 p3_cost.AddStateCost(p3_lane_l_cost);
251 const auto p1_min_v_cost = std::make_shared<SemiquadraticCost>(
252 kMaxVCostWeight, kP1VIdx, kMinV, !kOrientedRight,
"MinV");
253 const auto p1_max_v_cost = std::make_shared<SemiquadraticCost>(
254 kMaxVCostWeight, kP1VIdx, kP1MaxV, kOrientedRight,
"MaxV");
255 const auto p1_nominal_v_cost = std::make_shared<QuadraticCost>(
256 kNominalVCostWeight, kP1VIdx, kP1NominalV,
"NominalV");
257 p1_cost.AddStateCost(p1_min_v_cost);
258 p1_cost.AddStateCost(p1_max_v_cost);
259 p1_cost.AddStateCost(p1_nominal_v_cost);
261 const auto p2_min_v_cost = std::make_shared<SemiquadraticCost>(
262 kMaxVCostWeight, kP2VIdx, kMinV, !kOrientedRight,
"MinV");
263 const auto p2_max_v_cost = std::make_shared<SemiquadraticCost>(
264 kMaxVCostWeight, kP2VIdx, kP2MaxV, kOrientedRight,
"MaxV");
265 const auto p2_nominal_v_cost = std::make_shared<QuadraticCost>(
266 kNominalVCostWeight, kP2VIdx, kP2NominalV,
"NominalV");
267 p2_cost.AddStateCost(p2_min_v_cost);
268 p2_cost.AddStateCost(p2_max_v_cost);
269 p2_cost.AddStateCost(p2_nominal_v_cost);
271 const auto p3_min_v_cost = std::make_shared<SemiquadraticCost>(
272 kMaxVCostWeight, kP3VIdx, kMinV, !kOrientedRight,
"MinV");
273 const auto p3_max_v_cost = std::make_shared<SemiquadraticCost>(
274 kMaxVCostWeight, kP3VIdx, kP3MaxV, kOrientedRight,
"MaxV");
275 const auto p3_nominal_v_cost = std::make_shared<QuadraticCost>(
276 kNominalVCostWeight, kP3VIdx, kP3NominalV,
"NominalV");
277 p3_cost.AddStateCost(p3_min_v_cost);
278 p3_cost.AddStateCost(p3_max_v_cost);
279 p3_cost.AddStateCost(p3_nominal_v_cost);
282 const auto p1_omega_cost = std::make_shared<QuadraticCost>(
283 kOmegaCostWeight, kP1OmegaIdx, 0.0,
"Steering");
284 const auto p1_jerk_cost =
285 std::make_shared<QuadraticCost>(kACostWeight, kP1AIdx, 0.0,
"A");
286 p1_cost.AddControlCost(0, p1_omega_cost);
287 p1_cost.AddControlCost(0, p1_jerk_cost);
289 const auto p2_omega_cost = std::make_shared<QuadraticCost>(
290 kOmegaCostWeight, kP2OmegaIdx, 0.0,
"Steering");
291 const auto p2_jerk_cost = std::make_shared<QuadraticCost>(
292 kACostWeight, kP2AIdx, 0.0,
"Acceleration");
293 p2_cost.AddControlCost(1, p2_omega_cost);
294 p2_cost.AddControlCost(1, p2_jerk_cost);
296 const auto p3_omega_cost = std::make_shared<QuadraticCost>(
297 kOmegaCostWeight, kP3OmegaIdx, 0.0,
"Steering");
298 const auto p3_a_cost = std::make_shared<QuadraticCost>(kACostWeight, kP3AIdx,
299 0.0,
"Acceleration");
300 p3_cost.AddControlCost(2, p3_omega_cost);
301 p3_cost.AddControlCost(2, p3_a_cost);
304 const std::shared_ptr<ProxCost> p1p2_proximity_cost(
305 new ProxCost(kProximityCostWeight, {kP1XIdx, kP1YIdx}, {kP2XIdx, kP2YIdx},
306 kMinProximity,
"ProxCostP2"));
307 const std::shared_ptr<ProxCost> p1p3_proximity_cost(
308 new ProxCost(kProximityCostWeight, {kP1XIdx, kP1YIdx}, {kP3XIdx, kP3YIdx},
309 kMinProximity,
"ProxCostP3"));
310 p1_cost.AddStateCost(p1p2_proximity_cost);
311 p1_cost.AddStateCost(p1p3_proximity_cost);
313 const std::shared_ptr<ProxCost> p2p1_proximity_cost(
314 new ProxCost(kProximityCostWeight, {kP2XIdx, kP2YIdx}, {kP1XIdx, kP1YIdx},
315 kMinProximity,
"ProxCostP1"));
316 const std::shared_ptr<ProxCost> p2p3_proximity_cost(
317 new ProxCost(kProximityCostWeight, {kP2XIdx, kP2YIdx}, {kP3XIdx, kP3YIdx},
318 kMinProximity,
"ProxCostP3"));
319 p2_cost.AddStateCost(p2p1_proximity_cost);
320 p2_cost.AddStateCost(p2p3_proximity_cost);
322 const std::shared_ptr<ProxCost> p3p1_proximity_cost(
323 new ProxCost(kProximityCostWeight, {kP3XIdx, kP3YIdx}, {kP1XIdx, kP1YIdx},
324 kMinProximity,
"ProxCostP1"));
325 const std::shared_ptr<ProxCost> p3p2_proximity_cost(
326 new ProxCost(kProximityCostWeight, {kP3XIdx, kP3YIdx}, {kP2XIdx, kP2YIdx},
327 kMinProximity,
"ProxCostP2"));
328 p3_cost.AddStateCost(p3p1_proximity_cost);
329 p3_cost.AddStateCost(p3p2_proximity_cost);
332 inline std::vector<float> ModifiedThreePlayerIntersectionExample::Xs(
333 const VectorXf& x)
const {
334 return {x(kP1XIdx), x(kP2XIdx), x(kP3XIdx)};
337 inline std::vector<float> ModifiedThreePlayerIntersectionExample::Ys(
338 const VectorXf& x)
const {
339 return {x(kP1YIdx), x(kP2YIdx), x(kP3YIdx)};
342 inline std::vector<float> ModifiedThreePlayerIntersectionExample::Thetas(
343 const VectorXf& x)
const {
344 return {x(kP1HeadingIdx), x(kP2HeadingIdx), x(kP3HeadingIdx)};