use rustsim::prelude::{AllowedModes, LinkClass, LinkProperties, TravelMode};
use rustsim::rustsim_mobility::prelude::*;
use rustsim::rustsim_traffic::{TransportLinkMetadata, TransportLinkOps, TransportLinkSpace};
use rustsim::rustsim_transit::{Boarding, Route, Schedule, Stop, TransitVehicle, Waiter};
use rustsim::rustsim_vehicle::{idm, Vehicle, VehicleModel};
fn main() {
let mut network = TransportLinkSpace::new();
let home = network.add_node();
let stop_a = network.add_node();
let stop_b = network.add_node();
let work = network.add_node();
let (walk_geom, walk_props) = LinkProperties::pedestrian(80.0, 3.0).unwrap();
let walk_to_stop = network
.add_link(home, stop_a, walk_geom, walk_props)
.unwrap();
let (bus_geom, bus_props) = LinkProperties::urban(600.0, 40.0, 1).unwrap();
let bus_link = network
.add_link(stop_a, stop_b, bus_geom, bus_props)
.unwrap();
let (walk_out_geom, walk_out_props) = LinkProperties::pedestrian(80.0, 3.0).unwrap();
let walk_to_work = network
.add_link(stop_b, work, walk_out_geom, walk_out_props)
.unwrap();
let (direct_geom, direct_props) = LinkProperties::pedestrian(1_200.0, 3.0).unwrap();
let direct_walk = network
.add_link(home, work, direct_geom, direct_props)
.unwrap();
let metadata = vec![
TransportLinkMetadata::new(
walk_to_stop,
home,
stop_a,
LinkClass::Walkway,
AllowedModes::pedestrian_only(),
),
TransportLinkMetadata::new(
bus_link,
stop_a,
stop_b,
LinkClass::Transitway,
AllowedModes::none().with_mode(TravelMode::Transit),
),
TransportLinkMetadata::new(
walk_to_work,
stop_b,
work,
LinkClass::Walkway,
AllowedModes::pedestrian_only(),
),
TransportLinkMetadata::new(
direct_walk,
home,
work,
LinkClass::Walkway,
AllowedModes::pedestrian_only(),
),
];
let graph = ModalGraph::from_transport_links(&network, metadata).unwrap();
let route = shortest_path(
&graph,
home as u64,
work as u64,
AllowedModes::pedestrian_only().with_mode(TravelMode::Transit),
)
.unwrap();
println!(
"nodes={:?}, total_cost_s={:.1}",
route.nodes, route.total_cost
);
let stop_a_def = Stop::at_ground(10, "Home stop", 80.0, 0.0, 80);
let stop_b_def = Stop::at_ground(20, "Work stop", 680.0, 0.0, 80);
let transit_route = Route::new(
5,
"Blue",
vec![stop_a_def.id, stop_b_def.id],
vec![network.link_free_flow_time(bus_link)],
Schedule::fixed_headway(300.0),
);
let plan = TripPlan {
id: 1,
legs: vec![
Leg::Walk {
from: Waypoint::ground(0.0, 0.0),
to: Waypoint::ground(stop_a_def.pos[0], stop_a_def.pos[1]),
},
Leg::Transit {
route: transit_route.id,
board_at: stop_a_def.id,
alight_at: stop_b_def.id,
},
Leg::Walk {
from: Waypoint::ground(stop_b_def.pos[0], stop_b_def.pos[1]),
to: Waypoint::ground(760.0, 0.0),
},
],
};
let traveller_id = 42;
let controller = ModeController;
let mut traveller = TravellerContext::new(traveller_id);
controller.enter_current_leg(&mut traveller, &plan);
controller.complete_leg(&mut traveller, &plan);
let mut queue = Boarding::new();
let waiter = Waiter {
passenger: traveller_id,
destination: stop_b_def.id,
arrived_at: 0.0,
};
assert!(CapacityStopQueuePolicy.can_enqueue(&stop_a_def, &queue, &waiter));
queue.enqueue(waiter);
assert_eq!(
ScheduledDispatchPolicy.decide(DispatchContext::new(&transit_route, 0.0)),
DispatchDecision::Dispatch { departure_s: 0.0 }
);
let mut service = TransitVehicle::idle(99, transit_route.id, 30);
let mut passenger_destinations = Vec::new();
let boarded = queue.board_vehicle_with_policy(
&mut service,
&transit_route.stops,
&mut passenger_destinations,
&FifoBoardingPolicy::unlimited(),
);
let dwell = LinearDwellPolicy::default().dwell_time(0, boarded.boarded);
controller.board_transit(&mut traveller, service.id, stop_b_def.id);
network
.add_agent_to_link(service.id, bus_link, 0.0)
.unwrap();
let speed = network
.agent_speed_with_policy(service.id, &FifoGapPolicy::default())
.unwrap();
network.advance_agent(service.id, speed * 10.0).unwrap();
let bus = Vehicle {
pos: [stop_a_def.pos[0], stop_a_def.pos[1]],
speed,
..Vehicle::default_bus()
};
let mut bus_platoon = [bus];
rustsim::rustsim_vehicle::IntelligentDriverModel.step(
&mut bus_platoon,
&idm::Params::default(),
1.0,
);
let bus = bus_platoon[0];
let pedestrian = rustsim::rustsim_crowd::Pedestrian::new(
[stop_a_def.pos[0] - 2.0, 0.0],
[1.0, 0.0],
0.25,
1.3,
[stop_a_def.pos[0], 0.0],
);
let ped_obstacle = PedestrianObstacle::ground(traveller_id, &pedestrian).snapshot();
let bus_obstacle = VehicleObstacle::ground(service.id, &bus).snapshot();
let alighted = service.alight_at(stop_b_def.id, &passenger_destinations);
controller.alight_transit(&mut traveller, &plan);
controller.complete_leg(&mut traveller, &plan);
println!(
"boarded={}, dwell_s={:.1}, alighted={}, bus_x={:.1}, ped_radius={:.2}, bus_radius={:.2}, final_state={:?}",
boarded.boarded,
dwell.total,
alighted.len(),
bus.pos[0],
ped_obstacle.radius,
bus_obstacle.radius,
traveller.state
);
assert_eq!(traveller.state, ModeState::Finished);
}