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