├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── ROADMAP.md
├── assets
└── kaiwu_match.jpg
├── benchmark
├── aircraft
│ ├── asset
│ │ ├── airship.png
│ │ └── drone.png
│ ├── check_ac_env.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── ac_env.py
│ │ └── ac_wrapper.py
├── sumo_envs
│ ├── J1
│ │ ├── add
│ │ │ ├── e2.add.xml
│ │ │ └── tls.add.xml
│ │ └── env
│ │ │ ├── J1.net.xml
│ │ │ ├── J1.rou.xml
│ │ │ └── J1.sumocfg
│ ├── OSM
│ │ ├── add
│ │ │ ├── e2.add.xml
│ │ │ └── tls.add.xml
│ │ ├── env
│ │ │ ├── osm.net.xml
│ │ │ ├── osm.png
│ │ │ ├── osm.rou.xml
│ │ │ ├── osm.sumocfg
│ │ │ └── viewsettings.xml
│ │ └── generate_routes_osm.py
│ ├── multi_junctions_tsc
│ │ ├── add
│ │ │ ├── e1.add.xml
│ │ │ ├── e1_internal.add.xml
│ │ │ ├── e2.add.xml
│ │ │ ├── e3.add.xml
│ │ │ └── tls.add.xml
│ │ ├── env
│ │ │ ├── three_junctions.net.xml
│ │ │ ├── three_junctions.rou.xml
│ │ │ └── three_junctions.sumocfg
│ │ └── generate_routes.py
│ ├── veh_bottleneck
│ │ ├── veh.net.xml
│ │ ├── veh.sumocfg
│ │ └── veh_threeagents.rou.xml
│ └── veh_rlhf
│ │ ├── generate_routes_veh.py
│ │ ├── veh_rlhf.net.xml
│ │ ├── veh_rlhf.rou.xml
│ │ └── veh_rlhf.sumocfg
├── traffic_light
│ ├── README.md
│ ├── assets
│ │ ├── multi_agents_reward.png
│ │ ├── multi_agents_rl.gif
│ │ ├── single_agent_reward.png
│ │ └── single_agent_rl.gif
│ ├── multi_agents
│ │ ├── check_pz_env.py
│ │ ├── check_rl_env.py
│ │ ├── check_rl_parallel_env.py
│ │ ├── env_utils
│ │ │ ├── make_tsc_env.py
│ │ │ ├── pz_env.py
│ │ │ ├── tsc_env.py
│ │ │ └── tsc_wrapper.py
│ │ ├── eval_mappo.py
│ │ ├── log
│ │ │ ├── 0.monitor.csv
│ │ │ ├── 1.monitor.csv
│ │ │ ├── 2.monitor.csv
│ │ │ ├── 3.monitor.csv
│ │ │ ├── 4.monitor.csv
│ │ │ ├── 5.monitor.csv
│ │ │ ├── eval.monitor.csv
│ │ │ ├── rl_env.monitor.csv
│ │ │ └── tsc_pz_env.monitor.csv
│ │ ├── mappo_tensorboard
│ │ │ └── events.out.tfevents.1698766231.WMNPower.77672.0
│ │ ├── plot_rewards.py
│ │ ├── reward.png
│ │ ├── train_mappo.py
│ │ └── train_utils
│ │ │ ├── make_log.py
│ │ │ └── make_modules.py
│ └── single_agent
│ │ ├── check_tsc_env.py
│ │ ├── eval_rl_agent.py
│ │ ├── log
│ │ ├── 0.monitor.csv
│ │ ├── 1.monitor.csv
│ │ ├── 2.monitor.csv
│ │ ├── 3.monitor.csv
│ │ ├── 4.monitor.csv
│ │ └── 5.monitor.csv
│ │ ├── models
│ │ ├── last_rl_model.zip
│ │ └── last_vec_normalize.pkl
│ │ ├── plot_rewards.py
│ │ ├── ruled_method.py
│ │ ├── sb3_ppo.py
│ │ ├── tensorboard
│ │ └── J1_tensorboard.tfevents
│ │ └── utils
│ │ ├── __init__.py
│ │ ├── custom_models.py
│ │ ├── make_tsc_env.py
│ │ ├── sb3_utils.py
│ │ ├── tsc_env.py
│ │ └── tsc_wrapper.py
├── vehicle_bottleneck
│ ├── __init__.py
│ ├── check_pz_env.py
│ ├── check_rl_parallel_env.py
│ ├── check_vehicle_env.py
│ ├── env_utils
│ │ ├── __Init__.py
│ │ ├── make_veh_env.py
│ │ ├── pz_veh_env.py
│ │ ├── veh_env.py
│ │ ├── veh_wrapper.py
│ │ └── wrapper_utils.py
│ ├── eval_mappo.py
│ ├── plot_rewards.py
│ ├── single_agent
│ │ ├── check_ego_env.py
│ │ ├── eval_rl_agent.py
│ │ ├── plot_rewards.py
│ │ ├── sb3_ppo.py
│ │ └── utils
│ │ │ ├── __Init__.py
│ │ │ ├── custom_models.py
│ │ │ ├── make_veh_env.py
│ │ │ ├── sb3_utils.py
│ │ │ ├── veh_env.py
│ │ │ ├── veh_wrapper.py
│ │ │ └── wrapper_utils.py
│ ├── train_mappo.py
│ └── train_utils
│ │ ├── make_log.py
│ │ └── make_modules.py
└── vehicle_rlhf
│ ├── check_vehicle_env.py
│ └── utils
│ ├── veh_env.py
│ └── veh_wrapper.py
├── docs
├── .readthedocs.yaml
├── Makefile
├── make.bat
├── requirements.txt
└── source
│ ├── _static
│ ├── object
│ │ ├── aircraft_action.gif
│ │ ├── single_junction.png
│ │ ├── traffic_light_example.gif
│ │ └── vehicle_example.gif
│ ├── stepbystep_tutorial
│ │ └── create_scenario
│ │ │ ├── background_view_setting.png
│ │ │ ├── create_scenario_flow.gif
│ │ │ ├── osm_export.png
│ │ │ ├── sumo_net.png
│ │ │ └── sumonet_background.png
│ ├── sumo_tools
│ │ ├── detector_add.png
│ │ ├── e2_detectors.png
│ │ └── flow_interpolation.png
│ ├── tshub3d_sensors
│ │ ├── aircraft
│ │ │ ├── follow_vehicle.gif
│ │ │ ├── horizontal.gif
│ │ │ └── vertical.gif
│ │ ├── junction
│ │ │ ├── junction_back.gif
│ │ │ ├── junction_back_example.png
│ │ │ ├── junction_front.gif
│ │ │ └── junction_front_example.png
│ │ ├── traffic_scenario
│ │ │ ├── sumo.gif
│ │ │ └── tshub3d.gif
│ │ ├── vehicle
│ │ │ ├── vehicle_ego0_all.gif
│ │ │ ├── vehicle_ego0_vehicle.gif
│ │ │ ├── vehicle_ego1_all.gif
│ │ │ ├── vehicle_ego1_vehicle.gif
│ │ │ ├── vehicle_ego2_all.gif
│ │ │ ├── vehicle_ego2_vehicle.gif
│ │ │ └── vehicle_sensor_example.png
│ │ └── vehicle_types
│ │ │ ├── emergency.png
│ │ │ ├── fire_engine.png
│ │ │ ├── police.png
│ │ │ ├── suv_blue.png
│ │ │ ├── suv_grey.png
│ │ │ ├── suv_orange.png
│ │ │ ├── taxi.png
│ │ │ ├── vehicle_blue.png
│ │ │ ├── vehicle_pink.png
│ │ │ └── vehicle_white.png
│ └── v2x
│ │ └── packet_loss.png
│ ├── conf.py
│ ├── index.rst
│ └── locales
│ ├── en
│ ├── index.rst
│ ├── installation
│ │ └── index.rst
│ ├── introduction
│ │ └── index.rst
│ └── tshub3d_sensors
│ │ ├── aircraft.rst
│ │ ├── index.rst
│ │ ├── junction.rst
│ │ ├── traffic_scenario.rst
│ │ ├── vehicle.rst
│ │ └── vehicle_types.rst
│ └── zh_CN
│ ├── index.rst
│ ├── installation
│ └── index.rst
│ ├── introduction
│ └── index.rst
│ ├── object
│ ├── aircraft.rst
│ ├── index.rst
│ ├── traffic_light.rst
│ └── vehicle.rst
│ ├── stepbystep_tutorial
│ ├── create_scenario.rst
│ └── index.rst
│ ├── sumo_tools
│ ├── generate_detectors.rst
│ ├── generate_routes.rst
│ ├── index.rst
│ └── tls_addition.rst
│ ├── tshub3d_sensors
│ ├── aircraft.rst
│ ├── index.rst
│ ├── junction.rst
│ ├── traffic_scenario.rst
│ ├── vehicle.rst
│ └── vehicle_types.rst
│ └── v2x
│ ├── index.rst
│ ├── outage_probability.rst
│ └── v2x.rst
├── examples
├── aircraft
│ ├── aircraft_actions
│ │ ├── aircraft_combined.py
│ │ ├── aircraft_horizontal.py
│ │ ├── aircraft_stationary.py
│ │ └── aircraft_vectical.py
│ ├── aircraft_custom_update_cover_radius.py
│ └── get_aircraft_state.py
├── map
│ ├── get_grid_info.py
│ ├── get_net_info.py
│ ├── get_poly_info.py
│ ├── plot_net.py
│ └── polt_poly_shape.py
├── person
│ └── get_person_state.py
├── sumo_env
│ ├── ego_crash
│ │ ├── ego_crash_car_following
│ │ │ ├── env.sumocfg
│ │ │ ├── lane.net.xml
│ │ │ └── lane.rou.xml
│ │ ├── ego_crash_intersection
│ │ │ ├── add
│ │ │ │ ├── tls_programs.add.xml
│ │ │ │ ├── tls_state.add.xml
│ │ │ │ ├── tls_switch_states.add.xml
│ │ │ │ └── tls_switches.add.xml
│ │ │ ├── env.sumocfg
│ │ │ ├── inter.net.xml
│ │ │ ├── inter.rou.xml
│ │ │ └── inter_tsc.net.xml
│ │ └── ego_crash_lane_change
│ │ │ ├── bottleneck.rou.xml
│ │ │ ├── scenario.sumocfg
│ │ │ └── veh.net.xml
│ ├── osm_berlin
│ │ ├── add
│ │ │ ├── e2.add.xml
│ │ │ └── tls.add.xml
│ │ ├── berlin.osm
│ │ ├── env
│ │ │ ├── background.png
│ │ │ ├── berlin.net.xml
│ │ │ ├── berlin.netgcfg
│ │ │ ├── berlin.poly.xml
│ │ │ ├── berlin.polygcfg
│ │ │ ├── berlin.rou.xml
│ │ │ ├── berlin.sumocfg
│ │ │ └── viewsettings.xml
│ │ └── script
│ │ │ ├── generate_routes.py
│ │ │ ├── generate_tls_additions.py
│ │ │ └── generate_tls_detectors.py
│ ├── pedestrian_cross
│ │ ├── add
│ │ │ └── tls.add.xml
│ │ ├── detectors
│ │ │ ├── e1.add.xml
│ │ │ ├── e1_internal.add.xml
│ │ │ ├── e2.add.xml
│ │ │ └── e3.add.xml
│ │ └── env
│ │ │ ├── pedestrian.rou.xml
│ │ │ ├── pedestrian_cross.net.xml
│ │ │ ├── pedestrian_cross.sumocfg
│ │ │ └── vehicle.rou.xml
│ ├── single_junction
│ │ ├── add
│ │ │ └── tls.add.xml
│ │ ├── detectors
│ │ │ ├── e1_internal.add.xml
│ │ │ └── e2.add.xml
│ │ ├── env
│ │ │ ├── single_junction.net.xml
│ │ │ ├── single_junction.sumocfg
│ │ │ └── straight.rou.xml
│ │ └── generate_routes.py
│ └── three_junctions
│ │ ├── add
│ │ └── tls.add.xml
│ │ ├── detectors
│ │ ├── e1.add.xml
│ │ ├── e1_internal.add.xml
│ │ ├── e2.add.xml
│ │ └── e3.add.xml
│ │ └── env
│ │ ├── 3junctions.net.xml
│ │ ├── 3junctions.rou.xml
│ │ └── 3junctions.sumocfg
├── sumo_tools
│ ├── additional_file
│ │ └── tls_additions.py
│ ├── analysis_output
│ │ ├── add
│ │ │ └── tls_program.out.xml
│ │ ├── analysis_route.py
│ │ ├── analysis_tls_program.py
│ │ ├── analysis_tls_program_visualization.py
│ │ └── analysis_tripinfo.py
│ ├── generate_pedestrian_route.py
│ ├── generate_route
│ │ ├── trip.py
│ │ └── turn_def.py
│ ├── generate_routes.py
│ ├── generate_routes_fromOD.py
│ ├── generate_tls_detectors.py
│ ├── interpolation
│ │ ├── flow.py
│ │ └── turn_prob.py
│ ├── osm_build.py
│ ├── osm_filter.py
│ └── sumo_infos
│ │ ├── get_edge_info.py
│ │ └── get_tls_connections.py
├── traffic_light
│ ├── get_tls_state.py
│ └── traffic_light_action
│ │ ├── tls_adjustCycleDuration.py
│ │ ├── tls_choosenextphase.py
│ │ ├── tls_choosenextphase_syn.py
│ │ ├── tls_nextornot.py
│ │ └── tls_setPhaseDuration.py
├── tshub_dataset
│ └── osm2net.py
├── tshub_env
│ ├── tshub_env_all_objects.py
│ ├── tshub_env_map.py
│ ├── tshub_env_output.py
│ ├── tshub_env_person.py
│ └── tshub_env_vehicle_crash.py
├── tshub_env3d
│ ├── map_model_merge
│ │ ├── model
│ │ │ ├── ground.glb
│ │ │ ├── lane_lines.glb
│ │ │ ├── map.glb
│ │ │ └── road_lines.glb
│ │ ├── sumo
│ │ │ ├── merge.net.xml
│ │ │ ├── merge.rou.xml
│ │ │ └── merge.sumocfg
│ │ ├── sumonet_to_3d.py
│ │ └── vehicle_view.py
│ ├── multi_junctions
│ │ ├── 3d_assets
│ │ │ ├── ground.glb
│ │ │ ├── lane_lines.glb
│ │ │ ├── map.glb
│ │ │ └── road_lines.glb
│ │ ├── a_sumonet_to_3d.py
│ │ ├── b_multi_junctions_aircraft.py
│ │ ├── c_multi_junctions_tls.py
│ │ └── sumo_net
│ │ │ ├── generate_routes.py
│ │ │ ├── multi_junctions.net.xml
│ │ │ ├── multi_junctions.rou.xml
│ │ │ └── multi_junctions.sumocfg
│ ├── save_env3d_to_gif.py
│ └── single_junction
│ │ ├── 3d_assets
│ │ ├── ground.glb
│ │ ├── lane_lines.glb
│ │ ├── map.glb
│ │ └── road_lines.glb
│ │ ├── a_sumonet_to_3d.py
│ │ ├── b_aircraft_view.py
│ │ ├── c_tls_view.py
│ │ ├── d_vehicle_view.py
│ │ ├── e_tls_view_save_image.py
│ │ └── sumo_net
│ │ ├── generate_routes.py
│ │ ├── single_junction.net.xml
│ │ ├── single_junction.rou.xml
│ │ └── single_junction.sumocfg
├── tshub_env_render
│ ├── README.md
│ ├── assets
│ │ ├── rgb_global.gif
│ │ ├── rgb_node.gif
│ │ ├── rgb_vehicle.gif
│ │ ├── sumogui_global.gif
│ │ ├── sumogui_node.gif
│ │ └── sumogui_vehicle.gif
│ ├── rgb_render
│ │ ├── render_global.py
│ │ ├── render_node.py
│ │ └── render_vehicle.py
│ └── sumo_gui_render
│ │ ├── render_global.py
│ │ ├── render_node.py
│ │ └── render_vehicle.py
├── utils
│ ├── nested_dict_example.py
│ └── parse_trip_info
│ │ ├── analysis_trip_info.py
│ │ ├── output.csv
│ │ ├── simulate_with_trioinfo.py
│ │ └── single_junction.tripinfo.xml
├── v2x
│ ├── v2x
│ │ ├── i2v_channel.py
│ │ ├── v2i_channel.py
│ │ └── v2v_channel.py
│ ├── v2x_tshub_cosim
│ │ └── single_junction_v2x.py
│ └── v2x_utils
│ │ └── snr_to_packetloss.py
└── vehicles
│ ├── ego_vehicles
│ ├── vehicle_ego.py
│ ├── vehicle_laneChange_crash.py
│ └── vehicle_speed_crash.py
│ ├── get_vehicle_state.py
│ └── vehicle_action
│ ├── vehicle_lane.py
│ ├── vehicle_lane_with_continuous_speed.py
│ └── vehicle_speed.py
├── requirements.txt
├── setup.py
├── test
└── test_tshub_version.py
└── tshub
├── __init__.py
├── aircraft
├── __init__.py
├── aircraft.png
├── aircraft.py
├── aircraft_action_type.py
├── aircraft_builder.py
└── aircraft_type
│ ├── __init__.py
│ ├── base_aircraft_action.py
│ ├── combined_movement.py
│ ├── horizontal_movement.py
│ ├── stationary.py
│ └── vertical_movement.py
├── features
└── __init__.py
├── map
├── __init__.py
├── grid.py
├── map_builder.py
└── polygon.py
├── person
├── __init__.py
├── person.py
└── person_builder.py
├── sumo_tools
├── __init__.py
├── additional_files
│ ├── __init__.py
│ └── traffic_light_additions.py
├── analysis_output
│ ├── __init__.py
│ ├── route_analysis.py
│ ├── tls_program_analysis.py
│ ├── tls_program_visualization.py
│ └── tripinfo_analysis.py
├── detectors
│ ├── __init__.py
│ ├── base_detectors.py
│ ├── e1_detectors.py
│ ├── e1_internal_detectors.py
│ ├── e2_detectors.py
│ └── e3_detectors.py
├── generate_detectors.py
├── generate_route
│ ├── __init__.py
│ ├── generate_odTrip.py
│ ├── generate_person.py
│ ├── generate_trip.py
│ └── generate_turn_def.py
├── generate_routes.py
├── generate_routes_fromOD.py
├── interpolation
│ ├── __init__.py
│ ├── repeat_values.py
│ ├── values_interpolation.py
│ └── visualize_interpolations.py
├── osm_build.py
├── osm_build_type
│ ├── __init__.py
│ ├── net.typ.xml
│ └── poly.typ.xml
├── osm_filter.py
└── sumo_infos
│ ├── __init__.py
│ ├── edge_info.py
│ ├── tls_connections.py
│ ├── traffic_light_ids.py
│ └── turndef
│ ├── __init__.py
│ ├── connections.py
│ └── turndefinitions.py
├── traffic_light
├── __init__.py
├── tls_type
│ ├── __init__.py
│ ├── adjust_cycle_duration.py
│ ├── base_tls.py
│ ├── choose_next_phase.py
│ ├── choose_next_phase_syn.py
│ ├── next_or_not.py
│ └── set_phase_duration.py
├── traffic_light.py
├── traffic_light_action_type.py
├── traffic_light_builder.py
└── traffic_light_feature_convert.py
├── tshub_env
├── __init__.py
├── base_builder.py
├── base_sumo_env.py
└── tshub_env.py
├── tshub_env3d
├── __init__.py
├── _assets_3d
│ ├── map_road_lines
│ │ ├── dashed_line_shader.frag
│ │ └── dashed_line_shader.vert
│ ├── shader
│ │ ├── unlit_shader.frag
│ │ └── unlit_shader.vert
│ ├── skybox
│ │ ├── skybox.bam
│ │ ├── skybox.frag.glsl
│ │ ├── skybox.jpg
│ │ └── skybox.vert.glsl
│ ├── terrain
│ │ ├── terrain.frag.glsl
│ │ └── terrain.vert.glsl
│ └── vehicles
│ │ ├── README.md
│ │ ├── _assets
│ │ ├── emergency.png
│ │ ├── fire_engine.png
│ │ ├── police.png
│ │ ├── suv_blue.png
│ │ ├── suv_grey.png
│ │ ├── suv_orange.png
│ │ ├── taxi.png
│ │ ├── vehicle_blue.png
│ │ ├── vehicle_pink.png
│ │ └── vehicle_white.png
│ │ └── blender2bam.txt
├── base_env3d.py
├── show_sensor_images.py
├── tshub_env3d.py
├── vis3d_output_tools
│ ├── __init__.py
│ └── merge_gif.py
├── vis3d_renderer
│ ├── __init__.py
│ ├── _showbase_instance.py
│ ├── base_render.py
│ ├── rendering_components
│ │ ├── __init__.py
│ │ ├── scene_loader.py
│ │ └── scene_sync.py
│ ├── sensors
│ │ ├── __init__.py
│ │ ├── base_sensors
│ │ │ ├── __init__.py
│ │ │ ├── base_camera_sensor.py
│ │ │ └── base_sensor.py
│ │ ├── cameras
│ │ │ ├── __init__.py
│ │ │ ├── build_offscreen_camera.py
│ │ │ └── offscreen_camera
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aircraft_camera.py
│ │ │ │ ├── back_camera.py
│ │ │ │ ├── base_offscreen_camera
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base_off_camera.py
│ │ │ │ └── base_off_camera_mixin.py
│ │ │ │ ├── bev_camera.py
│ │ │ │ ├── front_camera.py
│ │ │ │ ├── junction_camera.py
│ │ │ │ └── offscreen_camera_type.py
│ │ └── rgb_sensor.py
│ ├── traffic_elements
│ │ ├── __init__.py
│ │ ├── aircraft.py
│ │ ├── base_element.py
│ │ ├── traffic_signals.py
│ │ └── vehicle.py
│ └── tshub_render.py
├── vis3d_sumonet_convert
│ ├── __init__.py
│ ├── element_to_glb
│ │ ├── __init__.py
│ │ ├── ground_glb.py
│ │ ├── lane_glb.py
│ │ ├── map_glb.py
│ │ └── road_glb.py
│ ├── map_elements
│ │ ├── __init__.py
│ │ ├── base_road_map.py
│ │ ├── feature.py
│ │ ├── lane.py
│ │ ├── road.py
│ │ └── surface.py
│ ├── sumonet_convert_utils
│ │ ├── __init__.py
│ │ ├── geometry.py
│ │ └── glb_data.py
│ └── sumonet_to_tshub3d.py
└── vis3d_utils
│ ├── __init__.py
│ ├── colors.py
│ ├── coordinates.py
│ ├── core_math.py
│ └── masks.py
├── utils
├── __init__.py
├── check_folder.py
├── format_dict.py
├── get_abs_path.py
├── init_log.py
├── nested_dict_conversion.py
├── normalization_dict.py
├── parse_trip_info.py
├── plot_reward_curves.py
└── plt_to_array.py
├── v2x
├── README.md
├── __init__.py
├── v2i_channel.py
├── v2v_channel.py
├── v2x_channel.py
└── v2x_utils
│ ├── __init__.py
│ └── snr_to_packetloss.py
├── vehicle
├── __init__.py
├── vehicle.py
├── vehicle_action_type.py
├── vehicle_builder.py
└── vehicle_type
│ ├── __init__.py
│ ├── base_vehicle_action.py
│ ├── lane.py
│ ├── lane_with_continuous_speed.py
│ └── speed.py
└── visualization
├── __init__.py
├── filter_objects.py
├── vis_map_feature.py
├── vis_vehicles.py
└── visualize_map.py
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include tshub/aircraft/aircraft.png
2 | include tshub/sumo_tools/osm_build_type/net.typ.xml
3 | include tshub/sumo_tools/osm_build_type/poly.typ.xml
4 | recursive-include tshub/tshub_env3d/_assets_3d/ *
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
7 | # TransSimHub
8 |
9 | TransSimHub is a lightweight Python library for simulating and controlling transportation systems.
10 |
11 | Get started at
12 | [English Docs](https://transsimhub.readthedocs.io/en/latest/) |
13 | [中文文档](https://transsimhub.readthedocs.io/en/latest/locales/zh_CN/index.html)
14 |
15 | ## Test
16 |
17 | 1. **Run the Tests:** You can use Python's unittest discovery mode to automatically find and run tests. From the root directory of your project, run:
18 |
19 | ```shell
20 | python -m unittest discover -s test
21 | ```
22 |
23 | The `-s test` option tells unittest to start discovery in the `test` directory. Python will automatically find files named like `test*.py` and execute the test cases defined within them.
24 |
25 | 2. **Review the Test Results:**
26 | - An `OK` output indicates all tests passed, confirming the `tshub` package is installed correctly and its version is greater than 1.
27 | - A `FAIL` or `ERROR` output indicates some tests did not pass. Review the output details to understand what went wrong.
28 |
--------------------------------------------------------------------------------
/assets/kaiwu_match.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/assets/kaiwu_match.jpg
--------------------------------------------------------------------------------
/benchmark/aircraft/asset/airship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/aircraft/asset/airship.png
--------------------------------------------------------------------------------
/benchmark/aircraft/asset/drone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/aircraft/asset/drone.png
--------------------------------------------------------------------------------
/benchmark/aircraft/utils/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-14 13:48:06
4 | @Description:
5 | @LastEditTime: 2023-09-14 13:48:08
6 | '''
7 |
--------------------------------------------------------------------------------
/benchmark/aircraft/utils/ac_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-14 13:48:19
4 | @Description: Aircraft Environment
5 | @LastEditTime: 2023-09-14 16:02:21
6 | '''
7 | import gymnasium as gym
8 |
9 | from typing import Dict, Any
10 | from tshub.tshub_env.tshub_env import TshubEnvironment
11 |
12 | class ACEnvironment(gym.Env):
13 | def __init__(self, sumo_cfg:str, num_seconds:int, aircraft_inits:Dict[str, Any], use_gui:bool=False) -> None:
14 | super().__init__()
15 |
16 | self.tsc_env = TshubEnvironment(
17 | sumo_cfg=sumo_cfg,
18 | is_aircraft_builder_initialized=True,
19 | is_vehicle_builder_initialized=True,
20 | is_traffic_light_builder_initialized=False,
21 | aircraft_inits=aircraft_inits,
22 | num_seconds=num_seconds,
23 | use_gui=use_gui,
24 | is_libsumo=(not use_gui), # 如果不开界面, 就是用 libsumo
25 | )
26 |
27 | def reset(self):
28 | state_infos = self.tsc_env.reset()
29 | return state_infos
30 |
31 | def step(self, action:Dict[str, Dict[str, int]]):
32 | action = {'aircraft': action} # 这里只控制 aircraft 即可
33 | states, rewards, infos, dones = self.tsc_env.step(action)
34 | truncated = dones
35 |
36 | return states, rewards, truncated, dones, infos
37 |
38 | def close(self) -> None:
39 | self.tsc_env._close_simulation()
--------------------------------------------------------------------------------
/benchmark/sumo_envs/J1/add/tls.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/J1/env/J1.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/OSM/env/osm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/sumo_envs/OSM/env/osm.png
--------------------------------------------------------------------------------
/benchmark/sumo_envs/OSM/env/osm.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/OSM/env/viewsettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/multi_junctions_tsc/add/tls.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/multi_junctions_tsc/env/three_junctions.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/veh_bottleneck/veh.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/benchmark/sumo_envs/veh_rlhf/generate_routes_veh.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-10-27 20:51:49
4 | @Description: 给 Vehicle Lane Change RLHF 环境生成 route 的例子
5 | @LastEditTime: 2023-11-17 16:29:35
6 | '''
7 | import numpy as np
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 | from tshub.sumo_tools.generate_routes import generate_route
11 |
12 | # 初始化日志
13 | current_file_path = get_abs_path(__file__)
14 | set_logger(current_file_path('./'))
15 |
16 | # 开启仿真 --> 指定 net 文件
17 | sumo_net = current_file_path("./veh_rlhf.net.xml")
18 |
19 | # 指定要生成的路口 id 和探测器保存的位置
20 | generate_route(
21 | sumo_net=sumo_net,
22 | interval=[1,2,3], # 有 3 个时间段
23 | edge_flow_per_minute={
24 | 'E0': [10,20,15],
25 | }, # 每分钟每个 edge 有多少车
26 | edge_turndef={},
27 | veh_type={
28 | 'ego': {'color':'26, 188, 156', 'length':7, 'speed':11, 'probability':0.1},
29 | 'background': {'color':'155, 89, 182', 'speed':6, 'length':7, 'probability':0.9},
30 | },
31 | output_trip=current_file_path('./testflow.trip.xml'),
32 | output_turndef=current_file_path('./testflow.turndefs.xml'),
33 | output_route=current_file_path('./veh_rlhf.rou.xml'),
34 | interpolate_flow=False,
35 | interpolate_turndef=False,
36 | )
--------------------------------------------------------------------------------
/benchmark/sumo_envs/veh_rlhf/veh_rlhf.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/assets/multi_agents_reward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/assets/multi_agents_reward.png
--------------------------------------------------------------------------------
/benchmark/traffic_light/assets/multi_agents_rl.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/assets/multi_agents_rl.gif
--------------------------------------------------------------------------------
/benchmark/traffic_light/assets/single_agent_reward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/assets/single_agent_reward.png
--------------------------------------------------------------------------------
/benchmark/traffic_light/assets/single_agent_rl.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/assets/single_agent_rl.gif
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/check_rl_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-10-29 22:46:51
4 | @Description: 多智能体的环境测试
5 | @LastEditTime: 2023-11-01 12:18:56
6 | '''
7 | from loguru import logger
8 |
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 |
12 | from env_utils.make_tsc_env import make_multi_envs
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 |
18 | if __name__ == '__main__':
19 | sumo_cfg = path_convert("../../sumo_envs/multi_junctions_tsc/env/three_junctions.sumocfg")
20 | log_path = path_convert('./log/rl_env')
21 | tsc_env = make_multi_envs(
22 | sumo_cfg=sumo_cfg,
23 | num_seconds=1600,
24 | tls_ids=['J1', 'J2', 'J3'],
25 | use_gui=True,
26 | log_file=log_path,
27 | device='cpu'
28 | )
29 |
30 | # Simulation with environment
31 | print(f'Group Map: {tsc_env.group_map}')
32 | print(f'Reward Key: {tsc_env.reward_key}')
33 | rollouts = tsc_env.rollout(1_000, break_when_any_done=False)
34 | for r in rollouts:
35 | logger.info(f'RL: {r}')
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/check_rl_parallel_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-10-30 23:01:03
4 | @Description: 检查同时开启多个仿真环境
5 | @LastEditTime: 2023-12-18 20:31:02
6 | '''
7 | from loguru import logger
8 |
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 | from env_utils.make_tsc_env import make_parallel_env
12 |
13 | path_convert = get_abs_path(__file__)
14 | set_logger(path_convert('./'))
15 |
16 | if __name__ == '__main__':
17 | sumo_cfg = path_convert("../../sumo_envs/multi_junctions_tsc/env/three_junctions.sumocfg")
18 | log_path = path_convert('./log/')
19 | tsc_env = make_parallel_env(
20 | num_envs=1,
21 | sumo_cfg=sumo_cfg,
22 | num_seconds=1300,
23 | tls_ids=['J1', 'J2', 'J3'],
24 | use_gui=True,
25 | prefix='check_parallel',
26 | log_file=log_path
27 | )
28 |
29 | rollouts = tsc_env.rollout(1_000, break_when_any_done=False)
30 | for r in rollouts:
31 | logger.info(f'RL: {r}')
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/env_utils/tsc_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-10-29 23:26:57
4 | @Description: 多路口信号灯控制环境
5 | @LastEditTime: 2023-10-30 15:49:22
6 | '''
7 | import gymnasium as gym
8 | from typing import List, Dict
9 | from tshub.tshub_env.tshub_env import TshubEnvironment
10 |
11 | class TSCEnvironment(gym.Env):
12 | def __init__(
13 | self, sumo_cfg:str,
14 | num_seconds:int,
15 | tls_ids:List[str],
16 | tls_action_type:str,
17 | use_gui:bool=False
18 | ) -> None:
19 | super().__init__()
20 |
21 | self.tls_ids = tls_ids # 需要控制的路口 ID
22 | self.tsc_env = TshubEnvironment(
23 | sumo_cfg=sumo_cfg,
24 | is_aircraft_builder_initialized=False,
25 | is_vehicle_builder_initialized=True, # 用于获得 vehicle 的 waiting time 来计算 reward
26 | is_traffic_light_builder_initialized=True,
27 | tls_ids=tls_ids,
28 | num_seconds=num_seconds,
29 | tls_action_type=tls_action_type,
30 | use_gui=use_gui,
31 | is_libsumo=(not use_gui), # 如果不开界面, 就是用 libsumo
32 | )
33 |
34 | def reset(self):
35 | state_infos = self.tsc_env.reset()
36 | return state_infos
37 |
38 | def step(self, action:Dict[str, Dict[str, int]]):
39 | action = {'tls': action} # 这里只控制 tls 即可
40 | states, rewards, infos, dones = self.tsc_env.step(action)
41 | truncated = dones
42 |
43 | return states, rewards, truncated, dones, infos
44 |
45 | def close(self) -> None:
46 | self.tsc_env._close_simulation()
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/eval_mappo.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-10-29 22:47:54
4 | @Description: 测试训练好的 MAPPO 模型
5 | @LastEditTime: 2024-04-25 01:34:20
6 | '''
7 | import torch
8 |
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 |
12 | from train_utils.make_modules import policy_module
13 | from env_utils.make_tsc_env import make_multi_envs
14 |
15 | path_convert = get_abs_path(__file__)
16 | set_logger(path_convert('./'))
17 |
18 |
19 | if __name__ == '__main__':
20 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
21 | sumo_cfg = path_convert("../../sumo_envs/multi_junctions_tsc/env/three_junctions.sumocfg")
22 | log_path = path_convert('./log/eval')
23 | n_agents = 3
24 |
25 | # 1. Create Env
26 | tsc_env = make_multi_envs(
27 | sumo_cfg=sumo_cfg,
28 | num_seconds=1300,
29 | tls_ids=['J1', 'J2', 'J3'],
30 | use_gui=True,
31 | log_file=log_path
32 | )
33 |
34 | # 2. Load Model Dict
35 | policy_gen = policy_module(tsc_env, n_agents, device)
36 | policy_gen.load_model(path_convert('mappo_models/actor_147.pkl'))
37 | policy = policy_gen.make_policy_module()
38 |
39 | # 3. Simulation with environment using the policy
40 | rollouts = tsc_env.rollout(
41 | policy=policy,
42 | auto_reset=True,
43 | auto_cast_to_device=True,
44 | break_when_any_done=True,
45 | max_steps=1_000
46 | )
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/log/eval.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1713981057.4386466}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/log/rl_env.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1713981023.4841964}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/log/tsc_pz_env.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1713963723.6476073}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/mappo_tensorboard/events.out.tfevents.1698766231.WMNPower.77672.0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/multi_agents/mappo_tensorboard/events.out.tfevents.1698766231.WMNPower.77672.0
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/plot_rewards.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-01 23:39:42
4 | @Description: 绘制 Reward Curve with Standard Deviation
5 | @LastEditTime: 2024-04-24 23:24:27
6 | '''
7 | from tshub.utils.plot_reward_curves import plot_reward_curve
8 | from tshub.utils.get_abs_path import get_abs_path
9 | path_convert = get_abs_path(__file__)
10 |
11 |
12 | if __name__ == '__main__':
13 | log_files = [
14 | path_convert(f'./log/{i}.monitor.csv')
15 | for i in range(6)
16 | ]
17 | output_file = path_convert('./reward.png')
18 | plot_reward_curve(log_files, output_file=output_file, window_size=2)
19 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/multi_agents/reward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/multi_agents/reward.png
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/check_tsc_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 15:57:34
4 | @Description: 测试 TSC Env 环境
5 | @LastEditTime: 2023-11-01 17:06:21
6 | '''
7 | import numpy as np
8 | from loguru import logger
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 | from stable_baselines3.common.env_checker import check_env
12 | from utils.make_tsc_env import make_env
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 |
18 | if __name__ == '__main__':
19 | sumo_cfg = path_convert("../../sumo_envs/J1/env/J1.sumocfg")
20 | log_path = path_convert('./log/')
21 | tsc_env_generate = make_env(
22 | tls_id='J4',
23 | num_seconds=3600,
24 | sumo_cfg=sumo_cfg,
25 | use_gui=True,
26 | log_file=log_path,
27 | env_index=0,
28 | )
29 | tsc_env = tsc_env_generate()
30 |
31 | # Check Env
32 | print(tsc_env.observation_space.sample())
33 | print(tsc_env.action_space.n)
34 | check_env(tsc_env)
35 |
36 | # Simulation with environment
37 | dones = False
38 | tsc_env.reset()
39 | while not dones:
40 | action = np.random.randint(4)
41 | states, rewards, truncated, dones, infos = tsc_env.step(action=action)
42 | logger.info(f"SIM: {infos['step_time']} \n+State:{states}; \n+Reward:{rewards}.")
43 | tsc_env.close()
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/eval_rl_agent.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 18:57:35
4 | @Description: 使用训练好的 RL Agent 进行测试
5 | @LastEditTime: 2023-12-21 16:55:51
6 | '''
7 | import torch
8 | from loguru import logger
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 | from stable_baselines3 import PPO
12 | from stable_baselines3.common.vec_env import VecNormalize, SubprocVecEnv
13 |
14 | from utils.make_tsc_env import make_env
15 |
16 | path_convert = get_abs_path(__file__)
17 | logger.remove()
18 |
19 | if __name__ == '__main__':
20 | # #########
21 | # Init Env
22 | # #########
23 | sumo_cfg = path_convert("../../sumo_envs/J1/env/J1.sumocfg")
24 | params = {
25 | 'tls_id':'J4',
26 | 'num_seconds': 2000,
27 | 'sumo_cfg':sumo_cfg,
28 | 'use_gui':True,
29 | 'log_file':path_convert('./log/'),
30 | }
31 | env = SubprocVecEnv([make_env(env_index=f'{i}', **params) for i in range(1)])
32 | env = VecNormalize.load(load_path=path_convert('./models/last_vec_normalize.pkl'), venv=env)
33 | env.training = False # 测试的时候不要更新
34 | env.norm_reward = False
35 |
36 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
37 | model_path = path_convert('./models/last_rl_model.zip')
38 | model = PPO.load(model_path, env=env, device=device)
39 |
40 | # 使用模型进行测试
41 | obs = env.reset()
42 | dones = False # 默认是 False
43 | total_reward = 0
44 |
45 | while not dones:
46 | action, _state = model.predict(obs, deterministic=True)
47 | obs, rewards, dones, infos = env.step(action)
48 | total_reward += rewards
49 |
50 | env.close()
51 | print(f'累积奖励为, {total_reward}.')
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/log/0.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1718721049.842907, "env_id": "None"}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/log/1.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1718721049.725677, "env_id": "None"}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/log/2.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1718721049.7750447, "env_id": "None"}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/log/3.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1718721049.724594, "env_id": "None"}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/log/4.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1718721049.7245784, "env_id": "None"}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/log/5.monitor.csv:
--------------------------------------------------------------------------------
1 | #{"t_start": 1718721049.8597445, "env_id": "None"}
2 | r,l,t
3 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/models/last_rl_model.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/single_agent/models/last_rl_model.zip
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/models/last_vec_normalize.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/single_agent/models/last_vec_normalize.pkl
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/plot_rewards.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-01 23:46:03
4 | @Description: Reward Curve for Single TSC
5 | @LastEditTime: 2023-11-02 13:28:45
6 | '''
7 | from tshub.utils.plot_reward_curves import plot_reward_curve
8 | from tshub.utils.get_abs_path import get_abs_path
9 | path_convert = get_abs_path(__file__)
10 |
11 |
12 | if __name__ == '__main__':
13 | log_files = [
14 | path_convert(f'./log/{i}.monitor.csv')
15 | for i in range(6)
16 | ]
17 | plot_reward_curve(log_files)
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/ruled_method.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 19:45:37
4 | @Description: 基于规则的方法, 每次选择排队最大的相位
5 | @LastEditTime: 2023-09-08 20:44:54
6 | '''
7 | from loguru import logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 | from utils.make_tsc_env import make_env
11 |
12 | path_convert = get_abs_path(__file__)
13 | set_logger(path_convert('./'))
14 |
15 |
16 | if __name__ == '__main__':
17 | sumo_cfg = path_convert("../../sumo_envs/J1/env/J1.sumocfg")
18 | log_path = path_convert('./log/')
19 | tsc_env_generate = make_env(
20 | tls_id='J4',
21 | num_seconds=2600,
22 | sumo_cfg=sumo_cfg,
23 | use_gui=True,
24 | log_file=log_path,
25 | env_index=0,
26 | )
27 | tsc_env = tsc_env_generate()
28 |
29 | # Simulation with environment
30 | dones = False
31 | phase_occ = {0:0, 1:0, 2:0, 3:0}
32 | total_reward = 0
33 | tsc_env.reset()
34 | while not dones:
35 | action = max(phase_occ, key=phase_occ.get)
36 | states, rewards, dones, truncated, infos = tsc_env.step(action=action)
37 | total_reward += rewards
38 | phase_occ = infos['phase_occ']
39 | logger.info(f"SIM: {infos['step_time']} \n+State:{phase_occ};\n+Action:{action}; \n+Reward:{rewards}.")
40 | tsc_env.close()
41 | logger.info(f'累积奖励, {total_reward}.')
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/tensorboard/J1_tensorboard.tfevents:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/benchmark/traffic_light/single_agent/tensorboard/J1_tensorboard.tfevents
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/utils/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 15:53:56
4 | @Description: Single Agent Control Example
5 | @LastEditTime: 2023-09-08 15:53:57
6 | '''
7 |
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/utils/custom_models.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 18:34:24
4 | @Description: Custom Model
5 | @LastEditTime: 2023-12-21 17:35:11
6 | '''
7 | import gym
8 | import torch.nn as nn
9 | from stable_baselines3.common.torch_layers import BaseFeaturesExtractor
10 |
11 | class CustomModel(BaseFeaturesExtractor):
12 | def __init__(self, observation_space: gym.Space, features_dim: int = 16):
13 | """特征提取网络
14 | """
15 | super().__init__(observation_space, features_dim)
16 | net_shape = observation_space.shape[-1] # 12
17 |
18 | self.embedding = nn.Sequential(
19 | nn.Linear(net_shape, 32),
20 | nn.ReLU(),
21 | ) # 5*12 -> 5*32
22 |
23 | self.lstm = nn.LSTM(
24 | input_size=32, hidden_size=64,
25 | num_layers=1, batch_first=True
26 | )
27 | self.relu = nn.ReLU()
28 |
29 | self.output = nn.Sequential(
30 | nn.Linear(64, 32),
31 | nn.ReLU(),
32 | nn.Linear(32, features_dim)
33 | )
34 |
35 | def forward(self, observations):
36 | embedding = self.embedding(observations)
37 |
38 | output, (hn, cn) = self.lstm(embedding)
39 | hn = hn.view(-1, 64)
40 | hn = self.relu(hn)
41 |
42 | output = self.output(hn)
43 | return output
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/utils/make_tsc_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 17:45:54
4 | @Description: 创建 TSC Env + Wrapper
5 | @LastEditTime: 2023-09-08 18:25:42
6 | '''
7 | import gymnasium as gym
8 | from utils.tsc_env import TSCEnvironment
9 | from utils.tsc_wrapper import TSCEnvWrapper
10 | from stable_baselines3.common.monitor import Monitor
11 |
12 | def make_env(
13 | tls_id:str,num_seconds:int,sumo_cfg:str,use_gui:bool,
14 | log_file:str, env_index:int,
15 | ):
16 | def _init() -> gym.Env:
17 | tsc_scenario = TSCEnvironment(
18 | sumo_cfg=sumo_cfg,
19 | num_seconds=num_seconds,
20 | tls_ids=[tls_id],
21 | tls_action_type='choose_next_phase',
22 | use_gui=use_gui,
23 | )
24 | tsc_wrapper = TSCEnvWrapper(tsc_scenario, tls_id=tls_id)
25 | return Monitor(tsc_wrapper, filename=f'{log_file}/{env_index}')
26 |
27 | return _init
--------------------------------------------------------------------------------
/benchmark/traffic_light/single_agent/utils/tsc_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-04 20:43:53
4 | @Description: 信号灯控制环境
5 | @LastEditTime: 2023-09-13 16:15:50
6 | '''
7 | import gymnasium as gym
8 |
9 | from typing import List, Dict
10 | from tshub.tshub_env.tshub_env import TshubEnvironment
11 |
12 | class TSCEnvironment(gym.Env):
13 | def __init__(self, sumo_cfg:str, num_seconds:int, tls_ids:List[str], tls_action_type:str, use_gui:bool=False) -> None:
14 | super().__init__()
15 |
16 | self.tsc_env = TshubEnvironment(
17 | sumo_cfg=sumo_cfg,
18 | is_aircraft_builder_initialized=False,
19 | is_vehicle_builder_initialized=True, # 用于获得 vehicle 的 waiting time 来计算 reward
20 | is_traffic_light_builder_initialized=True,
21 | tls_ids=tls_ids,
22 | num_seconds=num_seconds,
23 | tls_action_type=tls_action_type,
24 | use_gui=use_gui,
25 | is_libsumo=(not use_gui), # 如果不开界面, 就是用 libsumo
26 | )
27 |
28 | def reset(self):
29 | state_infos = self.tsc_env.reset()
30 | return state_infos
31 |
32 | def step(self, action:Dict[str, Dict[str, int]]):
33 | action = {'tls': action} # 这里只控制 tls 即可
34 | states, rewards, infos, dones = self.tsc_env.step(action)
35 | truncated = dones
36 |
37 | return states, rewards, truncated, dones, infos
38 |
39 | def close(self) -> None:
40 | self.tsc_env._close_simulation()
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-12-18 17:42:44
4 | @Description: Control Ego Vehicle in Bottleneck
5 | @LastEditTime: 2023-12-18 17:42:46
6 | '''
7 |
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/check_rl_parallel_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-10-30 23:01:03
4 | @Description: 检查同时开启多个仿真环境
5 | -> 首先设置一个环境, GUI 打开, 查看仿真结束是否正确
6 | -> 接着开启多个仿真, 关闭 GUI, 查看是否可以运行
7 | @LastEditTime: 2023-12-18 22:05:11
8 | '''
9 | from loguru import logger
10 | from tshub.utils.init_log import set_logger
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from env_utils.make_veh_env import make_parallel_env
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 | if __name__ == '__main__':
18 | sumo_cfg = path_convert("../sumo_envs/veh_bottleneck/veh.sumocfg")
19 | log_path = path_convert('./log/')
20 |
21 | veh_env = make_parallel_env(
22 | num_envs=4,
23 | prefix='check_parallel',
24 | sumo_cfg=sumo_cfg,
25 | warmup_steps=100, # reset 的时候初始的步数
26 | num_seconds=600, # 仿真时间 (这里实际没有被用到)
27 | ego_ids=[
28 | 'E0__0__ego.1',
29 | 'E0__1__ego.2',
30 | 'E0__2__ego.3',
31 | ], # ego vehicle 的 id
32 | edge_ids=['E0','E1','E2'],
33 | edge_lane_num={
34 | 'E0':4,
35 | 'E1':4,
36 | 'E2':4
37 | }, # 每一个 edge 对应的车道数
38 | bottle_necks=['E2'], # bottleneck 的 edge id
39 | bottle_neck_positions=(700, 70), # bottle neck 的坐标, 用于计算距离
40 | calc_features_lane_ids=[
41 | 'E0_0', 'E0_1', 'E0_2', 'E0_3',
42 | 'E1_0', 'E1_1', 'E1_2', 'E1_3',
43 | 'E2_0', 'E2_1', 'E2_2', 'E2_3',
44 | ], # 计算对应的 lane 的信息
45 | use_gui=False,
46 | log_file=log_path
47 | )
48 |
49 | rollouts = veh_env.rollout(1_000, break_when_any_done=False)
50 | for r in rollouts:
51 | logger.info(f'RL: {r}')
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/env_utils/__Init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-12-17 21:48:14
4 | @Description: Ego Vehicle Speed Environment
5 | @LastEditTime: 2023-12-17 21:48:15
6 | '''
7 |
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/env_utils/veh_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: Liu Lu & WANG Maonan
3 | @Date: 2023-10-27 20:16:40
4 | @Description: 基础车辆环境
5 | @LastEditTime: 2023-12-16 22:22:16
6 | '''
7 | import gymnasium as gym
8 |
9 | from typing import Dict
10 | from tshub.tshub_env.tshub_env import TshubEnvironment
11 |
12 | class VehEnvironment(gym.Env):
13 | def __init__(self,
14 | sumo_cfg:str, num_seconds:int,
15 | vehicle_action_type:str, use_gui:bool=False,
16 | trip_info: str = None # 添加 trip_info 参数
17 |
18 | ) -> None:
19 | super().__init__()
20 | self.num_seconds = num_seconds # 将 num_seconds 保存为一个属性
21 |
22 | self.tsc_env = TshubEnvironment(
23 | sumo_cfg=sumo_cfg,
24 | is_vehicle_builder_initialized=True, # 只需要获得车辆的信息
25 | is_aircraft_builder_initialized=False,
26 | is_traffic_light_builder_initialized=False,
27 | is_map_builder_initialized=False,
28 | is_person_builder_initialized=False,
29 | vehicle_action_type=vehicle_action_type,
30 | num_seconds=num_seconds,
31 | use_gui=use_gui,
32 | is_libsumo=(not use_gui), # 如果不开界面, 就是用 libsumo
33 | trip_info=trip_info
34 | )
35 |
36 | def reset(self):
37 | state_infos = self.tsc_env.reset()
38 | return state_infos
39 |
40 | def step(self, action:Dict[str, Dict[str, int]]):
41 | action = {'vehicle': action}
42 | states, rewards, infos, dones = self.tsc_env.step(action)
43 | truncated = dones
44 |
45 | return states, rewards, truncated, dones, infos
46 |
47 | def close(self) -> None:
48 | self.tsc_env._close_simulation()
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/plot_rewards.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-01 23:39:42
4 | @Description: 绘制 Reward Curve with Standard Deviation
5 | @LastEditTime: 2023-11-02 13:28:31
6 | '''
7 | from tshub.utils.plot_reward_curves import plot_reward_curve
8 | from tshub.utils.get_abs_path import get_abs_path
9 | path_convert = get_abs_path(__file__)
10 |
11 |
12 | if __name__ == '__main__':
13 | log_files = [
14 | path_convert(f'./log/train_{i}.monitor.csv')
15 | for i in range(6)
16 | ]
17 | plot_reward_curve(log_files)
18 |
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/single_agent/plot_rewards.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-01 23:46:03
4 | @Description: Reward Curve for Single TSC
5 | @LastEditTime: 2023-11-02 13:28:45
6 | '''
7 | from tshub.utils.plot_reward_curves import plot_reward_curve
8 | from tshub.utils.get_abs_path import get_abs_path
9 | path_convert = get_abs_path(__file__)
10 |
11 |
12 | if __name__ == '__main__':
13 | log_files = [
14 | path_convert(f'./log/{i}.monitor.csv')
15 | for i in range(6)
16 | ]
17 | plot_reward_curve(log_files)
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/single_agent/utils/__Init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-12-17 21:48:14
4 | @Description: Ego Vehicle Speed Environment
5 | @LastEditTime: 2023-12-17 21:48:15
6 | '''
7 |
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/single_agent/utils/custom_models.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-08 18:34:24
4 | @Description: Custom Model
5 | @LastEditTime: 2023-12-21 17:35:11
6 | '''
7 | import gym
8 | import torch.nn as nn
9 | from stable_baselines3.common.torch_layers import BaseFeaturesExtractor
10 |
11 | class CustomModel(BaseFeaturesExtractor):
12 | def __init__(self, observation_space: gym.Space, features_dim: int = 16):
13 | """特征提取网络
14 | """
15 | super().__init__(observation_space, features_dim)
16 | net_shape = observation_space.shape[-1] # 12
17 |
18 | self.embedding = nn.Sequential(
19 | nn.Linear(net_shape, 128),
20 | nn.ReLU(),
21 | ) # 5*12 -> 5*32
22 |
23 | self.output = nn.Sequential(
24 | nn.Linear(128, 64),
25 | nn.ReLU(),
26 | nn.Linear(64, 32),
27 | nn.ReLU(),
28 | nn.Linear(32, features_dim)
29 | )
30 |
31 | def forward(self, observations):
32 | embedding = self.embedding(observations)
33 |
34 | output = self.output(embedding)
35 | return output
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/single_agent/utils/make_veh_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-12-21 14:42:14
4 | @Description: veh_env + veh_wrapper
5 | @LastEditTime: 2023-12-21 16:37:35
6 | '''
7 | import gymnasium as gym
8 |
9 | from typing import List, Dict, Tuple
10 | from utils.veh_env import VehEnvironment
11 | from utils.veh_wrapper import VehEnvWrapper
12 | from stable_baselines3.common.monitor import Monitor
13 |
14 | def make_env(
15 | sumo_cfg:str,
16 | num_seconds:int, warmup_steps:int,
17 | ego_ids:List[str], out_edge_ids:List[str], bottle_necks:List[str],
18 | bottle_neck_positions:Tuple[int],
19 | calc_features_lane_ids:List[str], use_gui:bool,
20 | log_file:str, env_index:int,
21 | trip_info:str=None
22 | ):
23 | def _init() -> gym.Env:
24 | veh_env = VehEnvironment(
25 | sumo_cfg=sumo_cfg,
26 | num_seconds=num_seconds,
27 | vehicle_action_type='lane_continuous_speed',
28 | use_gui=use_gui,
29 | trip_info=trip_info,
30 | )
31 | tsc_wrapper = VehEnvWrapper(
32 | env=veh_env,
33 | warmup_steps=warmup_steps,
34 | ego_ids=ego_ids,
35 | out_edge_ids=out_edge_ids,
36 | bottle_necks=bottle_necks,
37 | bottle_neck_positions=bottle_neck_positions,
38 | calc_features_lane_ids=calc_features_lane_ids
39 | )
40 | return Monitor(tsc_wrapper, filename=f'{log_file}/{env_index}')
41 |
42 | return _init
--------------------------------------------------------------------------------
/benchmark/vehicle_bottleneck/single_agent/utils/veh_env.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: Liu Lu & WANG Maonan
3 | @Date: 2023-10-27 20:16:40
4 | @Description: 基础车辆环境
5 | @LastEditTime: 2023-12-16 22:22:16
6 | '''
7 | import gymnasium as gym
8 |
9 | from typing import Dict
10 | from tshub.tshub_env.tshub_env import TshubEnvironment
11 |
12 | class VehEnvironment(gym.Env):
13 | def __init__(self,
14 | sumo_cfg:str, num_seconds:int,
15 | vehicle_action_type:str, use_gui:bool=False,
16 | trip_info: str = None # 添加 trip_info 参数
17 |
18 | ) -> None:
19 | super().__init__()
20 | self.num_seconds = num_seconds # 将 num_seconds 保存为一个属性
21 |
22 | self.tsc_env = TshubEnvironment(
23 | sumo_cfg=sumo_cfg,
24 | is_vehicle_builder_initialized=True, # 只需要获得车辆的信息
25 | is_aircraft_builder_initialized=False,
26 | is_traffic_light_builder_initialized=False,
27 | is_map_builder_initialized=False,
28 | is_person_builder_initialized=False,
29 | vehicle_action_type=vehicle_action_type,
30 | num_seconds=num_seconds,
31 | use_gui=use_gui,
32 | is_libsumo=(not use_gui), # 如果不开界面, 就是用 libsumo
33 | trip_info=trip_info
34 | )
35 |
36 | def reset(self):
37 | state_infos = self.tsc_env.reset()
38 | return state_infos
39 |
40 | def step(self, action:Dict[str, Dict[str, int]]):
41 | action = {'vehicle': action}
42 | states, rewards, infos, dones = self.tsc_env.step(action)
43 | truncated = dones
44 |
45 | return states, rewards, truncated, dones, infos
46 |
47 | def close(self) -> None:
48 | self.tsc_env._close_simulation()
--------------------------------------------------------------------------------
/docs/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Set the OS, Python version and other tools you might need
9 | build:
10 | os: ubuntu-22.04
11 | tools:
12 | python: "3.11"
13 | # You can also specify other tool versions:
14 | # nodejs: "19"
15 | # rust: "1.64"
16 | # golang: "1.19"
17 |
18 | # Build documentation in the "docs/" directory with Sphinx
19 | sphinx:
20 | configuration: docs/source/conf.py
21 |
22 | # Optionally build your docs in additional formats such as PDF and ePub
23 | # formats:
24 | # - pdf
25 | # - epub
26 |
27 | # Optional but recommended, declare the Python requirements required
28 | # to build your documentation
29 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
30 | python:
31 | install:
32 | - requirements: docs/requirements.txt
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | %SPHINXBUILD% >NUL 2>NUL
14 | if errorlevel 9009 (
15 | echo.
16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17 | echo.installed, then set the SPHINXBUILD environment variable to point
18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
19 | echo.may add the Sphinx directory to PATH.
20 | echo.
21 | echo.If you don't have Sphinx installed, grab it from
22 | echo.https://www.sphinx-doc.org/
23 | exit /b 1
24 | )
25 |
26 | if "%1" == "" goto help
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx
2 | sphinx_rtd_theme
--------------------------------------------------------------------------------
/docs/source/_static/object/aircraft_action.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/object/aircraft_action.gif
--------------------------------------------------------------------------------
/docs/source/_static/object/single_junction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/object/single_junction.png
--------------------------------------------------------------------------------
/docs/source/_static/object/traffic_light_example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/object/traffic_light_example.gif
--------------------------------------------------------------------------------
/docs/source/_static/object/vehicle_example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/object/vehicle_example.gif
--------------------------------------------------------------------------------
/docs/source/_static/stepbystep_tutorial/create_scenario/background_view_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/stepbystep_tutorial/create_scenario/background_view_setting.png
--------------------------------------------------------------------------------
/docs/source/_static/stepbystep_tutorial/create_scenario/create_scenario_flow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/stepbystep_tutorial/create_scenario/create_scenario_flow.gif
--------------------------------------------------------------------------------
/docs/source/_static/stepbystep_tutorial/create_scenario/osm_export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/stepbystep_tutorial/create_scenario/osm_export.png
--------------------------------------------------------------------------------
/docs/source/_static/stepbystep_tutorial/create_scenario/sumo_net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/stepbystep_tutorial/create_scenario/sumo_net.png
--------------------------------------------------------------------------------
/docs/source/_static/stepbystep_tutorial/create_scenario/sumonet_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/stepbystep_tutorial/create_scenario/sumonet_background.png
--------------------------------------------------------------------------------
/docs/source/_static/sumo_tools/detector_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/sumo_tools/detector_add.png
--------------------------------------------------------------------------------
/docs/source/_static/sumo_tools/e2_detectors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/sumo_tools/e2_detectors.png
--------------------------------------------------------------------------------
/docs/source/_static/sumo_tools/flow_interpolation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/sumo_tools/flow_interpolation.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/aircraft/follow_vehicle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/aircraft/follow_vehicle.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/aircraft/horizontal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/aircraft/horizontal.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/aircraft/vertical.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/aircraft/vertical.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/junction/junction_back.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/junction/junction_back.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/junction/junction_back_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/junction/junction_back_example.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/junction/junction_front.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/junction/junction_front.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/junction/junction_front_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/junction/junction_front_example.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/traffic_scenario/sumo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/traffic_scenario/sumo.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/traffic_scenario/tshub3d.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/traffic_scenario/tshub3d.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego0_all.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego0_all.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego0_vehicle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego0_vehicle.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego1_all.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego1_all.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego1_vehicle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego1_vehicle.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego2_all.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego2_all.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego2_vehicle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_ego2_vehicle.gif
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle/vehicle_sensor_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle/vehicle_sensor_example.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/emergency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/emergency.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/fire_engine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/fire_engine.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/police.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/police.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/suv_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/suv_blue.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/suv_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/suv_grey.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/suv_orange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/suv_orange.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/taxi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/taxi.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/vehicle_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/vehicle_blue.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/vehicle_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/vehicle_pink.png
--------------------------------------------------------------------------------
/docs/source/_static/tshub3d_sensors/vehicle_types/vehicle_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/tshub3d_sensors/vehicle_types/vehicle_white.png
--------------------------------------------------------------------------------
/docs/source/_static/v2x/packet_loss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/docs/source/_static/v2x/packet_loss.png
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-30 20:41:24
4 | @Description: TransSimHub Documentation
5 | @LastEditTime: 2024-08-10 20:49:36
6 | '''
7 | # Configuration file for the Sphinx documentation builder.
8 | #
9 | # For the full list of built-in configuration values, see the documentation:
10 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
11 |
12 | # -- Project information -----------------------------------------------------
13 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
14 |
15 | project = 'TransSimHub'
16 | copyright = '2023, Traffic-Alpha'
17 | author = 'Traffic-Alpha'
18 | release = '0.9'
19 |
20 | # -- General configuration ---------------------------------------------------
21 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
22 |
23 | extensions = [
24 | 'sphinx.ext.autodoc',
25 | 'sphinx.ext.viewcode',
26 | 'sphinx.ext.githubpages',
27 | ]
28 |
29 | templates_path = ['_templates']
30 | exclude_patterns = []
31 |
32 |
33 |
34 | # -- Options for HTML output -------------------------------------------------
35 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
36 |
37 | html_theme = 'sphinx_rtd_theme'
38 | html_static_path = ['_static']
39 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. TransSimHub documentation master file, created by
2 | sphinx-quickstart on Wed Aug 30 20:41:24 2023.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to TransSimHub's documentation!
7 | =======================================
8 |
9 | .. toctree::
10 | :maxdepth: 2
11 | :caption: Contents:
12 |
13 | locales/en/index
14 | locales/zh_CN/index
15 |
16 |
17 | Indices and tables
18 | ==================
19 |
20 | * :ref:`genindex`
21 | * :ref:`modindex`
22 | * :ref:`search`
23 |
--------------------------------------------------------------------------------
/docs/source/locales/en/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub Documentation
2 | ===============================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Table of Content
7 |
8 | introduction/index
9 | installation/index
10 | tshub3d_sensors/index
--------------------------------------------------------------------------------
/docs/source/locales/en/introduction/index.rst:
--------------------------------------------------------------------------------
1 | .. _introduction:
2 |
3 | TransSimHub Introduction
4 | ===========================
5 |
6 | TransSimHub (TSHub) is a Python library for simulating air-land traffic using SUMO. It provides a range of powerful tools and models for scenario creation, real-time retrieval, and control of vehicles, aircraft, and traffic lights.
7 |
8 | Key Features
9 | ------------
10 |
11 | - **Scenario Creation**: Includes automated tools for generating mixed traffic flows and laying out detectors at intersections.
12 | - **Air-Land Integration**: Provides interfaces for retrieving information and controlling vehicles, aircraft, and traffic lights.
13 | - **Reinforcement Learning Support**: TransSimHub is compatible with the Gym library interface and integrates with the rllib reinforcement learning framework.
14 |
15 | With TransSimHub, you can easily create complex scenarios, interact with vehicles and aircraft in real-time, and leverage reinforcement learning algorithms for advanced control and optimization.
16 |
17 | Installation
18 | ------------
19 |
20 | To install TransSimHub, please refer to the :doc:`../installation/index` section.
21 |
22 | Next, let's explore the capabilities of TransSimHub and learn how to use it effectively.
23 |
24 | .. note::
25 | If you encounter any issues during the installation process or while using TransSimHub, refer to the project's documentation or seek help from the community.
26 |
--------------------------------------------------------------------------------
/docs/source/locales/en/tshub3d_sensors/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub 3D Rendering
2 | =============================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Objects
7 |
8 | traffic_scenario
9 | vehicle_types
10 | junction
11 | vehicle
12 | aircraft
13 |
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub 中文文档
2 | ==========================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: 目录
7 |
8 | introduction/index
9 | installation/index
10 | sumo_tools/index
11 | object/index
12 | tshub3d_sensors/index
13 | v2x/index
14 | stepbystep_tutorial/index
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/installation/index.rst:
--------------------------------------------------------------------------------
1 | .. _install:
2 |
3 | TransSimHub 安装
4 | =====================
5 |
6 | 通过 GitHub 安装
7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 |
9 | 您可以通过 GitHub 源码来安装 `TransSimHub`,请按照以下步骤操作:
10 |
11 | 1. 克隆 GitHub 仓库:
12 |
13 | .. code-block:: bash
14 |
15 | git clone https://github.com/Traffic-Alpha/TransSimHub.git
16 | cd TransSimHub
17 |
18 | 2. 使用 pip 安装:
19 |
20 | .. code-block:: bash
21 |
22 | pip install -e .
23 |
24 | 安装完成后,您可以使用以下Python命令检查TransSimHub是否安装成功,并查看其版本号:
25 |
26 | .. code-block:: python
27 |
28 | import tshub
29 | print(tshub.__version__)
30 |
31 |
32 | 特殊版本
33 | ~~~~~~~~~~~~
34 |
35 | 如果您希望启用 TransSimHub 的额外功能并安装相关依赖,请添加额外的参数。例如加上 doc 可以启动 TransSimHub 的文档编辑:
36 |
37 | .. code-block:: bash
38 |
39 | # 安装Sphinx和相关包
40 | pip install -U -e ".[doc]"
41 |
42 | 如果希望一次性将 **所有的依赖** 全部安装完毕,强烈建议使用参数 **all**,如下所示:
43 |
44 | .. code-block:: bash
45 |
46 | pip install -U -e ".[all]"
47 |
48 | 请注意,这可能需要一些额外的时间和资源来安装和构建所需的依赖项。
49 |
50 | 通过按照上述步骤,您将成功安装 TransSimHub,并准备好在Python环境中使用它。
51 |
52 | .. note::
53 | 如果在安装过程中遇到任何问题,请参考项目的GitHub仓库进行故障排除,或向项目的社区寻求帮助。
54 |
55 | 接下来,让我们了解如何在您的项目中使用TransSimHub。
56 |
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/introduction/index.rst:
--------------------------------------------------------------------------------
1 | .. _introduction:
2 |
3 | TransSimHub 介绍
4 | =====================
5 |
6 | TransSimHub(TSHub)是一个基于 SUMO 的 Python 库,用于模拟空天地交通。它提供了一系列功能强大的工具和模型,用于场景创建、实时获取和控制车辆、飞机和交通信号灯。
7 |
8 | 主要功能
9 | ~~~~~~~~~~~~~~
10 |
11 | - **场景创建**:包括自动化工具,用于生成混合交通流并在交叉口布置探测器。
12 | - **空天地一体化**:提供了用于获取信息和控制车辆、飞机和交通信号灯的接口。
13 | - **强化学习支持**:TransSimHub 与 Gym 库接口兼容,并与 rllib 等强化学习框架集成。
14 |
15 | 通过TransSimHub,您可以轻松创建复杂的场景,实时与车辆和飞机进行交互,并利用强化学习算法进行高级控制和优化。
16 |
17 | 安装
18 | ~~~~~~~~~~~
19 |
20 | 要安装 TransSimHub,请参考 :doc:`../installation/index` 部分。
21 |
22 |
23 | 接下来,让我们探索 TransSimHub 的功能,并学习如何有效地使用它。
24 |
25 | .. note::
26 | 如果在安装过程中或使用 TransSimHub 时遇到任何问题,请参考项目的文档或向社区寻求帮助。
27 |
28 |
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/object/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub Objects
2 | =======================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Objects
7 |
8 | aircraft
9 | vehicle
10 | traffic_light
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/stepbystep_tutorial/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub 使用例子
2 | ===============================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Objects
7 |
8 | create_scenario
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/sumo_tools/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub 场景创建
2 | ========================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Objects
7 |
8 | tls_addition
9 | generate_detectors
10 | generate_routes
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/tshub3d_sensors/aircraft.rst:
--------------------------------------------------------------------------------
1 | 飞行器 RGB 传感器
2 | ===================
3 |
4 | 在 TSHub3D 的模拟环境中,飞行器搭载的 RGB 传感器为交通监控和自动驾驶研究提供了一个独特的视角。本节将详细介绍三种不同飞行模式的飞行器传感器效果。
5 |
6 | 飞行器垂直方向飞行
7 | -----------------------
8 |
9 | 垂直飞行模式的飞行器可以在垂直方向上升和下降,从而改变拍摄角度和视野范围。随着飞行器上升,可观察到的区域范围扩大,但同时物体的细节将变得不那么清晰。相反,当飞行器下降时,可以捕获到更多的细节信息。
10 |
11 | .. figure:: ../../../_static/tshub3d_sensors/aircraft/vertical.gif
12 | :alt: 飞行器垂直方向飞行效果
13 | :align: center
14 |
15 | 飞行器垂直方向飞行效果。图中展示了飞行器上升和下降时视角的变化。
16 |
17 | 飞行器水平面飞行
18 | -----------------------
19 |
20 | 在水平面飞行模式中,飞行器围绕路口进行旋转飞行,这使得我们能够从多个角度动态地观察到路口周围的情况。
21 |
22 | .. figure:: ../../../_static/tshub3d_sensors/aircraft/horizontal.gif
23 | :alt: 飞行器水平面飞行效果
24 | :align: center
25 |
26 | 飞行器水平面飞行效果。图中显示了飞行器围绕路口旋转时捕捉到的连续画面。
27 |
28 | 飞行器跟车
29 | -------------------
30 |
31 | 第三种模式是飞行器跟随特定车辆飞行,这样可以从空中密切观察和记录车辆的周围环境及其交互情况。
32 |
33 | .. figure:: ../../../_static/tshub3d_sensors/aircraft/follow_vehicle.gif
34 | :alt: 飞行器跟车效果
35 | :align: center
36 |
37 | 飞行器跟车效果。图中展示了飞行器跟随车辆时的视角和捕捉到的信息。
38 |
39 | 通过这些传感器配置,TSHub3D 为研究者提供了一个全方位的交通监控工具,不仅能够从地面车辆的视角分析交通情况,还能从空中视角提供补充信息,有助于深入理解交通流和驾驶行为。
40 |
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/tshub3d_sensors/index.rst:
--------------------------------------------------------------------------------
1 | TransSimHub 3D 渲染
2 | =============================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Objects
7 |
8 | traffic_scenario
9 | vehicle_types
10 | junction
11 | vehicle
12 | aircraft
13 |
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/tshub3d_sensors/junction.rst:
--------------------------------------------------------------------------------
1 | 路口 RGB 传感器
2 | =======================
3 |
4 | TSHub3D 提供了全方位的路口监控功能,通过在十字路口的每个进入方向部署 **前拍** 和 **后拍** 传感器,从而实现全面的交通路口监控。以下是前拍和后拍传感器的详细介绍以及它们捕获的效果。
5 |
6 | 前拍传感器
7 | --------------------
8 |
9 | 前拍传感器主要负责拍摄车辆的前部,能够有效地捕捉到车辆的前方情况以及车道的排队状况。下面的图片展示了一个前拍传感器的示例图像。
10 |
11 | .. figure:: ../../../_static/tshub3d_sensors/junction/junction_front_example.png
12 | :alt: 前拍传感器示例
13 | :align: center
14 | :figwidth: 75%
15 |
16 | 前拍传感器示例。图中显示了车辆的前部以及车道的排队情况。
17 |
18 | 接下来,我们看到的是 TSHub3D 中前拍传感器捕获的动态效果。这些图像可以用于交通监控分析,也可以作为自动驾驶系统模型训练的标签数据。
19 |
20 | .. figure:: ../../../_static/tshub3d_sensors/junction/junction_front.gif
21 | :alt: 前拍传感器捕获效果
22 | :align: center
23 |
24 | 前拍传感器捕获效果。图中展示了四个不同方向的前拍传感器捕获的场景和车辆信息。
25 |
26 |
27 | 后拍传感器
28 | --------------------
29 |
30 | 后拍传感器则是专注于捕捉车辆的尾部,这对于判断车辆行驶方向(直行或转弯)非常有帮助。同时,后拍传感器也能够观测到路口对面车道的交通状况。以下是后拍传感器的示例图像。
31 |
32 | .. figure:: ../../../_static/tshub3d_sensors/junction/junction_back_example.png
33 | :alt: 后拍传感器示例
34 | :align: center
35 | :figwidth: 75%
36 |
37 | 后拍传感器示例。图中显示了车辆的后部以及路口对面车道的排队情况。
38 |
39 | 下面的动态图展示了 TSHub3D 中后拍传感器捕获的效果。与前拍传感器类似,后拍传感器也提供了全方位的监控视角。
40 |
41 | .. figure:: ../../../_static/tshub3d_sensors/junction/junction_back.gif
42 | :alt: 后拍传感器捕获效果
43 | :align: center
44 |
45 | 后拍传感器捕获效果。图中展示了四个不同方向的后拍传感器捕获的完整场景和车辆信息。
46 |
47 | 通过结合前拍和后拍传感器,TSHub3D 能够提供一个十字路口全面的交通监控解决方案,这对于交通流量分析、事故预防以及自动驾驶算法的开发具有重要意义。
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/tshub3d_sensors/traffic_scenario.rst:
--------------------------------------------------------------------------------
1 | TransSimHub 3D 渲染
2 | ===========================
3 |
4 | 在本节中,我们将介绍如何使用 TransSimHub (TSHub) 来创建和渲染一个交通模拟的三维场景。我们的示例场景是一个 **标准的单十字路口**,其中包括:
5 |
6 | * 三辆自动驾驶车辆(ego vehicle);
7 | * 两个飞行器(aircraft):一个垂直飞行的飞行器和一个水平飞行的飞行器;
8 |
9 |
10 | SUMO 可视化
11 | --------------------
12 |
13 | 首先我们使用 SUMO 来展示十字路口的交通流动情况。如下图所示,你可以看到车辆在路口的通行情况,以及在路口上空进行飞行任务的两个飞行器。其中,水平飞行的无人机保持通信半径大小不变,而垂直飞行的无人机则根据高度变化调整其通信范围。
14 |
15 | .. figure:: ../../../_static/tshub3d_sensors/traffic_scenario/sumo.gif
16 | :alt: SUMO 模拟效果图
17 | :align: center
18 | :figwidth: 75%
19 |
20 | SUMO模拟效果图。图中展示了十字路口的车辆通行以及无人机的飞行状态。
21 |
22 | TSHub3D 可视化
23 | ----------------------
24 |
25 | 接下来,我们使用 **TSHub 3D** 来进行三维可视化。TSHub 3D 允许我们将传感器放置在场景中的任意位置,从而捕捉到不同角度的视觉效果。如下图所示,我们将传感器部署在路口上方并围绕路口渲染,以获取更加生动和真实的三维视觉效果。
26 |
27 | .. figure:: ../../../_static/tshub3d_sensors/traffic_scenario/tshub3d.gif
28 | :alt: TSHub3D 可视化效果图
29 | :align: center
30 | :figwidth: 75%
31 |
32 | TSHub3D 可视化效果图。图中显示了传感器捕捉的三维场景,包括车道、车道线和路口的车辆。
33 |
34 | 在上述可视化中,我们可以清晰地看到每个车辆的位置,以及它们在模拟环境中的动态交互。TSHub 3D 的这些功能对于交通研究和自动驾驶系统的开发至关重要,它们提供了一个强大的工具来将交通场景进行 3D 的展示。
35 |
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/v2x/index.rst:
--------------------------------------------------------------------------------
1 | V2X 通信
2 | =========
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Objects
7 |
8 | v2x
9 | outage_probability
--------------------------------------------------------------------------------
/docs/source/locales/zh_CN/v2x/outage_probability.rst:
--------------------------------------------------------------------------------
1 | 中断概率 (Outage Probability)
2 | =========================================
3 |
4 | 中断概率是指在给定的目标速率下,当前信道容量小于该速率的概率。
5 |
6 | 在瑞利衰落信道的假设下,信道的功率衰减量 :math:`\mu = |h|^2` 服从参数为 1 的指数分布。因此,中断概率 :math:`P_{\text{out}}(R)` 可以表示为:
7 |
8 | .. math::
9 |
10 | \begin{align*}
11 | P_{\text{out}}(R) &= \Pr\left(\mu < \frac{2^R - 1}{SNR_t}\right) \\
12 | &= \int_0^{\frac{2^R - 1}{SNR_t}} e^{-u} \, du \\
13 | &= 1 - \exp\left(-\frac{2^R - 1}{SNR_t}\right)
14 | \end{align*}
15 |
16 | 其中:
17 |
18 | - :math:`R` 是给定的目标速率(单位:比特/秒/赫兹)
19 | - :math:`SNR_t` 是该时刻的信噪比(单位:分贝)
20 |
21 |
22 |
23 | 中断概率例子
24 | ---------------
25 |
26 | 例如,假设信道带宽为 30 kHz,目标速率为 20 kb/s,信噪比 \( SNR \) 为 10 dB,我们可以计算中断概率为:
27 |
28 | .. math::
29 |
30 | 1 - \exp\left(-\frac{2^{\frac{20 \times 10^3}{30 \times 10^3}} - 1}{10}\right) \approx 0.057
31 |
32 | 这个结果表明,在当前的信噪比下,有大约 5.7% 的概率会发生中断。
33 |
34 | 下图展示了在信道带宽为 30 kHz,目标速率为 20 kb/s 的时候,中断概率与 SNR 的关系。可以看到 SNR 越大,中断概率越低。
35 |
36 |
37 | .. figure:: ../../../_static/v2x/packet_loss.png
38 | :alt: Packet Loss 和 SNR 的关系
39 | :align: center
--------------------------------------------------------------------------------
/examples/aircraft/aircraft_actions/aircraft_stationary.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 12:03:53
4 | @Description: Aircraft 静止
5 | @LastEditTime: 2023-09-14 16:25:55
6 | '''
7 | import traci
8 | import sumolib
9 | from loguru import logger
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.aircraft.aircraft_builder import AircraftBuilder
13 | from tshub.utils.init_log import set_logger
14 | from tshub.utils.format_dict import dict_to_str
15 |
16 | sumoBinary = sumolib.checkBinary('sumo-gui')
17 |
18 | path_convert = get_abs_path(__file__)
19 | set_logger(path_convert('./'))
20 |
21 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
22 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
23 | conn = traci.getConnection('0')
24 |
25 | aircraft_inits = {
26 | 'a1': {
27 | "aircraft_type": "drone",
28 | "action_type": "stationary",
29 | "position":(1500,1110,100), "speed":10, "heading":(1,1,0), "communication_range":200,
30 | "if_sumo_visualization":True, "img_file":None},
31 | 'a2': {
32 | "aircraft_type": "drone",
33 | "action_type": "stationary",
34 | "position":(1900,800,100), "speed":10, "heading":(1,1,0), "communication_range":200,
35 | "if_sumo_visualization":True, "img_file":None
36 | }
37 | }
38 |
39 | scene_aircraft = AircraftBuilder(sumo=conn, aircraft_inits=aircraft_inits)
40 | while conn.simulation.getMinExpectedNumber() > 0:
41 | conn.simulationStep() # 仿真到某一步
42 | actions = {
43 | "a1": (1, 1),
44 | "a2": (1, 1),
45 | } # 这里的 action 不会移动 aircraft
46 | scene_aircraft.control_objects(actions)
47 | aircraft_state = scene_aircraft.get_objects_infos()
48 | logger.info(f'SIM: {dict_to_str(aircraft_state)}')
49 |
50 | conn.close()
--------------------------------------------------------------------------------
/examples/aircraft/get_aircraft_state.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 20:21:16
4 | @Description: 测试获得 AirCraft 的信息
5 | @LastEditTime: 2023-09-14 16:31:48
6 | '''
7 | from loguru import logger
8 | from tshub.aircraft.aircraft_builder import AircraftBuilder
9 | from tshub.utils.format_dict import dict_to_str
10 |
11 | aircraft_inits = {
12 | 'a1': {
13 | "aircraft_type": "drone",
14 | "action_type": "horizontal_movement",
15 | "position":(10,10,50), "speed":10, "heading":(1,1,0), "communication_range":100
16 | },
17 | 'a2': {
18 | "aircraft_type": "drone",
19 | "action_type": "horizontal_movement",
20 | "position":(10,10,50), "speed":10, "heading":(1,1,0), "communication_range":100
21 | }
22 | }
23 |
24 | scene_aircraft = AircraftBuilder(
25 | sumo=None,
26 | aircraft_inits=aircraft_inits
27 | )
28 | aircraft_state = scene_aircraft.get_objects_infos()
29 | logger.info(dict_to_str(aircraft_state))
--------------------------------------------------------------------------------
/examples/map/get_grid_info.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-29 15:01:25
4 | @Description: 将地图划分为 grid, 获得每个 grid 每个座标点的信息, 例如 SNR
5 | @LastEditTime: 2024-05-29 16:37:55
6 | '''
7 | from loguru import logger
8 |
9 | from tshub.map.map_builder import MapBuilder
10 | from tshub.utils.get_abs_path import get_abs_path
11 | from tshub.utils.init_log import set_logger
12 | from tshub.utils.format_dict import dict_to_str
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 | net_file = path_convert("../sumo_env/berlin_UAM/berlin_UAM.net.xml")
18 | snir_file = path_convert("../sumo_env/berlin_UAM/berlin_UAM_SNIR_100.txt")
19 |
20 | map_builder = MapBuilder(
21 | net_file=net_file,
22 | radio_map_files={'SNIR_100': snir_file}
23 | )
24 | map_infos = map_builder.get_objects_infos()
25 | # 获得信息
26 | map_infos['grid']['SNIR_100'].get_value_at_coordinate(500, 1000) # 获得每一个点的信息
27 | map_infos['grid']['SNIR_100'].grid_z # 获得地图的信息
28 | logger.info(f'SIM: \n{dict_to_str(map_infos)}')
--------------------------------------------------------------------------------
/examples/map/get_net_info.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-12 14:48:21
4 | @Description: 只获取 net 的信息, 包含 edge 和 node 的 shape
5 | @LastEditTime: 2024-04-09 22:52:44
6 | '''
7 | from loguru import logger
8 |
9 | from tshub.map.map_builder import MapBuilder
10 | from tshub.utils.get_abs_path import get_abs_path
11 | from tshub.utils.init_log import set_logger
12 | from tshub.utils.format_dict import dict_to_str
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 | net_file = path_convert("../sumo_env/osm_berlin/env/berlin.net.xml")
18 |
19 | map_builder = MapBuilder(
20 | net_file=net_file,
21 | )
22 | map_infos = map_builder.get_objects_infos()
23 | logger.info(f'SIM: \n{dict_to_str(map_infos)}')
--------------------------------------------------------------------------------
/examples/map/get_poly_info.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-22 14:38:20
4 | @Description: 获得地图中所有的 Polygon 的信息
5 | @LastEditTime: 2023-11-12 14:27:30
6 | '''
7 | from loguru import logger
8 |
9 | from tshub.map.map_builder import MapBuilder
10 | from tshub.utils.get_abs_path import get_abs_path
11 | from tshub.utils.init_log import set_logger
12 | from tshub.utils.format_dict import dict_to_str
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 | net_file = path_convert("../sumo_env/osm_berlin/env/berlin.net.xml")
18 | poly_file = path_convert("../sumo_env/osm_berlin/env/berlin.poly.xml")
19 | osm_file = path_convert("../sumo_env/osm_berlin/berlin.osm")
20 |
21 | map_builder = MapBuilder(
22 | net_file=net_file,
23 | poly_file=poly_file,
24 | osm_file=osm_file
25 | )
26 | map_infos = map_builder.get_objects_infos()
27 | logger.info(f'SIM: \n{dict_to_str(map_infos)}')
--------------------------------------------------------------------------------
/examples/map/plot_net.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-12 12:51:49
4 | @Description: 绘制 net 路网
5 | @LastEditTime: 2023-11-12 14:03:00
6 | '''
7 | import sumolib
8 | import matplotlib.pyplot as plt
9 | from matplotlib.collections import LineCollection
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | path_convert = get_abs_path(__file__)
13 |
14 |
15 | def plotNet(net):
16 | net = sumolib.net.readNet(net)
17 | shapes = [] # shape 的坐标
18 | c = [] # 每一个 shape 的颜色
19 | w = 1 # 每一个 shape 的宽度
20 | ls = [] # shape 的样式
21 |
22 | # 绘制 lane
23 | for e in net._edges: # 获得所有的 edge
24 | for _lane in e._lanes: # 获取每一个 edge 所有的 lane
25 | shapes.append(sumolib.geomhelper.line2boundary(_lane.getShape(), _lane.getWidth())) # 获得每一个 lane 的 shape
26 | c.append('gray')
27 | ls.append('-')
28 | # sumolib.geomhelper.line2boundary(_lane.getShape(), _lane.getWidth())
29 |
30 | # 绘制 node
31 | for _node in net.getNodes():
32 | print(_node.getType())
33 | if _node.getType() != 'dead_end': # 这里看一下还有哪些 type
34 | _shape = _node.getShape()
35 | shapes.append(_shape+[_shape[0]]) # 确保首尾相连
36 | c.append('b')
37 | ls.append('--')
38 |
39 | line_segments = LineCollection(shapes, linewidths=w, colors=c, linestyles=ls)
40 | ax = plt.gca()
41 | ax.add_collection(line_segments)
42 | ax.set_xmargin(0.1)
43 | ax.set_ymargin(0.1)
44 | ax.autoscale_view(True, True, True)
45 | plt.show()
46 |
47 | if __name__ == '__main__':
48 | net_file = path_convert("../sumo_env/osm_berlin/env/berlin.net.xml")
49 | plotNet(net=net_file)
--------------------------------------------------------------------------------
/examples/person/get_person_state.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-24 16:06:00
4 | @Description: 查看行人的 state
5 | @LastEditTime: 2023-11-24 17:35:53
6 | '''
7 | import sumolib
8 | from loguru import logger
9 |
10 | from tshub.utils.get_abs_path import get_abs_path
11 | from tshub.utils.init_log import set_logger
12 | from tshub.utils.format_dict import dict_to_str
13 | from tshub.person.person_builder import PersonBuilder
14 |
15 | import traci
16 | sumoBinary = sumolib.checkBinary('sumo-gui')
17 |
18 | path_convert = get_abs_path(__file__)
19 | set_logger(path_convert('./'))
20 |
21 | sumocfg_file = path_convert("../sumo_env/pedestrian_cross/env/pedestrian_cross.sumocfg")
22 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
23 | conn = traci.getConnection('0')
24 |
25 | scene_people = PersonBuilder(sumo=conn)
26 | while conn.simulation.getMinExpectedNumber() > 0:
27 | data = scene_people.get_objects_infos() # 获得行人的信息
28 | logger.info(f'SIM: {dict_to_str(data)}')
29 |
30 | conn.simulationStep()
31 |
32 | conn.close()
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_car_following/env.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_intersection/add/tls_programs.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_intersection/add/tls_state.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_intersection/add/tls_switch_states.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_intersection/add/tls_switches.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_intersection/env.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_intersection/inter.rou.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_lane_change/bottleneck.rou.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/sumo_env/ego_crash/ego_crash_lane_change/scenario.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/env/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/sumo_env/osm_berlin/env/background.png
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/env/berlin.polygcfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/env/berlin.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/env/viewsettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/script/generate_routes.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-25 18:02:47
4 | @Description:
5 | @LastEditTime: 2023-09-25 19:37:57
6 | '''
7 | '''
8 | @Author: WANG Maonan
9 | @Date: 2023-09-01 13:45:26
10 | @Description: 给场景生成路网
11 | @LastEditTime: 2023-09-01 14:32:04
12 | '''
13 | from tshub.utils.get_abs_path import get_abs_path
14 | from tshub.utils.init_log import set_logger
15 | from tshub.sumo_tools.generate_routes import generate_route
16 |
17 | # 初始化日志
18 | current_file_path = get_abs_path(__file__)
19 | set_logger(current_file_path('./'))
20 |
21 | # 开启仿真 --> 指定 net 文件
22 | sumo_net = current_file_path("../env/berlin.net.xml")
23 |
24 | # 指定要生成的路口 id 和探测器保存的位置
25 | generate_route(
26 | sumo_net=sumo_net,
27 | interval=[5,5,5],
28 | edge_flow_per_minute={
29 | '65040946#0': [8, 8, 8],
30 | '24242838#0': [8, 8, 8],
31 | '1152723807': [7, 7, 7],
32 | '-32938173#2': [7, 7, 7],
33 | '-1147648945#1': [10, 10, 13],
34 | '-1152723815': [10, 10, 7],
35 | '-1105574288#1': [10, 10, 9],
36 | '-23755718#2': [10, 10, 7]
37 | }, # 每分钟每个 edge 有多少车
38 | edge_turndef={
39 | '24242838#0__24242838#5': [0.7, 0.7, 0.8],
40 | '24242838#5__1105574288#0': [0.9, 0.9, 0.9],
41 | },
42 | veh_type={
43 | 'ego': {'color':'26, 188, 156', 'probability':0.3},
44 | 'background': {'color':'155, 89, 182', 'speed':15, 'probability':0.7},
45 | },
46 | output_trip=current_file_path('./testflow.trip.xml'),
47 | output_turndef=current_file_path('./testflow.turndefs.xml'),
48 | output_route=current_file_path('../env/berlin.rou.xml'),
49 | interpolate_flow=False,
50 | interpolate_turndef=False,
51 | )
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/script/generate_tls_additions.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-25 18:03:05
4 | @Description: 为 berlin.net.xml 生成 Traffic Light 的 add 文件
5 | @LastEditTime: 2023-09-25 18:03:28
6 | '''
7 | from tshub.sumo_tools.additional_files.traffic_light_additions import generate_traffic_lights_additions
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'))
14 |
15 | # 指定 net 文件
16 | sumo_net = current_file_path("../env/berlin.net.xml")
17 |
18 | generate_traffic_lights_additions(
19 | network_file=sumo_net,
20 | output_file=current_file_path('../add/tls.add.xml')
21 | )
--------------------------------------------------------------------------------
/examples/sumo_env/osm_berlin/script/generate_tls_detectors.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2021-11-18 12:56:54
4 | @Description: 在 berlin.net.xml, 生成探测器
5 | @LastEditTime: 2023-09-25 19:15:25
6 | '''
7 | import libsumo as traci
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 | from tshub.sumo_tools.generate_detectors import generate_detector
11 |
12 | # 初始化日志
13 | current_file_path = get_abs_path(__file__)
14 | set_logger(current_file_path('./'))
15 |
16 | # 开启仿真 --> 指定 net 文件
17 | netfile_path = current_file_path("../env/berlin.net.xml")
18 | traci.start(["sumo", "-n", netfile_path])
19 |
20 | # 指定要生成的路口 id 和探测器保存的位置
21 | g_detectors = generate_detector(traci)
22 | g_detectors.generate_multiple_detectors(
23 | tls_list=['25663405', '25663436', '25663407', '25663429', '25663423', '25663426'],
24 | result_folder=current_file_path("../add"),
25 | detectors_dict={'e2':{'detector_length':50}}
26 | )
--------------------------------------------------------------------------------
/examples/sumo_env/pedestrian_cross/add/tls.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/sumo_env/pedestrian_cross/env/pedestrian_cross.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/sumo_env/single_junction/add/tls.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/sumo_env/single_junction/env/single_junction.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/sumo_env/single_junction/generate_routes.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 13:45:26
4 | @Description: 给场景生成路网 (180s)
5 | @LastEditTime: 2024-07-21 04:30:02
6 | '''
7 | from tshub.utils.get_abs_path import get_abs_path
8 | from tshub.utils.init_log import set_logger
9 | from tshub.sumo_tools.generate_routes import generate_route
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'), file_log_level='WARNING', terminal_log_level='INFO')
14 |
15 | # 开启仿真 --> 指定 net 文件
16 | sumo_net = current_file_path("./env/single_junction.net.xml")
17 |
18 | # 指定要生成的路口 id 和探测器保存的位置
19 | generate_route(
20 | sumo_net=sumo_net,
21 | interval=[1,1,1],
22 | edge_flow_per_minute={
23 | 'gsndj_n7': [15, 15, 15],
24 | '29257863#2': [15, 15, 15],
25 | 'gsndj_s4': [7, 7, 7],
26 | '161701303#7.248': [7, 7, 7],
27 | }, # 每分钟每个 edge 有多少车
28 | edge_turndef={},
29 | veh_type={
30 | 'ego': {'color':'26, 188, 156', 'accel':1, 'decel':1, 'probability':0.07},
31 | 'background': {'color':'155, 89, 182', 'speed':15, 'probability':0.93},
32 | },
33 | output_trip=current_file_path('./testflow.trip.xml'),
34 | output_turndef=current_file_path('./testflow.turndefs.xml'),
35 | output_route=current_file_path('./testflow.rou.xml'),
36 | interpolate_flow=False,
37 | interpolate_turndef=False,
38 | )
--------------------------------------------------------------------------------
/examples/sumo_env/three_junctions/add/tls.add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/sumo_env/three_junctions/env/3junctions.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/sumo_tools/additional_file/tls_additions.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 15:42:25
4 | @Description: 生成 Traffic Light 的 add 文件
5 | @LastEditTime: 2023-09-01 15:52:52
6 | '''
7 | from tshub.sumo_tools.additional_files.traffic_light_additions import generate_traffic_lights_additions
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'))
14 |
15 | # 指定 net 文件
16 | sumo_net = current_file_path("../../sumo_env/three_junctions/env/3junctions.net.xml")
17 |
18 | generate_traffic_lights_additions(
19 | network_file=sumo_net,
20 | output_file=current_file_path('./tls.add.xml')
21 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/analysis_output/analysis_tls_program.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-05 23:16:45
4 | @Description: 分析 tls program 文件, 可视化部分见 analysis_tls_program_visualization.py 文件
5 | @LastEditTime: 2024-06-25 23:44:19
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.sumo_tools.analysis_output.tls_program_analysis import TLSProgramAnalysis
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'), file_log_level="INFO")
14 |
15 | # 初始化 TLSProgramAnalysis
16 | tls_program_file = current_file_path('./output/add/tls_program.out.xml')
17 | tls_analysis = TLSProgramAnalysis(tls_program_file)
18 |
19 | # 获得每个周期内, 每个相位的持续时间 -> 可以利用这个数据进一步处理
20 | print(tls_analysis.cycle_durations) # 每个周期每个相位的持续时间
21 | print(tls_analysis.percentage_cycles) # 持续时间占比
22 | print(tls_analysis.pattern_states) # 获得周期内 state 的顺序
--------------------------------------------------------------------------------
/examples/sumo_tools/analysis_output/analysis_tls_program_visualization.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-06-25 22:57:05
4 | @Description: 对 Traffic Phase Visualization (所有相位绘制在一起)
5 | @LastEditTime: 2024-06-25 23:41:13
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.sumo_tools.analysis_output.tls_program_visualization import TLSProgram_PDVis
10 |
11 | current_file_path = get_abs_path(__file__)
12 | set_logger(current_file_path('./'), file_log_level="INFO")
13 |
14 | # 初始化 TLSProgramAnalysis
15 | tls_program_file = current_file_path('./output/add/tls_program.out.xml')
16 | tls_analysis = TLSProgram_PDVis(tls_program_file)
17 |
18 | # 将所有的 Traffic Phase 绘制在一起
19 | directions_state = [
20 | 'grrrrrgGGGrgrrrgGGr',
21 | 'GrrrrrGrrrGGrrrGrrG',
22 | 'GGGGrrGrrrrGGGrGrrr',
23 | 'GrrrGGGrrrrGrrGGrrr'
24 | ]
25 | tls_analysis.plot_allphase_ratio(
26 | directions_state, traffic_light_duration=120,
27 | image_path=current_file_path(f"./all_phase_duration.pdf")
28 | )
29 |
30 | # 绘制指定的 Traffic Phase Duration (使用折线图)
31 | directions_state = [
32 | 'grrrrrgGGGrgrrrgGGr',
33 | 'GGGGrrGrrrrGGGrGrrr',
34 | ]
35 | tls_analysis.plot_phase_ratio_line(
36 | phase_strs=directions_state,
37 | phase_label=['NS-SN', 'WE-EW'],
38 | fig_text='Phase Duration for Mehtod A',
39 | image_path=current_file_path(f"./phase_duration_line.pdf")
40 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/analysis_output/analysis_tripinfo.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-06-25 22:07:05
4 | @Description: 分析 TripInfo 文件
5 | @LastEditTime: 2024-06-25 22:09:24
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.sumo_tools.analysis_output.tripinfo_analysis import TripInfoAnalysis
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'), file_log_level="INFO")
14 |
15 | tripinfo_file = current_file_path("./output/tripinfo.out.xml")
16 | tripinfo_parser = TripInfoAnalysis(tripinfo_file)
17 | stats = tripinfo_parser.get_all_stats()
18 | tripinfo_parser.print_stats()
--------------------------------------------------------------------------------
/examples/sumo_tools/generate_pedestrian_route.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-23 22:56:22
4 | @Description: 同时生成行人和车辆的 route
5 | @LastEditTime: 2023-11-23 23:16:24
6 | '''
7 | from tshub.utils.get_abs_path import get_abs_path
8 | from tshub.utils.init_log import set_logger
9 | from tshub.sumo_tools.generate_routes import generate_route
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'))
14 |
15 | # 开启仿真 --> 指定 net 文件
16 | sumo_net = current_file_path("../sumo_env/pedestrian_cross/env/pedestrian_cross.net.xml")
17 |
18 | # 指定要生成的路口 id 和探测器保存的位置
19 | generate_route(
20 | sumo_net=sumo_net,
21 | interval=[5,10,15],
22 | edge_flow_per_minute={
23 | 'E1': [15, 15, 15],
24 | '-E4': [15, 15, 15],
25 | '-E2': [7, 7, 7],
26 | 'E3': [7, 7, 7],
27 | }, # 每分钟每个 edge 有多少车
28 | edge_turndef={
29 | '-E4__-E3': [0.7, 0.7, 0.8],
30 | },
31 | veh_type={
32 | 'ego': {'color':'26, 188, 156', 'probability':0.3, 'length':4.5},
33 | 'background': {'color':'155, 89, 182', 'speed':15, 'probability':0.7, 'length':4.5},
34 | },
35 | walk_flow_per_minute={
36 | 'E1__E2': [20, 30, 50],
37 | 'E1__E4': [20, 30, 50],
38 | 'E1__-E3': [20, 30, 50]
39 | },
40 | walkfactor=0.5,
41 | output_trip=current_file_path('./_testflow.trip.xml'),
42 | output_turndef=current_file_path('./_testflow.turndefs.xml'),
43 | person_trip_file=current_file_path('./_pedestrian.trip.xml'),
44 | output_route=current_file_path('./vehicle.rou.xml'),
45 | output_person_file=current_file_path('./pedestrian.rou.xml'),
46 | interpolate_flow=False,
47 | interpolate_turndef=False,
48 | interpolate_walkflow=False
49 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/generate_route/trip.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 17:42:33
4 | @Description: 测试生成 .trip.xml 文件
5 | @LastEditTime: 2023-09-01 13:49:17
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.sumo_tools.generate_route.generate_trip import GenerateTrip
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'))
14 |
15 | # 初始化参数
16 | intervals = [5,10,15] # 每个阶段的持续时间
17 | edge_flow_per_minute = {
18 | 'edge_1': [10,5,7],
19 | 'edge_2': [21,15,2],
20 | 'edge_3': [2,12,3],
21 | } # 每个阶段每分钟的车辆
22 | veh_type = {
23 | 'ego': {'color':'26, 188, 156', 'probability':0.3},
24 | 'background': {'color':'155, 89, 182', 'probability':0.7},
25 | } # 车辆的类型
26 | output_file = current_file_path('./test.trip.xml')
27 |
28 | # 生成 trip 文件
29 | g_trip = GenerateTrip(
30 | intervals=intervals,
31 | edge_flow_per_minute=edge_flow_per_minute,
32 | veh_type=veh_type,
33 | output_file=output_file
34 | )
35 | g_trip.generate_trip_xml()
36 | g_trip.edit_trip_xml()
--------------------------------------------------------------------------------
/examples/sumo_tools/generate_route/turn_def.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 20:05:01
4 | @Description: 生成转向概率
5 | @LastEditTime: 2023-09-01 13:53:52
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.sumo_tools.generate_route.generate_turn_def import GenerateTurnDef
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'))
14 |
15 | # 初始化参数
16 | intervals = [5,10,15] # 每个阶段的持续时间
17 | edge_turndef = {
18 | '-E9__E4': [0.7, 0.7, 0.8],
19 | '-E9__-E0': [0.1, 0.1, 0.1],
20 | } # 每个阶段每分钟的车辆
21 | sumo_net = current_file_path("../../sumo_env/three_junctions/env/3junctions.net.xml")
22 | output_file = current_file_path('./test.trundefs.xml')
23 |
24 | # 生成 trip 文件
25 | g_turndefs = GenerateTurnDef(
26 | intervals=intervals,
27 | edge_turndef=edge_turndef,
28 | sumo_net=sumo_net,
29 | output_file=output_file
30 | )
31 | g_turndefs.generate_turn_definition()
32 | g_turndefs.edit_turn_definition()
--------------------------------------------------------------------------------
/examples/sumo_tools/generate_routes.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 13:45:26
4 | @Description: 给场景生成路网
5 | @LastEditTime: 2024-04-08 16:56:27
6 | '''
7 | from tshub.utils.get_abs_path import get_abs_path
8 | from tshub.utils.init_log import set_logger
9 | from tshub.sumo_tools.generate_routes import generate_route
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'), file_log_level='WARNING', terminal_log_level='INFO')
14 |
15 | # 开启仿真 --> 指定 net 文件
16 | sumo_net = current_file_path("../sumo_env/three_junctions/env/3junctions.net.xml")
17 |
18 | # 指定要生成的路口 id 和探测器保存的位置
19 | generate_route(
20 | sumo_net=sumo_net,
21 | interval=[5,10,15],
22 | edge_flow_per_minute={
23 | 'E0': [15, 15, 15],
24 | '-E3': [15, 15, 15],
25 | '-E9': [7, 7, 7],
26 | '-E4': [7, 7, 7],
27 | '-E5': [3, 3, 3],
28 | '-E8': [3, 3, 3],
29 | '-E6': [3, 3, 3],
30 | '-E7': [3, 3, 3]
31 | }, # 每分钟每个 edge 有多少车
32 | edge_turndef={
33 | '-E9__E4': [0.7, 0.7, 1],
34 | '-E9__-E0': [0.1, 0.1, 0],
35 | },
36 | veh_type={
37 | 'ego': {'color':'26, 188, 156', 'accel':1, 'decel':1, 'probability':0.3},
38 | 'background': {'color':'155, 89, 182', 'speed':15, 'probability':0.7},
39 | },
40 | output_trip=current_file_path('./testflow.trip.xml'),
41 | output_turndef=current_file_path('./testflow.turndefs.xml'),
42 | output_route=current_file_path('./testflow.rou.xml'),
43 | interpolate_flow=False,
44 | interpolate_turndef=False,
45 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/generate_routes_fromOD.py:
--------------------------------------------------------------------------------
1 | '''
2 | Author: Maonan Wang
3 | Date: 2024-09-16 14:56:35
4 | LastEditTime: 2024-09-17 10:13:27
5 | LastEditors: Maonan Wang
6 | Description: 根据起点终点生成 route
7 | FilePath: /TransSimHub/examples/sumo_tools/generate_routes_fromOD.py
8 | '''
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 | from tshub.sumo_tools.generate_routes_fromOD import generate_route_fromOD
12 |
13 | # 初始化日志
14 | current_file_path = get_abs_path(__file__)
15 | set_logger(current_file_path('./'), file_log_level='WARNING', terminal_log_level='INFO')
16 |
17 | # 开启仿真 --> 指定 net 文件
18 | sumo_net = current_file_path("../sumo_env/three_junctions/env/3junctions.net.xml")
19 |
20 | # 指定要生成的路口 id 和探测器保存的位置
21 | generate_route_fromOD(
22 | sumo_net=sumo_net,
23 | interval=[5,10,15],
24 | od_flow_per_minute={
25 | ('E0', 'E3'): [15, 15, 15], # (start, end)
26 | ('-E3', '-E0'): [15, 15, 15],
27 | }, # 每分钟每个 edge 有多少车
28 | veh_type={
29 | 'ego': {'color':'26, 188, 156', 'accel':1, 'decel':1, 'probability':0.3},
30 | 'background': {'color':'155, 89, 182', 'speed':15, 'probability':0.7},
31 | },
32 | output_trip=current_file_path('./testflow.trip.xml'),
33 | output_route=current_file_path('./testflow.rou.xml'),
34 | interpolate_flow=False,
35 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/generate_tls_detectors.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2021-11-18 12:56:54
4 | @Description: 测试在指定路网和 tls_id, 生成探测器
5 | @LastEditTime: 2023-08-24 17:52:54
6 | '''
7 | import libsumo as traci
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 | from tshub.sumo_tools.generate_detectors import generate_detector
11 |
12 | # 初始化日志
13 | current_file_path = get_abs_path(__file__)
14 | set_logger(current_file_path('./'))
15 |
16 | # 开启仿真 --> 指定 net 文件
17 | netfile_path = current_file_path("../sumo_env/three_junctions/env/3junctions.net.xml")
18 | traci.start(["sumo", "-n", netfile_path])
19 |
20 | # 指定要生成的路口 id 和探测器保存的位置
21 | g_detectors = generate_detector(traci)
22 | g_detectors.generate_multiple_detectors(
23 | tls_list=['J1','J2','J3'],
24 | result_folder=current_file_path("../sumo_env/three_junctions/detectors"),
25 | detectors_dict={'e1':dict(), 'e1_internal':dict(), 'e2':{'detector_length':30}, 'e3':dict()}
26 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/interpolation/flow.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 15:43:39
4 | @Description: 对 flow 进行插值
5 | @LastEditTime: 2023-09-01 14:11:45
6 | '''
7 | from tshub.sumo_tools.interpolation.values_interpolation import InterpolationValues
8 | from tshub.sumo_tools.interpolation.visualize_interpolations import visualize_interpolations
9 |
10 | flow = [10,20,30,20,10] # 每个时间段的车流量, 每分钟多少车
11 | period = [5,5,5,5,5] # 每个时间段的持续时间
12 | smooth_flow = InterpolationValues(values=flow, intervals=period)
13 |
14 | # test get_smooth_turndef
15 | smooth_flow_list = smooth_flow.get_smooth_values()
16 | print(smooth_flow_list)
17 |
18 | # visualize
19 | visualize_interpolations(values=flow, period=period, smooth_values=smooth_flow_list)
--------------------------------------------------------------------------------
/examples/sumo_tools/interpolation/turn_prob.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 15:43:07
4 | @Description: 对转向概率进行插值, 对插值前后的结果进行可视化
5 | @LastEditTime: 2023-09-01 14:12:23
6 | '''
7 | from tshub.sumo_tools.interpolation.values_interpolation import InterpolationValues
8 | from tshub.sumo_tools.interpolation.visualize_interpolations import visualize_interpolations
9 |
10 | turn_def = [0.25, 0.5, 0.4, 0.7, 0.4, 0.5] # 每个时间段的转向比
11 | period = [10, 10, 10, 15, 10, 15] # 每个时间段的持续时间
12 | smooth_turn_def = InterpolationValues(values=turn_def, intervals=period)
13 |
14 | # test _interpolation
15 | print(smooth_turn_def._interpolation(15))
16 | print(smooth_turn_def._interpolation(30))
17 |
18 | # test get_smooth_turndef
19 | smooth_turndef_list = smooth_turn_def.get_smooth_values()
20 | print(smooth_turndef_list)
21 |
22 | # visualize
23 | visualize_interpolations(values=turn_def, period=period, smooth_values=smooth_turndef_list)
--------------------------------------------------------------------------------
/examples/sumo_tools/osm_build.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-25 15:15:19
4 | @Description: 测试 osm_build 的功能, 快速从 OSM 中创建场景
5 | @LastEditTime: 2023-11-23 23:27:32
6 | '''
7 | from tshub.utils.get_abs_path import get_abs_path
8 | from tshub.utils.init_log import set_logger
9 | from tshub.sumo_tools.osm_build import scenario_build
10 |
11 | current_file_path = get_abs_path(__file__)
12 | set_logger(current_file_path('./'))
13 |
14 |
15 | if __name__ == '__main__':
16 | osm_file = current_file_path("../sumo_env/osm_berlin/berlin.osm")
17 | output_directory = current_file_path("../sumo_env/osm_berlin/env/")
18 | scenario_build(
19 | osm_file=osm_file,
20 | output_directory=output_directory
21 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/osm_filter.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-27 13:14:57
4 | @Description: Convert OSM to Net
5 | @LastEditTime: 2024-05-27 16:16:34
6 | '''
7 | import os
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 | from tshub.sumo_tools.osm_build import scenario_build # osm -> net.xml & poly.xml
11 | from tshub.sumo_tools.osm_filter import extract_ids, filter_osm # net.xml & poly.xml -> osm
12 |
13 | current_file_path = get_abs_path(__file__)
14 | set_logger(current_file_path('./'))
15 |
16 |
17 | if __name__ == '__main__':
18 | osm_file = current_file_path("../sumo_env/osm_berlin/berlin.osm")
19 | output_directory = current_file_path("../sumo_env/osm_berlin/env/")
20 | scenario_build(
21 | osm_file=osm_file,
22 | output_directory=output_directory
23 | )
24 |
25 | keep_ids = extract_ids(
26 | poly_xml_path=os.path.join(output_directory, 'berlin.poly.xml'),
27 | net_xml_path=os.path.join(output_directory, 'berlin.net.xml'),
28 | )
29 | filter_osm(
30 | ways_to_keep=keep_ids,
31 | input_osm=osm_file,
32 | output_osm=current_file_path("./berlin_filter.osm")
33 | )
--------------------------------------------------------------------------------
/examples/sumo_tools/sumo_infos/get_edge_info.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 19:34:43
4 | @Description: 获得 edge in 和 out 的信息
5 | @LastEditTime: 2023-08-31 19:39:51
6 | '''
7 | import sumolib
8 | from loguru import logger
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.format_dict import dict_to_str
11 | from tshub.sumo_tools.sumo_infos.edge_info import get_in_outgoing
12 |
13 | current_file_path = get_abs_path(__file__)
14 |
15 | sumo_net = current_file_path("../../sumo_env/three_junctions/env/3junctions.net.xml")
16 | net = sumolib.net.readNet(sumo_net) # 读取 sumo net
17 |
18 | edge_info = get_in_outgoing(net=net, edge_id='-E9')
19 | logger.info(f'SIM: \n{dict_to_str(edge_info)}.')
--------------------------------------------------------------------------------
/examples/sumo_tools/sumo_infos/get_tls_connections.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 17:16:06
4 | @Description: 获得多个路口, 每一个路口的所有的 connection
5 | @LastEditTime: 2023-08-24 17:36:33
6 | '''
7 | from loguru import logger
8 | import libsumo as traci
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.format_dict import dict_to_str
11 | from tshub.sumo_tools.sumo_infos.tls_connections import tls_connection
12 |
13 | current_file_path = get_abs_path(__file__)
14 |
15 | # 开启环境
16 | traci.start(["sumo", "-c", current_file_path("../../sumo_env/three_junctions/env/3junctions.sumocfg")])
17 | conn = traci
18 |
19 | # 打印对应 traffic junction 的 id 的信息
20 | junctions = ['J1','J2','J3']
21 | junctions_info = tls_connection(conn)
22 | results = junctions_info.get_tls_connections(junctions)
23 | json_str = dict_to_str(results) # dict -> str
24 | logger.info(json_str)
--------------------------------------------------------------------------------
/examples/traffic_light/get_tls_state.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 13:28:22
4 | @Description: 获得 Traffic Light Signal State
5 | @LastEditTime: 2023-08-30 16:23:38
6 | '''
7 | import sumolib
8 | from loguru import logger
9 |
10 | from tshub.traffic_light.traffic_light_builder import TrafficLightBuilder
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.utils.init_log import set_logger
13 | from tshub.utils.format_dict import dict_to_str
14 |
15 | import traci
16 | sumoBinary = sumolib.checkBinary('sumo-gui')
17 |
18 | path_convert = get_abs_path(__file__)
19 | set_logger(path_convert('./'))
20 |
21 | sumocfg_file = path_convert("../sumo_env/single_junction/env/single_junction.sumocfg")
22 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
23 | conn = traci.getConnection('0')
24 |
25 | # 两种动作设计, 分别是 choose_next_phase 和 next_or_not
26 | scene_traffic_lights = TrafficLightBuilder(sumo=conn, tls_ids=['htddj_gsndj'], action_type='next_or_not')
27 | while conn.simulation.getMinExpectedNumber() > 0:
28 | tls_infos = scene_traffic_lights.get_objects_infos()
29 | logger.info(f'SIM: \n{dict_to_str(tls_infos)}')
30 |
31 | conn.simulationStep() # 仿真到某一步
32 |
33 | conn.close()
--------------------------------------------------------------------------------
/examples/traffic_light/traffic_light_action/tls_adjustCycleDuration.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-01 15:34:53
4 | @Description: 每个周期内对所有的相位持续时间进行调整
5 | @LastEditTime: 2024-05-01 15:59:36
6 | '''
7 | import sumolib
8 | import numpy as np
9 | from loguru import logger
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.utils.init_log import set_logger
13 | from tshub.utils.format_dict import dict_to_str
14 |
15 | from tshub.traffic_light.traffic_light_builder import TrafficLightBuilder
16 |
17 | import traci
18 | sumoBinary = sumolib.checkBinary('sumo-gui')
19 |
20 | path_convert = get_abs_path(__file__)
21 | set_logger(path_convert('./'))
22 |
23 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
24 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
25 | conn = traci.getConnection('0')
26 |
27 | action_index = 0 # 动作的 id
28 | scene_traffic_lights = TrafficLightBuilder(sumo=conn, tls_ids=['htddj_gsndj'], action_type='adjust_cycle_duration')
29 | while conn.simulation.getMinExpectedNumber() > 0:
30 | # 获得路口信息
31 | tls_infos = scene_traffic_lights.get_objects_infos() # 返回路口信息
32 | logger.info(f'SIM: \n{dict_to_str(tls_infos)}')
33 |
34 | # 控制路口信息
35 | if tls_infos['htddj_gsndj']['can_perform_action']:
36 | # 每个相位时间随机增加或者减少
37 | scene_traffic_lights.control_objects({'htddj_gsndj':[np.random.choice([-5,0,5]) for _ in range(4)]})
38 | else: # 此时下发的动作会无效
39 | scene_traffic_lights.control_objects({'htddj_gsndj':None})
40 |
41 | conn.simulationStep() # 仿真到某一步
42 |
43 | conn.close()
--------------------------------------------------------------------------------
/examples/traffic_light/traffic_light_action/tls_choosenextphase.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 13:28:22
4 | @Description: 控制 Traffic Light Signal, 使用 Choose Next Phase 的动作设计
5 | @LastEditTime: 2023-08-30 16:24:13
6 | '''
7 | import sumolib
8 | from loguru import logger
9 |
10 | from tshub.traffic_light.traffic_light_builder import TrafficLightBuilder
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.utils.init_log import set_logger
13 | from tshub.utils.format_dict import dict_to_str
14 |
15 | import traci
16 | sumoBinary = sumolib.checkBinary('sumo-gui')
17 |
18 | path_convert = get_abs_path(__file__)
19 | set_logger(path_convert('./'))
20 |
21 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
22 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
23 | conn = traci.getConnection('0')
24 |
25 | action_index = 0 # 动作的 id
26 | scene_traffic_lights = TrafficLightBuilder(sumo=conn, tls_ids=['htddj_gsndj'], action_type='choose_next_phase')
27 | while conn.simulation.getMinExpectedNumber() > 0:
28 | # 获得路口信息
29 | tls_infos = scene_traffic_lights.get_objects_infos() # 返回路口信息
30 | logger.info(f'SIM: \n{dict_to_str(tls_infos)}')
31 |
32 | # 控制路口信息
33 | if tls_infos['htddj_gsndj']['can_perform_action']:
34 | scene_traffic_lights.control_objects({'htddj_gsndj':action_index})
35 | action_index = (action_index+1)%4
36 | logger.debug(f'SIM: Action Index: {action_index}')
37 | else: # 此时下发的动作会无效
38 | scene_traffic_lights.control_objects({'htddj_gsndj':None})
39 |
40 | conn.simulationStep() # 仿真到某一步
41 |
42 | conn.close()
--------------------------------------------------------------------------------
/examples/traffic_light/traffic_light_action/tls_choosenextphase_syn.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 13:28:22
4 | @Description: 控制 Traffic Light Signal (Synchronize), 使用 Choose Next Phase 的动作设计
5 | @LastEditTime: 2024-04-24 20:47:28
6 | '''
7 | import sumolib
8 | from loguru import logger
9 |
10 | from tshub.traffic_light.traffic_light_builder import TrafficLightBuilder
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.utils.init_log import set_logger
13 | from tshub.utils.format_dict import dict_to_str
14 |
15 | import traci
16 | sumoBinary = sumolib.checkBinary('sumo-gui')
17 |
18 | path_convert = get_abs_path(__file__)
19 | set_logger(path_convert('./'))
20 |
21 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
22 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
23 | conn = traci.getConnection('0')
24 |
25 | action_index = 0 # 动作的 id
26 | scene_traffic_lights = TrafficLightBuilder(sumo=conn, tls_ids=['htddj_gsndj'], action_type='choose_next_phase_syn')
27 | while conn.simulation.getMinExpectedNumber() > 0:
28 | # 获得路口信息
29 | tls_infos = scene_traffic_lights.get_objects_infos() # 返回路口信息
30 | logger.info(f'SIM: \n{dict_to_str(tls_infos)}')
31 |
32 | # 控制路口信息
33 | if tls_infos['htddj_gsndj']['can_perform_action']:
34 | scene_traffic_lights.control_objects({'htddj_gsndj':action_index})
35 | action_index = (action_index+1)%4
36 | logger.debug(f'SIM: Action Index: {action_index}')
37 | else: # 此时下发的动作会无效
38 | scene_traffic_lights.control_objects({'htddj_gsndj':None})
39 |
40 | conn.simulationStep() # 仿真到某一步
41 |
42 | conn.close()
--------------------------------------------------------------------------------
/examples/traffic_light/traffic_light_action/tls_nextornot.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 13:28:22
4 | @Description: 控制 Traffic Light Signal, 使用 Next or Not 的动作设计
5 | @LastEditTime: 2023-08-30 16:24:07
6 | '''
7 | import sumolib
8 | from loguru import logger
9 |
10 | from tshub.traffic_light.traffic_light_builder import TrafficLightBuilder
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.utils.init_log import set_logger
13 | from tshub.utils.format_dict import dict_to_str
14 |
15 | import traci
16 | sumoBinary = sumolib.checkBinary('sumo-gui')
17 |
18 | path_convert = get_abs_path(__file__)
19 | set_logger(path_convert('./'))
20 |
21 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
22 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
23 | conn = traci.getConnection('0')
24 |
25 | # 两种动作设计, 分别是 choose_next_phase 和 next_or_not
26 | action_index = 0 # 动作的 id
27 | scene_traffic_lights = TrafficLightBuilder(sumo=conn, tls_ids=['htddj_gsndj'], action_type='next_or_not')
28 | while conn.simulation.getMinExpectedNumber() > 0:
29 | # 获得路口信息
30 | tls_infos = scene_traffic_lights.get_objects_infos() # 返回路口信息
31 | logger.info(f'SIM: \n{dict_to_str(tls_infos)}')
32 |
33 | # 控制路口信息
34 | if tls_infos['htddj_gsndj']['can_perform_action']:
35 | scene_traffic_lights.control_objects({'htddj_gsndj':action_index})
36 | action_index = (action_index+1)%2
37 | else: # 此时下发的动作会无效
38 | scene_traffic_lights.control_objects({'htddj_gsndj':None})
39 |
40 | conn.simulationStep() # 仿真到某一步
41 |
42 | conn.close()
--------------------------------------------------------------------------------
/examples/traffic_light/traffic_light_action/tls_setPhaseDuration.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-06-27 19:05:17
4 | @Description: 每次调整单个相位的持续时间
5 | @LastEditTime: 2024-06-27 19:42:29
6 | '''
7 | import sumolib
8 | import numpy as np
9 | from loguru import logger
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.utils.init_log import set_logger
13 | from tshub.utils.format_dict import dict_to_str
14 |
15 | from tshub.traffic_light.traffic_light_builder import TrafficLightBuilder
16 |
17 | import traci
18 | sumoBinary = sumolib.checkBinary('sumo-gui')
19 |
20 | path_convert = get_abs_path(__file__)
21 | set_logger(path_convert('./'))
22 |
23 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
24 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
25 | conn = traci.getConnection('0')
26 |
27 | action_index = 0 # 动作的 id
28 | scene_traffic_lights = TrafficLightBuilder(
29 | sumo=conn,
30 | tls_ids=['htddj_gsndj'],
31 | action_type='set_phase_diration',
32 | delta_time=None # 这里推荐设置为 None
33 | )
34 | while conn.simulation.getMinExpectedNumber() > 0:
35 | # 获得路口信息
36 | tls_infos = scene_traffic_lights.get_objects_infos() # 返回路口信息
37 | logger.info(f'SIM: \n{dict_to_str(tls_infos)}')
38 |
39 | # 控制路口信息
40 | if tls_infos['htddj_gsndj']['can_perform_action']:
41 | # 每个相位的持续时间选择是从 10,15,20 里面选择
42 | new_phase_duration = np.random.choice([10, 15, 20])
43 | scene_traffic_lights.control_objects({'htddj_gsndj':new_phase_duration})
44 | else: # 此时下发的动作会无效
45 | scene_traffic_lights.control_objects({'htddj_gsndj':None})
46 |
47 | conn.simulationStep() # 仿真到某一步
48 |
49 | conn.close()
--------------------------------------------------------------------------------
/examples/tshub_dataset/osm2net.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-27 13:14:57
4 | @Description: Convert OSM to Net
5 | @LastEditTime: 2024-05-28 17:54:58
6 | '''
7 | import os
8 | from tshub.utils.get_abs_path import get_abs_path
9 | from tshub.utils.init_log import set_logger
10 | from tshub.sumo_tools.osm_build import scenario_build # osm -> net.xml & poly.xml
11 | from tshub.sumo_tools.osm_filter import extract_ids, filter_osm # net.xml & poly.xml -> osm
12 |
13 | current_file_path = get_abs_path(__file__)
14 | set_logger(current_file_path('./'))
15 |
16 |
17 | if __name__ == '__main__':
18 | osm_file = current_file_path("./shanghai_songjiang.osm")
19 | output_directory = current_file_path("./shanghai_songjiang/")
20 | scenario_build(
21 | osm_file=osm_file,
22 | output_directory=output_directory
23 | )
24 | keep_ids = extract_ids(
25 | poly_xml_path=os.path.join(output_directory, 'shanghai_songjiang.poly.xml'),
26 | net_xml_path=os.path.join(output_directory, 'shanghai_songjiang.net.xml'),
27 | )
28 | filter_osm(
29 | ways_to_keep=keep_ids,
30 | input_osm=osm_file,
31 | output_osm=current_file_path("./shanghai_songjiang_filter.osm")
32 | )
--------------------------------------------------------------------------------
/examples/tshub_env/tshub_env_person.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-24 18:05:38
4 | @Description: 环境返回行人的信息
5 | @LastEditTime: 2023-11-24 18:27:07
6 | '''
7 | import numpy as np
8 | from loguru import logger
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 | from tshub.tshub_env.tshub_env import TshubEnvironment
12 | from tshub.utils.format_dict import dict_to_str
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 | sumo_cfg = path_convert("../sumo_env/pedestrian_cross/env/pedestrian_cross.sumocfg")
18 | net_file = path_convert("../sumo_env/pedestrian_cross/env/pedestrian_cross.net.xml")
19 |
20 | tshub_env = TshubEnvironment(
21 | sumo_cfg=sumo_cfg,
22 | is_map_builder_initialized=True,
23 | is_aircraft_builder_initialized=False,
24 | is_vehicle_builder_initialized=True,
25 | is_traffic_light_builder_initialized=True,
26 | is_person_builder_initialized=True,
27 | # map builder
28 | net_file=net_file,
29 | # traffic light builder
30 | tls_ids=['J4'],
31 | tls_action_type='next_or_not',
32 | # vehicle builder
33 | vehicle_action_type='lane',
34 | use_gui=True, num_seconds=700
35 | )
36 |
37 | obs = tshub_env.reset()
38 | done = False
39 |
40 | while not done:
41 | actions = {
42 | 'vehicle': dict(),
43 | }
44 | obs, reward, info, done = tshub_env.step(actions=actions)
45 | logger.info(f"SIM: {info['step_time']} \n{dict_to_str(obs)}")
46 | tshub_env._close_simulation()
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/model/ground.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/map_model_merge/model/ground.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/model/lane_lines.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/map_model_merge/model/lane_lines.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/model/map.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/map_model_merge/model/map.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/model/road_lines.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/map_model_merge/model/road_lines.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/sumo/merge.rou.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/sumo/merge.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/tshub_env3d/map_model_merge/sumonet_to_3d.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 16:34:37
4 | @Description: 将 SUMO Net 转换为 3D 的素材
5 | LastEditTime: 2025-03-28 18:45:34
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 |
10 | from tshub.tshub_env3d.vis3d_sumonet_convert.sumonet_to_tshub3d import SumoNet3D
11 |
12 | path_convert = get_abs_path(__file__)
13 | set_logger(path_convert('./'), terminal_log_level='INFO')
14 |
15 | if __name__ == '__main__':
16 | netxml = path_convert("./sumo/merge.net.xml") # 路网路径
17 | sumonet_to_3d = SumoNet3D(net_file=netxml)
18 | sumonet_to_3d.to_glb(glb_dir=path_convert(f"./model/"))
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/3d_assets/ground.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/multi_junctions/3d_assets/ground.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/3d_assets/lane_lines.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/multi_junctions/3d_assets/lane_lines.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/3d_assets/map.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/multi_junctions/3d_assets/map.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/3d_assets/road_lines.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/multi_junctions/3d_assets/road_lines.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/a_sumonet_to_3d.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 16:34:37
4 | @Description: 将 SUMO Net 转换为 3D 的素材 (多路口)
5 | LastEditTime: 2025-04-15 15:22:55
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 |
10 | from tshub.tshub_env3d.vis3d_sumonet_convert.sumonet_to_tshub3d import SumoNet3D
11 |
12 | path_convert = get_abs_path(__file__)
13 | set_logger(path_convert('./'), terminal_log_level='INFO')
14 |
15 | if __name__ == '__main__':
16 | netxml = path_convert("./sumo_net/multi_junctions.net.xml")
17 | sumonet_to_3d = SumoNet3D(net_file=netxml)
18 | sumonet_to_3d.to_glb(glb_dir=path_convert(f"./3d_assets/"))
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/sumo_net/generate_routes.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 13:45:26
4 | @Description: 随机生成车辆, 包含不同的车辆类型
5 | LastEditTime: 2025-04-15 15:20:04
6 | '''
7 | from tshub.utils.get_abs_path import get_abs_path
8 | from tshub.utils.init_log import set_logger
9 | from tshub.sumo_tools.generate_routes import generate_route
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'), file_log_level='WARNING', terminal_log_level='INFO')
14 |
15 | # 开启仿真 --> 指定 net 文件
16 | sumo_net = current_file_path("./multi_junctions.net.xml")
17 |
18 | # 指定要生成的路口 id 和探测器保存的位置
19 | generate_route(
20 | sumo_net=sumo_net,
21 | interval=[1,1,1],
22 | edge_flow_per_minute={
23 | 'E0': [10, 10, 10],
24 | 'E1': [10, 10, 10],
25 | '-E2': [10, 10, 10],
26 | 'E5': [10, 10, 10],
27 | '-E6': [10, 10, 10],
28 | '-E8': [10, 10, 10],
29 | '-E7': [10, 10, 10],
30 | }, # 每分钟每个 edge 有多少车
31 | edge_turndef={},
32 | veh_type={
33 | 'background': {'color':'220,220,220', 'length': 5, 'probability':0.6},
34 | 'police': {'color':'0,0,255', 'length': 5, 'probability':0.1},
35 | 'emergency': {'color':'255,165,0', 'length': 6.5, 'probability':0.1},
36 | 'fire_engine': {'color':'255,0,0', 'length': 7.1, 'probability':0.1},
37 | 'taxi': {'color':'255,255,0', 'length': 5, 'probability':0.1},
38 | },
39 | output_trip=current_file_path('./testflow.trip.xml'),
40 | output_turndef=current_file_path('./testflow.turndefs.xml'),
41 | output_route=current_file_path('./multi_junctions.rou.xml'),
42 | interpolate_flow=False,
43 | interpolate_turndef=False,
44 | )
--------------------------------------------------------------------------------
/examples/tshub_env3d/multi_junctions/sumo_net/multi_junctions.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/3d_assets/ground.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/single_junction/3d_assets/ground.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/3d_assets/lane_lines.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/single_junction/3d_assets/lane_lines.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/3d_assets/map.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/single_junction/3d_assets/map.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/3d_assets/road_lines.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env3d/single_junction/3d_assets/road_lines.glb
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/a_sumonet_to_3d.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 16:34:37
4 | @Description: 将 SUMO Net 转换为 3D 的素材
5 | LastEditTime: 2025-03-28 18:45:34
6 | '''
7 | from tshub.utils.init_log import set_logger
8 | from tshub.utils.get_abs_path import get_abs_path
9 |
10 | from tshub.tshub_env3d.vis3d_sumonet_convert.sumonet_to_tshub3d import SumoNet3D
11 |
12 | path_convert = get_abs_path(__file__)
13 | set_logger(path_convert('./'), terminal_log_level='INFO')
14 |
15 | if __name__ == '__main__':
16 | netxml = path_convert("./sumo_net/single_junction.net.xml") # 路网路径
17 | sumonet_to_3d = SumoNet3D(net_file=netxml)
18 | sumonet_to_3d.to_glb(glb_dir=path_convert(f"./3d_assets/"))
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/sumo_net/generate_routes.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 13:45:26
4 | @Description: 随机生成车辆, 包含不同的车辆类型
5 | LastEditTime: 2025-04-14 19:51:26
6 | '''
7 | from tshub.utils.get_abs_path import get_abs_path
8 | from tshub.utils.init_log import set_logger
9 | from tshub.sumo_tools.generate_routes import generate_route
10 |
11 | # 初始化日志
12 | current_file_path = get_abs_path(__file__)
13 | set_logger(current_file_path('./'), file_log_level='WARNING', terminal_log_level='INFO')
14 |
15 | # 开启仿真 --> 指定 net 文件
16 | sumo_net = current_file_path("./single_junction.net.xml")
17 |
18 | # 指定要生成的路口 id 和探测器保存的位置
19 | generate_route(
20 | sumo_net=sumo_net,
21 | interval=[1,1,1],
22 | edge_flow_per_minute={
23 | 'E2': [10, 10, 10],
24 | '-E1': [10, 10, 10],
25 | '-E3': [7, 7, 7],
26 | 'E0': [7, 7, 7],
27 | }, # 每分钟每个 edge 有多少车
28 | edge_turndef={},
29 | veh_type={
30 | 'background': {'color':'220,220,220', 'length': 5, 'probability':0.6},
31 | 'police': {'color':'0,0,255', 'length': 5, 'probability':0.1},
32 | 'emergency': {'color':'255,165,0', 'length': 6.5, 'probability':0.1},
33 | 'fire_engine': {'color':'255,0,0', 'length': 7.1, 'probability':0.1},
34 | 'taxi': {'color':'255,255,0', 'length': 5, 'probability':0.1},
35 | },
36 | output_trip=current_file_path('./testflow.trip.xml'),
37 | output_turndef=current_file_path('./testflow.turndefs.xml'),
38 | output_route=current_file_path('./single_junction.rou.xml'),
39 | interpolate_flow=False,
40 | interpolate_turndef=False,
41 | )
--------------------------------------------------------------------------------
/examples/tshub_env3d/single_junction/sumo_net/single_junction.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/tshub_env_render/assets/rgb_global.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env_render/assets/rgb_global.gif
--------------------------------------------------------------------------------
/examples/tshub_env_render/assets/rgb_node.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env_render/assets/rgb_node.gif
--------------------------------------------------------------------------------
/examples/tshub_env_render/assets/rgb_vehicle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env_render/assets/rgb_vehicle.gif
--------------------------------------------------------------------------------
/examples/tshub_env_render/assets/sumogui_global.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env_render/assets/sumogui_global.gif
--------------------------------------------------------------------------------
/examples/tshub_env_render/assets/sumogui_node.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env_render/assets/sumogui_node.gif
--------------------------------------------------------------------------------
/examples/tshub_env_render/assets/sumogui_vehicle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/examples/tshub_env_render/assets/sumogui_vehicle.gif
--------------------------------------------------------------------------------
/examples/utils/nested_dict_example.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 16:18:38
4 | @Description:
5 | @LastEditTime: 2023-08-24 16:18:39
6 | '''
7 | from collections import defaultdict
8 | from tshub.utils.nested_dict_conversion import create_nested_defaultdict, defaultdict2dict
9 |
10 | # 测试 create_nested_defaultdict 函数
11 | nested_dict = create_nested_defaultdict()
12 | nested_dict['a']['b']['c'] = 123
13 | print(nested_dict['a']['b']['c']) # 输出: 123
14 |
15 | # 测试 defaultdict2dict 函数
16 | nested_dict = create_nested_defaultdict()
17 | nested_dict['a']['b']['c'] = 123
18 |
19 | regular_dict = defaultdict2dict(nested_dict)
20 | print(regular_dict) # 输出: {'a': {'b': {'c': 123}}}
21 |
--------------------------------------------------------------------------------
/examples/utils/parse_trip_info/analysis_trip_info.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-12-01 20:14:30
4 | @Description: 分析 Trip Info 文件
5 | @LastEditTime: 2023-12-01 20:15:54
6 | '''
7 | from tshub.utils.parse_trip_info import TripInfoStats
8 | from tshub.utils.get_abs_path import get_abs_path
9 |
10 | path_convert = get_abs_path(__file__)
11 |
12 | if __name__ == '__main__':
13 | stats = TripInfoStats(path_convert('./single_junction.tripinfo.xml'))
14 | print(stats.output_str())
15 | stats.to_csv(path_convert('./output.csv'))
--------------------------------------------------------------------------------
/examples/utils/parse_trip_info/output.csv:
--------------------------------------------------------------------------------
1 | vType,stat_name,count,min,max,median,mean,std
2 | car_2,duration,291,44.0,132.0,85.0,86.76975945017182,19.00927372550046
3 | car_2,routeLength,291,1021.63,1446.0,1432.04,1259.6446391752604,190.84964267560454
4 | car_2,speed,291,9.279478260869567,25.572142857142858,14.16732558139535,15.13455341906012,3.7575284006830434
5 | car_2,stopTime,291,0.0,0.0,0.0,0.0,0.0
6 | car_2,timeLoss,291,6.81,74.63,39.99,40.141340206185575,18.081083332934092
7 | car_2,waitingCount,291,0.0,3.0,1.0,0.8625429553264605,0.5452125857119926
8 | car_2,waitingTime,291,0.0,56.0,18.0,19.123711340206185,16.535034802402908
9 | car_1,duration,318,40.0,132.0,83.0,82.28301886792453,23.687465059590682
10 | car_1,routeLength,318,1019.63,1444.0,1065.14,1206.8944654088086,199.9407727276456
11 | car_1,speed,318,8.64093220338983,26.254545454545454,15.54391304347826,15.772481499401115,4.469235553081967
12 | car_1,stopTime,318,0.0,0.0,0.0,0.0,0.0
13 | car_1,timeLoss,318,5.87,85.31,36.41,38.03025157232706,22.19696289071844
14 | car_1,waitingCount,318,0.0,2.0,1.0,0.6855345911949685,0.5336284338443956
15 | car_1,waitingTime,318,0.0,58.0,11.0,18.79559748427673,19.697373466997018
16 |
--------------------------------------------------------------------------------
/examples/utils/parse_trip_info/simulate_with_trioinfo.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-12-01 14:39:47
4 | @Description: 开启仿真同时保存 tripinfo, 只对车辆进行仿真, 同时保存 tripinfo
5 | @LastEditTime: 2023-12-01 20:13:18
6 | '''
7 | import numpy as np
8 | from loguru import logger
9 | from tshub.utils.get_abs_path import get_abs_path
10 | from tshub.utils.init_log import set_logger
11 | from tshub.tshub_env.tshub_env import TshubEnvironment
12 | from tshub.utils.format_dict import dict_to_str
13 |
14 | path_convert = get_abs_path(__file__)
15 | set_logger(path_convert('./'))
16 |
17 | sumo_cfg = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
18 |
19 | tshub_env = TshubEnvironment(
20 | sumo_cfg=sumo_cfg,
21 | is_map_builder_initialized=False,
22 | is_aircraft_builder_initialized=False,
23 | is_vehicle_builder_initialized=True,
24 | is_traffic_light_builder_initialized=False,
25 | tls_ids=['htddj_gsndj'],
26 | vehicle_action_type='lane',
27 | tls_action_type='next_or_not',
28 | use_gui=True,
29 | num_seconds=2000,
30 | trip_info=path_convert('./single_junction.tripinfo.xml')
31 | )
32 |
33 | obs = tshub_env.reset()
34 | done = False
35 |
36 | while not done:
37 | actions = {
38 | 'vehicle': dict(),
39 | 'tls': {'htddj_gsndj':0},
40 | 'aircraft': {
41 | "a1": (1, np.random.randint(8)),
42 | "a2": (1, np.random.randint(8)),
43 | }
44 | }
45 | obs, reward, info, done = tshub_env.step(actions=actions)
46 | logger.info(f"SIM: {info['step_time']} \n{dict_to_str(obs)}")
47 | tshub_env._close_simulation()
--------------------------------------------------------------------------------
/examples/v2x/v2x_utils/snr_to_packetloss.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-08-10 20:22:49
4 | @Description:
5 | @LastEditTime: 2024-08-10 21:04:47
6 | '''
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 | from tshub.v2x import calculate_outage_probability
10 |
11 | if __name__ == '__main__':
12 | snr_input = 10 # SNR in dB
13 | outage_prob = calculate_outage_probability(snr_input)
14 | print(f"The outage probability is {outage_prob:.4f}")
15 |
16 | # 绘制 snr 与 packet loss 的关系
17 | snr_values = np.linspace(-20, 30, 300)
18 | outage_probabilities = [calculate_outage_probability(snr) for snr in snr_values]
19 |
20 | # Plotting the outage probability against SNR
21 | plt.figure(figsize=(10, 6))
22 | plt.plot(snr_values, outage_probabilities, label='Outage Probability')
23 | plt.xlabel('SNR (dB)')
24 | plt.ylabel('Packet Loss Probability')
25 | plt.title('Packet Loss Probability vs. SNR')
26 | plt.grid(True)
27 | plt.legend()
28 | plt.show()
--------------------------------------------------------------------------------
/examples/vehicles/ego_vehicles/vehicle_ego.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 14:45:54
4 | @Description: 使用 Lane 来控制车辆, 只控制是 ego 类型的车
5 | @LastEditTime: 2024-08-11 19:36:55
6 | '''
7 | import traci
8 | import sumolib
9 | import numpy as np
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.vehicle.vehicle_builder import VehicleBuilder
13 | from tshub.utils.init_log import set_logger
14 |
15 | def filter_ego_id(vehicle_data):
16 | ego_ids = []
17 | for _veh_id, _veh_info in vehicle_data.items():
18 | if _veh_info['vehicle_type'] == 'ego':
19 | ego_ids.append(_veh_id)
20 | return ego_ids
21 |
22 | sumoBinary = sumolib.checkBinary('sumo-gui')
23 |
24 | path_convert = get_abs_path(__file__)
25 | set_logger(path_convert('./'))
26 |
27 | sumocfg_file = path_convert("../../sumo_env/three_junctions/env/3junctions.sumocfg")
28 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
29 | conn = traci.getConnection('0')
30 |
31 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='lane')
32 | while conn.simulation.getMinExpectedNumber() > 0:
33 | # 获得车辆的信息
34 | data = scene_vehicles.get_objects_infos()
35 |
36 | # 控制部分车辆, 分别是 lane_change, speed
37 | ego_vehicles = filter_ego_id(data)
38 | actions = {
39 | _veh_id:{'lane_change': np.random.randint(4)}
40 | for _veh_id in ego_vehicles
41 | }
42 | scene_vehicles.control_objects(actions)
43 |
44 | conn.simulationStep()
45 |
46 | conn.close()
--------------------------------------------------------------------------------
/examples/vehicles/ego_vehicles/vehicle_laneChange_crash.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-05 14:50:29
4 | @Description: 控制车辆进行碰撞, 由于换道引发的碰撞
5 | @LastEditTime: 2024-08-11 19:39:46
6 | '''
7 | import traci
8 | import sumolib
9 | import numpy as np
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.vehicle.vehicle_builder import VehicleBuilder
13 | from tshub.utils.init_log import set_logger
14 |
15 | sumoBinary = sumolib.checkBinary('sumo-gui')
16 |
17 | path_convert = get_abs_path(__file__)
18 | set_logger(path_convert('./'))
19 |
20 | sumocfg_file = path_convert("../../sumo_env/ego_crash/ego_crash_lane_change/scenario.sumocfg")
21 | traci.start([sumoBinary, "-c", sumocfg_file, "--collision.action", "remove"], label='0') # 需要加入 collision.action
22 | conn = traci.getConnection('0')
23 |
24 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='lane_continuous_speed')
25 |
26 | while conn.simulation.getMinExpectedNumber() > 0:
27 | # 获得车辆的信息
28 | data = scene_vehicles.get_objects_infos()
29 |
30 | actions = {}
31 | if "1" in data:
32 | actions["1"] = {'lane_change': np.random.randint(3), 'target_speed':15}
33 | print(actions)
34 | scene_vehicles.control_objects(actions)
35 |
36 | conn.simulationStep()
37 |
38 | conn.close()
--------------------------------------------------------------------------------
/examples/vehicles/ego_vehicles/vehicle_speed_crash.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-04-13 15:01:42
4 | @Description: 控制车辆进行碰撞, 由于速度引发的碰撞
5 | => ego_crash_car_following, 追尾测试
6 | => ego_crash_intersection, 无保护左转撞车测试
7 | @LastEditTime: 2024-08-11 19:40:01
8 | '''
9 | import traci
10 | import sumolib
11 |
12 | from tshub.utils.get_abs_path import get_abs_path
13 | from tshub.vehicle.vehicle_builder import VehicleBuilder
14 | from tshub.utils.init_log import set_logger
15 |
16 | CRASH_TYPE = "ego_crash_car_following" # ego_crash_car_following, ego_crash_intersection
17 |
18 | sumoBinary = sumolib.checkBinary('sumo-gui')
19 |
20 | path_convert = get_abs_path(__file__)
21 | set_logger(path_convert('./'))
22 |
23 | sumocfg_file = path_convert(f"../../sumo_env/ego_crash/{CRASH_TYPE}/env.sumocfg")
24 | traci.start([sumoBinary, "-c", sumocfg_file, "--collision.action", "warn"], label='0') # 需要加入 collision.action
25 | conn = traci.getConnection('0')
26 |
27 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='lane_continuous_speed')
28 |
29 | while conn.simulation.getMinExpectedNumber() > 0:
30 | # 获得车辆的信息
31 | data = scene_vehicles.get_objects_infos()
32 |
33 | actions = {}
34 | if "ego_1" in data:
35 | actions["ego_1"] = {'lane_change': 0, 'target_speed':12}
36 | if "ego_2" in data:
37 | actions["ego_2"] = {'lane_change': 0, 'target_speed':12}
38 | if "ego_3" in data:
39 | actions["ego_3"] = {'lane_change': 0, 'target_speed':12}
40 | if "ego_4" in data:
41 | actions["ego_4"] = {'lane_change': 0, 'target_speed':12}
42 | scene_vehicles.control_objects(actions)
43 |
44 | conn.simulationStep()
45 |
46 | conn.close()
--------------------------------------------------------------------------------
/examples/vehicles/get_vehicle_state.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 15:50:00
4 | @Description: 获得场景中所有车辆的信息
5 | # 这里需要可以在每隔 Ns 获得当前车辆的所有信息
6 | @LastEditTime: 2024-04-09 21:12:05
7 | '''
8 | import sumolib
9 | from loguru import logger
10 |
11 | from tshub.utils.get_abs_path import get_abs_path
12 | from tshub.vehicle.vehicle_builder import VehicleBuilder
13 | from tshub.utils.init_log import set_logger
14 | from tshub.utils.format_dict import dict_to_str
15 |
16 | import traci
17 | sumoBinary = sumolib.checkBinary('sumo-gui')
18 |
19 | path_convert = get_abs_path(__file__)
20 | set_logger(path_convert('./'), terminal_log_level='INFO')
21 |
22 | sumocfg_file = path_convert("../sumo_env/single_junction/env/single_junction.sumocfg")
23 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
24 | conn = traci.getConnection('0')
25 |
26 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='lane')
27 | while conn.simulation.getMinExpectedNumber() > 0:
28 | data = scene_vehicles.get_objects_infos() # 获得车辆的信息
29 | logger.info(f'SIM: {dict_to_str(data)}')
30 |
31 | conn.simulationStep()
32 |
33 | conn.close()
--------------------------------------------------------------------------------
/examples/vehicles/vehicle_action/vehicle_lane.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 16:55:45
4 | @Description: 控制车辆, 四个离散的动作
5 | @LastEditTime: 2024-08-11 19:28:00
6 | '''
7 | import traci
8 | import random
9 | import numpy as np
10 | import sumolib
11 |
12 | from tshub.utils.get_abs_path import get_abs_path
13 | from tshub.vehicle.vehicle_builder import VehicleBuilder
14 | from tshub.utils.init_log import set_logger
15 |
16 | def select_keys(dictionary):
17 | keys = list(dictionary.keys())
18 | selected_keys = random.sample(keys, k=int(len(keys) * 0.1))
19 | return selected_keys
20 |
21 | sumoBinary = sumolib.checkBinary('sumo-gui')
22 |
23 | path_convert = get_abs_path(__file__)
24 | set_logger(path_convert('./'))
25 |
26 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
27 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
28 | conn = traci.getConnection('0')
29 |
30 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='lane')
31 | while conn.simulation.getMinExpectedNumber() > 0:
32 | # 获得车辆的信息
33 | data = scene_vehicles.get_objects_infos()
34 |
35 | # 控制部分车辆, 分别是 lane_change, speed
36 | selected_vehicles = select_keys(data)
37 | actions = {
38 | _veh_id:{'lane_change': np.random.randint(4)}
39 | for _veh_id in selected_vehicles
40 | }
41 | scene_vehicles.control_objects(actions)
42 |
43 | conn.simulationStep()
44 |
45 | conn.close()
--------------------------------------------------------------------------------
/examples/vehicles/vehicle_action/vehicle_lane_with_continuous_speed.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-30 16:19:47
4 | @Description: 控制车辆, 同时控制换道和速度
5 | @LastEditTime: 2024-08-11 19:35:45
6 | '''
7 | import traci
8 | import random
9 | import numpy as np
10 | import sumolib
11 |
12 | from tshub.utils.get_abs_path import get_abs_path
13 | from tshub.vehicle.vehicle_builder import VehicleBuilder
14 | from tshub.utils.init_log import set_logger
15 |
16 | def select_keys(dictionary):
17 | keys = list(dictionary.keys())
18 | selected_keys = random.sample(keys, k=int(len(keys) * 0.1))
19 | return selected_keys
20 |
21 | sumoBinary = sumolib.checkBinary('sumo-gui')
22 |
23 | path_convert = get_abs_path(__file__)
24 | set_logger(path_convert('./'))
25 |
26 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
27 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
28 | conn = traci.getConnection('0')
29 |
30 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='lane_continuous_speed')
31 | while conn.simulation.getMinExpectedNumber() > 0:
32 | # 获得车辆的信息
33 | data = scene_vehicles.get_objects_infos()
34 |
35 | # 控制部分车辆, 分别是 lane_change, speed
36 | selected_vehicles = select_keys(data)
37 | actions = {
38 | _veh_id:{'lane_change': np.random.randint(3), 'target_speed':12}
39 | for _veh_id in selected_vehicles
40 | }
41 | scene_vehicles.control_objects(actions)
42 |
43 | conn.simulationStep()
44 |
45 | conn.close()
--------------------------------------------------------------------------------
/examples/vehicles/vehicle_action/vehicle_speed.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-08-11 18:50:35
4 | @Description: 单纯控制车辆的速度
5 | @LastEditTime: 2024-08-11 19:30:09
6 | '''
7 | import traci
8 | import random
9 | import numpy as np
10 | import sumolib
11 |
12 | from tshub.utils.get_abs_path import get_abs_path
13 | from tshub.vehicle.vehicle_builder import VehicleBuilder
14 | from tshub.utils.init_log import set_logger
15 |
16 | def select_keys(dictionary):
17 | keys = list(dictionary.keys())
18 | selected_keys = random.sample(keys, k=int(len(keys) * 1))
19 | return selected_keys
20 |
21 | sumoBinary = sumolib.checkBinary('sumo-gui')
22 |
23 | path_convert = get_abs_path(__file__)
24 | set_logger(path_convert('./'))
25 |
26 | sumocfg_file = path_convert("../../sumo_env/single_junction/env/single_junction.sumocfg")
27 | traci.start([sumoBinary, "-c", sumocfg_file], label='0')
28 | conn = traci.getConnection('0')
29 |
30 | scene_vehicles = VehicleBuilder(sumo=conn, action_type='speed')
31 | while conn.simulation.getMinExpectedNumber() > 0:
32 | # 获得车辆的信息
33 | data = scene_vehicles.get_objects_infos()
34 |
35 | # 控制部分车辆, 分别是 lane_change, speed
36 | selected_vehicles = select_keys(data)
37 | actions = {
38 | _veh_id:{
39 | 'speed_action': 1, # 0:加速, 1:减速, 2:保持不变
40 | 'acceleration_rate': 2,
41 | }
42 | for _veh_id in selected_vehicles
43 | }
44 | scene_vehicles.control_objects(actions)
45 |
46 | conn.simulationStep()
47 |
48 | conn.close()
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | loguru
2 | numpy
3 | traci
4 | sumolib
5 | libsumo
6 | scipy
7 | scienceplots
--------------------------------------------------------------------------------
/test/test_tshub_version.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-26 05:21:00
4 | @Description: 检测是否安装成功
5 | @LastEditTime: 2024-07-26 05:23:51
6 | '''
7 | import tshub
8 | import unittest
9 | from packaging import version
10 |
11 | class TestTSHubInstallation(unittest.TestCase):
12 | def test_version_greater_than_1(self) -> None:
13 | """Test if the installed TSHub package version is greater than 1.
14 | """
15 | self.assertTrue(version.parse(tshub.__version__) >= version.parse("1.0"))
16 |
17 | if __name__ == '__main__':
18 | unittest.main()
19 |
--------------------------------------------------------------------------------
/tshub/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 11:02:35
4 | @Description: tshub
5 | @LastEditTime: 2024-07-26 05:19:00
6 | '''
7 | __TITLE__ = 'TransSimHub'
8 | __VERSION__ = 'v1.1'
9 | __DESCRIPTION__ = 'A lightweight Python library for simulating and controlling transportation systems'
10 | __AUTHOR__ = "Traffic-Alpha"
11 | __version__ = __VERSION__
--------------------------------------------------------------------------------
/tshub/aircraft/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/tshub/aircraft/__init__.py
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/tshub/aircraft/aircraft.png
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft_action_type.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 17:59:13
4 | @Description: Aircraft Action Type. Aircraft 共有四种动作类型,分别是:
5 | 1. 在固定的位置保持不动
6 | 2. 在固定的高度,只能水平面移动
7 | 3. 只能改变高度,水平方向无法移动
8 | 4. 可以同时改变高度和在水平方向移动,但是动作空间是离散的
9 | @LastEditTime: 2023-08-29 20:30:59
10 | '''
11 | import enum
12 |
13 | class aircraft_action_type(enum.Enum):
14 | Stationary = 'stationary'
15 | """
16 | Aircraft remains stationary at a fixed position.
17 | """
18 |
19 | HorizontalMovement = 'horizontal_movement'
20 | """
21 | Aircraft can only move in the horizontal plane while maintaining a fixed altitude.
22 | + Speed: float, 连续控制
23 | + Heading: int, 这里输入是 heading index, 平面内被分为 8 个 heading 角度
24 | """
25 |
26 | VerticalMovement = 'vertical_movement'
27 | """
28 | Aircraft can only change altitude while remaining in the same horizontal position.
29 | + Speed: float, 连续控制
30 | + Heading: int, 这里输入是 heading index, 共有三种情况, (1) 向上; (2) 向下; (3) 平稳
31 | """
32 |
33 | CombinedMovement = 'combined_movement'
34 | """
35 | Aircraft can simultaneously change altitude and move in the horizontal direction. The motion space is discrete.
36 | """
37 |
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft_type/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 17:58:42
4 | @Description: 四种 aircraft 动作类型
5 | @LastEditTime: 2023-08-29 17:58:43
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft_type/base_aircraft_action.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 20:18:04
4 | @Description: Base Aircraft Action
5 | @LastEditTime: 2023-08-30 18:18:56
6 | '''
7 | from loguru import logger
8 | from typing import Tuple
9 | from abc import ABC, abstractmethod
10 |
11 | class AircraftAction(ABC):
12 | def __init__(self, id) -> None:
13 | super().__init__()
14 | self.aircraft_id = id
15 |
16 | @abstractmethod
17 | def execute(self) -> None:
18 | pass
19 |
20 | def calculate_new_position(self,
21 | position:Tuple[float, float, float],
22 | speed: float, heading:Tuple[float, float, float]
23 | ) -> Tuple[float, float, float]:
24 | new_position = [
25 | position[0] + speed * heading[0],
26 | position[1] + speed * heading[1],
27 | position[2] + speed * heading[2]
28 | ]
29 | if new_position[2] <= 0:
30 | logger.warning(f'SIM: Aircraft 的高度不能小于 0, 现在高度为 {new_position[2]}.')
31 | logger.warning('SIM: Aircraft 的位置不变.')
32 | new_position[2] = position[2] # 保持原来的高度不变
33 | return new_position
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft_type/combined_movement.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 18:11:40
4 | @Description: 飞翔器水平和垂直同时移动
5 | @LastEditTime: 2023-08-30 16:05:22
6 | '''
7 | import math
8 | from typing import Tuple
9 | from .base_aircraft_action import AircraftAction
10 |
11 | class CombinedMovementAction(AircraftAction):
12 | def __init__(self, id) -> None:
13 | super().__init__(id)
14 | AZIMUTHS = [0, 45, 90, 135, 180, 225, 270, 315] # Eight discrete azimuth angles
15 | ELEVATIONS = [-90, -45, 0, 45, 90] # Five discrete elevation angles
16 | self.combinations = [(azimuth, elevation)
17 | for azimuth in AZIMUTHS
18 | for elevation in ELEVATIONS
19 | ]
20 |
21 | def execute(self,
22 | position:Tuple[float, float, float],
23 | speed: float, heading_index: int) -> None:
24 | heading_combinations = self.combinations[heading_index]
25 | heading = self.calculate_heading_3d(*heading_combinations)
26 | new_position = self.calculate_new_position(position=position, speed=speed, heading=heading)
27 | return new_position, heading
28 |
29 | def calculate_heading_3d(self, azimuth:float, elevation:float) -> Tuple[float, float, float]:
30 | # 将方位角和俯仰角转换为弧度
31 | azimuth_rad = math.radians(azimuth)
32 | elevation_rad = math.radians(elevation)
33 |
34 | # 计算 heading 向量的 x、y 和 z 分量
35 | x = math.cos(azimuth_rad) * math.cos(elevation_rad)
36 | y = math.sin(azimuth_rad) * math.cos(elevation_rad)
37 | z = math.sin(elevation_rad)
38 |
39 | # 返回 heading 向量作为一个包含 x、y 和 z 分量的元组
40 | return (x, y, z)
41 |
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft_type/stationary.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 18:10:45
4 | @Description: 飞翔器保持不动
5 | @LastEditTime: 2023-08-30 15:31:05
6 | '''
7 | from .base_aircraft_action import AircraftAction
8 |
9 | class StationaryAction(AircraftAction):
10 | def __init__(self, id) -> None:
11 | super().__init__(id)
12 |
13 | def execute(self, *args, **kwargs) -> None:
14 | position = kwargs['position']
15 | heading = (0,0,0) # heading 为 0, 保持不变
16 | return position, heading
--------------------------------------------------------------------------------
/tshub/aircraft/aircraft_type/vertical_movement.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 18:11:22
4 | @Description: 飞翔器垂直方向移动
5 | @LastEditTime: 2023-08-30 15:28:00
6 | '''
7 | from typing import Tuple
8 | from .base_aircraft_action import AircraftAction
9 |
10 | class VerticalMovementAction(AircraftAction):
11 | HEADINGS = {
12 | 0: (0, 0, 0), # No change
13 | 1: (0, 0, 1), # Upward movement
14 | 2: (0, 0, -1) # Downward movement
15 | }
16 |
17 | def __init__(self, id) -> None:
18 | super().__init__(id)
19 |
20 | def execute(self, position:Tuple[float, float, float],
21 | speed: float, heading_index: int) -> None:
22 | heading = self.HEADINGS[heading_index]
23 | new_position = self.calculate_new_position(position=position, speed=speed, heading=heading)
24 | return new_position, heading
25 |
26 |
--------------------------------------------------------------------------------
/tshub/features/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 15:46:27
4 | @Description:
5 | @LastEditTime: 2023-08-23 15:46:28
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/map/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-22 14:03:37
4 | @Description: Map Info and Builder
5 | @LastEditTime: 2023-09-22 14:03:41
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/person/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-24 15:47:03
4 | @Description: Person Info
5 | @LastEditTime: 2023-11-24 15:47:05
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 13:37:55
4 | @Description: 关于 SUMO 使用的一些工具
5 | @LastEditTime: 2023-08-23 13:37:56
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/additional_files/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 15:15:51
4 | @Description: 生成额外加载的 additional 文件
5 | @LastEditTime: 2023-09-01 15:15:52
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/analysis_output/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-03-24 15:07:32
4 | @Description: 分析 SUMO Output 的文件
5 | @LastEditTime: 2024-03-24 15:08:00
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/detectors/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 16:13:11
4 | @Description: 生成探测器
5 | @LastEditTime: 2023-08-24 16:13:12
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/generate_route/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 14:16:05
4 | @Description: route 生成模块
5 | @LastEditTime: 2023-08-31 14:16:05
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/interpolation/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 14:17:35
4 | @Description: 对 route 或是 turndef 进行插值
5 | @LastEditTime: 2023-08-31 14:17:36
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/interpolation/repeat_values.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 17:01:13
4 | @Description:
5 | @LastEditTime: 2023-08-31 17:03:33
6 | '''
7 | from typing import List
8 |
9 | def repeat_values(values, period) -> List[float]:
10 | """
11 | 根据 period 列表中的数值,对 values 列表进行重复。
12 |
13 | 例如:
14 | + period 表示每个阶段的持续时间 (分钟);
15 | + values 表示每个阶段内每分钟的结果
16 |
17 | 例如:
18 | + values = [0.25, 0.5] # 每个时间段的转向比
19 | + period = [3, 3] # 每个时间段的持续时间
20 | -> 这里会转换为 [0.25, 0.25, 0.25, 0.5, 0.5, 0.5], 重复对应的次数
21 |
22 | 参数:
23 | values (list): 需要重复的数值。
24 | period (list): 每个时间段的持续时间列表。
25 |
26 | 返回:
27 | list: 重复后的结果。
28 | """
29 | repeated_values = []
30 | for i, num in enumerate(values):
31 | repeated_values.extend([num] * period[i])
32 | return repeated_values
--------------------------------------------------------------------------------
/tshub/sumo_tools/interpolation/visualize_interpolations.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 17:06:54
4 | @Description: 对插值之后的结果进行可视化展示
5 | @LastEditTime: 2023-08-31 17:16:20
6 | '''
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 | from .repeat_values import repeat_values
10 |
11 | def visualize_interpolations(values, period, smooth_values) -> None:
12 | """
13 | 可视化原始转弯概率数据和平滑后的转弯概率数据。
14 |
15 | 参数:
16 | values (list): 每个周期内的值。
17 | period (int): 每个周期持续的时长。
18 | smooth_values (list): 平滑后的每分钟的值。
19 | """
20 | # 创建时间间隔
21 | time_intervals = np.arange(len(smooth_values))
22 |
23 | # 将 values 按照 period 重复
24 | repeated_values = repeat_values(values, period)
25 |
26 | # 绘制原始转弯概率数据
27 | plt.plot(time_intervals, repeated_values, 'o-', label='Original')
28 | # 绘制平滑后的转弯概率数据
29 | plt.plot(time_intervals, smooth_values, 's-', label='Smoothed')
30 |
31 | # 设置图表标题和轴标签
32 | plt.title('Comparison of Interpolations Results')
33 | plt.xlabel('Time Intervals')
34 |
35 | # 添加图例
36 | plt.legend()
37 |
38 | # 显示图表
39 | plt.show()
--------------------------------------------------------------------------------
/tshub/sumo_tools/osm_build_type/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-05-27 16:11:27
4 | @Description: net & poly files
5 | @LastEditTime: 2024-05-27 16:11:28
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/sumo_infos/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 17:06:29
4 | @Description: 从 SUMO 中提取结构化的数据
5 | @LastEditTime: 2023-08-24 17:06:30
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/sumo_infos/traffic_light_ids.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-09-01 15:33:56
4 | @Description: 获得路网中所有的 traffic light 的 id
5 | @LastEditTime: 2023-09-01 15:36:42
6 | '''
7 | import sumolib
8 | from typing import List
9 |
10 | def get_tlsID_list(network_file) -> List[str]:
11 | """返回一个路网文件所有的 Traffic Light Signal ID list
12 |
13 | Args:
14 | network_file (str): network 文件所在的路径
15 |
16 | Returns:
17 | list: tls id 组成的列表
18 | """
19 | tls_list = []
20 | net = sumolib.net.readNet(network_file)
21 | for node in net.getNodes():
22 | if node.getType() == 'traffic_light':
23 | tls_list.append(node.getID())
24 | return tls_list
25 |
--------------------------------------------------------------------------------
/tshub/sumo_tools/sumo_infos/turndef/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2021-12-01 21:42:00
4 | @Description: 来自 tools/turn-defs/ 文件
5 | @LastEditTime: 2023-08-31 19:42:47
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/traffic_light/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 11:16:05
4 | @Description: traffic signal light module
5 | @LastEditTime: 2023-08-25 11:16:06
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/traffic_light/tls_type/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 17:08:46
4 | @Description: 不同的 Traffic Light Signal 的控制类型 (action design)
5 | @LastEditTime: 2024-04-24 16:32:40
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/traffic_light/traffic_light_action_type.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 16:55:36
4 | @Description: Traffic Light Signal Action Type
5 | @LastEditTime: 2024-06-27 19:00:42
6 | '''
7 | import enum
8 |
9 | class tls_action_type(enum.Enum):
10 | ChooseNextPhase = 'choose_next_phase'
11 | """
12 | Action= ``int``. Discrete action that can choose from all phases
13 | """
14 |
15 | ChooseNextPhaseSyn = 'choose_next_phase_syn'
16 | """
17 | Action= ``int``. Discrete action that can choose from all phases (Synchronize)
18 | """
19 |
20 | NextorNot = 'next_or_not'
21 | """
22 | Action= ``int``. Discrete action from one of
23 |
24 | + 0, Change to the next phase
25 | + 1, Keep the current phase
26 | """
27 |
28 | AdjustCycleDuration = 'adjust_cycle_duration'
29 | """Action= ``List``. Fine-tuning of each phase duration
30 | """
31 |
32 | SetPhaseDuration = 'set_phase_diration'
33 | """Action= ``int``. The new phase duration for the current traffic phase.
34 | """
--------------------------------------------------------------------------------
/tshub/traffic_light/traffic_light_feature_convert.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 19:37:07
4 | @Description: TSC 中 id 和 meaning 的转换
5 | @LastEditTime: 2023-09-11 19:56:28
6 | '''
7 | class TSCKeyMeaningsConverter:
8 | def __init__(self):
9 | self.key_to_meaning = {
10 | 17: 'last_step_mean_speed',
11 | 18: 'last_step_vehicle_id_list',
12 | 24: 'jam_length_vehicle',
13 | 25: 'jam_length_meters',
14 | 19: 'last_step_occupancy',
15 | }
16 | self.meaning_to_key = {v: k for k, v in self.key_to_meaning.items()}
17 |
18 | def get_meaning(self, key):
19 | return self.key_to_meaning.get(key, '')
20 |
21 | def get_key(self, meaning):
22 | return self.meaning_to_key.get(meaning, '')
23 |
--------------------------------------------------------------------------------
/tshub/tshub_env/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 15:34:58
4 | @Description: TransSimHub 环境
5 | @LastEditTime: 2023-08-23 15:34:59
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/tshub_env/base_builder.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-29 18:05:16
4 | @Description: builder 基类
5 | @LastEditTime: 2023-08-30 15:14:36
6 | '''
7 | from abc import ABC, abstractmethod
8 |
9 | class BaseBuilder(ABC):
10 | @abstractmethod
11 | def create_objects(self) -> None:
12 | """创建场景内所有的 object
13 | """
14 | pass
15 |
16 | @abstractmethod
17 | def update_objects_state(self) -> None:
18 | """更新场景内所有 object 的信息
19 | 1. 对于 vehicle 和 traffic light, 需要从 sumo 中获得信息来进行更新;
20 | 2. 对于 aircraft, 每次 control 之后自动进行更新;
21 | """
22 | pass
23 |
24 | @abstractmethod
25 | def get_objects_infos(self) -> None:
26 | """返回场景内所有 object 的信息
27 | """
28 | pass
29 |
30 | @abstractmethod
31 | def control_objects(self) -> None:
32 | """控制场景内所有的 objects
33 | """
34 | pass
--------------------------------------------------------------------------------
/tshub/tshub_env3d/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 16:01:43
4 | @Description: 将 TSHub 转换为 3D 的场景
5 | Modify according to the following two projects:
6 | - SMARTS, https://github.com/huawei-noah/SMARTS
7 | - MetaDrive, https://github.com/metadriverse/metadrive
8 | @LastEditTime: 2024-07-07 23:25:39
9 | '''
10 |
--------------------------------------------------------------------------------
/tshub/tshub_env3d/_assets_3d/map_road_lines/dashed_line_shader.frag:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | out vec4 FragColor;
4 |
5 | flat in vec3 StartPos;
6 | in vec3 VertPos;
7 |
8 | uniform vec4 p3d_Color;
9 | uniform vec2 iResolution;
10 |
11 | void main()
12 | {
13 | uint pattern = 0x00FFu;
14 | float factor = 2.0;
15 |
16 | vec2 dir = (VertPos.xy - StartPos.xy) * iResolution / 2.0;
17 | float dist = length(dir);
18 |
19 | uint bit = uint(round(dist / factor)) & 15U;
20 | if ((pattern & (1U< None:
16 | """初始化的时候需要使用 self._follow_actor 初始化 sensor 的位置
17 | """
18 | pass
19 |
20 | @abstractmethod
21 | def init_actor(self, element_pose) -> None:
22 | """初始化相机的位置
23 | """
24 | raise NotImplementedError
25 |
26 | @abstractmethod
27 | def step(self, element_pose) -> None:
28 | """更新 camera 的位置, 确保可以获得指定 element 的信息
29 | """
30 | raise NotImplementedError
31 |
32 | def teardown(self, **kwargs) -> None:
33 | self.camera.teardown()
34 |
35 | @property
36 | def serializable(self) -> bool:
37 | return False
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/base_sensors/base_sensor.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-07 22:26:18
4 | @Description: 定义基础的传感器
5 | @LastEditTime: 2024-07-08 23:32:36
6 | '''
7 | import abc
8 | from typing import Any, Dict
9 |
10 | class BaseSensor(metaclass=abc.ABCMeta):
11 | """The sensor base class.
12 | """
13 | def step(self, tshub_obs: Dict[str, Any], **kwargs):
14 | """Update sensor state (根据 TSHub 返回值更新 sensor).
15 | """
16 | pass
17 |
18 | @abc.abstractmethod
19 | def teardown(self, **kwargs):
20 | """Clean up internal resources
21 | """
22 | raise NotImplementedError
23 |
24 | @abc.abstractmethod
25 | def __call__(self, *args: Any, **kwds: Any) -> Any:
26 | raise NotImplementedError
27 |
28 | @property
29 | def mutable(self) -> bool:
30 | """If this sensor mutates on call."""
31 | return True
32 |
33 | @property
34 | def serializable(self) -> bool:
35 | """If this sensor can be serialized."""
36 | return True
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/cameras/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-07 22:03:33
4 | @Description: 场景相机, 包含 Off-screen camera & Shader camera
5 | @LastEditTime: 2024-07-07 22:03:33
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/cameras/offscreen_camera/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-15 11:52:22
4 | @Description: 创建基础相机组建
5 | @LastEditTime: 2024-07-21 03:14:48
6 | '''
7 | from .bev_camera import OffscreenBEVCamera
8 | from .aircraft_camera import OffscreenAircraftCamera
9 |
10 | from .front_camera import (
11 | OffscreenFrontCamera,
12 | OffscreenFrontLeftCamera,
13 | OffscreenFrontRightCamera,
14 | )
15 |
16 | from .back_camera import (
17 | OffscreenBackCamera,
18 | OffscreenBackLeftCamera,
19 | OffscreenBackRightCamera
20 | )
21 |
22 | from .junction_camera import (
23 | OffscreenJunctionFrontCamera,
24 | OffscreenJunctionBackCamera,
25 | )
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/cameras/offscreen_camera/aircraft_camera.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-21 03:08:43
4 | @Description: 飞行器上面的飞行器
5 | @LastEditTime: 2024-07-21 03:58:09
6 | '''
7 | from typing import Tuple
8 | from dataclasses import dataclass
9 |
10 | from .base_offscreen_camera import (
11 | BaseOffscreenCamera,
12 | _BaseOffCameraMixin
13 | )
14 | from .....vis3d_utils.coordinates import Pose
15 |
16 | @dataclass
17 | class OffscreenAircraftCamera(_BaseOffCameraMixin, BaseOffscreenCamera):
18 | """无人机上面的相机, 从无人机往下拍
19 | """
20 | def init_pos(self, pose:Pose, *args, **kwargs) -> None:
21 | """初始化 camera 的位置
22 | """
23 | self.update(pose, *args, **kwargs)
24 |
25 | def update(self, pose: Pose, *args, **kwargs) -> None:
26 | """Update the location of the camera (这里 Update 可以使得 camera 跟踪车辆或是其他的 object).
27 | Args:
28 | pose:
29 | The pose of the camera target.
30 | height:
31 | The height of the camera above the camera target.
32 | """
33 | pos, heading = pose.as_panda3d()
34 | # 俯视的角度
35 | self.camera_np.setPos(pos[0], pos[1], pos[2])
36 | self.camera_np.lookAt(pos[0], pos[1], 2) # 查看 UAV/UAM 正下方
37 | # self.camera_np.setH(heading) # 航向角
38 |
39 | @property
40 | def position(self) -> Tuple[float, float, float]:
41 | return self.camera_np.getPos()
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/cameras/offscreen_camera/base_offscreen_camera/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-20 14:33:19
4 | @Description: Base Class for Offscreen Camera
5 | @LastEditTime: 2024-07-20 14:38:38
6 | '''
7 | from .base_off_camera import BaseOffscreenCamera
8 | from .base_off_camera_mixin import _BaseOffCameraMixin
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/cameras/offscreen_camera/bev_camera.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-07 22:04:09
4 | @Description: BEV Camera (俯视摄像头)
5 | @LastEditTime: 2024-07-21 03:11:56
6 | '''
7 | from typing import Tuple
8 | from dataclasses import dataclass
9 |
10 | from .base_offscreen_camera import (
11 | BaseOffscreenCamera,
12 | _BaseOffCameraMixin
13 | )
14 | from .....vis3d_utils.coordinates import Pose
15 |
16 | @dataclass
17 | class OffscreenBEVCamera(_BaseOffCameraMixin, BaseOffscreenCamera):
18 | """A camera used for rendering images to a graphics buffer (这里是 BEV 的视角).
19 | """
20 | def init_pos(self, pose:Pose, height:float=30, *args, **kwargs) -> None:
21 | """初始化 camera 的位置
22 | """
23 | self.update(pose, height, *args, **kwargs)
24 |
25 | def update(self, pose: Pose, height:float=30, *args, **kwargs) -> None:
26 | """Update the location of the camera (这里 Update 可以使得 camera 跟踪车辆或是其他的 object).
27 | Args:
28 | pose:
29 | The pose of the camera target.
30 | height:
31 | The height of the camera above the camera target.
32 | """
33 | pos, heading = pose.as_panda3d()
34 | # 俯视的角度
35 | self.camera_np.setPos(pos[0], pos[1], pos[2]+height)
36 | self.camera_np.lookAt(pos[0], pos[1], 2) # 查看 UAV/UAM 正下方
37 | self.camera_np.setH(heading) # 航向角, 这样让车道正前方
38 |
39 | @property
40 | def position(self) -> Tuple[float, float, float]:
41 | return self.camera_np.getPos()
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/sensors/cameras/offscreen_camera/offscreen_camera_type.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-15 12:12:53
4 | @Description: Offscreen Camera 的类型
5 | @LastEditTime: 2024-07-21 03:13:42
6 | '''
7 | import enum
8 |
9 | class OffscreenCameraType(enum.Enum):
10 | # 十字路口摄像头
11 | Junction_Front = "Off_Junction_Front_Camera"
12 | Junction_Back = "Off_Junction_Back_Camera"
13 | # 摄像头在前方
14 | Front = 'Off_Front_Camera'
15 | Front_LEFT = 'Off_FrontLeft_Camera'
16 | Front_RIGHT = 'Off_FrontRight_Camera'
17 | # 摄像头在后方
18 | Back = 'Off_Back_Camera'
19 | Back_LEFT = 'Off_BackLeft_Camera'
20 | Back_RIGHT = 'Off_BackRight_Camera'
21 | # 跟随车辆的视角
22 | BEV = 'Off_BEV_Camera'
23 | # 无人机的视角
24 | Aircraft = 'Off_Aircraft_Camera'
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_renderer/traffic_elements/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-08 21:49:27
4 | @Description: 3D 场景内基本的物体
5 | @LastEditTime: 2024-07-08 23:11:24
6 | '''
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 23:28:34
4 | @Description: 路网转换的工具
5 | @LastEditTime: 2024-07-03 23:28:34
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/element_to_glb/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-13 07:25:27
4 | @Description: 分别将地图元素转换为 glb
5 | @LastEditTime: 2024-07-13 07:43:21
6 | '''
7 | import trimesh
8 | from typing import Final
9 |
10 | OLD_TRIMESH: Final[bool] = tuple(int(d) for d in trimesh.__version__.split(".")) <= (
11 | 3,
12 | 9,
13 | 29,
14 | )
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/element_to_glb/road_glb.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-13 07:27:10
4 | @Description: 生成 road glb 文件
5 | @LastEditTime: 2024-07-13 07:51:47
6 | '''
7 | import math
8 | import warnings
9 | from typing import List, Tuple
10 |
11 | import numpy as np
12 | import trimesh.visual
13 |
14 | from ...vis3d_utils.colors import Colors
15 | from ..sumonet_convert_utils.glb_data import GLBData
16 |
17 | # Suppress trimesh deprecation warning
18 | with warnings.catch_warnings():
19 | warnings.filterwarnings(
20 | "ignore",
21 | message="Please use `coo_matrix` from the `scipy.sparse` namespace, the `scipy.sparse.coo` namespace is deprecated.",
22 | category=DeprecationWarning,
23 | )
24 | import trimesh # only suppress the warnings caused by trimesh
25 | from trimesh.exchange import gltf
26 |
27 | def make_road_glb(lines: List[List[Tuple[float, float]]]) -> GLBData:
28 | """Create a GLB file from a list of road lines (使用实线连接).
29 | """
30 | scene = trimesh.Scene()
31 | for line_pts in lines:
32 | # Create a list of vertices with a z-coordinate of 0.1
33 | vertices = np.array([(*pt, 0.1) for pt in line_pts])
34 | # Create a Path3D directly from the vertices
35 | path = trimesh.load_path(vertices)
36 | path.apply_transform(
37 | trimesh.transformations.rotation_matrix(math.pi / 2, [-1, 0, 0])
38 | )
39 | path.visual = trimesh.visual.ColorVisuals(
40 | vertex_colors=np.array([Colors.White.value for _ in range(len(vertices))])
41 | )
42 | scene.add_geometry(path)
43 | return GLBData(gltf.export_glb(scene))
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/map_elements/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-13 05:02:54
4 | @Description: 路网的基础组成部分
5 | @LastEditTime: 2024-07-13 05:02:55
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/map_elements/surface.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-05 19:10:34
4 | @Description: 定义 SUMO Surface
5 | @LastEditTime: 2024-07-13 05:10:54
6 | '''
7 | import itertools
8 | from typing import List, Optional
9 |
10 | from .base_road_map import RoadMap
11 | from ...vis3d_utils.coordinates import Pose
12 |
13 | class Surface(RoadMap.Surface):
14 | """Describes a Sumo surface (lane & road).
15 | """
16 | def __init__(self, surface_id: str, road_map):
17 | self._surface_id = surface_id
18 | self._map = road_map
19 | self._features = dict()
20 |
21 | @property
22 | def surface_id(self) -> str:
23 | return self._surface_id
24 |
25 | @property
26 | def is_drivable(self) -> bool:
27 | # all surfaces on SUMO road networks are drivable
28 | return True
29 |
30 | @property
31 | def features(self) -> List[RoadMap.Feature]:
32 | return list(self._features.values())
33 |
34 | def features_near(self, pose: Pose, radius: float) -> List[RoadMap.Feature]:
35 | pt = pose.point
36 | return [
37 | feat
38 | for feat in self._features.values()
39 | if radius >= feat.min_dist_from(pt)
40 | ]
41 |
42 | def surface_by_id(self, surface_id: str) -> Optional[RoadMap.Surface]:
43 | return self._surfaces.get(surface_id)
44 |
45 | @staticmethod
46 | def pairwise(iterable):
47 | """Generates pairs of neighboring elements.
48 | >>> list(pairwise('ABCDEFG'))
49 | [('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'E'), ('E', 'F'), ('F', 'G')]
50 | """
51 | a, b = itertools.tee(iterable)
52 | next(b, None)
53 | return zip(a, b)
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/sumonet_convert_utils/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-13 07:34:19
4 | @Description: 路网转换工具
5 | @LastEditTime: 2024-07-13 07:34:19
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/sumonet_convert_utils/geometry.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 16:13:17
4 | @Description: 路网转换的小工具
5 | Reference, https://github.com/huawei-noah/SMARTS/blob/master/smarts/core/utils/geometry.py
6 | @LastEditTime: 2024-07-13 07:21:38
7 | '''
8 | from shapely.ops import triangulate
9 | from shapely.geometry import LineString, MultiPolygon, Polygon
10 | from shapely.geometry.base import CAP_STYLE, JOIN_STYLE
11 |
12 | def buffered_shape(shape, width: float = 1.0) -> Polygon:
13 | """收一个形状(shape)和一个宽度(width)作为参数,
14 | 然后生成一个在原始形状周围添加了宽度为 width 的缓冲区的新形状
15 | """
16 | ls = LineString(shape).buffer(
17 | width / 2,
18 | 1,
19 | cap_style=CAP_STYLE.flat,
20 | join_style=JOIN_STYLE.round,
21 | mitre_limit=5.0,
22 | )
23 | if isinstance(ls, MultiPolygon):
24 | # Sometimes it oddly outputs a MultiPolygon and then we need to turn it into a convex hull
25 | ls = ls.convex_hull # 将其转换为凸包(convex hull)
26 | elif not isinstance(ls, Polygon):
27 | raise RuntimeError("Shapely `object.buffer` behavior may have changed.")
28 | return ls
29 |
30 |
31 | def triangulate_polygon(polygon: Polygon):
32 | """Attempts to convert a polygon into triangles.
33 | """
34 | # XXX: shapely.ops.triangulate current creates a convex fill of triangles.
35 | return [
36 | tri_face
37 | for tri_face in triangulate(polygon)
38 | if tri_face.centroid.within(polygon)
39 | ]
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_sumonet_convert/sumonet_convert_utils/glb_data.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-13 07:28:05
4 | @Description: GLB Class
5 | @LastEditTime: 2024-07-13 07:28:05
6 | '''
7 | from pathlib import Path
8 | from typing import Union
9 |
10 | class GLBData:
11 | """Convenience class for writing GLB files.
12 | """
13 | def __init__(self, bytes_) -> None:
14 | self._bytes = bytes_
15 |
16 | def write_glb(self, output_path: Union[str, Path]) -> None:
17 | """Generate a geometry file."""
18 | with open(output_path, "wb") as f:
19 | f.write(self._bytes)
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_utils/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-03 16:02:23
4 | @Description: 3d 可视化的辅助工具
5 | 1. 将 SUMO Net 转换为 3D 模型
6 | 2. 不同交通参与者对应的 3D 模型
7 | 3.
8 | @LastEditTime: 2024-07-03 16:02:24
9 | '''
10 |
--------------------------------------------------------------------------------
/tshub/tshub_env3d/vis3d_utils/masks.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-07-06 20:56:50
4 | @Description: 定义 Masks, 决定哪些对象会被渲染
5 | @LastEditTime: 2024-07-14 20:26:47
6 | '''
7 | from panda3d.core import BitMask32
8 |
9 | class RenderMasks:
10 | """Rendering mask flags
11 | """
12 | NONE = 0x00 # 没有任何对象被隐藏,所有对象都会被渲染
13 | OCCUPANCY_HIDE = 0x01 # 隐藏那些被标记为 "occupancy" 的对象
14 | RGB_HIDE = 0x02 # 用于隐藏那些被标记为 "RGB" 的对象
15 | DRIVABLE_AREA_HIDE = 0x04 # 用于隐藏那些被标记为 "drivable area" 的对象
16 |
17 | class CamMask():
18 | AllOn = BitMask32.allOn() # 全部是 1
19 | AllOff = BitMask32.allOff() # 全部是 0
20 | VehMask = BitMask32.bit(1) # 车辆的 mask
21 | MapMask = BitMask32.bit(2) # 环境 mask, 包括 map, road, line
22 | GroundMask = BitMask32.bit(3) # 环境的 ground
23 | SkyBoxMask = BitMask32.bit(4) # skybox
--------------------------------------------------------------------------------
/tshub/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Traffic-Alpha/TransSimHub/339d051fbfb27daba060521b57321ace68a290b5/tshub/utils/__init__.py
--------------------------------------------------------------------------------
/tshub/utils/check_folder.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2021-11-19 15:11:24
4 | @Description: 判断文件夹是否存在, 不存在则创建
5 | @LastEditTime: 2023-08-24 17:01:27
6 | '''
7 | import os
8 | from loguru import logger
9 |
10 | def check_folder(folder_path) -> None:
11 | """判断文件夹是否存在, 如果不存在则进行创建
12 |
13 | Args:
14 | folder_path (str): 文件夹的路径
15 | """
16 | if not os.path.isdir(folder_path): # 判断路径是否存在
17 | os.makedirs(folder_path, exist_ok=True) # 不存在则创建
18 | logger.warning('SIM: 文件夹 {} 不存在, 已创建!'.format(folder_path))
--------------------------------------------------------------------------------
/tshub/utils/format_dict.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 17:34:14
4 | @Description: 将 dict 转换为字符串, 带有环行
5 | LastEditTime: 2025-03-21 11:21:05
6 | '''
7 | import json
8 | import numpy as np
9 | from loguru import logger
10 |
11 | def dict_to_str(my_dict) -> str:
12 | """将字典转换为格式化的 JSON 字符串
13 | """
14 | def convert_to_serializable(obj):
15 | if isinstance(obj, np.ndarray):
16 | return obj.tolist() # 将ndarray转换为列表
17 | raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
18 |
19 | json_str = json.dumps(my_dict, indent=4, default=convert_to_serializable)
20 | return json_str
21 |
22 | def save_str_to_json(my_dict, file_path:str, indent:int=4) -> None:
23 | """将 dict 串保存为 JSON 文件
24 | """
25 | with open(file_path, 'w', encoding='utf-8') as f:
26 | json.dump(my_dict, f, ensure_ascii=False, indent=indent)
27 | logger.info(f'SIM: 字典已成功保存到 {file_path}')
--------------------------------------------------------------------------------
/tshub/utils/get_abs_path.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 11:27:57
4 | @Description: 将相对路径转换为绝对路径
5 | @LastEditTime: 2023-08-24 17:01:22
6 | '''
7 | import os
8 | from loguru import logger
9 | from typing import Optional
10 |
11 | class get_abs_path(object):
12 |
13 | def __init__(self, file_abspath: Optional[str] = None) -> None:
14 | self.file_abspath = file_abspath # 当前文件的完整路径
15 |
16 | def __call__(self, file_relpath: str):
17 | """将相对路径转换为绝对路径
18 | """
19 | if self.file_abspath is None:
20 | logger.warning('SIM: 没有设置当前文件路径')
21 | self.file_abspath = os.path.abspath(__file__)
22 |
23 | folder_abspath = os.path.dirname(self.file_abspath)
24 | return os.path.join(folder_abspath, file_relpath)
--------------------------------------------------------------------------------
/tshub/utils/nested_dict_conversion.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-24 16:16:20
4 | @Description: 处理 defaultdict
5 | @LastEditTime: 2023-08-24 16:20:55
6 | '''
7 | from collections import defaultdict
8 | from typing import Union
9 |
10 | def create_nested_defaultdict() -> defaultdict:
11 | """生成无限嵌套的 defaultdict
12 | """
13 | return defaultdict(create_nested_defaultdict)
14 |
15 |
16 | def defaultdict2dict(data: Union[defaultdict, dict]) -> dict:
17 | """将嵌套的 defaultdict 转换为普通的 dict
18 | """
19 | if isinstance(data, dict):
20 | return {k: defaultdict2dict(v) for k, v in data.items()}
21 | else:
22 | return data
--------------------------------------------------------------------------------
/tshub/utils/normalization_dict.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-31 17:53:38
4 | @Description: 字典中的值归一化, 使其和为 1
5 | @LastEditTime: 2023-08-31 17:55:06
6 | '''
7 | def normalize_dict(input_dict):
8 | """
9 | 将字典中的值归一化,使其和为1。例如:
10 | + Input: a = {1:1, 2:2, 3:3},
11 | + Output: {1: 0.16666666666666666, 2: 0.3333333333333333, 3: 0.5}
12 |
13 | Args:
14 | input_dict (dict): 输入的字典数据。
15 |
16 | Returns:
17 | dict: 归一化后的字典。
18 | """
19 | # 计算字典值的总和
20 | total_value = sum(input_dict.values())
21 |
22 | # 归一化字典
23 | normalized_dict = {key: value / total_value for key, value in input_dict.items()}
24 |
25 | return normalized_dict
26 |
--------------------------------------------------------------------------------
/tshub/utils/plt_to_array.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-13 21:25:42
4 | @Description: 将 fig 转换为 array, for render
5 | @LastEditTime: 2023-12-01 14:36:43
6 | '''
7 | import numpy as np
8 |
9 | def plt2arr(fig):
10 | """
11 | need to draw if figure is not drawn yet
12 | """
13 | fig.canvas.draw()
14 | rgba_buf = fig.canvas.buffer_rgba()
15 | (w,h) = fig.canvas.get_width_height()
16 | rgba_arr = np.frombuffer(rgba_buf, dtype=np.uint8).reshape((h,w,4))
17 | return rgba_arr
--------------------------------------------------------------------------------
/tshub/v2x/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-08-09 11:26:23
4 | @Description: Channel Models
5 | @LastEditTime: 2024-08-10 20:22:07
6 | '''
7 | from .v2x_channel import V2XChannel
8 | from .v2i_channel import V2IChannel
9 | from .v2v_channel import V2VChannel
10 |
11 | from .v2x_utils.snr_to_packetloss import calculate_outage_probability
--------------------------------------------------------------------------------
/tshub/v2x/v2x_utils/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-08-10 18:00:50
4 | @Description: 包含 v2x 的工具, 例如将 SNR 转换为 packet loss 等
5 | @LastEditTime: 2024-08-10 18:01:52
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/v2x/v2x_utils/snr_to_packetloss.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-08-10 20:18:53
4 | @Description: 将 SNR 转换为 Packet Loss
5 | @LastEditTime: 2024-08-10 20:27:00
6 | '''
7 | import numpy as np
8 |
9 | def calculate_outage_probability(snr_db, bandwidth_hz=30e3, target_rate_bps=20e3):
10 | """
11 | Calculate the outage probability in a Rayleigh fading channel.
12 |
13 | Parameters:
14 | snr_db (float): The signal-to-noise ratio in decibels (dB).
15 | bandwidth_hz (float): The channel bandwidth in Hertz (default is 30kHz).
16 | target_rate_bps (float): The target rate in bits per second (default is 20kb/s).
17 |
18 | Returns:
19 | float: The calculated outage probability.
20 | """
21 | # Convert SNR from dB to linear scale
22 | snr_linear = 10 ** (snr_db / 10)
23 |
24 | # Calculate the threshold u based on the target rate and SNR
25 | u_threshold = (2 ** (target_rate_bps / bandwidth_hz) - 1) / snr_linear
26 |
27 | # Calculate the outage probability
28 | outage_probability = 1 - np.exp(-u_threshold)
29 |
30 | return outage_probability
--------------------------------------------------------------------------------
/tshub/vehicle/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 15:18:54
4 | @Description: vehicle data and controller
5 | @LastEditTime: 2023-08-23 15:18:55
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/vehicle/vehicle_action_type.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-23 17:03:19
4 | @Description: Vehicle Action Type
5 | - 这两种动作都是设置变道和速度,在底层就是直接调用 SUMO 来进行控制的
6 | @LastEditTime: 2024-08-11 18:42:36
7 | '''
8 | import enum
9 |
10 | class vehicle_action_type(enum.Enum):
11 | Lane = 'lane'
12 | """
13 | Action= ``str``. Discrete lane action from one of
14 |
15 | + "keep_lane",
16 | + "slow_down",
17 | + "change_lane_left", and
18 | + "change_lane_right".
19 | """
20 |
21 | Speed = 'speed'
22 | """
23 | Action= ``str``. Discrete speed action from one of
24 |
25 | + "accelerate",
26 | + "decelerate",
27 | + "maintain_speed".
28 | """
29 |
30 | LaneWithContinuousSpeed = 'lane_continuous_speed'
31 | """
32 | Action=(target_speed, lane_change).
33 |
34 | + target_speed: Baseline target speed (controller may give more or less regardless). Type=float.
35 | + lane_change: Discrete lane change value. Can be one of
36 | + -1 : change to right lane
37 | + 0 : keep to current lane
38 | + 1 : change to left lane
39 | """
--------------------------------------------------------------------------------
/tshub/vehicle/vehicle_type/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-25 17:57:35
4 | @Description: 不同的 vehicle 控制类型
5 | @LastEditTime: 2024-08-11 18:48:04
6 | '''
7 | from .lane import LaneAction
8 | from .speed import SpeedAction
9 | from .lane_with_continuous_speed import LaneWithContinuousSpeedAction
--------------------------------------------------------------------------------
/tshub/vehicle/vehicle_type/lane_with_continuous_speed.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-08-28 18:24:56
4 | @Description: 变车道+连续速度控制
5 | @LastEditTime: 2024-08-11 18:58:02
6 | '''
7 | import enum
8 | from loguru import logger
9 | from .base_vehicle_action import VehicleAction
10 |
11 | class LaneChangeActionType(enum.Enum):
12 | default = -1
13 | keep_lane = 0
14 | change_lane_left = 1
15 | change_lane_right = 2
16 |
17 | class LaneWithContinuousSpeedAction(VehicleAction):
18 | def __init__(self, id, vehicle_type, sumo) -> None:
19 | super().__init__(id, vehicle_type, sumo)
20 |
21 | def execute(self, lane_change:int, target_speed:float,
22 | current_lane_index:int, current_road_id:str,
23 | *args, **kwargs,
24 | ) -> None:
25 | lane_change = LaneChangeActionType(lane_change)
26 | if lane_change == LaneChangeActionType.keep_lane:
27 | self.change_lane(0, current_lane=current_lane_index, current_edge=current_road_id)
28 | elif lane_change == LaneChangeActionType.change_lane_left:
29 | self.change_lane(1, current_lane=current_lane_index, current_edge=current_road_id)
30 | elif lane_change == LaneChangeActionType.change_lane_right:
31 | self.change_lane(-1, current_lane=current_lane_index, current_edge=current_road_id)
32 | elif lane_change == LaneChangeActionType.default:
33 | logger.debug(f'SIM: SUMO Control Lane Change Automatic')
34 |
35 | if target_speed != -1: # If we set target speed to -1, then speed of the vehicle will not change
36 | self.sumo.vehicle.slowDown(self.veh_id, target_speed, duration=1)
37 | else:
38 | logger.debug(f'SIM: SUMO Set Speed Automatic')
39 |
--------------------------------------------------------------------------------
/tshub/vehicle/vehicle_type/speed.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2024-08-11 18:38:39
4 | @Description: 控制速度, 变道由 SUMO 控制
5 | @LastEditTime: 2024-08-11 19:35:01
6 | '''
7 | import enum
8 | from loguru import logger
9 | from .base_vehicle_action import VehicleAction
10 |
11 | class SpeedActionType(enum.Enum):
12 | accelerate = 0 # 加速
13 | decelerate = 1 # 减速
14 | maintain_speed = 2 # 保持不变
15 |
16 | class SpeedAction(VehicleAction):
17 | def __init__(self, id, vehicle_type, sumo) -> None:
18 | super().__init__(id, vehicle_type, sumo)
19 |
20 | def execute(self,
21 | current_speed: float, speed_action: SpeedActionType,
22 | acceleration_rate:float=2, # m/s
23 | *args, **kwargs,
24 | ) -> None:
25 | action = SpeedActionType(speed_action)
26 | # Speed control logic
27 | if action == SpeedActionType.accelerate:
28 | new_speed = current_speed + acceleration_rate
29 | logger.info(f'SIM: 车辆 {self.veh_id} 加速到 {new_speed}.')
30 | self.sumo.vehicle.setSpeed(self.veh_id, new_speed)
31 | elif action == SpeedActionType.decelerate:
32 | new_speed = max(1, current_speed - acceleration_rate) # Prevent negative speed
33 | logger.info(f'SIM: 车辆 {self.veh_id} 减速到 {new_speed}.')
34 | self.sumo.vehicle.setSpeed(self.veh_id, new_speed)
35 | elif action == SpeedActionType.maintain_speed:
36 | # No change to the vehicle's speed
37 | pass
38 | else:
39 | logger.debug(f'SIM: SUMO Speed Action Unknown')
40 |
--------------------------------------------------------------------------------
/tshub/visualization/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-12 16:19:10
4 | @Description: Visualization for TsHub Env
5 | @LastEditTime: 2023-11-12 16:19:11
6 | '''
7 |
--------------------------------------------------------------------------------
/tshub/visualization/vis_map_feature.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-12 16:20:15
4 | @Description: 对地图元素的可视化
5 | @LastEditTime: 2023-11-12 22:50:08
6 | '''
7 | from matplotlib.lines import Line2D
8 |
9 | def plot_map_feature(ax, map_edges, map_nodes) -> None:
10 | # Draw edges
11 | for _, edge_info in map_edges.items():
12 | edge_shape = edge_info.get('shape')
13 | for i in range(len(edge_shape)):
14 | x_values = [edge_shape[i - 1][0], edge_shape[i][0]]
15 | y_values = [edge_shape[i - 1][1], edge_shape[i][1]]
16 | line = Line2D(x_values, y_values, linewidth=1, color='grey', linestyle='-')
17 | ax.add_line(line)
18 |
19 | # Draw nodes
20 | for _, node_info in map_nodes.items():
21 | node_shape = node_info.get('shape')
22 | for i in range(len(node_shape)):
23 | x_values = [node_shape[i - 1][0], node_shape[i][0]]
24 | y_values = [node_shape[i - 1][1], node_shape[i][1]]
25 | line = Line2D(x_values, y_values, linewidth=3, color='grey', linestyle='--')
26 | ax.add_line(line)
27 |
28 |
--------------------------------------------------------------------------------
/tshub/visualization/visualize_map.py:
--------------------------------------------------------------------------------
1 | '''
2 | @Author: WANG Maonan
3 | @Date: 2023-11-12 16:22:16
4 | @Description: 对地图的可视化
5 | @LastEditTime: 2023-11-13 19:21:58
6 | '''
7 | import matplotlib.pyplot as plt
8 |
9 | from .vis_map_feature import plot_map_feature
10 | from .vis_vehicles import plot_vehicle
11 |
12 | def render_map(focus_id, map_edges, map_nodes, vehicles, x_range, y_range):
13 | fig, ax = plt.subplots(figsize=(6, 6))
14 |
15 | plot_map_feature(ax, map_edges, map_nodes)
16 | plot_vehicle(ax, focus_id, vehicles)
17 |
18 | ax.set_axis_off() # 去掉 x,y 轴
19 | plt.axis('equal') # x,y 的比例一样
20 |
21 | # 设置 x 和 y 轴的范围
22 | ax.set_xlim(x_range)
23 | ax.set_ylim(y_range)
24 |
25 | fig = plt.gcf() # 获得当前的图像
26 | return fig
27 |
--------------------------------------------------------------------------------