mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 00:12:55 +03:00
basic impl of crossing entire long lane and waiting at the end
This commit is contained in:
parent
409de8ea83
commit
b547db43b6
@ -43,9 +43,11 @@
|
||||
|
||||
## Discrete-event model
|
||||
|
||||
- make space toggle play for time travel or sim or simple model
|
||||
- Make cars cover an entire lane when it's short or long
|
||||
- avoid impossible accel/deaccel
|
||||
- Handle lead car being faster
|
||||
- The speed stated in the middle of intervals is clearly wrong for the follower car
|
||||
|
||||
- Prototype alternate driving model
|
||||
- branch or forked code?
|
||||
|
@ -1,5 +1,5 @@
|
||||
use geom::{Acceleration, Distance, Duration, Speed};
|
||||
use map_model::{LaneID, Map, Traversable};
|
||||
use map_model::{Lane, LaneID, Map, Traversable};
|
||||
use sim::{CarID, CarState, DrawCarInput, VehicleType};
|
||||
|
||||
const FOLLOWING_DISTANCE: Distance = Distance::const_meters(1.0);
|
||||
@ -24,9 +24,11 @@ impl World {
|
||||
start_dist: Distance::meters(5.0),
|
||||
start_time: Duration::ZERO,
|
||||
};
|
||||
leader.accel_from_rest_to_speed_limit(0.5 * speed_limit);
|
||||
leader.stop_at_end_of_lane(lane, 0.5 * speed_limit);
|
||||
/*leader.accel_from_rest_to_speed_limit(0.5 * speed_limit);
|
||||
leader.freeflow(Duration::seconds(10.0));
|
||||
leader.deaccel_to_rest();
|
||||
leader.deaccel_to_rest();*/
|
||||
leader.wait(Duration::seconds(5.0));
|
||||
|
||||
let mut follower = Car {
|
||||
id: CarID::tmp_new(1, VehicleType::Car),
|
||||
@ -125,7 +127,7 @@ impl Interval {
|
||||
) -> Interval {
|
||||
assert!(start_dist >= Distance::ZERO);
|
||||
assert!(start_time >= Duration::ZERO);
|
||||
assert!(start_dist < end_dist);
|
||||
assert!(start_dist <= end_dist);
|
||||
assert!(start_time < end_time);
|
||||
assert!(start_speed >= Speed::ZERO);
|
||||
assert!(end_speed >= Speed::ZERO);
|
||||
@ -311,6 +313,13 @@ impl Car {
|
||||
self.next_state(speed * time, speed, time);
|
||||
}
|
||||
|
||||
fn freeflow_to_cross(&mut self, dist: Distance) {
|
||||
let speed = self.last_state().1;
|
||||
assert_ne!(dist, Distance::ZERO);
|
||||
|
||||
self.next_state(dist, speed, dist / speed);
|
||||
}
|
||||
|
||||
fn deaccel_to_rest(&mut self) {
|
||||
let speed = self.last_state().1;
|
||||
assert_ne!(speed, Speed::ZERO);
|
||||
@ -328,6 +337,16 @@ impl Car {
|
||||
self.next_state(dist_covered, Speed::ZERO, time_needed);
|
||||
}
|
||||
|
||||
fn stopping_distance(&self, from_speed: Speed) -> Distance {
|
||||
// TODO Copies partly from deaccel_to_rest
|
||||
let time_needed = -from_speed / self.max_deaccel;
|
||||
from_speed * time_needed
|
||||
+ Distance::meters(
|
||||
0.5 * self.max_deaccel.inner_meters_per_second_squared()
|
||||
* time_needed.inner_seconds().powi(2),
|
||||
)
|
||||
}
|
||||
|
||||
// Returns interval indices too.
|
||||
fn find_earliest_hit(&self, other: &Car) -> Option<(Duration, Distance, usize, usize)> {
|
||||
// TODO Do we ever have to worry about having the same intervals? I think this should
|
||||
@ -360,7 +379,7 @@ impl Car {
|
||||
self.intervals.split_off(idx1 + 1);
|
||||
|
||||
// Option 1: Might be too sharp.
|
||||
if false {
|
||||
if true {
|
||||
{
|
||||
let mut our_adjusted_last = self.intervals.pop().unwrap();
|
||||
our_adjusted_last.end_speed = our_adjusted_last.speed(hit_time);
|
||||
@ -429,6 +448,23 @@ impl Car {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn stop_at_end_of_lane(&mut self, lane: &Lane, speed_limit: Speed) {
|
||||
// TODO Argh, this code is awkward.
|
||||
// TODO Handle shorter lanes.
|
||||
self.accel_from_rest_to_speed_limit(speed_limit);
|
||||
let stopping_dist = self.stopping_distance(speed_limit);
|
||||
self.freeflow_to_cross(
|
||||
lane.length() - self.intervals.last().as_ref().unwrap().end_dist - stopping_dist,
|
||||
);
|
||||
self.deaccel_to_rest();
|
||||
}
|
||||
|
||||
fn wait(&mut self, time: Duration) {
|
||||
let speed = self.last_state().1;
|
||||
assert_eq!(speed, Speed::ZERO);
|
||||
self.next_state(Distance::ZERO, Speed::ZERO, time);
|
||||
}
|
||||
}
|
||||
|
||||
fn overlap<A: PartialOrd>((a_start, a_end): (A, A), (b_start, b_end): (A, A)) -> bool {
|
||||
|
@ -137,6 +137,17 @@ impl ops::Div<f64> for Distance {
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Div<Speed> for Distance {
|
||||
type Output = Duration;
|
||||
|
||||
fn div(self, other: Speed) -> Duration {
|
||||
if other == Speed::ZERO {
|
||||
panic!("Can't divide {} / {}", self, other);
|
||||
}
|
||||
Duration::seconds(self.0 / other.0)
|
||||
}
|
||||
}
|
||||
|
||||
// In seconds. Can be negative.
|
||||
// TODO Naming is awkward. Can represent a moment in time or a duration.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user