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

Vehicle assignments #85

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft

Conversation

antrim
Copy link

@antrim antrim commented Dec 13, 2024

Proposed spec in response to issue #28 "Allocating drivers and vehicles in ODS".
Includes changes for PR #81 "potential rosters and employee assignment spec". (We can take this out if it causes process issues)

Copy link

@antrim
Copy link
Author

antrim commented Dec 13, 2024

Based on this #28 (comment) - what @skyqrose outlined in August

Notes:

  • vehicles.txt and vehicle_categories.txt crib liberally from http://bit.ly/gtfs-vehicles. That proposal aligned with platform descriptions for GTFS-Pathways. I don't know the current status of that proposal. I included a baseline of fields; perhaps more should be included in this proposal.
  • I considered whether to relate vehicle assignments to run_events.txt, but since mid-run events would never involve the change of a vehicle, this would have created more complexity.
  • vehicle_assignments can map to trip_id or block_id. This is for cases where block_id is not universally supplied, perhaps because a GTFS feed follows the original usage of block_id - indicating allowed in-seat transfers.

@antrim
Copy link
Author

antrim commented Dec 13, 2024

Some internal discussion at Optibus:
Timon Kelter suggested that vehicle_categories sounds very abstract, but vehicle_types would be more natural and is descriptive. I agree. I had was cribbing from the GTFS-Vehicles proposal, but don't see a reason to keep this term. Will plan to change to vehicle_types.txt.
BTW, I have invited Optibus team to share more discussion here. So we'll expose a bit more deliberation that might otherwise have been internal :)

@antrim
Copy link
Author

antrim commented Dec 13, 2024

These are vehicle properties that Optibus currently exports in a non TODS format. Which properties should be included in TODS?

Vehicle properties example.xlsx

vehicle_id ID Identifies a vehicle.
agency_id ID referencing agency.agency_id Agency for the specified vehicle.
start_date Date Day when the vehicle begins to be part of the fleet.
license_plate Text License plate of the specified vehicle.
make Text Make of the specified vehicle.
model Text Model of the specified vehicle.
owner Text Vehicle owner entity.
registration_date Date Date of the first registration.
available_seats Non-negative Integer Number of seating places.
available_standing Non-negative Integer Number of standing places.
typology Enum Vehicle typology.
0 or empty = unknown typology
1 = Urban Mini
2 = Urban Midi
3 = Urban Standard
4 = Urban Articulated
5 = Inter-urban Standard
6 = Inter-urban Articulated
7 = Tourism
vclass Enum Vehicle class.
0 or empty = unknown class
1 = A (Urban Mini)
2 = I (Urban Midi, Urban Standard, Urban Articulated)
3 = II (Inter-urban Standard, Inter-urban Articulated)
4 = III (Tourism)
propulsion Enum Propulsion technology.
0 or empty = unknown propulsion
1 = Gasoline
2 = Diesel
3 = LPG auto
4 = Mixture
5 = Biodiesel
6 = Electricity
7 = Hybrid
8 = Natural Gas
9 = Other
emission Enum Emissions class.
0 or empty = unkwon emissions class
1 = EURO I
2 = EURO II
3 = EURO III
4 = EURO IV
5 = EURO V
6 = EURO VI
new_seminew Enum New or Semi-New.
0 or empty = no
1 = yes
ecological Enum Non-polluting or energy-efficient vehicle.
0 or empty = no
1 = yes
climatization Enum Climatization.
0 or empty = no
1 = yes
wheelchair Enum Wheelchair accessible.
0 or empty = no
1 = yes
corridor Enum Passageway for wheelchairs / baby strollers.
0 or empty = no
1 = yes
lowered_floor Enum Lowered floor.
0 or empty = no
1 = yes
ramp Enum Ramp for people with reduced mobility.
0 or empty = no
1 = yes
folding_system Enum Folding system for boarding and exiting of people with reduced mobility.
0 or empty = no
1 = yes
kneeling Enum Vehicle "kneeling" to reduce entry height.
0 or empty = no
1 = yes
static_information Enum Posters and fixed signage.
0 or empty = no
1 = yes
onboard_monitor Enum On-board monitor.
0 or empty = no
1 = yes
front_display Enum External front destination display.
0 or empty = no
1 = yes
rear_display Enum External rear destination panel.
0 or empty = no
1 = yes
side_display Enum External right side destination panel.
0 or empty = no
1 = yes
internal_sound Enum Internal sound information (on-board Public Address).
0 or empty = no
1 = yes
external_sound Enum External sound information (external Public Address).
0 or empty = no
1 = yes
consumption_meter Enum Consumption measurement.
0 or empty = no
1 = yes
bicycles Enum Permission to transport non-folding bicycles (folding bicycles are always allowed).
0 or empty = no
1 = yes
passenger_counting Enum Vehicle has a passenger counting system.
0 or empty = no
1 = yes
video_surveillance Enum Vehicle has a video surveillance system.
0 or empty = no
1 = yes

@timon-k
Copy link

timon-k commented Dec 13, 2024

From the fields mentioned above, I would remove at least new_seminew, ecological, static_information, onboard_monitor, all *_display fields, all *_sound fields and consumption_meter.

To me, those look too undefined, covered by other attributes like emission already or just not needed for operational purposes.

I'm also very unsure about folding_system, ramp and kneeling. Given that we have wheelchair and lowered_floow already that looks like too many details on the same question.

| `block_id` | ID referencing `trips.block_id` | Conditionally required | Identifies the block. Either `trip_id` or `block_id` must be specified. |
| `trip_id` | ID referencing `trips.trip_id` | Conditionally required | Either `trip_id` or `block_id` must be specified. In the case where both are supplied, `trip_id` overrides `block_id`. Note: multiple vehicles are allowed on the same block+date, but this is not recommended. |
| `vehicle_id` | ID referencing `vehicles.vehicle_id` | Conditionally required | Refers to a specific vehicle in the transit fleet. Either `vehicle_id` or `vehicle_category_id` MUST be supplied. |
| `vehicle_category_id` | ID referencing `vehicle_categories.vehicle_category_id` | Conditionally required | Refers to a category of vehicle in the transit fleet if there is no specific vehicle assignment. Either `vehicle_id` or `vehicle_category_id` MUST be supplied. |
Copy link

Choose a reason for hiding this comment

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

Having the category here sounds good, but perhaps we should then stress that this is the operationally assigned category of vehicle, not the planned one.

The planned vehicle category/type would be more naturally placed in routes_supplement.txt or trips_supplement.txt. Usually, planned and real vehicle type should be identical, but there could be differences.

Copy link
Author

Choose a reason for hiding this comment

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

Yes. GTFS-Vehicles had proposed to add a routes.vehicle_category_id field that would define "a default vehicle category for all trips belonging to this route". This could be useful for rider-facing applications (i.e. accessibility & amenity information) and for planning, scheduling, and operational purposes as well, I imagine.

docs/spec/index.md Outdated Show resolved Hide resolved
@antrim
Copy link
Author

antrim commented Dec 13, 2024

@skyqrose @safrazier17 Can you help guide process here? Since I worked off the #81 branch, this has the rosters and employee assignments spec draft. Should I remove those changes?

Will we vote on the two PRs separately or together? Merge separately?

Copy link
Contributor

@skyqrose skyqrose left a comment

Choose a reason for hiding this comment

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

I've left lots of line-by-line comments.

As for the process, I think this is completely independent from #81. We could split them into two separate PRs/votes.


Not every trip or block and date combo needs to have a vehicle specified.

### `vehicle_categories.txt`
Copy link
Contributor

Choose a reason for hiding this comment

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

If vehicle_categories comes from the other extension, does it need to be part of TODS? Could you instead say that vehicle_category_id references the extension file, which should be in public GTFS, so that the spec isn't duplicated in the extension and in TODS?

Copy link
Author

Choose a reason for hiding this comment

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

It would make sense for vehicle_categories (now vehicle_types.txt) to live outside of TODS. However, I do not believe that it has been implemented yet. So, I think we should implement in TODS in a way that could become part of a "primary GTFS" dataset later.

|---|---|---|---|
| `vehicle_category_id` | ID, primary key | Required | Defines an ID for a vehicle category. |
| `vehicle_category_name` | Text | Optional | The vehicle_category_name field defines the name of the vehicle category. E.g. “MR73” in Montréal, “TGV Duplex” in France or “8-car Waratah Train” in Sydney. |
| `fuel_type` | Enum | Optional | 0 or empty - unknown propulsion <br />1 - Gasoline <br /> 2 - Diesel <br /> 3 - LPG auto <br /> 4 - Mixture <br /> 5 - Biodiesel <br /> 6 - Electricity <br /> 7 - Hybrid <br /> 8 - Natural Gas <br /> 9 - Other |
Copy link
Contributor

Choose a reason for hiding this comment

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

Does there need to be a distinction between battery buses that charge at a station, and trolley buses that charge under catenary? Does there need to be a Hydrogen category?

There are so many options here, I wonder if it'd be better to have an unrestricted string enum, or if the field should be removed and an agency should know (from some other non-TODS record) what fuel type each vehicle_type_name uses.

Copy link
Author

Choose a reason for hiding this comment

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

Also, this list is messy -- properties are mixed up. "Hybrid" isn't a fuel type. For now, I favor removing or replacing with a text string if it's necessary for an immediate use case. (But imagining that the vehicle_category_name could make useful distinctions, e.g. vehicle_category_name="40' LNG Bus".

| `seating_capacity` | Non-negative Integer | Optional | This number denotes the number of seats dedicated to riders, excluding folding seats. A seat is considered accommodating only one rider in a seated position. |
| `max_capacity` | Non-negative Integer | Optional | This number denotes the maximum number of riders that the vehicle can carry. |
| `wheelchair_capacity` | Non-negative Integer | Optional | This number denotes the maximum number of riders in a wheelchair that the vehicle can carry. |

Copy link
Contributor

Choose a reason for hiding this comment

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

There are so many fields that could be included here. (Height clearance, platform height, wheel gauge, length, make, model, ...)

What determines whether something should be included, vs something that should be looked up elsewhere based on vehicle_type_name? If it's referenced in GTFS? If it matters to riders?

Copy link
Author

Choose a reason for hiding this comment

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

At this point, I think we should implement only fields that will be consumed by some software either out-of-the-gate or soon. Any other fields discussed could be implemented when there is a use later.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to exclude folding seats from the seating_capacity field? (Is the idea that it is the max number of seats inclusive of wheelchairs in one vehicle?)

I know there are many agencies that almost exclusively use transverse folding seats, which could lead to artificially-lower seating_capacity values.


| Field Name | Type | Required | Description |
|---|---|---|---|
| `vehicle_id` | ID, primary key | Required | Defines an ID for a vehicle. |
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the same ID as shows up in GTFS-RT? If so, that should probably be mentioned, though agencies might not have a consistent mapping of phsyical vehicle to GTFS-RT vehicle_id, which might make it impossible to use the same ID here.

Copy link
Author

Choose a reason for hiding this comment

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

There is theoretical usefulness of a consistent vehicle_id. So the spec might make a recommendation. How shall we assess this? Ask reps from Transit, Swiftly, GMV, transit agencies or others to say whether this makes sense, offers value?

| `max_capacity` | Non-negative Integer | Optional | This number denotes the maximum number of riders that the vehicle can carry. |
| `wheelchair_capacity` | Non-negative Integer | Optional | This number denotes the maximum number of riders in a wheelchair that the vehicle can carry. |

### `vehicles.txt`
Copy link
Contributor

Choose a reason for hiding this comment

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

How do consists of multiple cars work, both for trains made of all the same car, and trains made of multiple different cars? Would there be a type_id for each type of car, or for each unique way to assemble a train? And then a vehicle_id for each car, or a vehicle_id for the whole train? Is a 4-car train the same type as a 6-car train of the same cars? If a train reverses and now has its control car in front and locomotive in the back, is that the same vehicle_id?

Copy link
Author

Choose a reason for hiding this comment

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

So, this is one of the reasons that I have proposed to build off GTFS-Vehicles. The draft spec has something called GTFS-VehicleCouplings that answers this.

| Field Name | Type | Required | Description |
|---|---|---|---|
| `date` | Date | Required | |
| `service_id` | ID referencing `calendar.service_id` or `calendar_dates.service_id` | Optional | Identifies a set of dates when the run is scheduled to take place. Required if `block_id`s are repeated between different `service_id`s. |
Copy link
Contributor

Choose a reason for hiding this comment

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

description mentions runs, probably a copy-paste error.

How do date and service_id interact? Why do you need service_id when you already have a date? Are block_ids unique within the service but not the date?

Copy link
Author

Choose a reason for hiding this comment

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

description mentions runs, probably a copy-paste error.

Oops, will fix.

Why do you need service_id when you already have a date?

Service periods defined by calendar.txt can overlap. E.g. Monday-Sunday with additional Monday-Friday only trips.

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Minor thing (assuming we're in agreement): we should probably clarify that it's service_date, not just the date of assignment or the trip's calendar date of operation.

| `date` | Date | Required | |
| `service_id` | ID referencing `calendar.service_id` or `calendar_dates.service_id` | Optional | Identifies a set of dates when the run is scheduled to take place. Required if `block_id`s are repeated between different `service_id`s. |
| `block_id` | ID referencing `trips.block_id` | Conditionally required | Identifies the block. Either `trip_id` or `block_id` must be specified. |
| `trip_id` | ID referencing `trips.trip_id` | Conditionally required | Either `trip_id` or `block_id` must be specified. In the case where both are supplied, `trip_id` overrides `block_id`. Note: multiple vehicles are allowed on the same block+date, but this is not recommended. |
Copy link
Contributor

Choose a reason for hiding this comment

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

Would an agency ever schedule multiple vehicles to the same block? Doesn't that go against the definition of block? I know that might happen as a realtime adjustment, but if it's scheduled to happen, shouldn't they change the schedule so it's multiple different blocks?

If we can make that assumption, then this field could be removed.

Copy link
Author

@antrim antrim Dec 15, 2024

Choose a reason for hiding this comment

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

I included trip_id as an option for cases where block_id is not supplied in the GTFS. On 2nd thought I'd favor removing, unless we know this is a case to plan for out of the gate.

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd recommend including it for specific trips. This works for agencies that don't publish blocks and may not wish to make specific trip-specific block assignments in TODS, and likewise works for agencies with interchangeable operations. (I could see us making these assignments on a trip-specific level to specify requirements by trip prior to building out cycles.)

Copy link

Choose a reason for hiding this comment

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

I'm in favour of keeping it as it is now, with the trip_id removed.

If we allow assignments of individual trips to vehicles it breaks the logic of blocks as @skyqrose pointed out.

If we allow assignments of individual trips to vehicle types/categories it overlaps content-wise with http://bit.ly/gtfs-vehicles (which already has a route-to-vehicle-category assignment modeling a "requirement"). The case that you pointed out last ("specify requirements by trip prior to building out cycles") should probably be modeled using http://bit.ly/gtfs-vehicles.

"agencies that don't publish blocks" can still wrap each trip in an artificial block and assign it this way and/or add their real blocks in the non-public trips_supplement.txt only.

So overall, it seems like we can transmit the operational plan (including which vehicles/types will really be running the trips) without allowing to include trip_id in the assignments.

|---|---|---|---|
| `date` | Date | Required | |
| `service_id` | ID referencing `calendar.service_id` or `calendar_dates.service_id` | Optional | Identifies a set of dates when the run is scheduled to take place. Required if `block_id`s are repeated between different `service_id`s. |
| `block_id` | ID referencing `trips.block_id` | Conditionally required | Identifies the block. Either `trip_id` or `block_id` must be specified. |
Copy link
Contributor

Choose a reason for hiding this comment

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

Block could be always required if:

  • We say you can only use this feature if you use block IDs (they're optional in trips.txt)
  • Either:
    • You have to include the block, even if you include the trip. (And the block must be the same block as the trip's block.)
    • trip_id is removed (see previous comment).

Alternatively, it would also be possible to say that exactly one of block_id and trip_id is required, which might be less error-prone than allowing both and ignoring the block if the trip exists.

Copy link
Author

Choose a reason for hiding this comment

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

Let's explore removing vehicle_assignments.trip_id

Copy link
Author

Choose a reason for hiding this comment

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

Comment on lines 227 to 228
| `vehicle_id` | ID referencing `vehicles.vehicle_id` | Conditionally required | Refers to a specific vehicle in the transit fleet. Either `vehicle_id` or `vehicle_type_id` MUST be supplied. |
| `vehicle_type_id` | ID referencing `vehicle_types.vehicle_type_id` | Conditionally required | Refers to a type of vehicle in the transit fleet if there is no specific vehicle assignment. Either `vehicle_id` or `vehicle_type_id` MUST be supplied. |
Copy link
Contributor

Choose a reason for hiding this comment

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

Can both vehicle_id and vehicle_type_id be specified? If so, then the spec should specify that the vehicle must have that type.

Copy link
Author

Choose a reason for hiding this comment

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


### `vehicle_assignments.txt`

Primary Key: `*`
Copy link
Contributor

Choose a reason for hiding this comment

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

This key allows multiple vehicles/types to be assigned to the same block/trip. Is that intentional, as a way to allow any of the vehicles to run the trip? If so, then that should be mentioned in the docs. If not, then a primary key that would prevent that is (date, block_id, trip_id).

Copy link
Author

@antrim antrim Dec 15, 2024

Choose a reason for hiding this comment

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

Hmm… I'll add a primary key. (date, block_id, service_id).
Allowing multiple assignments or planning for vehicle couplings seems like a complex case.

Copy link
Author

Choose a reason for hiding this comment

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

@antrim antrim marked this pull request as draft December 15, 2024 20:24
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.

4 participants