mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-04 12:36:46 +03:00
Start some new RoutingParams for bikes to avoid steep hills and
stressful roads. Initially experiment in the route debugger UI. #743 This is a binary map format change, but temporarily working around that...
This commit is contained in:
parent
0ad76921fd
commit
8c2c0e2e65
@ -207,7 +207,7 @@ fn params_to_controls(ctx: &mut EventCtx, mode: TripMode, params: &RoutingParams
|
||||
.margin_right(20),
|
||||
Spinner::widget(
|
||||
ctx,
|
||||
"unprotected turn penalty",
|
||||
"unprotected_turn_penalty",
|
||||
(Duration::seconds(1.0), Duration::seconds(100.0)),
|
||||
params.unprotected_turn_penalty,
|
||||
Duration::seconds(1.0),
|
||||
@ -219,7 +219,7 @@ fn params_to_controls(ctx: &mut EventCtx, mode: TripMode, params: &RoutingParams
|
||||
"Bike lane penalty:".text_widget(ctx).margin_right(20),
|
||||
Spinner::widget(
|
||||
ctx,
|
||||
"bike lane penalty",
|
||||
"bike_lane_penalty",
|
||||
(0.0, 2.0),
|
||||
params.bike_lane_penalty,
|
||||
0.1,
|
||||
@ -229,7 +229,7 @@ fn params_to_controls(ctx: &mut EventCtx, mode: TripMode, params: &RoutingParams
|
||||
"Bus lane penalty:".text_widget(ctx).margin_right(20),
|
||||
Spinner::widget(
|
||||
ctx,
|
||||
"bus lane penalty",
|
||||
"bus_lane_penalty",
|
||||
(0.0, 2.0),
|
||||
params.bus_lane_penalty,
|
||||
0.1,
|
||||
@ -239,12 +239,34 @@ fn params_to_controls(ctx: &mut EventCtx, mode: TripMode, params: &RoutingParams
|
||||
"Driving lane penalty:".text_widget(ctx).margin_right(20),
|
||||
Spinner::widget(
|
||||
ctx,
|
||||
"driving lane penalty",
|
||||
"driving_lane_penalty",
|
||||
(0.0, 2.0),
|
||||
params.driving_lane_penalty,
|
||||
0.1,
|
||||
),
|
||||
]));
|
||||
rows.push(Widget::row(vec![
|
||||
"Avoid steep inclines (>= 8%):"
|
||||
.text_widget(ctx)
|
||||
.margin_right(20),
|
||||
Spinner::widget(
|
||||
ctx,
|
||||
"avoid_steep_incline_penalty",
|
||||
(0.0, 2.0),
|
||||
params.avoid_steep_incline_penalty,
|
||||
0.1,
|
||||
),
|
||||
]));
|
||||
rows.push(Widget::row(vec![
|
||||
"Avoid high-stress roads:".text_widget(ctx).margin_right(20),
|
||||
Spinner::widget(
|
||||
ctx,
|
||||
"avoid_high_stress",
|
||||
(0.0, 2.0),
|
||||
params.avoid_high_stress,
|
||||
0.1,
|
||||
),
|
||||
]));
|
||||
}
|
||||
Widget::col(rows)
|
||||
}
|
||||
@ -252,16 +274,18 @@ fn params_to_controls(ctx: &mut EventCtx, mode: TripMode, params: &RoutingParams
|
||||
fn controls_to_params(panel: &Panel) -> (TripMode, RoutingParams) {
|
||||
let mut params = RoutingParams::default();
|
||||
if !panel.is_button_enabled("cars") {
|
||||
params.unprotected_turn_penalty = panel.spinner("unprotected turn penalty");
|
||||
params.unprotected_turn_penalty = panel.spinner("unprotected_turn_penalty");
|
||||
return (TripMode::Drive, params);
|
||||
}
|
||||
if !panel.is_button_enabled("pedestrians") {
|
||||
return (TripMode::Walk, params);
|
||||
}
|
||||
params.unprotected_turn_penalty = panel.spinner("unprotected turn penalty");
|
||||
params.bike_lane_penalty = panel.spinner("bike lane penalty");
|
||||
params.bus_lane_penalty = panel.spinner("bus lane penalty");
|
||||
params.driving_lane_penalty = panel.spinner("driving lane penalty");
|
||||
params.unprotected_turn_penalty = panel.spinner("unprotected_turn_penalty");
|
||||
params.bike_lane_penalty = panel.spinner("bike_lane_penalty");
|
||||
params.bus_lane_penalty = panel.spinner("bus_lane_penalty");
|
||||
params.driving_lane_penalty = panel.spinner("driving_lane_penalty");
|
||||
params.avoid_steep_incline_penalty = panel.spinner("avoid_steep_incline_penalty");
|
||||
params.avoid_high_stress = panel.spinner("avoid_high_stress");
|
||||
(TripMode::Bike, params)
|
||||
}
|
||||
|
||||
@ -400,7 +424,7 @@ impl State<App> for AllRoutesExplorer {
|
||||
((*after as isize) - (*before as isize)).abs() as usize
|
||||
})
|
||||
.max()
|
||||
.unwrap() as f64;
|
||||
.unwrap_or(0) as f64;
|
||||
for (r, before, after) in comparisons {
|
||||
match after.cmp(&before) {
|
||||
std::cmp::Ordering::Less => {
|
||||
|
@ -159,11 +159,28 @@ pub fn zone_cost(mvmnt: MovementID, constraints: PathConstraints, map: &Map) ->
|
||||
pub struct RoutingParams {
|
||||
// For all vehicles. This is added to the cost of a movement as an additional delay.
|
||||
pub unprotected_turn_penalty: Duration,
|
||||
|
||||
// For bike routing. Multiplied by the base cost, since spending more time on the wrong lane
|
||||
// type matters.
|
||||
pub bike_lane_penalty: f64,
|
||||
pub bus_lane_penalty: f64,
|
||||
pub driving_lane_penalty: f64,
|
||||
|
||||
// For bike routing.
|
||||
// "Steep" is a fixed threshold of 8% incline, uphill only. Multiply by the base cost. (Note
|
||||
// that cost already includes a reduction of speed to account for the incline -- this is a
|
||||
// further "delay" on top of that!)
|
||||
// TODO But even steeper roads matter more!
|
||||
// TODO Serialize as usual. Requires regenerating all maps, not ready to do that yet.
|
||||
#[serde(skip_serializing, skip_deserializing, default = "one")]
|
||||
pub avoid_steep_incline_penalty: f64,
|
||||
// If the road is `high_stress_for_bikes`, multiply by the base cost.
|
||||
#[serde(skip_serializing, skip_deserializing, default = "one")]
|
||||
pub avoid_high_stress: f64,
|
||||
}
|
||||
|
||||
fn one() -> f64 {
|
||||
1.0
|
||||
}
|
||||
|
||||
impl RoutingParams {
|
||||
@ -172,9 +189,13 @@ impl RoutingParams {
|
||||
// This is a total guess -- it really depends on the traffic patterns of the particular
|
||||
// road at the time we're routing.
|
||||
unprotected_turn_penalty: Duration::const_seconds(30.0),
|
||||
|
||||
bike_lane_penalty: 1.0,
|
||||
bus_lane_penalty: 1.1,
|
||||
driving_lane_penalty: 1.5,
|
||||
|
||||
avoid_steep_incline_penalty: 1.0,
|
||||
avoid_high_stress: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,10 +317,31 @@ pub fn vehicle_cost(
|
||||
PathConstraints::Pedestrian => unreachable!(),
|
||||
};
|
||||
|
||||
let mut multiplier = 1.0;
|
||||
if constraints == PathConstraints::Bike && params.avoid_steep_incline_penalty != 1.0 {
|
||||
let road = map.get_r(dr.id);
|
||||
let percent_incline = if dr.dir == Direction::Fwd {
|
||||
road.percent_incline
|
||||
} else {
|
||||
-road.percent_incline
|
||||
};
|
||||
if percent_incline >= 0.08 {
|
||||
multiplier *= params.avoid_steep_incline_penalty;
|
||||
}
|
||||
}
|
||||
|
||||
if constraints == PathConstraints::Bike && params.avoid_high_stress != 1.0 {
|
||||
let road = map.get_r(dr.id);
|
||||
if road.high_stress_for_bikes(map) {
|
||||
multiplier *= params.avoid_high_stress;
|
||||
}
|
||||
}
|
||||
|
||||
let mut extra = Duration::ZERO;
|
||||
// Penalize unprotected turns at a stop sign from smaller to larger roads.
|
||||
if map.is_unprotected_turn(dr.id, mvmnt.to.id, mvmnt_turn_type) {
|
||||
base + params.unprotected_turn_penalty
|
||||
} else {
|
||||
base
|
||||
extra += params.unprotected_turn_penalty
|
||||
}
|
||||
|
||||
multiplier * base + extra
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user