feat: avoid matching departure of prior trips - #609
Conversation
fe6e824 to
cf8e8d9
Compare
| end | ||
|
|
||
| @spec direction_from_stations(String.t(), String.t()) :: :ambiguous | 0 | 1 | ||
| def direction_from_stations(origin, dest) do |
There was a problem hiding this comment.
observation: anecdotally I'm not aware of a significant number of intraday Ashmont-Braintree cross-pollination. I'm fairly confident that makes it okay to remove this, as you wrote in the description?
There was a problem hiding this comment.
Are you talking about the case of handling Ashmont <--> Braintree specifically, or just direction comparison in general?
There was a problem hiding this comment.
I looked more into whether to drop the direction comparison, and I'm leaning toward keeping it? For example, I notice that we detect departure events in the southbound direction at Ashmont (as part of the vehicle turning around), meaning that if we're not careful, we could consider the current trip prematurely departed. I realize that's not exactly the same scenario as what I'm fixing here, but think it still provides value to do this check. Happy to talk about it further.
There was a problem hiding this comment.
...although I am now remembering that we already have special-case handling for Ashmont turnarounds.
|
|
||
| defimpl Jason.Encoder, for: Orbit.Vehicle do | ||
| def encode(value, opts) do | ||
| # Omit the past trips for now, since the frontend does not expect or care about it |
| trips | ||
| |> Enum.map(fn trip -> {trip, match_departure?(trip, event)} end) | ||
| |> Enum.reject(fn {_trip, {result, _}} -> result == :no_match end) | ||
| |> Enum.min_by(fn {_trip, {:match, offset}} -> offset end, fn -> {nil, nil} end) |
There was a problem hiding this comment.
question: is it correct that you're using offset to refer both to OCS offsets as well as match offsets?
There was a problem hiding this comment.
Correct. Now that you point that out, it's maybe confusing. I will consider a different term for the offset here.
|
|
||
| true -> | ||
| expected_departure_time = | ||
| DateTime.add(ocs_trip.scheduled_departure || ocs_trip.assigned_at, ocs_trip.offset || 0) |
There was a problem hiding this comment.
question: could you remind me why assigned_at works as a fallback?
There was a problem hiding this comment.
I am just trying to get a rough idea of when a trip was supposed to depart for comparison with the vehicle event timestamps. Previously, we'd only do this with current trips, which meant that we were comparing against "now". For past trips, I'm using the scheduled start time (+ the inspector offset) if they exist. If not, the assigned_at timestamp is something that I think anecdotally comes in pretty close to departure for most trips, beyond maybe morning pullouts which can get assigned much before the trip leaves.
Realizing that I am adding the offset to the assigned_at time, which is maybe weird. In practice I find it hard to imagine that a trip would have an inspector offset but not a scheduled start time, although I suppose we could be missing the start time if Orbit somehow missed a TSCH_NEW message. Maybe I'll change this to only add the offset in the case that the scheduled departure is used.
Let me know if that answered your question?
There was a problem hiding this comment.
Changed in 7a91269 - Now only adding inspector offset to scheduled time, not assigned_at time
| if best_trip == current do | ||
| put_in(vehicle.ocs_trips.current.actual_departure, actual_departure.timestamp) |
There was a problem hiding this comment.
comment: I'm hoping that as a side effect this helps out with what I was looking into for 🛰️ Investigate how often Orbit trip assignments are for previous trip 🤞 ?
| # Scenario: Vehicle making multiple trips: | ||
| # trip_1: Park St to Braintree | ||
| # trip_2: Braintree to Park St | ||
| # trip_3: Part St to Braintree | ||
| # Current trip is trip_3, but the departure from Park St was not detected | ||
| # so there is no VehicleEvent. However there is a VehicleEvent for the prior | ||
| # departure on trip_1 |
There was a problem hiding this comment.
praise: 🙏🙏🙏🙏🙏🙏🙏 ty for comment on behalf of present and future me
cho-jos
left a comment
There was a problem hiding this comment.
LGTM, though would like resolution of Preston's comment before merge
observation: anecdotally I'm not aware of a significant number of intraday Ashmont-Braintree cross-pollination. I'm fairly confident that makes it okay to remove this, as you wrote in the description?
Asana Task: 🛰️ 🐞 Orbit is sometimes showing Actual Departure for previous trip
Problem
Orbit observes and records
VehicleEvents as vehicles arrive at and depart from stations. These are matched against current trips in OCS to find each vehicle's "Actual" departure time.But sometimes a
VehicleEventis missed, such as in the case captured in the ticket, wherein OCS seemingly skipped some TMOVs, which caused RTR to never publish that the vehicle hadSTOPPED_ATthe trip origin/destination. In such cases, whenTripMatchertries to find the departure event for the given trip, since the event is missing, it may erroneously match to the prior trip's departure, and thereby showing the wrong departure time.We do have a timing threshold in place to try to avoid finding old departures, but it is difficult to pick a single threshold that works in all cases. For example, this ticket demonstrates a case where service from Braintree was only running up to Park St, meaning that the trips were much shorter than usual.
Proposed solution
When checking the most recent departure event for a trip's origin, also consider the known prior trips for the same vehicle, and if there is a better match to a prior trip, then avoid the assignment. Some notes:
Checklist