Comprehensive Traffic Generation Example#
This demo shows all the possible ways of generating traffic by PyBTLS and conducts load effect calculation for an example bridge. Again, 1-month data is generated in this example.
The steps are:
Step 1: Define the traffic generators;
Step 2: Define the bridge and the load effect being interested;
Step 3: Request the output we want - the time-history data, and the vehicle files;
Step 4: Set and start a new simulation;
Step 5: Load the generated traffic data.
Compared to the previous Basic Example, the bridge definition step is new here. The traffic generation part is more detailed and includes all the possible ways of generating traffic in PyBTLS.
Import all the necessary modules.
[1]:
import pybtls as pb
from pathlib import Path
Step 1: Define four traffic generators for four lanes. Note that we do not do this in practice, and here is just for illustration purpose.
PyBTLS provides three vehicle generators and four headway generators. Except for the HeDS headway generator, all other vehicle and headway generators can be combined freely to form different traffic generators.
Vehicle Generators |
Descriptions |
|---|---|
Grave |
Trucks are generated from pre-defined distributions |
Garage |
Trucks are sampled from an existing WIM database |
Nominal |
Trucks are based on a user-defined vehicle |
Headway Generators |
Descriptions |
|---|---|
Freeflow |
Headways follow the Poisson arrival model |
Congested |
Headways are generated based on user-defined jam spacing and flow speed |
Constant |
Headways are constant values, and flow speed is constant |
HeDS |
A truck-only headway model specifically proposed for Auxerre trucks |
1.1 Lane 1 -> Grave (Auxerre) + HeDS
1.2 Lane 2 -> Garage + Freeflow
1.3 Lane 3 -> Garage + Congested
1.4 Lane 4 -> Nominal + Constant
[2]:
traffic_gen = pb.TrafficGenerator(no_lane = 4)
1.1 Lane 1 -> Grave (Auxerre) + HeDS
[3]:
lfc_lane1 = pb.LaneFlowComposition(lane_index = 1, lane_dir = 1)
lfc_lane1.assign_lane_data( # 24 hours per day by default
hourly_truck_flow=[80] * 24,
hourly_car_flow=[20] * 24,
hourly_speed_mean=[80 / 3.6 * 10] * 24, # in dm/s
hourly_speed_std=[10 / 3.6 * 10] * 24, # in dm/s
hourly_truck_composition=[[23, 2.8, 31.7, 42.5]] * 24,
)
vehicle_gen_lane1 = pb.VehicleGenGrave(traffic_site = "Auxerre")
headway_gen_lane1 = pb.HeadwayGenHeDS()
traffic_gen.add_lane(
vehicle_gen = vehicle_gen_lane1,
headway_gen = headway_gen_lane1,
lfc = lfc_lane1,
)
1.2 Lane 2 -> Garage + Freeflow
[4]:
lfc_lane2 = pb.LaneFlowComposition(lane_index = 2, lane_dir = 1)
lfc_lane2.assign_lane_data( # 24 hours per day by default
hourly_truck_flow=[80] * 24,
hourly_car_flow=[20] * 24,
hourly_speed_mean=[80 / 3.6 * 10] * 24, # in dm/s
hourly_speed_std=[10 / 3.6 * 10] * 24, # in dm/s
)
# Note that we do not need the truck composition information here, as the garage already contains it.
garage = pb.garage.read_garage_file(
garage_path = Path("./garage.txt"),
garage_format = 4,
)
vehicle_gen_lane2 = pb.VehicleGenGarage(
garage = garage,
kernel = [ # The kernel ensures variety in vehicle configuration
[1.0, 0.08],
[1.0, 0.05],
[1.0, 0.02]
],
)
headway_gen_lane2 = pb.HeadwayGenFreeflow()
traffic_gen.add_lane(
vehicle_gen = vehicle_gen_lane2,
headway_gen = headway_gen_lane2,
lfc = lfc_lane2,
)
1.3 Lane 3 -> Garage + Congested
[5]:
lfc_lane3 = pb.LaneFlowComposition(lane_index = 3, lane_dir = 1)
lfc_lane3.assign_lane_data( # We dont need any information from lfc for congested headway generation actually, but we still need to assign something.
hourly_truck_flow=[1] * 24,
hourly_car_flow=[1] * 24,
)
garage = pb.garage.read_garage_file(
garage_path = Path("./garage.txt"),
garage_format = 4,
)
vehicle_gen_lane3 = pb.VehicleGenGarage(
garage = garage,
kernel = [ # The kernel ensures variety in vehicle configuration
[1.0, 0.08],
[1.0, 0.05],
[1.0, 0.02]
],
)
headway_gen_lane3 = pb.HeadwayGenCongested(
congested_spacing = 10.0, # in m
congested_speed = 40.0, # in km/h
)
traffic_gen.add_lane(
vehicle_gen = vehicle_gen_lane3,
headway_gen = headway_gen_lane3,
lfc = lfc_lane3,
)
1.4 Lane 4 -> Nominal + Constant
[6]:
lfc_lane4 = pb.LaneFlowComposition(lane_index = 4, lane_dir = 1)
lfc_lane4.assign_lane_data( # We dont need any information from lfc for constant headway generation actually, but we still need to assign something.
hourly_truck_flow=[1] * 24,
hourly_car_flow=[1] * 24,
)
nominal_truck = pb.Vehicle(2)
nominal_truck.set_axle_weights([20.0, 20.0]) # in kN
nominal_truck.set_axle_spacings([5.0]) # in m
vehicle_gen_lane4 = pb.VehicleGenNominal(
nominal_vehicle = nominal_truck,
COV_list = [0.1, 0.05], # This ensures variety in vehicle configuration
)
headway_gen_lane4 = pb.HeadwayGenConstant(
constant_speed = 60.0, # in km/h
constant_gap = 60.0, # in s
)
traffic_gen.add_lane(
vehicle_gen = vehicle_gen_lane4,
headway_gen = headway_gen_lane4,
lfc = lfc_lane4,
)
Step 2: Define the bridge and the load effect.
The bridge is:
Simply supported;
4 uni-directional lanes;
20m span length.
We are interested in its mid-span bending moment.
[ ]:
inf_line = pb.InfluenceLine(IL_type = "built-in")
inf_line.set_IL( # Read the documentation for other built-in ILs
id = 1, # Simply supported beam mid-span bending moment
length = 20.0,
)
bridge = pb.Bridge(length = 20.0, no_lane = 4)
bridge.add_load_effect(inf_line_surf = inf_line)
Step 3: Request the output we want - the time-history data, and the vehicle files.
[8]:
output_config = pb.OutputConfig()
output_config.set_event_output(write_time_history = True)
output_config.set_vehicle_file_output(write_vehicle_file = True)
Step 4: Set and start a new simulation.
The finished traffic output is stored in ./temp/sim_gen_example.
[ ]:
sim_task = pb.Simulation(output_dir = Path("./temp")) # Can specify a different output directory here.
sim_task.add_sim(
bridge = bridge,
traffic = traffic_gen,
no_day = 25, # 25 working days per month
output_config = output_config,
tag = "sim_gen_example",
)
sim_task.run()
Step 5: Load the generated time-history data and traffic.
[11]:
sim_output = sim_task.get_output()["sim_gen_example"]
time_history_data = sim_output.read_data("time_history")["TH_20"]
generated_traffic = sim_output.read_data("traffic")["output_traffic"]
from IPython.display import display # Display the variable in jupyter notebook (optional)
display(time_history_data)
display(generated_traffic)
| Time | No. Trucks | Effect 1 | |
|---|---|---|---|
| 0 | 1.21 | 1 | 0.000 |
| 1 | 1.31 | 1 | 5.556 |
| 2 | 1.41 | 1 | 11.111 |
| 3 | 1.51 | 1 | 16.667 |
| 4 | 1.61 | 1 | 24.444 |
| ... | ... | ... | ... |
| 22386570 | 2160000.10 | 3 | 107.431 |
| 22386571 | 2160000.20 | 2 | 113.336 |
| 22386572 | 2160000.30 | 2 | 130.758 |
| 22386573 | 2160000.40 | 2 | 163.699 |
| 22386574 | 2160000.50 | 2 | 192.728 |
22386575 rows × 3 columns
| Head | Year | Month | Day | Hour | Min | Sec | NoAxles | NoAxleGroups | GVW | Velocity | Length | Lane | Dir | Trns | AxleWeights | AxleSpacings | AxleWidths | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1001 | 1 | 1 | 0 | 0 | 0 | 1.210 | 2 | 0 | 20.00259 | 11.111111 | 4.000 | 3 | 1 | 1.8 | [9.996390000000002, 9.996390000000002] | [4.0, 0.0] | [1.98, 1.98] |
| 1 | 1001 | 1 | 1 | 0 | 0 | 0 | 2.398 | 2 | 0 | 20.00259 | 11.111111 | 4.000 | 3 | 1 | 1.8 | [9.996390000000002, 9.996390000000002] | [4.0, 0.0] | [1.98, 1.98] |
| 2 | 1001 | 1 | 1 | 0 | 0 | 0 | 3.736 | 2 | 0 | 20.00259 | 11.111111 | 4.000 | 3 | 1 | 1.8 | [9.996390000000002, 9.996390000000002] | [4.0, 0.0] | [1.98, 1.98] |
| 3 | 1001 | 1 | 1 | 0 | 0 | 0 | 4.064 | 5 | 0 | 263.44755 | 15.833333 | 10.613 | 1 | 1 | 1.8 | [52.46388, 95.39244000000001, 38.5336800000000... | [3.147, 5.296, 1.056, 1.114, 0.0] | [1.98, 1.98, 1.98, 1.98, 1.98] |
| 4 | 1001 | 1 | 1 | 0 | 0 | 0 | 5.002 | 2 | 0 | 20.00259 | 11.111111 | 4.000 | 3 | 1 | 1.8 | [9.996390000000002, 9.996390000000002] | [4.0, 0.0] | [1.98, 1.98] |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1571330 | 1001 | 25 | 1 | 0 | 23 | 59 | 56.137 | 2 | 0 | 20.00259 | 11.111111 | 4.000 | 3 | 1 | 1.8 | [9.996390000000002, 9.996390000000002] | [4.0, 0.0] | [1.98, 1.98] |
| 1571331 | 1376923 | 25 | 1 | 0 | 23 | 59 | 57.449 | 5 | 3 | 213.66180 | 11.111111 | 9.913 | 3 | 1 | 1.8 | [69.8472, 37.611540000000005, 31.2056100000000... | [3.628, 1.295, 3.785, 1.205, 0.0] | [1.98, 1.98, 1.98, 1.98, 1.98] |
| 1571332 | 1001 | 25 | 1 | 0 | 23 | 59 | 59.205 | 2 | 0 | 20.00259 | 11.111111 | 4.000 | 3 | 1 | 1.8 | [9.996390000000002, 9.996390000000002] | [4.0, 0.0] | [1.98, 1.98] |
| 1571333 | 1001 | 1 | 2 | 0 | 0 | 0 | 0.000 | 2 | 0 | 39.53430 | 16.666667 | 4.923 | 4 | 1 | 1.8 | [20.00259, 19.53171] | [4.923, 0.0] | [1.98, 1.98] |
| 1571334 | 1172017 | 1 | 2 | 0 | 0 | 0 | 0.539 | 2 | 2 | 46.76427 | 11.111111 | 3.754 | 3 | 1 | 1.8 | [20.16936, 26.594910000000002] | [3.754, 0.0] | [1.98, 1.98] |
1571335 rows × 18 columns