Open BTollison opened 9 months ago
It should be a stop_id when route_id is present or ops_location_id when is_deadhead = 1 Deadheads can happen to/from revenue stops.
In revenue service, how do the runtimes interact with dwell times? Are the runtimes always between adjacent stops, or could you have a runtime that covers multiple stations including their dwell times? Are the start/end always the arrival at a station, always the departure, or could it be either?
Would this proposal also need a way to describe typical dwell times and turnaround times?
I realize this is not currently supported in ODS, but I'll reiterate something I brought forth in some of the preliminary working group sessions (to minimize headache in adoption/extension down the road): the rail world often includes a number of non-public locations and/or timepoints on revenue trips.
The broader implication is that, in order for ODS to be adopted in the rail world, we need a mechanism to supplement existing stop_times.txt
entries with times at ops_location.txt
locations.
The specific implication relevant to this thread, though, is that the rail world requires the ability to have from
and to
locations reflect a pairing of both a stop_id
AND an ops_location_id
. Otherwise, as an example, an export from our scheduling system's database would omit standardized runtimes for any pair of subsequent passenger stops for which a switch or signal is located between the two stations.
Likewise, to Sky's point as it applies to default dwells, I think it's worth including standardized dwell times in this file, too. I believe many systems already model dwell as simply a runtime between a location and itself.
For dwell times, I think it would be valid to have a runtime between 1 point.
runtimes.txt | ||||
---|---|---|---|---|
start_time | end_time | from | to | runtime |
6:00 | 6:29:59 | a | b | 5 |
6:00 | 6:29:59 | b | b | 2 |
6:00 | 6:29:59 | b | c | 5 |
So where to from / to is both B that means that the vehicle should not move for 2 minutes.
For the situation where a runtime is between a service and non-service location, I guess in theory that could work right? The main thing would be the ops_location_id's and stop_id's need to be generated in a way where all values are unique. Is that currently how we think about this? I am definitely for this, that would eliminate the need to have separate deadhead and stop_id fields when looking to assign a from and a to location.
deadhead_times.txt
already has separate stop_id
and ops_location_id
columns, so I wouldn't mind this file, having four from_ops_location_id | from_stop_id | to_ops_location_id | to_stop_id
columns, but I think we should also separately note in ops_locations.txt
that the ops_location_id
s should ("SHOULD"? "MUST"?) be different from stop_id
s.
Edit: ops location ids are now going to be added as a _supplement
into stops.txt
so the column will just be to/from_stop_id
now.
If we represent dwell times as a runtime from a station to itself, is there a way to represent turnaround times at the end of the route? That might be useful for, e.g., generating predictions for when a return trip is going to start.
Minor idea: If the end_time
is exclusive instead of inclusive, then the end_times could be like 07:00:00
instead of 06:59:59
, which might be easier to deal with and prevent bugs. (E.g. if someone looks up the current runtime when it's 06:59:59.581.)
Yeah, I see how stop_id and ops_location_id have been incorporated into the other files, it feels like more of a workaround because there's no explicit "they must all be unique" clause. So, I am fully agreed that this would be the best approach.
We currently represent turnaround times that way. So long as the scheduling team has deadheads (ideally with distance), that should work.
I like the idea of exclusive, :) although I have never encountered a scheduling team that goes beyond seconds I could see how a real-time system may get tripped up!
To follow up on my earlier comment (https://github.com/cal-itp/operational-data-standard/issues/42#issuecomment-1836723950) which perhaps foreshadowed the supplemental GTFS concept (https://github.com/cal-itp/operational-data-standard/issues/55), we should be all set here with the caveat that from
and to
must now always equal a stop_id
in the ODS-supplemented GTFS data (i.e. public GTFS after processing the _supplement
files).
For dwells, I support treating them as runtime from x
to x
(akin to how most scheduling systems support it). Should the need ever arise to define turnaround times, I'd suggest those just be modeled as runtimes from a1
to a2
where a1
and a2
are children of the same parent (presumably a
in this example) in the ODS-supplemented GTFS, even if modeled to the same stop in the public GTFS.
And yes, I very much like @skyqrose's suggestion of exclusive for end_time
, even if most scheduling systems are currently inclusive.
@BTollison do you agree with @skyqrose and @jeffkessler-keolis 's comments above on handling?
@safrazier17 Agreed.
@jeffkessler-keolis Turnaround times are often modeled as runtimes between two children of a parent stop, so this indeed is covered (although perhaps different for rail due to collision avoidance needs?)
Revised for TODS 2.0
service_Id
From calendar.txt
or calendar_dates.txt
, runtimes.txt
entries are tied to a service_id
to ensure that they are up to date and relevant for the selected route and trips.
route_id
From routes.txt,
route_id
is used to tie the entry back to a route if relevant. When it is left blank it is assumed to be global.
shape_id
or direction_id
has a value.route_id
is supplied, it is assumed this is the default runtime for any service in this segment and is only superseded by an entry that has a route_id
for the same segment and overlapping start_time
and end_time
.direction_id
From trips.txt
, direction_id
is required when route_id
is present to differentiate runtime direction.
shape_id
Shape_id
is used to tie a runtime to a particular route_id
and shape_id
. If shape_id
is present then route_id
and direction_id
should have values.
from The from location that the runtime applies to.
stop_id
from either stops.txt
or stops_supplement.txt
timepoint
= 1 then a timepoint
is public, but if timepoint
= 0 then that timepoint
is for internal use.to The to location that the runtime applies to.
stop_id
from either stops.txt
or stops_supplement.txt
timepoint
= 1 then a timepoint
is public, but if timepoint
= 0 then that timepoint
is for internal use.start_time The start time of the period of which the runtime applies.
end_time The end time of the period of which the runtime applies.
runtime The amount of time it takes to travel from one point to another in seconds.
is_revenue Denotes if the runtime applies to in service trips or only non-revenue trips.
runtime_style Enum value for types of runtime. There are various methods for distributing running time, however it is not possible at the time of this proposal to add all of them due to a lack of information on how some of these runtimes are applied by some software.
0 = segment - this is by far the most common method of distributing running time. If there is a runtime between points A and B with running time periods between 6:00 and 6:29:59 of 5 minutes, and another runtime period between 6:30:00 and 6:59:59 of 6 minutes. A trip departing at point A at 6:29 will receive the running time of 5 minutes. If the trip were to depart at 6:30, then it would receive 6 minutes, this would be the case all trips up to the end of the period at 6:59:59.
1 = build location - this is when all running time periods for a trip are based on a specified point on a trip.
runtime_build_point
= 1 in stop_times_supplement.txt
from issue #43 @jeffkessler-keolis has a concern about running times that are regardling vehicles that are intended to stop and vehicles that are inteded to pass through locations. not_stopping
as a boolean value could be a solution, where 0 = stopping and 1 would mean that the vehicle does not stop. You can have two entries with the opposite boolean value to describe both situations. I shall investigate if this applies to other parts of the world to ensure completeness.
@BTollison's note is correct; for further context, the distinction that matters is whether something is passing at full-speed or a reduced speed (either stopping at a passenger station or slowing to diverge/"turn" at a switch). The default assumption for all points should be "stopping," unless otherwise designated. Since this parameter is dependent on the condition at both the start and end locations, this could either be Boolean fields of passing_from
and passing_to
, that each default to 0
("stopping" / slowing for a reduced speed diverging move), or 1
("passing" the point at full-speed). Another valid approach, per @BTollison's suggestion, would be to use a single field with an enum, such as:
0
: Stopping/slowing at both the "From" and "To" locations.1
: Passing at both the "From" and "To" locations.2
: Stopping/slowing at the "From" location, and passing at the "To" location.3
: Passing at the "From" location, and stopping/slowing at the "To" location.
The purpose of this proposal is to easily send running time information between software packages. In the current state, software must interpolate the running times from trips. However, if a trip is modified or if trips were generated with runtimes that are not "segment" based, it may be impossible to interpolate them. This is especially problematic in network planning software, where a user may want to modify trips and frequency but has no insight into when running times change during the day.
service_Id From calendar.txt or calendar_dates.txt, runtimes are tied to a service_id to ensure that they are up to date and relevant for the selected route and trips.
route_id From routes.txt, route_id is used to tie the runtime back to a route if relevant. When it is left blank it is assumed to be global.
direction_id From trips.txt, direction_id is required when route_id is present to differentiate runtime direction.
shape_id Shape_id is used to tie a runtime to a particular route_id and shape_id. If shape_id is present then route_id and direction_id should have values.
from The from location that the runtime applies to.
to The to location that the runtime applies to.
start_time The start time of the period of which the runtime applies.
end_time The end time of the period of which the runtime applies.
runtime The amount of time it takes to travel from one point to another in seconds.
is_deadhead Denotes if the runtime applies to in service trips or only deadhead trips.
runtime_style Enum value for types of runtime. There are various methods for distributing running time, however it is not possible at the time of this proposal to add all of them due to a lack of information on how some of these runtimes are applied by some software.
0 = segment - this is by far the most common method of distributing running time. If there is a runtime between points A and B with running time periods between 6:00 and 6:29:59 of 5 minutes, and another runtime period between 6:30:00 and 6:59:59 of 6 minutes. A trip departing at point A at 6:29 will receive the running time of 5 minutes. If the trip were to depart at 6:30, then it would receive 6 minutes, this would be the case all trips up to the end of the period at 6:59:59.
1 = build location - this is when all running time periods for a trip are based on a specified point on a trip.