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

feat: canceling prebooked drt requests #2930

Merged
merged 13 commits into from
Nov 21, 2023
Merged

feat: canceling prebooked drt requests #2930

merged 13 commits into from
Nov 21, 2023

Conversation

sebhoerl
Copy link
Contributor

Context
This is a follow-up PR to #2826. While #2826 introduces functionality to prebook requests in DRT, it is mainly aimed at fleet simulations where each person represents a single trip. Once we run simulations with a whole population, congestion, etc., things become trickier: What happens if we have a prebooked request, but the agent gets stuck during the day. Then the vehicle would wait indefinitely for the passenger. So as a remedy, we necessarily need some functionality to cancel requests during the day. And since we need the functionality in any case, it makes sense to also offer it as a clear interface, which allows modellers to set up an even more complex logic if they need to.

Interface
The main interface is added to the PrebookingManager that now allows, besides prebooking an agent's leg, to also cancel the associated request:

PrebookingManager.cancel(Leg)

The PrebookingManager also automatically cancels requests of agents for which a PersonStuckEvent is detected.

Scheduling
Technically, canceling a request means unscheduling the request if it has already been assigned to a vehicle. Currently, there are two implementations that can be chosen from the PrebookingParams:

  • SimpleUnscheduler simply removes DrtRequests from their associated DrtStopTask. This means that the vehicle will still visit the stop location, even if the stop becomes empty. However, this is a very robust and simple way to unschedule requests.
  • ComplexUnscheduler is a more complicated implementation that will perform the necessary rewriting of the schedule if in the process described above, some stops are left without any pickups or dropoffs. There is an extensive unit test covering this class, but I'm still not 100% sure if it will cover all potential edge cases. This is why I made it optional, with the simple version being the default.

DRT Changes
Major changes in DRT are that the DrtStopTask now has remove* methods, otherwise only prebooking code is affected.

Abandoning
Referring to the example from above (agent gets stuck), the concept of "abandoning a request" is introduced. Technically, the PrebookingStopActivity will always wait for a passenger until the earliestDepartureTime of the request has been reached. Beyond that point, it will make use of the AbandonVoter interface to check if the request should be left behind (which means canceling it). The default implementation, MaximumDelayAbandonVoter, will wait for an additional maximum delay and then abandon the request. This delay can be configured in the PrebookingParams and is set to infinity (= never) by default.

@sebhoerl
Copy link
Contributor Author

Right now all the commits from #2826 are included here. Once this one is merged, I will do a rebase.

@sebhoerl
Copy link
Contributor Author

Voilà, here is the rebase. The only major change in DRT (modulo prebooking) is that DrtStopTask gets two additional methods removePickupRequest and removeDropoffRequest.

@sebhoerl sebhoerl requested a review from michalmac November 16, 2023 16:18
Copy link
Member

@michalmac michalmac left a comment

Choose a reason for hiding this comment

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

Nice to have this functionality! 💯

I think there are a few issues that require addressing before merging (especially the ones around thread safety).

@sebhoerl
Copy link
Contributor Author

The race condition problem is a tricky one, I thought that at last in doSimStep we have synchronized on all events, but this doesn't seem to be the case ...

@michalmac
Copy link
Member

The race condition problem is a tricky one, I thought that at last in doSimStep we have synchronized on all events, but this doesn't seem to be the case ...

I think MobsimAfterSimStepListener is safe (at least as long as you do not trigger new events there).

@sebhoerl
Copy link
Contributor Author

Should be thread-safe now. I collect all scheduled/rejected/stuck events during the simulation step and process everything in notifyMobsimAfterSimStep. Also, I collect all outgoing events (booked/rejected) and publish them in the next simulation step.

@sebhoerl
Copy link
Contributor Author

Actually, forgot to switch processEvent/flushEvents to the next simstep after testing compatibility with the current version. This probably shifts some things by one second. Coming up.

@sebhoerl sebhoerl merged commit 6988e84 into master Nov 21, 2023
48 checks passed
@sebhoerl sebhoerl deleted the feat/canceling branch November 21, 2023 10:41
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