1use crate::conflict::ConflictPoint;
2use crate::debug::take_debug_frame;
3use crate::light::TrafficLight;
4use crate::link::{Link, LinkAttributes, TrafficControl};
5use crate::math::CubicFn;
6use crate::vehicle::{LaneChange, Vehicle, VehicleAttributes};
7use crate::{LinkGroup, LinkId, LinkSet, TrafficLightId, VehicleId, VehicleSet};
8use serde::{Deserialize, Serialize};
9use slotmap::SlotMap;
10use std::rc::Rc;
11
12#[derive(Default, Clone, Serialize, Deserialize)]
14pub struct Simulation {
15 links: LinkSet,
17 lights: SlotMap<TrafficLightId, TrafficLight>,
19 vehicles: VehicleSet,
21 conflicts: Vec<ConflictPoint>,
23 frozen_vehs: Vec<VehicleId>,
25 frame: usize,
27 seq: usize,
29 debug: serde_json::Value,
31}
32
33impl Simulation {
34 pub fn new() -> Self {
36 Default::default()
37 }
38
39 pub fn add_link(&mut self, attributes: &LinkAttributes) -> LinkId {
41 self.links.insert_with_key(|id| Link::new(id, attributes))
42 }
43
44 pub fn add_link_group(&mut self, link_ids: &[LinkId]) {
47 let links = link_ids
48 .iter()
49 .map(|id| &self.links[*id])
50 .collect::<Vec<_>>();
51 let group = Rc::new(LinkGroup::new(&links));
52 for id in link_ids {
53 self.links[*id].set_group(group.clone());
54 }
55 }
56
57 pub fn add_lane_change(&mut self, from: LinkId, to: LinkId) {
60 self.links[from].add_lane_change(to);
61 }
62
63 pub fn add_link_convergance(&mut self, a: LinkId, b: LinkId) {
65 if let Some([a, b]) = self.links.get_disjoint_mut([a, b]) {
66 if let Some(conflict_point) = ConflictPoint::new(a, b) {
67 for (link_id, link_conflict) in conflict_point.link_conflicts() {
68 self.links[link_id].add_conflict(link_conflict);
69 }
70 self.conflicts.push(conflict_point);
71 }
72 }
73 }
74
75 pub fn add_link_connection(&mut self, from: LinkId, to: LinkId) {
77 self.links[from].add_link_out(to);
78 self.links[to].add_link_in(from);
79 }
80
81 pub fn add_traffic_light(&mut self, light: TrafficLight) -> TrafficLightId {
83 self.lights.insert(light)
84 }
85
86 pub fn add_vehicle(&mut self, attributes: &VehicleAttributes, link: LinkId) -> VehicleId {
88 let vehicle_id = self.vehicles.insert_with_key(|id| {
89 let mut vehicle = Vehicle::new(id, attributes);
90 vehicle.set_location(link, 0.0, None);
91 vehicle.update_coords(&self.links);
92 vehicle
93 });
94 self.links[link].insert_vehicle(&self.vehicles, vehicle_id);
95 vehicle_id
96 }
97
98 pub fn set_vehicle_frozen(&mut self, vehicle_id: VehicleId, frozen: bool) {
102 let idx = self.frozen_vehs.iter().position(|id| *id == vehicle_id);
103 match (frozen, idx) {
104 (true, None) => {
105 self.frozen_vehs.push(vehicle_id);
106 }
107 (false, Some(idx)) => {
108 self.frozen_vehs.remove(idx);
109 }
110 _ => {}
111 }
112 }
113
114 pub fn get_vehicle_frozen(&mut self, vehicle_id: VehicleId) -> bool {
116 self.frozen_vehs.iter().any(|id| *id == vehicle_id)
117 }
118
119 pub fn step(&mut self, dt: f64) {
123 self.update_lights(dt);
124 self.apply_accelerations();
125 self.integrate(dt);
126 self.advance_vehicles();
127 self.update_vehicle_coords();
128 self.take_debug_frame();
129 self.frame += 1;
130 }
131
132 pub fn step_fast(&mut self, dt: f64) {
139 self.update_lights(dt);
140 self.integrate(dt);
141 self.advance_vehicles();
142 self.update_vehicle_coords();
143 self.take_debug_frame();
144 self.frame += 1;
145 }
146
147 pub fn frame(&self) -> usize {
149 self.frame
150 }
151
152 pub fn iter_links(&self) -> impl Iterator<Item = &Link> {
154 self.links.iter().map(|(_, link)| link)
155 }
156
157 pub fn iter_vehicles(&self) -> impl Iterator<Item = &Vehicle> {
159 self.vehicles.iter().map(|(_, veh)| veh)
160 }
161
162 pub fn get_vehicle(&self, vehicle_id: VehicleId) -> &Vehicle {
164 &self.vehicles[vehicle_id]
165 }
166
167 pub fn get_link(&self, link_id: LinkId) -> &Link {
169 &self.links[link_id]
170 }
171
172 pub fn set_link_control(&mut self, link_id: LinkId, control: TrafficControl) {
174 self.links[link_id].set_control(control);
175 }
176
177 pub fn debug(&mut self) -> serde_json::Value {
179 self.debug.take()
180 }
181
182 fn take_debug_frame(&mut self) {
184 self.debug = take_debug_frame();
185 }
186
187 fn update_lights(&mut self, dt: f64) {
189 for (_, light) in &mut self.lights {
190 light.step(dt);
191 for (link_id, control) in light.get_states() {
192 self.links[link_id].set_control(control);
193 }
194 }
195 }
196
197 fn apply_accelerations(&mut self) {
199 for (_, link) in &mut self.links {
200 link.deactivate();
201 }
202 for (_, vehicle) in &mut self.vehicles {
203 vehicle.reset();
204 vehicle.activate_links(&mut self.links);
205 }
206 self.apply_stoplines();
207 self.apply_link_accelerations();
208 self.apply_frozen_vehicles();
209 }
210
211 fn apply_stoplines(&self) {
214 for (_, link) in &self.links {
215 link.apply_stoplines(&self.links, &self.vehicles);
216 }
217 }
218
219 fn apply_link_accelerations(&mut self) {
221 for (_, link) in &self.links {
222 link.apply_accelerations(&self.links, &self.vehicles);
223 }
224 for conflict in &self.conflicts {
225 conflict.apply_accelerations(&self.links, &self.vehicles);
226 }
227 }
228
229 fn apply_frozen_vehicles(&mut self) {
231 self.frozen_vehs.retain(|vehicle_id| {
232 if let Some(vehicle) = self.vehicles.get(*vehicle_id) {
233 vehicle.emergency_stop();
234 true
235 } else {
236 false
237 }
238 })
239 }
240
241 fn integrate(&mut self, dt: f64) {
244 for (_, vehicle) in &mut self.vehicles {
245 vehicle.integrate(dt, &mut self.seq);
246 }
247 }
248
249 fn advance_vehicles(&mut self) {
252 let mut advanced = vec![];
253 let mut exited = vec![];
254
255 for (vehicle_id, vehicle) in &mut self.vehicles {
256 let link_id = vehicle.link_id().unwrap();
257 let did_advance = vehicle.advance(&self.links);
258
259 if did_advance {
260 self.links[link_id].remove_vehicle(vehicle_id);
261 if let Some(link_id) = vehicle.link_id() {
262 advanced.push((vehicle_id, link_id));
264 } else {
265 exited.push(vehicle_id);
267 }
268 }
269 }
270
271 for (vehicle_id, link_id) in advanced {
272 self.links[link_id].insert_vehicle(&self.vehicles, vehicle_id);
273 }
274
275 for vehicle_id in exited {
276 self.vehicles.remove(vehicle_id);
277 }
278 }
279
280 fn update_vehicle_coords(&mut self) {
282 for (_, vehicle) in &mut self.vehicles {
283 vehicle.update_coords(&self.links);
284 }
285 }
286
287 pub fn do_lane_change(&mut self, vehicle_id: VehicleId, link_id: LinkId, distance: f64) {
290 let vehicle = &mut self.vehicles[vehicle_id];
291
292 if let Some(link_id) = vehicle.link_id() {
294 self.links[link_id].remove_vehicle(vehicle_id);
295 }
296
297 let link = &mut self.links[link_id];
299 let (pos, offset, slope) = link
300 .curve()
301 .inverse_sample(vehicle.position(), vehicle.direction())
302 .unwrap();
303
304 let end_pos = pos + distance;
306 let lane_change = LaneChange {
307 end_pos,
308 offset: CubicFn::fit(pos, offset, slope, end_pos, 0.0, 0.0),
309 };
310 vehicle.set_location(link_id, pos, Some(lane_change));
311
312 link.insert_vehicle(&self.vehicles, vehicle_id);
314 }
315
316 pub fn set_vehicle_route(&mut self, vehicle_id: VehicleId, route: &[LinkId]) {
319 self.vehicles[vehicle_id].set_route(route, true);
320 }
321}