Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
935665f
initial av_trip_matching code
dhensle Jul 19, 2025
9b63b44
Merge branch 'main' of https://github.com/SANDAG/ABM into ABM3_AV_TNC…
dhensle Jul 19, 2025
53f6955
blacken and correct availability conditions
dhensle Jul 22, 2025
0629a2c
av_repositioning with next trip alternatives
dhensle Jul 28, 2025
25583ad
Merge branch 'main' of https://github.com/SANDAG/ABM into ABM3_AV_TNC…
dhensle Jul 28, 2025
f2c9127
running with av_repositioning
dhensle Aug 18, 2025
304e02b
missed import in extensions init
dhensle Aug 19, 2025
fd9174f
updated utils for av repositioning
aletzdy Sep 4, 2025
67261c7
initial taxi tnc routing commit
dhensle Sep 8, 2025
5b256ee
add timing to tnc routing
dhensle Sep 10, 2025
f4827e1
Merge branch 'ABM3_AV_TNC_routing' of https://github.com/SANDAG/ABM i…
dhensle Sep 10, 2025
ca813ec
working av_repositioning configs
dhensle Sep 12, 2025
dfab2b1
vehicle to trip matching and creation of veh trips
dhensle Sep 16, 2025
18ae057
runtime optimization, multiple trips on tour in time period, trip mat…
dhensle Sep 18, 2025
44e37b8
settings, test scenario code
dhensle Sep 25, 2025
8fbf7b7
tnc vehicle refueling
dhensle Sep 30, 2025
ee5c11d
skim data periods, maz in outputs
dhensle Oct 1, 2025
46fc057
updating av_repositioning to handle multiple trips in tour in time pe…
dhensle Oct 3, 2025
ec134ec
fixing av_repositioning spec bug
dhensle Oct 3, 2025
7215a49
fixing refuel bug
dhensle Oct 15, 2025
e7418ae
fixing deadheading labeling and repositioning choosers
dhensle Oct 21, 2025
14dff05
repositioning spec updates
dhensle Oct 24, 2025
253dbf4
summary plots, special market demand
dhensle Nov 4, 2025
8322dc2
adding distance, batching, output id map, and bug fixes
dhensle Nov 14, 2025
60dd25c
taxi tnc settings yaml update
dhensle Nov 14, 2025
38eaae2
formatting
dhensle Nov 14, 2025
2d1b8f1
adding vehicle occupancy
dhensle Nov 17, 2025
7895862
removing unnecessary dummy coefficients
dhensle Nov 24, 2025
2d0e28c
Adding docstrings
dhensle Nov 24, 2025
1bb7ab9
fixing hard-coded simulation time bin in refueling
dhensle Dec 2, 2025
389cc41
deleting unused argument from check_refuel_needs
dhensle Dec 2, 2025
d031883
fixing bug looking at time instead of dist for refuel
dhensle Dec 2, 2025
039d5cf
implement chunking in av_trip_matching
dhensle Dec 23, 2025
7605180
adding explicit_chunk setting
dhensle Dec 23, 2025
7cd7742
initial commit of tnc_av_matrix_builder.py
dhensle Jan 29, 2026
6a6e1fa
improve mem by dropping unused cols in av_routing
dhensle Jan 29, 2026
6943ed9
blacken taxi_tnc_routing.py
dhensle Jan 29, 2026
62e8620
adding documentation to ABM3 wiki
dhensle Jan 30, 2026
249a439
Adding optional settings for max trips and avs to consider
dhensle Jan 30, 2026
9d3fabb
add user setting to specify the max number of next trips to consider …
dhensle Jan 30, 2026
a8cbc89
fixing pandas future warnings on fillna
dhensle Jan 30, 2026
1c15591
updating default settings for taxi_tnc_routing
dhensle Jan 30, 2026
e161bf5
adding av_routing to settings yamls
dhensle Jan 30, 2026
2a12758
excluding av trips from parking location choice model
dhensle Jan 30, 2026
10ca494
updating path settings to match ABM3 expectations
dhensle Jan 30, 2026
7322af7
sensitivity test summary notebooks
dhensle Jan 30, 2026
3b96120
Merge remote-tracking branch 'origin/main' into ABM3_AV_TNC_routing
dhensle Jan 30, 2026
5cac8ce
integrating updated MAAS into master run
dhensle Jan 30, 2026
1a49739
Add sample rate argument to matrix builder
dhensle Feb 5, 2026
25ba925
putting all tnc routing settings in the yaml file
dhensle Feb 5, 2026
837367a
updating checks on written vs inputs with sample rate
dhensle Feb 12, 2026
dc75ea7
Merge branch 'main' into ABM3_AV_TNC_routing
JiaXu1024 Feb 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/asim/configs/common/constants.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ autoParkingCostFactorAV: {policy-AV-autoParkingCostFactor:}
autoCostPerMileFactorAV: {policy-AV-autoCostPerMileFactor:}
autoTerminalTimeFactorAV: {policy-AV-autoTerminalTimeFactor:}
minAgeDriveAloneAV: {policy-AV-minAgeDriveAlone:}
AV_maxDuration: 1.5 # max duration for keeping car close (hrs)
AV_maxBenefit: 60 # max benefit for keeping car close (mins)
RemoteParkingCostPerHour: 3 #dollar


#valueOfTime: 8.00
Expand Down
31 changes: 31 additions & 0 deletions src/asim/configs/resident/av_repositioning.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Label,Description,Expression,stay_with_person,go_to_parking,go_home,service_next_trip_1,service_next_trip_2,service_next_trip_3
util_dummy_1,Dummy variable 1,1,1,1,1,1,1,1
# stay with person utils,,,,,,,,
util_stay_with_person_avail,Whether auto can park at destination,parkingConstrained,coef_unavailable,,,,,
util_cost_of_parking,Cost of parking at destination,parkingCost,coef_cost,,,,,
util_time_stay,Stay- Need car soon,"@np.where(df.duration_hrs < df.AV_maxDuration, (-1)*(df.AV_maxBenefit + (df.duration_hrs*df.slope)), 0)",coef_ivt,,,,,
# go to parking utils,,,,,,,,
util_time_go_to_parking,Remote- Need car soon,"@np.where(df.duration_hrs < df.AV_maxDuration, (-1)*(df.AV_maxBenefit + (df.duration_hrs*df.slope)), 0)",,coef_ivt,,,,
util_remote_cost,Remote park - Cost of parking until departure,duration_hrs * RemoteParkingCostPerHour * 100,,coef_cost,,,,
util_remote_ivt,in vehicle time to remote parking location,@v_to_parking_skim['SOV_TR_H_TIME'],,coef_ivt,,,,
util_remote_rel,reliability vehicle location to remote parking location,"@v_to_parking_skim['SOV_TR_H_REL'] * 14 / np.maximum(0.1, v_to_parking_skim['SOV_TR_H_DIST'])",,coef_ivt,,,,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What exactly is the factor 14 we are multiplying reliability by?

util_remote_auto_cost,auto operating cost from vehicle location to remote parking location,@(v_to_parking_skim['SOV_TR_H_DIST'] * costPerMile * autoCostPerMileFactorAV) + v_to_parking_skim['SOV_TR_H_TOLLCOST'],,coef_cost,,,,
# go home utils,,,,,,,,
util_home_ivt,in vehicle time to go home,@v_to_home_skim['SOV_TR_H_TIME'],,,coef_ivt,,,
util_home_rel,reliability vehicle location to home,"@v_to_home_skim['SOV_TR_H_REL'] * 14 / np.maximum(0.1, v_to_home_skim['SOV_TR_H_DIST'])",,,coef_ivt,,,
util_home_auto_cost,auto operating cost from vehicle location to home,@(v_to_home_skim['SOV_TR_H_DIST'] * costPerMile * autoCostPerMileFactorAV) + v_to_home_skim['SOV_TR_H_TOLLCOST'],,,coef_cost,,,
# service next trip util 1,,,,,,,,
util_next_trip_available,Unavailable if no next trip,next_trip_id_1 == -1,,,,coef_unavailable,,
util_next1_ivt,in vehicle time to next trip 1 origin,v_to_trip_orig1_time,,,,coef_ivt,,
util_next1_rel,reliability vehicle location to next trip 1 origin,"@df.v_to_trip_orig1_rel * 14 / np.maximum(0.1, df.v_to_trip_orig1_dist)",,,,coef_ivt,,
util_next1_auto_cost,auto operating cost from vehicle location to next trip 1 origin,@(df.v_to_trip_orig1_dist * costPerMile * autoCostPerMileFactorAV) + df.v_to_trip_orig1_toll,,,,coef_cost,,
# service next trip util 2,,,,,,,,
util_next_trip_available,Unavailable if no next trip,next_trip_id_2 == -1,,,,,coef_unavailable,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Based on line 28, should this be "util_next_trip_available_2"?

util_next2_ivt,in vehicle time to next trip 2 origin,v_to_trip_orig2_time,,,,,coef_ivt,
util_next2_rel,reliability vehicle location to next trip 2 origin,"@df.v_to_trip_orig2_rel * 14 / np.maximum(0.2, df.v_to_trip_orig2_dist)",,,,,coef_ivt,
util_next2_auto_cost,auto operating cost from vehicle location to next trip 2 origin,@(df.v_to_trip_orig2_dist * costPerMile * autoCostPerMileFactorAV) + df.v_to_trip_orig2_toll,,,,,coef_cost,
# service next trip util 3,,,,,,,,
util_next_trip_available_3,Unavailable if no next trip 3,next_trip_id_3 == -1,,,,,,coef_unavailable
util_next3_ivt,in vehicle time to next trip 3 origin,v_to_trip_orig3_time,,,,,,coef_ivt
util_next3_rel,reliability vehicle location to next trip 3 origin,"@df.v_to_trip_orig3_rel * 14 / np.maximum(0.3, df.v_to_trip_orig3_dist)",,,,,,coef_ivt
util_next3_auto_cost,auto operating cost from vehicle location to next trip 3 origin,@(df.v_to_trip_orig3_dist * costPerMile * autoCostPerMileFactorAV) + df.v_to_trip_orig3_toll,,,,,,coef_cost
4 changes: 4 additions & 0 deletions src/asim/configs/resident/av_repositioning_coefficients.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
coefficient_name,value,constrain
coef_unavailable,-999.0,F
coef_ivt,-0.03,F
coef_cost,-0.002,F
51 changes: 51 additions & 0 deletions src/asim/configs/resident/av_repositioning_preprocessor.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Description,Target,Expression
next trip start time,next_depart,df['trip_id'].map(trips.groupby('tour_id')['depart'].shift(-1).to_dict())
trip duration,duration_hrs,"np.where(next_depart.isna(), 0, next_depart - df.depart) / 2"
duration benefit,duration_benefit,"np.where((duration_hrs < 1.5) & (duration_hrs > 0), 60 - (60/1.5 * duration_hrs), 0)"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

duration_benefit term is not being used in av_repositioning.csv, maybe drop?

#Parking cost calculation,,
,tour_id,"reindex(trips.tour_id, df.trip_id)"
,tour_type,"reindex(tours.tour_type, tour_id)"
,person_id,"reindex(trips.person_id, df.trip_id)"
,ptype,"reindex(persons.ptype, person_id)"
,free_parking_at_work,"reindex(persons.free_parking_at_work, person_id)"
,free_parking_available,(tour_type == 'work') & free_parking_at_work
,number_of_participants,"reindex(tours.number_of_participants, tour_id)"
,is_indiv,(number_of_participants == 1)
person has free on-site parking at workplace,freeOnsite,"(free_parking_available)*np.where(is_indiv,1,0)"
new reimbursement amount,reimburseProportion,0
tour primary destination,tour_dest,"reindex(tours.destination, tour_id)"
half tour duration,tourDuration,"reindex(tours.duration, tour_id)/2"
new daily parking cost with reimbursement,parkingCostDayDollars,"reindex(land_use.exp_daily, tour_dest)"
new hourly parking cost with reimbursement,parkingCostHourDollars,"reindex(land_use.exp_hourly, tour_dest)"
new monthly parking cost with reimbursement,parkingCostMonthDollars,"reindex(land_use.exp_monthly, tour_dest)"
daily cost converted to cents,parkingCostDay,parkingCostDayDollars*100
hourly cost converted to cents,parkingCostHour,parkingCostHourDollars*100
monthly cost converted to cents,parkingCostMonth,parkingCostMonthDollars*100
Trip parking cost for full-time workers and university students,_parkingCostBeforeReimb,"ptype.isin([1,3]).values * is_indiv * np.minimum(parkingCostMonth/22, parkingCostDay)"
Trip parking cost for full-time workers and university students,_parkingCostBeforeReimb,"ptype.isin([1,3]).values * is_indiv * np.minimum(_parkingCostBeforeReimb, parkingCostHour * duration_hrs)"
,is_joint,(number_of_participants > 1)
Trip parking cost for other person types,parkingCostBeforeReimb,"np.where((~ptype.isin([1,3]).values * is_indiv) | (is_joint), np.minimum(parkingCostDay, parkingCostHour * duration_hrs), _parkingCostBeforeReimb)"
Reimbursement applies to this tour purpose,reimbursePurpose,tour_type=='work'
Effective parking cost for free parkers,_parkingCost,"0 * np.where(reimbursePurpose*freeOnsite,1,0)"
Effective parking cost for reimbursed parkers,_parkingCost,"np.where(is_indiv*reimbursePurpose*(1-freeOnsite), np.maximum((1-reimburseProportion) * parkingCostBeforeReimb, 0),_parkingCost)"
Effective parking cost,parkingCost,"np.where(is_joint+is_indiv*(1-reimbursePurpose), parkingCostBeforeReimb,_parkingCost)"
# These following two are from AutonomousVehicleAllocationChoice.xls,,
Maximim benefit for keeping car close (min),AV_maxBenefit,60
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We don't need to define these here because they are in configs/common/constants.yaml?

Maximum duration for keeping car close (hrs),AV_maxDuration,1.5
Slope of benefit calculation,slope, (-1)*(AV_maxBenefit / AV_maxDuration)
# below taken from parametersByYear.csv,,
,RemoteParkingCostPerHour,0.81
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same comment as above.

#,,
,parkingConstrained,"reindex(land_use.parking_type,df.destination)==1"
,v_to_trip_orig1_time,"np.where(df.next_trip_id_1 > 0, v_to_trip_orig1_skim['SOV_TR_H_TIME'], 0)"
,v_to_trip_orig2_time,"np.where(df.next_trip_id_2 > 0, v_to_trip_orig2_skim['SOV_TR_H_TIME'], 0)"
,v_to_trip_orig3_time,"np.where(df.next_trip_id_3 > 0, v_to_trip_orig3_skim['SOV_TR_H_TIME'], 0)"
,v_to_trip_orig1_dist,"np.where(df.next_trip_id_1 > 0, v_to_trip_orig1_skim['SOV_TR_H_DIST'], 0)"
,v_to_trip_orig2_dist,"np.where(df.next_trip_id_2 > 0, v_to_trip_orig2_skim['SOV_TR_H_DIST'], 0)"
,v_to_trip_orig3_dist,"np.where(df.next_trip_id_3 > 0, v_to_trip_orig3_skim['SOV_TR_H_DIST'], 0)"
,v_to_trip_orig1_rel,"np.where(df.next_trip_id_1 > 0, v_to_trip_orig1_skim['SOV_TR_H_REL'], 0)"
,v_to_trip_orig2_rel,"np.where(df.next_trip_id_2 > 0, v_to_trip_orig2_skim['SOV_TR_H_REL'], 0)"
,v_to_trip_orig3_rel,"np.where(df.next_trip_id_3 > 0, v_to_trip_orig3_skim['SOV_TR_H_REL'], 0)"
,v_to_trip_orig1_toll,"np.where(df.next_trip_id_1 > 0, v_to_trip_orig1_skim['SOV_TR_H_TOLLCOST'], 0)"
,v_to_trip_orig2_toll,"np.where(df.next_trip_id_2 > 0, v_to_trip_orig2_skim['SOV_TR_H_TOLLCOST'], 0)"
,v_to_trip_orig3_toll,"np.where(df.next_trip_id_3 > 0, v_to_trip_orig3_skim['SOV_TR_H_TOLLCOST'], 0)"
37 changes: 37 additions & 0 deletions src/asim/configs/resident/av_routing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# spec and coefficients for AV trip matching model
AV_TRIP_MATCHING_SPEC: av_trip_matching.csv
AV_TRIP_MATCHING_COEFFICIENTS: av_trip_matching_coefficients.csv

# spec and coefficients for AV repositioning model
AV_REPOSITIONING_SPEC: av_repositioning.csv
AV_REPOSITIONING_COEFFICIENTS: av_repositioning_coefficients.csv

# needed to pass logit settings validation, but not used in this model
SPEC: None

# Column in landuse DataFrame that indicates if a zone has AV parking available
AV_PARKING_ZONE_COLUMN: remoteAVParking

# Skim core for nearest parking zone calculations
NEAREST_ZONE_SKIM: DIST

# List of modes that are eligible for routing with a household AV
DRIVING_MODES:
- DRIVEALONE
- SHARED2
- SHARED3

av_trip_matching_preprocessor:
SPEC: av_trip_matching_preprocessor.csv
DF: df
TABLES:
- trips

av_repositioning_preprocessor:
SPEC: av_repositioning_preprocessor.csv
DF: df
TABLES:
- trips
- land_use
- tours
- persons
10 changes: 10 additions & 0 deletions src/asim/configs/resident/av_trip_matching.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Label,Description,Expression,coefficient
util_dummy_1,Dummy variable 1,1,coef_one
util_veh_to_trip_origin_time,Time veh to trip origin,"@np.where((df.veh_location == df.origin) | (df.veh_location < 0) | (df.origin < 0), 0, veho_tripo_t_skims['SOV_TR_L_TIME'])",coef_ivt
util_veh_to_trip_origin_cost,cost veh to trip origin,"@np.where((df.veh_location == df.origin) | (df.veh_location < 0) | (df.origin < 0), 0, (df.auto_operating_cost * veho_tripo_t_skims['SOV_TR_L_DIST']) + veho_tripo_t_skims['SOV_TR_L_TOLLCOST'])",coef_cost
# *14 multiplier to convert from ivt to reliability as used in previous iteration,,,
util_veh_to_trip_origin_reliability,reliability veh to trip origin,"@np.where((df.veh_location == df.origin) | (df.veh_location < 0) | (df.origin < 0), 0, veho_tripo_t_skims['SOV_NT_L_REL']) * 14",coef_ivt
util_trip_duration,Trip duration,df.duration_benefit,coef_ivt
util_no_vehicle,Alternative unavailable if no vehicle,df.vehicle_id.isna() & (df.trip_number > 0),coef_unavailable
util_no_trip,unavailable if no trip and alt is not idle,df.trip_id.isna() & (df.trip_number > 0),coef_unavailable
util_idle,Do not service any trips,(df.trip_number == 0) & ~df.vehicle_id.isna(),coef_idle
6 changes: 6 additions & 0 deletions src/asim/configs/resident/av_trip_matching_coefficients.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coefficient_name,value,constrain
coef_unavailable,-999.0,F
coef_one,1.0,F
coef_idle,-10.0,F
coef_ivt,-0.03,F
coef_cost,-0.002,F
4 changes: 4 additions & 0 deletions src/asim/configs/resident/av_trip_matching_preprocessor.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Description,Target,Expression
next trip start time,next_depart,df['trip_id'].map(trips.groupby('tour_id')['depart'].shift(-1).to_dict())
trip duration,duration_hrs,"np.where(next_depart.isna(), 0, next_depart - df.depart) / 2"
duration benefit,duration_benefit,"np.where((duration_hrs < 1.5) & (duration_hrs > 0), 60 - (60/1.5 * duration_hrs), 0)"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need to get AV_maxduration and AV_maxbenefit from configs/common/constants.yaml here?

1 change: 1 addition & 0 deletions src/asim/extensions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from . import av_ownership
from . import av_routing
from . import external_identification
from . import external_location_choice
from . import transponder_ownership
Expand Down
Loading