Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Variable phase #433

Merged
merged 2 commits into from
Dec 24, 2020
Merged

Add a Variable phase #433

merged 2 commits into from
Dec 24, 2020

Conversation

BruceBrown
Copy link
Contributor

Variable provides a min duration, a delay duration, and an additional duration. The maximum cycle time is min + additional. Once min has been exhausted, if there is demand, the cycle is extended by delay until there isn't any demand or the additional duration has been consumed.

Fix divide by zero.
Switch seattle_traffic_signals back.

Variable provides a min duration, a delay duration, and an additional duration. The maximum cycle time is min + additional. Once min has been exhausted, if there is demand, the cycle is extended by delay until there isn't any demand or the additional duration has been consumed.

Fix divide by zero.
Switch seattle_traffic_signals back.
Copy link
Collaborator

@dabreegster dabreegster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's awesome to see what feels like a complicated feature get implemented so simply. Thanks for doing this!

Could you run cargo update -p seattle_traffic_signals so the changes to Cargo.lock are in this PR too? Otherwise the change in the other git repo aren't picked up

@@ -72,6 +72,7 @@ struct State {
struct SignalState {
current_stage: usize,
stage_ends_at: Time,
iteration_count: usize,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other two variables are reasonably self-explanatory from the name. It's not clear what the iteration is without reading the code later. What if we called this extensions_count and had a comment like "The number of times a variable stage has been extended". Or maybe the var name is fine and just the comment would help

.small_heading()
.draw(ctx)]),
Widget::row(vec![
"Seconds:".draw_text(ctx),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd look slightly better with a .centered_vert() here and for the other two; mind adding it?

@@ -79,7 +114,9 @@ impl SimpleState<App> for ChangeDuration {
let new_type = if panel.is_checked("phase type") {
PhaseType::Fixed(dt)
} else {
PhaseType::Adaptive(dt)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this confused me a fair bit. I set the two new spinners but didn't toggle to adaptive, and I couldn't figure out why my changes weren't taking effect. How about we get rid of the Checkbox::toggle entirely and decide between Fixed and Variable based on if delay and additional are nonzero.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to think about that. I agree the toggle is sub-optimal. I actually had wanted a radio button, to preserve Adaptive, but opted out of it. I've done that several times as well, forgetting to toggle. In my head I'm trying to reconcile if just having additional != 0 is sufficient. However, it leaves delay dangling out there with no meaning for a fixed signal, which I dislike almost as much as having two fields being used to indicate fixed. Originally, I considered disabling/enabling delay and additional based upon the checkbox.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely something that @muzlee1113 can help with. The API for doing it isn't very ergonomic, but you can make the two extra sliders appear/disappear based on something being checked. You'd listen for Outcome::Changed, then do panel.replace() to make things appear or disappear.

For the purposes of this PR, we can leave it as it is.

@@ -212,7 +222,13 @@ fn draw_time_left(
) {
let radius = Distance::meters(2.0);
let center = app.map().get_i(i).polygon.center();
let percent = time_left / stage.phase_type.simple_duration();
let duration = stage.phase_type.simple_duration();
let percent = time_left
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think let percent = if duration > Duration::ZERO { time_left / duration } else { 1.0 } would be more clear

t <= Duration::seconds(5.0),
(t / stage.phase_type.simple_duration()) as f32,
)
if stage.phase_type.simple_duration() > Duration::const_seconds(0.0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use Duration::ZERO here

} else {
(false, 1.0)
};
let yellow = Color::YELLOW;
// The warning color for fixed is yellow, for anything else its orange to clue the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set a generous additional and delay time as an example, and watched the color become darker green, then jump to orange, then back to green (as the extra time was over 5s), then back to orange again, before finally going to the next stage. A little unintuitive at first, but I think it works. It's nice to be able to clearly see more detail!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be changed by checking the counter. We can make it part of a second PR.

}

impl PhaseType {
// TODO Maybe don't have this; force callers to acknowledge different policies
pub fn simple_duration(&self) -> Duration {
match self {
PhaseType::Fixed(d) | PhaseType::Adaptive(d) => *d,
PhaseType::Variable(duration, delay, _) => {
if *duration > Duration::const_seconds(0.0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duration::ZERO

@@ -134,6 +135,7 @@ impl IntersectionSimState {
}
if self.break_turn_conflict_cycles {
if let AgentID::Car(car) = agent {
//self.blocked_by.drain_filter(|(_, c)| *c == car);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the tmp debugging bit

Copy link
Contributor Author

@BruceBrown BruceBrown Dec 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, that drain_filter is a Rust experimental feature, which replaces this:
retain_btreeset(&mut self.blocked_by, |(_, c)| *c != car);
I was playing with it and forgot to remove the commented out line. Eventually, it should be used instead, although the predicate has opposite meaning, so caution should be used. I think I'll leave a todo in its place with appropriate commentary.

@BruceBrown
Copy link
Contributor Author

It's awesome to see what feels like a complicated feature get implemented so simply. Thanks for doing this!

Could you run cargo update -p seattle_traffic_signals so the changes to Cargo.lock are in this PR too? Otherwise the change in the other git repo aren't picked up

I didn't realize you committed the .lock file -- I guess I assumed you'd just generate on a checkout. I'll make the change.

@dabreegster
Copy link
Collaborator

I didn't realize you committed the .lock file -- I guess I assumed you'd just generate on a checkout.

I was confused about this for a while too, but then someone pointed me at https://doc.rust-lang.org/cargo/faq.html#why-do-binaries-have-cargolock-in-version-control-but-not-libraries

Additionally, swapped order of variable edit, to be Additional time, followed by delay.
@dabreegster dabreegster merged commit 3be45b8 into a-b-street:master Dec 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants