├── .flake8 ├── .gitignore ├── .gitlab-ci.yml ├── LICENSE ├── README.md ├── examples ├── NHTSA │ ├── Encroaching-Oncoming-Vehicles │ │ ├── EOV_S_25_20.py │ │ ├── EOV_S_45_40.py │ │ ├── EOV_S_65_60.py │ │ └── EOV_test_runner.sh │ ├── Move-Out-of-Travel-Lane │ │ ├── MOTL_Comp_15.py │ │ ├── MOTL_Comp_25.py │ │ ├── MOTL_Neg_15.py │ │ ├── MOTL_Neg_25.py │ │ ├── MOTL_Simp_15.py │ │ └── MOTL_Simp_25.py │ ├── Perform-Lane-Change │ │ ├── PLC_B_15.py │ │ ├── PLC_B_25.py │ │ ├── PLC_B_35.py │ │ ├── PLC_CP_15.py │ │ ├── PLC_CP_25.py │ │ ├── PLC_CP_35.py │ │ ├── PLC_SN_15.py │ │ ├── PLC_SN_25.py │ │ ├── PLC_SN_35.py │ │ ├── PLC_SP_15.py │ │ ├── PLC_SP_25.py │ │ ├── PLC_SP_35.py │ │ └── PLC_test_runner.sh │ └── Vehicle-Following │ │ ├── VF_S_25_Slow.py │ │ ├── VF_S_45_Slow.py │ │ ├── VF_S_65_Slow.py │ │ └── VF_test_runner.sh ├── Nav2 │ ├── single-robot-cut-in.py │ ├── single-robot-freemode.py │ ├── single-robot-sudden-braking.py │ └── single-robot-traffic-cones.py ├── SampleTestCases │ ├── cut-in.py │ ├── ped-crossing.py │ ├── random-traffic-local.py │ ├── random-traffic.py │ ├── red-light-runner.py │ └── sudden-braking.py └── kitti_parser.py ├── lgsvl ├── __init__.py ├── agent.py ├── controllable.py ├── dreamview │ ├── __init__.py │ └── dreamview.py ├── evaluator │ ├── __init__.py │ └── utils.py ├── geometry.py ├── remote.py ├── sensor.py ├── simulator.py ├── utils.py └── wise │ ├── __init__.py │ └── wise.py ├── package.xml ├── pyproject.toml ├── quickstart ├── 01-connecting-to-simulator.py ├── 02-loading-scene-show-spawns.py ├── 03-raycast.py ├── 04-ego-drive-straight.py ├── 05-ego-drive-in-circle.py ├── 06-save-camera-image.py ├── 07-save-lidar-point-cloud.py ├── 08-create-npc.py ├── 09-reset-scene.py ├── 10-npc-follow-the-lane.py ├── 11-collision-callbacks.py ├── 12-create-npc-on-lane.py ├── 13-npc-follow-waypoints.py ├── 14-create-pedestrians.py ├── 15-pedestrian-walk-randomly.py ├── 16-pedestrian-follow-waypoints.py ├── 17-many-pedestrians-walking.py ├── 18-weather-effects.py ├── 19-time-of-day.py ├── 20-enable-sensors.py ├── 21-map-coordinates.py ├── 22-connecting-bridge.py ├── 23-npc-callbacks.py ├── 24-ego-drive-straight-non-realtime.py ├── 25-waypoint-flying-npc.py ├── 26-npc-trigger-waypoints.py ├── 27-control-traffic-lights.py ├── 28-control-traffic-cone.py ├── 29-add-random-agents.py ├── 30-time-to-collision-trigger.py ├── 31-wait-for-distance-trigger.py ├── 32-pedestrian-time-to-collision.py ├── 33-ego-drive-stepped.py ├── 34-simulator-cam-set.py ├── 35-spawn-multi-robots.py ├── 36-send-destination-to-nav2.py ├── 98-npc-behaviour.py └── 99-utils-examples.py ├── requirements.txt ├── resource └── lgsvl ├── scripts └── run_and_create_coverage_report.sh ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── common.py ├── test_EGO.py ├── test_NPC.py ├── test_collisions.py ├── test_manual_features.py ├── test_peds.py ├── test_sensors.py ├── test_simulator.py └── test_utils.py /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 130 3 | max-complexity = 23 4 | 5 | ignore = E701, E501, W503 6 | exclude = 7 | .git 8 | tests/* 9 | examples/* 10 | 11 | per-file-ignores = 12 | lgsvl/__init__.py:F401 13 | lgsvl/dreamview/__init__.py:F401 14 | lgsvl/evaluator/__init__.py:F401 15 | lgsvl/wise/__init__.py:F401 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/__pycache__ 2 | *.egg-info 3 | .coverage 4 | htmlcov 5 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: "python:3.6.13" 2 | 3 | before_script: 4 | - python3 -m pip install -r requirements.txt .\[ci\] 5 | 6 | stages: 7 | - Style Guide Enforcement 8 | 9 | flake8: 10 | stage: Style Guide Enforcement 11 | script: 12 | - python3 -m flake8 13 | -------------------------------------------------------------------------------- /examples/NHTSA/Encroaching-Oncoming-Vehicles/EOV_S_25_20.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See EOV_C_25_20.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_EGO_SPEED = 11.111 # (40 km/h, 25 mph) 22 | MAX_POV_SPEED = 8.889 # (32 km/h, 20 mph) 23 | INITIAL_HEADWAY = 130 # spec says >30m 24 | SPEED_VARIANCE = 4 25 | TIME_LIMIT = 30 26 | TIME_DELAY = 3 27 | 28 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 29 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 30 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 31 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 32 | 33 | print("EOV_S_25_20 - ", end='') 34 | 35 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 36 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2laneopposing) 37 | if sim.current_scene == scene_name: 38 | sim.reset() 39 | else: 40 | sim.load(scene_name) 41 | 42 | # spawn EGO in the 2nd to right lane 43 | egoState = lgsvl.AgentState() 44 | # A point close to the desired lane was found in Editor. 45 | # This method returns the position and orientation of the closest lane to the point. 46 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(-1.6, 0, -65)) 47 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 48 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 49 | right = lgsvl.utils.transform_to_right(egoState.transform) 50 | 51 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 52 | 53 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 54 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneOpposing')) 55 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 56 | 57 | try: 58 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 59 | if len(modules) == 0: 60 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 61 | modules = [ 62 | 'Recorder', 63 | 'Localization', 64 | 'Perception', 65 | 'Transform', 66 | 'Routing', 67 | 'Prediction', 68 | 'Planning', 69 | 'Traffic Light', 70 | 'Control' 71 | ] 72 | except Exception: 73 | modules = [ 74 | 'Recorder', 75 | 'Localization', 76 | 'Perception', 77 | 'Transform', 78 | 'Routing', 79 | 'Prediction', 80 | 'Planning', 81 | 'Traffic Light', 82 | 'Control' 83 | ] 84 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 85 | 86 | destination = egoState.position + 135 * forward 87 | dv.setup_apollo(destination.x, destination.z, modules) 88 | 89 | finalPOVWaypointPosition = egoState.position - 2.15 * right 90 | 91 | POVState = lgsvl.AgentState() 92 | POVState.transform.position = egoState.position + (4.5 + INITIAL_HEADWAY) * forward - 2.15 * right 93 | POVState.transform.rotation = lgsvl.Vector(0, -180, 0) 94 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 95 | 96 | POVWaypoints = [] 97 | POVWaypoints.append(lgsvl.DriveWaypoint(POVState.transform.position, MAX_POV_SPEED, POVState.transform.rotation)) 98 | POVWaypoints.append(lgsvl.DriveWaypoint(finalPOVWaypointPosition, 0, POVState.transform.rotation)) 99 | 100 | 101 | def on_collision(agent1, agent2, contact): 102 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 103 | 104 | 105 | ego.on_collision(on_collision) 106 | POV.on_collision(on_collision) 107 | 108 | try: 109 | t0 = time.time() 110 | sim.run(TIME_DELAY) 111 | POV.follow(POVWaypoints) 112 | while True: 113 | egoCurrentState = ego.state 114 | if egoCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 115 | raise lgsvl.evaluator.TestException( 116 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_EGO_SPEED + SPEED_VARIANCE) 117 | ) 118 | POVCurrentState = POV.state 119 | if POVCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 120 | raise lgsvl.evaluator.TestException( 121 | "POV1 speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, MAX_POV_SPEED + SPEED_VARIANCE) 122 | ) 123 | sim.run(0.5) 124 | if time.time() - t0 > TIME_LIMIT: 125 | break 126 | except lgsvl.evaluator.TestException as e: 127 | exit("FAILED: {}".format(e)) 128 | 129 | print("PASSED") 130 | -------------------------------------------------------------------------------- /examples/NHTSA/Encroaching-Oncoming-Vehicles/EOV_S_45_40.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See EOV_C_25_20.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_EGO_SPEED = 20 # (72 km/h, 45 mph) 22 | MAX_POV_SPEED = 17.778 # (64 km/h, 40 mph) 23 | INITIAL_HEADWAY = 130 # spec says >68m 24 | SPEED_VARIANCE = 4 25 | TIME_LIMIT = 30 26 | TIME_DELAY = 4 27 | 28 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 29 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 30 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 31 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 32 | 33 | print("EOV_S_45_40 - ", end='') 34 | 35 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 36 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2laneopposing) 37 | if sim.current_scene == scene_name: 38 | sim.reset() 39 | else: 40 | sim.load(scene_name) 41 | 42 | # spawn EGO in the 2nd to right lane 43 | egoState = lgsvl.AgentState() 44 | # A point close to the desired lane was found in Editor. 45 | # This method returns the position and orientation of the closest lane to the point. 46 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(-1.6, 0, -65)) 47 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 48 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 49 | right = lgsvl.utils.transform_to_right(egoState.transform) 50 | 51 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 52 | 53 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 54 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneOpposing')) 55 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 56 | 57 | try: 58 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 59 | if len(modules) == 0: 60 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 61 | modules = [ 62 | 'Recorder', 63 | 'Localization', 64 | 'Perception', 65 | 'Transform', 66 | 'Routing', 67 | 'Prediction', 68 | 'Planning', 69 | 'Traffic Light', 70 | 'Control' 71 | ] 72 | except Exception: 73 | modules = [ 74 | 'Recorder', 75 | 'Localization', 76 | 'Perception', 77 | 'Transform', 78 | 'Routing', 79 | 'Prediction', 80 | 'Planning', 81 | 'Traffic Light', 82 | 'Control' 83 | ] 84 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 85 | 86 | destination = egoState.position + 135 * forward 87 | dv.setup_apollo(destination.x, destination.z, modules) 88 | 89 | finalPOVWaypointPosition = egoState.position - 2.15 * right 90 | 91 | POVState = lgsvl.AgentState() 92 | POVState.transform.position = egoState.position + (4.5 + INITIAL_HEADWAY) * forward - 2.15 * right 93 | POVState.transform.rotation = lgsvl.Vector(0, -180, 0) 94 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 95 | 96 | POVWaypoints = [] 97 | POVWaypoints.append(lgsvl.DriveWaypoint(POVState.transform.position, MAX_POV_SPEED, POVState.transform.rotation)) 98 | POVWaypoints.append(lgsvl.DriveWaypoint(finalPOVWaypointPosition, 0, POVState.transform.rotation)) 99 | 100 | 101 | def on_collision(agent1, agent2, contact): 102 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 103 | 104 | 105 | ego.on_collision(on_collision) 106 | POV.on_collision(on_collision) 107 | 108 | try: 109 | t0 = time.time() 110 | sim.run(TIME_DELAY) 111 | POV.follow(POVWaypoints) 112 | while True: 113 | egoCurrentState = ego.state 114 | if egoCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 115 | raise lgsvl.evaluator.TestException( 116 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_EGO_SPEED + SPEED_VARIANCE) 117 | ) 118 | POVCurrentState = POV.state 119 | if POVCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 120 | raise lgsvl.evaluator.TestException( 121 | "POV1 speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, MAX_POV_SPEED + SPEED_VARIANCE) 122 | ) 123 | sim.run(0.5) 124 | if time.time() - t0 > TIME_LIMIT: 125 | break 126 | except lgsvl.evaluator.TestException as e: 127 | exit("FAILED: {}".format(e)) 128 | 129 | print("PASSED") 130 | -------------------------------------------------------------------------------- /examples/NHTSA/Encroaching-Oncoming-Vehicles/EOV_S_65_60.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See EOV_C_25_20.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_EGO_SPEED = 29.167 # (105 km/h, 65 mph) 22 | MAX_POV_SPEED = 26.667 # (96 km/h, 60 mph) 23 | INITIAL_HEADWAY = 130 # spec says >105m 24 | SPEED_VARIANCE = 4 25 | TIME_LIMIT = 30 26 | TIME_DELAY = 5 27 | 28 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 29 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 30 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 31 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 32 | 33 | print("EOV_S_65_60 - ", end='') 34 | 35 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 36 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2laneopposing) 37 | if sim.current_scene == scene_name: 38 | sim.reset() 39 | else: 40 | sim.load(scene_name) 41 | 42 | # spawn EGO in the 2nd to right lane 43 | egoState = lgsvl.AgentState() 44 | # A point close to the desired lane was found in Editor. 45 | # This method returns the position and orientation of the closest lane to the point. 46 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(-1.6, 0, -65)) 47 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 48 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 49 | right = lgsvl.utils.transform_to_right(egoState.transform) 50 | 51 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 52 | 53 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 54 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneOpposing')) 55 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 56 | try: 57 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 58 | if len(modules) == 0: 59 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 60 | modules = [ 61 | 'Recorder', 62 | 'Localization', 63 | 'Perception', 64 | 'Transform', 65 | 'Routing', 66 | 'Prediction', 67 | 'Planning', 68 | 'Traffic Light', 69 | 'Control' 70 | ] 71 | except Exception: 72 | modules = [ 73 | 'Recorder', 74 | 'Localization', 75 | 'Perception', 76 | 'Transform', 77 | 'Routing', 78 | 'Prediction', 79 | 'Planning', 80 | 'Traffic Light', 81 | 'Control' 82 | ] 83 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 84 | 85 | destination = egoState.position + 135 * forward 86 | dv.setup_apollo(destination.x, destination.z, modules) 87 | 88 | finalPOVWaypointPosition = egoState.position - 2.15 * right 89 | 90 | POVState = lgsvl.AgentState() 91 | POVState.transform.position = egoState.position + (4.5 + INITIAL_HEADWAY) * forward - 2.15 * right 92 | POVState.transform.rotation = lgsvl.Vector(0, -180, 0) 93 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 94 | 95 | POVWaypoints = [] 96 | POVWaypoints.append(lgsvl.DriveWaypoint(POVState.transform.position, MAX_POV_SPEED, POVState.transform.rotation)) 97 | POVWaypoints.append(lgsvl.DriveWaypoint(finalPOVWaypointPosition, 0, POVState.transform.rotation)) 98 | 99 | 100 | def on_collision(agent1, agent2, contact): 101 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 102 | 103 | 104 | ego.on_collision(on_collision) 105 | POV.on_collision(on_collision) 106 | 107 | try: 108 | t0 = time.time() 109 | sim.run(TIME_DELAY) 110 | POV.follow(POVWaypoints) 111 | while True: 112 | egoCurrentState = ego.state 113 | if egoCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 114 | raise lgsvl.evaluator.TestException( 115 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_EGO_SPEED + SPEED_VARIANCE) 116 | ) 117 | POVCurrentState = POV.state 118 | if POVCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 119 | raise lgsvl.evaluator.TestException( 120 | "POV1 speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, MAX_POV_SPEED + SPEED_VARIANCE) 121 | ) 122 | sim.run(0.5) 123 | if time.time() - t0 > TIME_LIMIT: 124 | break 125 | except lgsvl.evaluator.TestException as e: 126 | exit("FAILED: {}".format(e)) 127 | 128 | print("PASSED") 129 | -------------------------------------------------------------------------------- /examples/NHTSA/Encroaching-Oncoming-Vehicles/EOV_test_runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | python3 EOV_S_25_20.py 6 | python3 EOV_S_45_40.py 7 | python3 EOV_S_65_60.py -------------------------------------------------------------------------------- /examples/NHTSA/Move-Out-of-Travel-Lane/MOTL_Simp_25.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See MOTL_Simp_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 11.111 # (40 km/h, 25 mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 30 # seconds 24 | PARKING_ZONE_LENGTH = 24 # meters 25 | 26 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 27 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 28 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 29 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 30 | 31 | print("MOTL_Simp_25 - ", end='') 32 | 33 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 34 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesamecurbrightintersection) 35 | if sim.current_scene == scene_name: 36 | sim.reset() 37 | else: 38 | sim.load(scene_name) 39 | 40 | # spawn EGO in the 2nd to right lane 41 | egoState = lgsvl.AgentState() 42 | # A point close to the desired lane was found in Editor. 43 | # This method returns the position and orientation of the closest lane to the point. 44 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(2.6, 0, 30)) 45 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 46 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 47 | right = lgsvl.utils.transform_to_right(egoState.transform) 48 | 49 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 50 | 51 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 52 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSameCurbRightIntersection')) 53 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 54 | try: 55 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 56 | if len(modules) == 0: 57 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 58 | modules = [ 59 | 'Recorder', 60 | 'Localization', 61 | 'Perception', 62 | 'Transform', 63 | 'Routing', 64 | 'Prediction', 65 | 'Planning', 66 | 'Traffic Light', 67 | 'Control' 68 | ] 69 | except Exception: 70 | modules = [ 71 | 'Recorder', 72 | 'Localization', 73 | 'Perception', 74 | 'Transform', 75 | 'Routing', 76 | 'Prediction', 77 | 'Planning', 78 | 'Traffic Light', 79 | 'Control' 80 | ] 81 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 82 | 83 | # Destination in the middle of the parking zone 84 | destination = egoState.position + (2.75 + 4.6 + 12 + PARKING_ZONE_LENGTH / 2) * forward + 3.6 * right 85 | dv.setup_apollo(destination.x, destination.z, modules) 86 | 87 | POVState = lgsvl.AgentState() 88 | POVState.transform = sim.map_point_on_lane(egoState.position + (4.55 + 12) * forward + 3.6 * right) 89 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 90 | 91 | 92 | def on_collision(agent1, agent2, contact): 93 | raise lgsvl.evaluator.TestException("{} collided with {}".format(agent1, agent2)) 94 | 95 | 96 | ego.on_collision(on_collision) 97 | POV.on_collision(on_collision) 98 | 99 | try: 100 | t0 = time.time() 101 | while True: 102 | egoCurrentState = ego.state 103 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 104 | raise lgsvl.evaluator.TestException( 105 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 106 | ) 107 | POVCurrentState = POV.state 108 | if POVCurrentState.speed > 0 + SPEED_VARIANCE: 109 | raise lgsvl.evaluator.TestException( 110 | "POV1 speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, 0 + SPEED_VARIANCE) 111 | ) 112 | sim.run(0.5) 113 | if time.time() - t0 > TIME_LIMIT: 114 | break 115 | except lgsvl.evaluator.TestException as e: 116 | exit("FAILED: {}".format(e)) 117 | 118 | parkingZoneBeginning = sim.map_point_on_lane(egoState.position + (2.75 + 4.6 + 12) * forward + 3.6 * right) 119 | parkingZoneEnd = sim.map_point_on_lane(parkingZoneBeginning.position + PARKING_ZONE_LENGTH * forward) 120 | 121 | finalEgoState = ego.state 122 | 123 | try: 124 | if not lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 125 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 126 | elif not lgsvl.evaluator.in_parking_zone( 127 | parkingZoneBeginning.position, 128 | parkingZoneEnd.position, 129 | finalEgoState.transform 130 | ): 131 | raise lgsvl.evaluator.TestException("Ego did not stop in parking zone") 132 | elif finalEgoState.speed > 0.2: 133 | raise lgsvl.evaluator.TestException("Ego did not park") 134 | else: 135 | print("PASSED") 136 | except ValueError as e: 137 | exit("FAILED: {}".format(e)) 138 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_B_15.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See PLC_SN_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 6.667 # (24 km/h, 15mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 15 # seconds 24 | 25 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 27 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 29 | 30 | print("PLC_B_15 - ", end='') 31 | 32 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 33 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesame) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name) 38 | 39 | # spawn EGO in the 2nd to right lane 40 | egoState = lgsvl.AgentState() 41 | # A point close to the desired lane was found in Editor. 42 | # This method returns the position and orientation of the closest lane to the point. 43 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(3.68, 0, -50)) 44 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 45 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 46 | right = lgsvl.utils.transform_to_right(egoState.transform) 47 | 48 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 49 | 50 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 51 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSame')) 52 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 53 | try: 54 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 55 | if len(modules) == 0: 56 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 57 | modules = [ 58 | 'Recorder', 59 | 'Localization', 60 | 'Perception', 61 | 'Transform', 62 | 'Routing', 63 | 'Prediction', 64 | 'Planning', 65 | 'Traffic Light', 66 | 'Control' 67 | ] 68 | except Exception: 69 | modules = [ 70 | 'Recorder', 71 | 'Localization', 72 | 'Perception', 73 | 'Transform', 74 | 'Routing', 75 | 'Prediction', 76 | 'Planning', 77 | 'Traffic Light', 78 | 'Control' 79 | ] 80 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 81 | 82 | destination = egoState.position + 120 * forward + 3.6 * right 83 | dv.setup_apollo(destination.x, destination.z, modules) 84 | 85 | 86 | def on_collision(agent1, agent2, contact): 87 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 88 | 89 | 90 | ego.on_collision(on_collision) 91 | 92 | try: 93 | t0 = time.time() 94 | while True: 95 | egoCurrentState = ego.state 96 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 97 | raise lgsvl.evaluator.TestException( 98 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 99 | ) 100 | sim.run(0.5) 101 | if time.time() - t0 > TIME_LIMIT: 102 | break 103 | except lgsvl.evaluator.TestException as e: 104 | exit("FAILED: {}".format(e)) 105 | 106 | finalEgoState = ego.state 107 | try: 108 | if lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 109 | print("PASSED") 110 | else: 111 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 112 | except lgsvl.evaluator.TestException as e: 113 | exit("FAILED: {}".format(e)) 114 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_B_25.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See PLC_SN_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 11.111 # (40 km/h, 25mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 15 # seconds 24 | 25 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 27 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 29 | 30 | print("PLC_B_25 - ", end='') 31 | 32 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 33 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesame) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name) 38 | 39 | # spawn EGO in the 2nd to right lane 40 | egoState = lgsvl.AgentState() 41 | # A point close to the desired lane was found in Editor. 42 | # This method returns the position and orientation of the closest lane to the point. 43 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(3.68, 0, -50)) 44 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 45 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 46 | right = lgsvl.utils.transform_to_right(egoState.transform) 47 | 48 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 49 | 50 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 51 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSame')) 52 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 53 | try: 54 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 55 | if len(modules) == 0: 56 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 57 | modules = [ 58 | 'Recorder', 59 | 'Localization', 60 | 'Perception', 61 | 'Transform', 62 | 'Routing', 63 | 'Prediction', 64 | 'Planning', 65 | 'Traffic Light', 66 | 'Control' 67 | ] 68 | except Exception: 69 | modules = [ 70 | 'Recorder', 71 | 'Localization', 72 | 'Perception', 73 | 'Transform', 74 | 'Routing', 75 | 'Prediction', 76 | 'Planning', 77 | 'Traffic Light', 78 | 'Control' 79 | ] 80 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 81 | 82 | destination = egoState.position + 120 * forward + 3.6 * right 83 | dv.setup_apollo(destination.x, destination.z, modules) 84 | 85 | 86 | def on_collision(agent1, agent2, contact): 87 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 88 | 89 | 90 | ego.on_collision(on_collision) 91 | 92 | try: 93 | t0 = time.time() 94 | while True: 95 | egoCurrentState = ego.state 96 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 97 | raise lgsvl.evaluator.TestException( 98 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 99 | ) 100 | sim.run(0.5) 101 | if time.time() - t0 > TIME_LIMIT: 102 | break 103 | except lgsvl.evaluator.TestException as e: 104 | exit("FAILED: {}".format(e)) 105 | 106 | finalEgoState = ego.state 107 | try: 108 | if lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 109 | print("PASSED") 110 | else: 111 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 112 | except lgsvl.evaluator.TestException as e: 113 | exit("FAILED: {}".format(e)) 114 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_B_35.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See PLC_SN_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 15.556 # (56 km/h, 35mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 15 # seconds 24 | 25 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 27 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 29 | 30 | print("PLC_B_35 - ", end='') 31 | 32 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 33 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesame) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name) 38 | 39 | # spawn EGO in the 2nd to right lane 40 | egoState = lgsvl.AgentState() 41 | # A point close to the desired lane was found in Editor. 42 | # This method returns the position and orientation of the closest lane to the point. 43 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(3.68, 0, -50)) 44 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 45 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 46 | right = lgsvl.utils.transform_to_right(egoState.transform) 47 | 48 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 49 | 50 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 51 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSame')) 52 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 53 | try: 54 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 55 | if len(modules) == 0: 56 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 57 | modules = [ 58 | 'Recorder', 59 | 'Localization', 60 | 'Perception', 61 | 'Transform', 62 | 'Routing', 63 | 'Prediction', 64 | 'Planning', 65 | 'Traffic Light', 66 | 'Control' 67 | ] 68 | except Exception: 69 | modules = [ 70 | 'Recorder', 71 | 'Localization', 72 | 'Perception', 73 | 'Transform', 74 | 'Routing', 75 | 'Prediction', 76 | 'Planning', 77 | 'Traffic Light', 78 | 'Control' 79 | ] 80 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 81 | 82 | destination = egoState.position + 120 * forward + 3.6 * right 83 | dv.setup_apollo(destination.x, destination.z, modules) 84 | 85 | 86 | def on_collision(agent1, agent2, contact): 87 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 88 | 89 | 90 | ego.on_collision(on_collision) 91 | 92 | try: 93 | t0 = time.time() 94 | while True: 95 | egoCurrentState = ego.state 96 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 97 | raise lgsvl.evaluator.TestException( 98 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 99 | ) 100 | sim.run(0.5) 101 | if time.time() - t0 > TIME_LIMIT: 102 | break 103 | except lgsvl.evaluator.TestException as e: 104 | exit("FAILED: {}".format(e)) 105 | 106 | finalEgoState = ego.state 107 | try: 108 | if lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 109 | print("PASSED") 110 | else: 111 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 112 | except lgsvl.evaluator.TestException as e: 113 | exit("FAILED: {}".format(e)) 114 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_SP_15.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See PLC_SN_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 6.667 # (24 km/h, 15 mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 15 # seconds 24 | 25 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 27 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 29 | 30 | print("PLC_SP_15 - ", end='') 31 | 32 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 33 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesame) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name) 38 | 39 | # spawn EGO in the 2nd to right lane 40 | egoState = lgsvl.AgentState() 41 | # A point close to the desired lane was found in Editor. 42 | # This method returns the position and orientation of the closest lane to the point. 43 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(3.68, 0, -50)) 44 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 45 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 46 | right = lgsvl.utils.transform_to_right(egoState.transform) 47 | 48 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 49 | 50 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 51 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSame')) 52 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 53 | try: 54 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 55 | if len(modules) == 0: 56 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 57 | modules = [ 58 | 'Recorder', 59 | 'Localization', 60 | 'Perception', 61 | 'Transform', 62 | 'Routing', 63 | 'Prediction', 64 | 'Planning', 65 | 'Traffic Light', 66 | 'Control' 67 | ] 68 | except Exception: 69 | modules = [ 70 | 'Recorder', 71 | 'Localization', 72 | 'Perception', 73 | 'Transform', 74 | 'Routing', 75 | 'Prediction', 76 | 'Planning', 77 | 'Traffic Light', 78 | 'Control' 79 | ] 80 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 81 | 82 | destination = egoState.position + 120 * forward + 3.6 * right 83 | dv.setup_apollo(destination.x, destination.z, modules) 84 | 85 | POV1State = lgsvl.AgentState() 86 | POV1State.transform = sim.map_point_on_lane(egoState.position + 11 * forward + 3.6 * right) 87 | POV1 = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POV1State) 88 | 89 | POV1.follow_closest_lane(True, MAX_SPEED, False) 90 | 91 | 92 | def on_collision(agent1, agent2, contact): 93 | raise lgsvl.evaluator.TestException("{} collided with {}".format(agent1, agent2)) 94 | 95 | 96 | ego.on_collision(on_collision) 97 | POV1.on_collision(on_collision) 98 | 99 | endOfRoad = egoState.position + 120 * forward + 3.6 * right 100 | 101 | try: 102 | t0 = time.time() 103 | while True: 104 | egoCurrentState = ego.state 105 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 106 | raise lgsvl.evaluator.TestException( 107 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 108 | ) 109 | POV1CurrentState = POV1.state 110 | if POV1CurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 111 | raise lgsvl.evaluator.TestException( 112 | "POV1 speed exceeded limit, {} > {} m/s".format(POV1CurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 113 | ) 114 | if lgsvl.evaluator.separation(POV1CurrentState.position, endOfRoad) < 5: 115 | break 116 | sim.run(0.5) 117 | if time.time() - t0 > TIME_LIMIT: 118 | break 119 | except lgsvl.evaluator.TestException as e: 120 | exit("FAILED: {}".format(e)) 121 | 122 | finalEgoState = ego.state 123 | try: 124 | if lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 125 | print("PASSED") 126 | else: 127 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 128 | except lgsvl.evaluator.TestException as e: 129 | exit("FAILED: {}".format(e)) 130 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_SP_25.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See PLC_SN_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 11.111 # (40 km/h, 25 mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 15 # seconds 24 | 25 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 27 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 29 | 30 | print("PLC_SP_25 - ", end='') 31 | 32 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 33 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesame) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name) 38 | 39 | # spawn EGO in the 2nd to right lane 40 | egoState = lgsvl.AgentState() 41 | # A point close to the desired lane was found in Editor. 42 | # This method returns the position and orientation of the closest lane to the point. 43 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(3.68, 0, -50)) 44 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 45 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 46 | right = lgsvl.utils.transform_to_right(egoState.transform) 47 | 48 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 49 | 50 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 51 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSame')) 52 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 53 | try: 54 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 55 | if len(modules) == 0: 56 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 57 | modules = [ 58 | 'Recorder', 59 | 'Localization', 60 | 'Perception', 61 | 'Transform', 62 | 'Routing', 63 | 'Prediction', 64 | 'Planning', 65 | 'Traffic Light', 66 | 'Control' 67 | ] 68 | except Exception: 69 | modules = [ 70 | 'Recorder', 71 | 'Localization', 72 | 'Perception', 73 | 'Transform', 74 | 'Routing', 75 | 'Prediction', 76 | 'Planning', 77 | 'Traffic Light', 78 | 'Control' 79 | ] 80 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 81 | 82 | destination = egoState.position + 120 * forward + 3.6 * right 83 | dv.setup_apollo(destination.x, destination.z, modules) 84 | 85 | POV1State = lgsvl.AgentState() 86 | POV1State.transform = sim.map_point_on_lane(egoState.position + 5 * forward + 3.6 * right) 87 | POV1 = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POV1State) 88 | 89 | POV1.follow_closest_lane(True, MAX_SPEED, False) 90 | 91 | 92 | def on_collision(agent1, agent2, contact): 93 | raise lgsvl.evaluator.TestException("{} collided with {}".format(agent1, agent2)) 94 | 95 | 96 | ego.on_collision(on_collision) 97 | POV1.on_collision(on_collision) 98 | 99 | endOfRoad = egoState.position + 120 * forward + 3.6 * right 100 | 101 | try: 102 | t0 = time.time() 103 | while True: 104 | egoCurrentState = ego.state 105 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 106 | raise lgsvl.evaluator.TestException( 107 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 108 | ) 109 | POV1CurrentState = POV1.state 110 | if POV1CurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 111 | raise lgsvl.evaluator.TestException( 112 | "POV1 speed exceeded limit, {} > {} m/s".format(POV1CurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 113 | ) 114 | if lgsvl.evaluator.separation(POV1CurrentState.position, endOfRoad) < 5: 115 | break 116 | sim.run(0.5) 117 | if time.time() - t0 > TIME_LIMIT: 118 | break 119 | except lgsvl.evaluator.TestException as e: 120 | exit("FAILED: {}".format(e)) 121 | 122 | finalEgoState = ego.state 123 | try: 124 | if lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 125 | print("PASSED") 126 | else: 127 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 128 | except lgsvl.evaluator.TestException as e: 129 | exit("FAILED: {}".format(e)) 130 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_SP_35.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See PLC_SN_15.py for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_SPEED = 15.556 # (56 km/h, 35 mph) 22 | SPEED_VARIANCE = 4 23 | TIME_LIMIT = 15 # seconds 24 | 25 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 27 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 29 | 30 | print("PLC_SP_35 - ", end='') 31 | 32 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 33 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight2lanesame) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name) 38 | 39 | # spawn EGO in the 2nd to right lane 40 | egoState = lgsvl.AgentState() 41 | # A point close to the desired lane was found in Editor. 42 | # This method returns the position and orientation of the closest lane to the point. 43 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(3.68, 0, -50)) 44 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 45 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 46 | right = lgsvl.utils.transform_to_right(egoState.transform) 47 | 48 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 49 | 50 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 51 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight2LaneSame')) 52 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 53 | try: 54 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 55 | if len(modules) == 0: 56 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 57 | modules = [ 58 | 'Recorder', 59 | 'Localization', 60 | 'Perception', 61 | 'Transform', 62 | 'Routing', 63 | 'Prediction', 64 | 'Planning', 65 | 'Traffic Light', 66 | 'Control' 67 | ] 68 | except Exception: 69 | modules = [ 70 | 'Recorder', 71 | 'Localization', 72 | 'Perception', 73 | 'Transform', 74 | 'Routing', 75 | 'Prediction', 76 | 'Planning', 77 | 'Traffic Light', 78 | 'Control' 79 | ] 80 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 81 | 82 | destination = egoState.position + 120 * forward + 3.6 * right 83 | dv.setup_apollo(destination.x, destination.z, modules) 84 | 85 | POV1State = lgsvl.AgentState() 86 | POV1State.transform = sim.map_point_on_lane(egoState.position + 5 * forward + 3.6 * right) 87 | POV1 = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POV1State) 88 | 89 | POV1.follow_closest_lane(True, MAX_SPEED, False) 90 | 91 | 92 | def on_collision(agent1, agent2, contact): 93 | raise lgsvl.evaluator.TestException("{} collided with {}".format(agent1, agent2)) 94 | 95 | 96 | ego.on_collision(on_collision) 97 | POV1.on_collision(on_collision) 98 | 99 | endOfRoad = egoState.position + 120 * forward + 3.6 * right 100 | 101 | try: 102 | t0 = time.time() 103 | while True: 104 | egoCurrentState = ego.state 105 | if egoCurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 106 | raise lgsvl.evaluator.TestException( 107 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 108 | ) 109 | POV1CurrentState = POV1.state 110 | if POV1CurrentState.speed > MAX_SPEED + SPEED_VARIANCE: 111 | raise lgsvl.evaluator.TestException( 112 | "POV1 speed exceeded limit, {} > {} m/s".format(POV1CurrentState.speed, MAX_SPEED + SPEED_VARIANCE) 113 | ) 114 | if lgsvl.evaluator.separation(POV1CurrentState.position, endOfRoad) < 5: 115 | break 116 | sim.run(0.5) 117 | if time.time() - t0 > TIME_LIMIT: 118 | break 119 | except lgsvl.evaluator.TestException as e: 120 | exit("FAILED: {}".format(e)) 121 | 122 | finalEgoState = ego.state 123 | try: 124 | if lgsvl.evaluator.right_lane_check(sim, finalEgoState.transform): 125 | print("PASSED") 126 | else: 127 | raise lgsvl.evaluator.TestException("Ego did not change lanes") 128 | except lgsvl.evaluator.TestException as e: 129 | exit("FAILED: {}".format(e)) 130 | -------------------------------------------------------------------------------- /examples/NHTSA/Perform-Lane-Change/PLC_test_runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | python3 PLC_B_15.py 6 | python3 PLC_B_25.py 7 | python3 PLC_B_35.py 8 | python3 PLC_CP_15.py 9 | python3 PLC_CP_25.py 10 | python3 PLC_CP_35.py 11 | python3 PLC_SN_15.py 12 | python3 PLC_SN_25.py 13 | python3 PLC_SN_35.py 14 | python3 PLC_SP_15.py 15 | python3 PLC_SP_25.py 16 | python3 PLC_SP_35.py -------------------------------------------------------------------------------- /examples/NHTSA/Vehicle-Following/VF_S_25_Slow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See VF_C_25_Slow for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_EGO_SPEED = 11.18 # (40 km/h, 25 mph) 22 | SPEED_VARIANCE = 10 # Simple Physics does not return an accurate value 23 | MAX_POV_SPEED = 8.94 # (32 km/h, 20 mph) 24 | MAX_POV_ROTATION = 5 # deg/s 25 | TIME_LIMIT = 30 # seconds 26 | TIME_DELAY = 3 27 | MAX_FOLLOWING_DISTANCE = 50 # Apollo 3.5 is very cautious 28 | 29 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 30 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 31 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 32 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 33 | 34 | print("VF_S_25_Slow - ", end='') 35 | 36 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 37 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight1lanesame) 38 | if sim.current_scene == scene_name: 39 | sim.reset() 40 | else: 41 | sim.load(scene_name) 42 | 43 | sim.set_time_of_day(12) 44 | # spawn EGO in the 2nd to right lane 45 | egoState = lgsvl.AgentState() 46 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(1, 0, 65)) 47 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 48 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 49 | right = lgsvl.utils.transform_to_right(egoState.transform) 50 | 51 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 52 | 53 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 54 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight1LaneSame')) 55 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 56 | try: 57 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 58 | if len(modules) == 0: 59 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 60 | modules = [ 61 | 'Recorder', 62 | 'Localization', 63 | 'Perception', 64 | 'Transform', 65 | 'Routing', 66 | 'Prediction', 67 | 'Planning', 68 | 'Traffic Light', 69 | 'Control' 70 | ] 71 | except Exception: 72 | modules = [ 73 | 'Recorder', 74 | 'Localization', 75 | 'Perception', 76 | 'Transform', 77 | 'Routing', 78 | 'Prediction', 79 | 'Planning', 80 | 'Traffic Light', 81 | 'Control' 82 | ] 83 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 84 | 85 | destination = egoState.position + 135 * forward 86 | dv.setup_apollo(destination.x, destination.z, modules) 87 | 88 | POVState = lgsvl.AgentState() 89 | POVState.transform = sim.map_point_on_lane(egoState.position + 35 * forward) 90 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 91 | 92 | 93 | def on_collision(agent1, agent2, contact): 94 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 95 | 96 | 97 | ego.on_collision(on_collision) 98 | POV.on_collision(on_collision) 99 | 100 | endOfRoad = egoState.position + 135 * forward 101 | 102 | try: 103 | t0 = time.time() 104 | sim.run(TIME_DELAY) # The EGO should start moving first 105 | POV.follow_closest_lane(True, MAX_POV_SPEED, False) 106 | while True: 107 | sim.run(0.5) 108 | egoCurrentState = ego.state 109 | if egoCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 110 | raise lgsvl.evaluator.TestException( 111 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_EGO_SPEED + SPEED_VARIANCE) 112 | ) 113 | POVCurrentState = POV.state 114 | if POVCurrentState.speed > MAX_POV_SPEED + SPEED_VARIANCE: 115 | raise lgsvl.evaluator.TestException( 116 | "POV speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, MAX_POV_SPEED + SPEED_VARIANCE) 117 | ) 118 | if POVCurrentState.angular_velocity.y > MAX_POV_ROTATION: 119 | raise lgsvl.evaluator.TestException( 120 | "POV angular rotation exceeded limit, {} > {} deg/s".format( 121 | POVCurrentState.angular_velocity, MAX_POV_ROTATION 122 | ) 123 | ) 124 | if lgsvl.evaluator.separation(POVCurrentState.position, endOfRoad) < 5: 125 | break 126 | if time.time() - t0 > TIME_LIMIT: 127 | break 128 | except lgsvl.evaluator.TestException as e: 129 | exit("FAILED: {}".format(e)) 130 | 131 | separation = lgsvl.evaluator.separation(egoCurrentState.position, POVCurrentState.position) 132 | try: 133 | if separation > MAX_FOLLOWING_DISTANCE: 134 | raise lgsvl.evaluator.TestException( 135 | "FAILED: EGO following distance was not maintained, {} > {}".format(separation, MAX_FOLLOWING_DISTANCE) 136 | ) 137 | else: 138 | print("PASSED") 139 | except lgsvl.evaluator.TestException as e: 140 | exit("FAILED: {}".format(e)) 141 | -------------------------------------------------------------------------------- /examples/NHTSA/Vehicle-Following/VF_S_45_Slow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See VF_C_25_Slow for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_EGO_SPEED = 20.12 # (72 km/h, 45 mph) 22 | SPEED_VARIANCE = 10 # Simple Physics does not return an accurate value 23 | MAX_POV_SPEED = 17.88 # (64 km/h, 40 mph) 24 | MAX_POV_ROTATION = 5 # deg/s 25 | TIME_LIMIT = 30 # seconds 26 | TIME_DELAY = 7 27 | MAX_FOLLOWING_DISTANCE = 100 # Apollo 3.5 is very cautious 28 | 29 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 30 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 31 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 32 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 33 | 34 | print("VF_S_45_Slow - ", end='') 35 | 36 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 37 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight1lanesame) 38 | if sim.current_scene == scene_name: 39 | sim.reset() 40 | else: 41 | sim.load(scene_name) 42 | 43 | # spawn EGO in the 2nd to right lane 44 | egoState = lgsvl.AgentState() 45 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(1, 0, 65)) 46 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 47 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 48 | right = lgsvl.utils.transform_to_right(egoState.transform) 49 | 50 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 51 | 52 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 53 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight1LaneSame')) 54 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 55 | try: 56 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 57 | if len(modules) == 0: 58 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 59 | modules = [ 60 | 'Recorder', 61 | 'Localization', 62 | 'Perception', 63 | 'Transform', 64 | 'Routing', 65 | 'Prediction', 66 | 'Planning', 67 | 'Traffic Light', 68 | 'Control' 69 | ] 70 | except Exception: 71 | modules = [ 72 | 'Recorder', 73 | 'Localization', 74 | 'Perception', 75 | 'Transform', 76 | 'Routing', 77 | 'Prediction', 78 | 'Planning', 79 | 'Traffic Light', 80 | 'Control' 81 | ] 82 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 83 | 84 | destination = egoState.position + 135 * forward 85 | dv.setup_apollo(destination.x, destination.z, modules) 86 | 87 | POVState = lgsvl.AgentState() 88 | POVState.transform = sim.map_point_on_lane(egoState.position + 68 * forward) 89 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 90 | 91 | 92 | def on_collision(agent1, agent2, contact): 93 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 94 | 95 | 96 | ego.on_collision(on_collision) 97 | POV.on_collision(on_collision) 98 | 99 | endOfRoad = egoState.position + 135 * forward 100 | 101 | try: 102 | t0 = time.time() 103 | sim.run(TIME_DELAY) # The EGO should start moving first 104 | POV.follow_closest_lane(True, MAX_POV_SPEED, False) 105 | while True: 106 | sim.run(0.5) 107 | egoCurrentState = ego.state 108 | if egoCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 109 | raise lgsvl.evaluator.TestException( 110 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_EGO_SPEED + SPEED_VARIANCE) 111 | ) 112 | POVCurrentState = POV.state 113 | if POVCurrentState.speed > MAX_POV_SPEED + SPEED_VARIANCE: 114 | raise lgsvl.evaluator.TestException( 115 | "POV speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, MAX_POV_SPEED + SPEED_VARIANCE) 116 | ) 117 | if POVCurrentState.angular_velocity.y > MAX_POV_ROTATION: 118 | raise lgsvl.evaluator.TestException( 119 | "POV angular rotation exceeded limit, {} > {} deg/s".format( 120 | POVCurrentState.angular_velocity, MAX_POV_ROTATION 121 | ) 122 | ) 123 | if lgsvl.evaluator.separation(POVCurrentState.position, endOfRoad) < 5: 124 | break 125 | if time.time() - t0 > TIME_LIMIT: 126 | break 127 | except lgsvl.evaluator.TestException as e: 128 | exit("FAILED: {}".format(e)) 129 | 130 | separation = lgsvl.evaluator.separation(egoCurrentState.position, POVCurrentState.position) 131 | try: 132 | if separation > MAX_FOLLOWING_DISTANCE: 133 | raise lgsvl.evaluator.TestException( 134 | "FAILED: EGO following distance was not maintained, {} > {}".format(separation, MAX_FOLLOWING_DISTANCE) 135 | ) 136 | else: 137 | print("PASSED") 138 | except lgsvl.evaluator.TestException as e: 139 | exit("FAILED: {}".format(e)) 140 | -------------------------------------------------------------------------------- /examples/NHTSA/Vehicle-Following/VF_S_65_Slow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # See VF_C_25_Slow for a commented script 9 | 10 | import time 11 | import logging 12 | from environs import Env 13 | import lgsvl 14 | 15 | FORMAT = "[%(levelname)6s] [%(name)s] %(message)s" 16 | logging.basicConfig(level=logging.WARNING, format=FORMAT) 17 | log = logging.getLogger(__name__) 18 | 19 | env = Env() 20 | 21 | MAX_EGO_SPEED = 29.06 # (105 km/h, 65 mph) 22 | SPEED_VARIANCE = 10 # Simple Physics does not return an accurate value 23 | MAX_POV_SPEED = 26.82 # (96 km/h, 60 mph) 24 | MAX_POV_ROTATION = 5 # deg/s 25 | TIME_LIMIT = 30 # seconds 26 | TIME_DELAY = 5 27 | MAX_FOLLOWING_DISTANCE = 100 # Apollo 3.5 is very cautious 28 | 29 | LGSVL__SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 30 | LGSVL__SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 31 | LGSVL__AUTOPILOT_0_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 32 | LGSVL__AUTOPILOT_0_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 33 | 34 | print("VF_S_65_Slow - ", end='') 35 | 36 | sim = lgsvl.Simulator(LGSVL__SIMULATOR_HOST, LGSVL__SIMULATOR_PORT) 37 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight1lanesame) 38 | if sim.current_scene == scene_name: 39 | sim.reset() 40 | else: 41 | sim.load(scene_name) 42 | 43 | # spawn EGO in the 2nd to right lane 44 | egoState = lgsvl.AgentState() 45 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(1, 0, 65)) 46 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 47 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 48 | right = lgsvl.utils.transform_to_right(egoState.transform) 49 | 50 | ego.connect_bridge(LGSVL__AUTOPILOT_0_HOST, LGSVL__AUTOPILOT_0_PORT) 51 | 52 | dv = lgsvl.dreamview.Connection(sim, ego, LGSVL__AUTOPILOT_0_HOST) 53 | dv.set_hd_map(env.str("LGSVL__AUTOPILOT_HD_MAP", 'Straight1LaneSame')) 54 | dv.set_vehicle(env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ')) 55 | try: 56 | modules = env.list("LGSVL__AUTOPILOT_0_VEHICLE_MODULES", subcast=str) 57 | if len(modules) == 0: 58 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is empty, using default list: {0}".format(modules)) 59 | modules = [ 60 | 'Recorder', 61 | 'Localization', 62 | 'Perception', 63 | 'Transform', 64 | 'Routing', 65 | 'Prediction', 66 | 'Planning', 67 | 'Traffic Light', 68 | 'Control' 69 | ] 70 | except Exception: 71 | modules = [ 72 | 'Recorder', 73 | 'Localization', 74 | 'Perception', 75 | 'Transform', 76 | 'Routing', 77 | 'Prediction', 78 | 'Planning', 79 | 'Traffic Light', 80 | 'Control' 81 | ] 82 | log.warning("LGSVL__AUTOPILOT_0_VEHICLE_MODULES is not set, using default list: {0}".format(modules)) 83 | 84 | destination = destination = egoState.position + 135 * forward 85 | dv.setup_apollo(destination.x, destination.z, modules) 86 | 87 | POVState = lgsvl.AgentState() 88 | POVState.transform = sim.map_point_on_lane(egoState.position + 105 * forward) 89 | POV = sim.add_agent("Sedan", lgsvl.AgentType.NPC, POVState) 90 | 91 | 92 | def on_collision(agent1, agent2, contact): 93 | raise lgsvl.evaluator.TestException("Ego collided with {}".format(agent2)) 94 | 95 | 96 | ego.on_collision(on_collision) 97 | POV.on_collision(on_collision) 98 | 99 | endOfRoad = egoState.position + 135 * forward 100 | 101 | try: 102 | t0 = time.time() 103 | sim.run(TIME_DELAY) # The EGO should start moving first 104 | POV.follow_closest_lane(True, MAX_POV_SPEED, False) 105 | while True: 106 | sim.run(0.5) 107 | egoCurrentState = ego.state 108 | if egoCurrentState.speed > MAX_EGO_SPEED + SPEED_VARIANCE: 109 | raise lgsvl.evaluator.TestException( 110 | "Ego speed exceeded limit, {} > {} m/s".format(egoCurrentState.speed, MAX_EGO_SPEED + SPEED_VARIANCE) 111 | ) 112 | POVCurrentState = POV.state 113 | if POVCurrentState.speed > MAX_POV_SPEED + SPEED_VARIANCE: 114 | raise lgsvl.evaluator.TestException( 115 | "POV speed exceeded limit, {} > {} m/s".format(POVCurrentState.speed, MAX_POV_SPEED + SPEED_VARIANCE) 116 | ) 117 | if POVCurrentState.angular_velocity.y > MAX_POV_ROTATION: 118 | raise lgsvl.evaluator.TestException( 119 | "POV angular rotation exceeded limit, {} > {} deg/s".format( 120 | POVCurrentState.angular_velocity, MAX_POV_ROTATION 121 | ) 122 | ) 123 | if lgsvl.evaluator.separation(POVCurrentState.position, endOfRoad) < 5: 124 | break 125 | if time.time() - t0 > TIME_LIMIT: 126 | break 127 | except lgsvl.evaluator.TestException as e: 128 | exit("FAILED: {}".format(e)) 129 | 130 | separation = lgsvl.evaluator.separation(egoCurrentState.position, POVCurrentState.position) 131 | try: 132 | if separation > MAX_FOLLOWING_DISTANCE: 133 | raise lgsvl.evaluator.TestException( 134 | "FAILED: EGO following distance was not maintained, {} > {}".format(separation, MAX_FOLLOWING_DISTANCE) 135 | ) 136 | else: 137 | print("PASSED") 138 | except lgsvl.evaluator.TestException as e: 139 | exit("FAILED: {}".format(e)) 140 | -------------------------------------------------------------------------------- /examples/NHTSA/Vehicle-Following/VF_test_runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | python3 VF_S_25_Slow.py 6 | python3 VF_S_45_Slow.py 7 | python3 VF_S_65_Slow.py 8 | # python3 VF_C_25_Slow.py 9 | # python3 VF_C_45_Slow.py 10 | # python3 VF_C_65_Slow.py 11 | -------------------------------------------------------------------------------- /examples/Nav2/single-robot-cut-in.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import os 9 | import lgsvl 10 | 11 | print("Navigation2 Example: Single Robot Cut In") 12 | 13 | TIME_DELAY = 5 14 | TIME_LIMIT = 70 15 | NAV_DST = ((10.9, -0, 0), (0, 0, 0, 1.0)) 16 | 17 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host) 18 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 19 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host) 20 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 21 | 22 | SCENE = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_lgseocho) 23 | ROBOT = os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2) 24 | 25 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 26 | if sim.current_scene == SCENE: 27 | sim.reset() 28 | else: 29 | sim.load(SCENE, seed=0) 30 | 31 | spawns = sim.get_spawn() 32 | egoState = lgsvl.AgentState() 33 | egoState.transform = spawns[0] 34 | 35 | ego = sim.add_agent(ROBOT, lgsvl.AgentType.EGO, egoState) 36 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 37 | ego.set_initial_pose() 38 | sim.run(TIME_DELAY) 39 | is_reached = False 40 | 41 | 42 | def on_destination_reached(agent): 43 | global is_reached 44 | is_reached = True 45 | print(f"Robot reached destination") 46 | sim.stop() 47 | return 48 | 49 | 50 | sim_dst = sim.map_from_nav(lgsvl.Vector(*NAV_DST[0]), lgsvl.Quaternion(*NAV_DST[1])) 51 | ego.set_destination(sim_dst) 52 | res = ego.on_destination_reached(on_destination_reached) 53 | 54 | right = lgsvl.utils.transform_to_right(egoState.transform) 55 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 56 | 57 | pedState = lgsvl.AgentState() 58 | pedState.transform.position = egoState.transform.position 59 | pedState.transform.position += 5 * right + 5 * forward 60 | ped = sim.add_agent("Robin", lgsvl.AgentType.PEDESTRIAN, pedState) 61 | 62 | 63 | def on_collision(agent1, agent2, contact): 64 | raise Exception("Failed: {} collided with {}".format(agent1, agent2)) 65 | 66 | 67 | ego.on_collision(on_collision) 68 | ped.on_collision(on_collision) 69 | waypoints = [] 70 | waypoints.append(lgsvl.WalkWaypoint(pedState.position, idle=0, trigger_distance=6)) 71 | waypoints.append(lgsvl.WalkWaypoint(pedState.transform.position - 5 * right, idle=15)) 72 | waypoints.append(lgsvl.WalkWaypoint(pedState.transform.position - 10 * right, idle=0)) 73 | ped.follow(waypoints) 74 | 75 | print(f"Running simulation for {TIME_LIMIT} seconds...") 76 | sim.run(TIME_LIMIT) 77 | 78 | if is_reached: 79 | print("PASSED") 80 | else: 81 | exit("FAILED: Ego did not reach the destination") 82 | -------------------------------------------------------------------------------- /examples/Nav2/single-robot-freemode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import os 9 | import lgsvl 10 | 11 | print("Navigation2 Example: Single Robot Freemode") 12 | 13 | TIME_DELAY = 5 14 | TIME_LIMIT = 70 15 | NAV_DST = ((10.9, -0, 0), (0, 0, 0, 1.0)) 16 | 17 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host) 18 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 19 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host) 20 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 21 | 22 | SCENE = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_lgseocho) 23 | ROBOT = os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2) 24 | 25 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 26 | if sim.current_scene == SCENE: 27 | sim.reset() 28 | else: 29 | sim.load(SCENE, seed=0) 30 | 31 | spawns = sim.get_spawn() 32 | state = lgsvl.AgentState() 33 | state.transform = spawns[0] 34 | 35 | ego = sim.add_agent(ROBOT, lgsvl.AgentType.EGO, state) 36 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 37 | ego.set_initial_pose() 38 | sim.run(TIME_DELAY) 39 | is_reached = False 40 | 41 | 42 | def on_destination_reached(agent): 43 | global is_reached 44 | is_reached = True 45 | print(f"Robot reached destination") 46 | sim.stop() 47 | return 48 | 49 | 50 | sim_dst = sim.map_from_nav(lgsvl.Vector(*NAV_DST[0]), lgsvl.Quaternion(*NAV_DST[1])) 51 | ego.set_destination(sim_dst) 52 | res = ego.on_destination_reached(on_destination_reached) 53 | 54 | print(f"Running simulation for {TIME_LIMIT} seconds...") 55 | sim.run(TIME_LIMIT) 56 | 57 | if is_reached: 58 | print("PASSED") 59 | else: 60 | exit("FAILED: Ego did not reach the destination") 61 | -------------------------------------------------------------------------------- /examples/Nav2/single-robot-sudden-braking.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import os 9 | import lgsvl 10 | 11 | print("Navigation2 Example: Single Robot Sudden Braking") 12 | 13 | TIME_DELAY = 5 14 | TIME_LIMIT = 70 15 | NAV_DST = ((10.9, -0, 0), (0, 0, 0, 1.0)) 16 | 17 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host) 18 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 19 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host) 20 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 21 | 22 | SCENE = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_lgseocho) 23 | ROBOT = os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2) 24 | 25 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 26 | if sim.current_scene == SCENE: 27 | sim.reset() 28 | else: 29 | sim.load(SCENE, seed=0) 30 | 31 | spawns = sim.get_spawn() 32 | egoState = lgsvl.AgentState() 33 | egoState.transform = spawns[0] 34 | 35 | ego = sim.add_agent(ROBOT, lgsvl.AgentType.EGO, egoState) 36 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 37 | ego.set_initial_pose() 38 | sim.run(TIME_DELAY) 39 | is_reached = False 40 | 41 | 42 | def on_destination_reached(agent): 43 | global is_reached 44 | is_reached = True 45 | print(f"Robot reached destination") 46 | sim.stop() 47 | return 48 | 49 | 50 | sim_dst = sim.map_from_nav(lgsvl.Vector(*NAV_DST[0]), lgsvl.Quaternion(*NAV_DST[1])) 51 | ego.set_destination(sim_dst) 52 | res = ego.on_destination_reached(on_destination_reached) 53 | 54 | right = lgsvl.utils.transform_to_right(egoState.transform) 55 | forward = lgsvl.utils.transform_to_forward(egoState.transform) 56 | 57 | pedState = lgsvl.AgentState() 58 | pedState.transform = egoState.transform 59 | pedState.transform.position += 2 * forward 60 | ped = sim.add_agent("Robin", lgsvl.AgentType.PEDESTRIAN, pedState) 61 | 62 | 63 | def on_collision(agent1, agent2, contact): 64 | raise Exception("Failed: {} collided with {}".format(agent1.name, agent2.name)) 65 | 66 | 67 | ego.on_collision(on_collision) 68 | ped.on_collision(on_collision) 69 | waypoints = [] 70 | waypoints.append(lgsvl.WalkWaypoint(pedState.position, idle=0, trigger_distance=1.5)) 71 | waypoints.append(lgsvl.WalkWaypoint(pedState.position + 3 * forward, 0, speed=1)) 72 | ped.follow(waypoints) 73 | 74 | print(f"Running simulation for {TIME_LIMIT} seconds...") 75 | sim.run(TIME_LIMIT) 76 | 77 | if is_reached: 78 | print("PASSED") 79 | else: 80 | exit("FAILED: Ego did not reach the destination") 81 | -------------------------------------------------------------------------------- /examples/Nav2/single-robot-traffic-cones.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import os 9 | import lgsvl 10 | 11 | print("Navigation2 Example: Single Robot Traffic Cones") 12 | 13 | TIME_DELAY = 5 14 | TIME_LIMIT = 90 15 | NAV_DST = ((10.9, -0, 0), (0, 0, 0, 1.0)) 16 | 17 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host) 18 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 19 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host) 20 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 21 | 22 | SCENE = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_lgseocho) 23 | ROBOT = os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2) 24 | 25 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 26 | if sim.current_scene == SCENE: 27 | sim.reset() 28 | else: 29 | sim.load(SCENE, seed=0) 30 | 31 | spawns = sim.get_spawn() 32 | state = lgsvl.AgentState() 33 | state.transform = spawns[0] 34 | 35 | ego = sim.add_agent(ROBOT, lgsvl.AgentType.EGO, state) 36 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 37 | ego.set_initial_pose() 38 | sim.run(TIME_DELAY) 39 | is_reached = False 40 | 41 | 42 | def on_destination_reached(agent): 43 | global is_reached 44 | is_reached = True 45 | print(f"Robot reached destination") 46 | sim.stop() 47 | return 48 | 49 | 50 | sim_dst = sim.map_from_nav(lgsvl.Vector(*NAV_DST[0]), lgsvl.Quaternion(*NAV_DST[1])) 51 | ego.set_destination(sim_dst) 52 | res = ego.on_destination_reached(on_destination_reached) 53 | 54 | right = lgsvl.utils.transform_to_right(state.transform) 55 | forward = lgsvl.utils.transform_to_forward(state.transform) 56 | 57 | sign = 1 58 | for j in range(2, 11, 2): 59 | sign *= -1 60 | for i in range(5): 61 | objState = lgsvl.ObjectState() 62 | objState.transform.position = state.transform.position 63 | offset = sign * 0.5 * i * right + j * forward 64 | objState.transform.position += offset 65 | sim.controllable_add("TrafficCone", objState) 66 | 67 | 68 | def on_collision(agent1, agent2, contact): 69 | name1 = "traffic cone" if agent1 is None else agent1.name 70 | name2 = "traffic cone" if agent2 is None else agent2.name 71 | raise Exception("Failed: {} collided with {}".format(name1, name2)) 72 | 73 | 74 | ego.on_collision(on_collision) 75 | print(f"Running simulation for {TIME_LIMIT} seconds...") 76 | sim.run(TIME_LIMIT) 77 | 78 | if is_reached: 79 | print("PASSED") 80 | else: 81 | exit("FAILED: Ego did not reach the destination") 82 | -------------------------------------------------------------------------------- /examples/SampleTestCases/cut-in.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # LGSVL__SIMULATOR_HOST and LGSVL__AUTOPILOT_0_HOST are environment variables 9 | # They can be set for the terminal instance with `export LGSVL__SIMULATOR_HOST=###` 10 | # which will use the set value for all future commands in that terminal. 11 | # To set the variable for only a particular execution, run the script in this way 12 | # `LGSVL__SIMULATOR_HOST=### LGSVL__AUTOPILOT_0_HOST=### python3 cut-in.py` 13 | 14 | # LGSVL__SIMULATOR_HOST is the IP of the computer running the simulator 15 | # LGSVL__AUTOPILOT_0_HOST is the IP of the computer running the bridge (from the perspective of the Simulator) 16 | # If the simulator and bridge are running on the same computer, then the default values will work. 17 | # Otherwise the variables must be set for in order to connect to the simulator and the bridge to receive data. 18 | # LGSVL__SIMULATOR_PORT and LGSVL__AUTOPILOT_0_HOST need to be set if non-default ports will be used 19 | 20 | import os 21 | import lgsvl 22 | 23 | import time 24 | import sys 25 | 26 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", "127.0.0.1") 27 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", 8181)) 28 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 29 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", 9090)) 30 | 31 | scene_name = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_sanfrancisco) 32 | 33 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 34 | if sim.current_scene == scene_name: 35 | sim.reset() 36 | else: 37 | sim.load(scene_name, seed=0) 38 | 39 | # spawn EGO 40 | egoState = lgsvl.AgentState() 41 | # Spawn point found in Unity Editor 42 | egoState.transform = sim.map_point_on_lane(lgsvl.Vector(773.29, 10.24, -10.79)) 43 | ego = sim.add_agent(os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 44 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 45 | 46 | right = lgsvl.utils.transform_to_right(egoState.transform) # Unit vector in the right direction of the EGO 47 | forward = lgsvl.utils.transform_to_forward(egoState.transform) # Unit vector in the forward direction of the EGO 48 | 49 | # spawn NPC 50 | npcState = lgsvl.AgentState() 51 | npcState.transform = egoState.transform 52 | npcState.transform.position = egoState.position - 3.6 * right # NPC is 3.6m to the left of the EGO 53 | npc = sim.add_agent("Jeep", lgsvl.AgentType.NPC, npcState) 54 | 55 | # This function will be called if a collision occurs 56 | def on_collision(agent1, agent2, contact): 57 | raise Exception("{} collided with {}".format(agent1, agent2)) 58 | 59 | ego.on_collision(on_collision) 60 | npc.on_collision(on_collision) 61 | 62 | controlReceived = False 63 | 64 | # This function will be called when the Simulator receives the first message on the topic defined in the CheckControlSensor configuration 65 | def on_control_received(agent, kind, context): 66 | global controlReceived 67 | # There can be multiple custom callbacks defined, this checks for the appropriate kind 68 | if kind == "checkControl": 69 | # Stops the Simulator running, this will only interrupt the first sim.run(30) call 70 | sim.stop() 71 | controlReceived = True 72 | 73 | ego.on_custom(on_control_received) 74 | 75 | # Run Simulator for at most 30 seconds for the AD stack to to initialize 76 | sim.run(30) 77 | 78 | # If a Control message was not received, then the AD stack is not ready and the scenario should not continue 79 | if not controlReceived: 80 | raise Exception("AD stack is not ready after 30 seconds") 81 | sys.exit() 82 | 83 | # NPC will follow the HD map at a max speed of 15 m/s (33 mph) and will not change lanes automatically 84 | # The speed limit of the road is 20m/s so the EGO should drive faster than the NPC 85 | npc.follow_closest_lane(follow=True, max_speed=8, isLaneChange=False) 86 | 87 | # t0 is the time when the Simulation started 88 | t0 = time.time() 89 | 90 | # This will keep track of if the NPC has already changed lanes 91 | npcChangedLanes = False 92 | 93 | # Run Simulation for 4 seconds before checking cut-in or end conditions 94 | sim.run(4) 95 | 96 | # The Simulation will pause every 0.5 seconds to check 2 conditions 97 | while True: 98 | sim.run(0.5) 99 | 100 | # If the NPC has not already changed lanes then the distance between the NPC and EGO is calculated 101 | if not npcChangedLanes: 102 | egoCurrentState = ego.state 103 | npcCurrentState = npc.state 104 | 105 | separationDistance = (egoCurrentState.position - npcCurrentState.position).magnitude() 106 | 107 | # If the EGO and NPC are within 15m, then NPC will change lanes to the right (in front of the EGO) 108 | if separationDistance <= 15: 109 | npc.change_lane(False) 110 | npcChangedLanes = True 111 | 112 | # Simulation will be limited to running for 30 seconds total 113 | if time.time() - t0 > 26: 114 | break 115 | -------------------------------------------------------------------------------- /examples/SampleTestCases/ped-crossing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # LGSVL__SIMULATOR_HOST and LGSVL__AUTOPILOT_0_HOST are environment variables 9 | # They can be set for the terminal instance with `export LGSVL__SIMULATOR_HOST=###` 10 | # which will use the set value for all future commands in that terminal. 11 | # To set the variable for only a particular execution, run the script in this way 12 | # `LGSVL__SIMULATOR_HOST=### LGSVL__AUTOPILOT_0_HOST=### python3 cut-in.py` 13 | 14 | # LGSVL__SIMULATOR_HOST is the IP of the computer running the simulator 15 | # LGSVL__AUTOPILOT_0_HOST is the IP of the computer running the bridge (from the perspective of the Simulator) 16 | # If the simulator and bridge are running on the same computer, then the default values will work. 17 | # Otherwise the variables must be set for in order to connect to the simulator and the bridge to receive data. 18 | # LGSVL__SIMULATOR_PORT and LGSVL__AUTOPILOT_0_HOST need to be set if non-default ports will be used 19 | 20 | import os 21 | import lgsvl 22 | 23 | import sys 24 | 25 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", 8181)) 27 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", 9090)) 29 | 30 | scene_name = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_straight1lanepedestriancrosswalk) 31 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 32 | if sim.current_scene == scene_name: 33 | sim.reset() 34 | else: 35 | sim.load(scene_name) 36 | 37 | # spawn EGO 38 | egoState = lgsvl.AgentState() 39 | egoState.transform = sim.get_spawn()[0] 40 | ego = sim.add_agent(os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 41 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 42 | 43 | # spawn PED 44 | pedState = lgsvl.AgentState() 45 | pedState.transform.position = lgsvl.Vector(-7.67, 0.2, 6.299) 46 | ped = sim.add_agent("Bob", lgsvl.AgentType.PEDESTRIAN, pedState) 47 | 48 | # This function will be called if a collision occurs 49 | def on_collision(agent1, agent2, contact): 50 | raise Exception("{} collided with {}".format(agent1, agent2)) 51 | 52 | ego.on_collision(on_collision) 53 | ped.on_collision(on_collision) 54 | 55 | controlReceived = False 56 | 57 | # This function will be called when the Simulator receives the first message on the topic defined in the CheckControlSensor configuration 58 | def on_control_received(agent, kind, context): 59 | global controlReceived 60 | # There can be multiple custom callbacks defined, this checks for the appropriate kind 61 | if kind == "checkControl": 62 | # Stops the Simulator running, this will only interrupt the first sim.run(30) call 63 | sim.stop() 64 | controlReceived = True 65 | 66 | ego.on_custom(on_control_received) 67 | 68 | # Run Simulator for at most 30 seconds for the AD stack to to initialize 69 | sim.run(30) 70 | 71 | # If a Control message was not received, then the AD stack is not ready and the scenario should not continue 72 | if not controlReceived: 73 | raise Exception("AD stack is not ready") 74 | sys.exit() 75 | 76 | # Create the list of waypoints for the pedestrian to follow 77 | waypoints = [] 78 | # Fist waypoint is the same position that the PED is spawned. The PED will wait here until the EGO is within 50m 79 | waypoints.append(lgsvl.WalkWaypoint(position=pedState.position, idle=0, trigger_distance=50)) 80 | # Second waypoint is across the crosswalk 81 | waypoints.append(lgsvl.WalkWaypoint(position=lgsvl.Vector(8.88, 0.2, 6.299), idle=0)) 82 | 83 | # List of waypoints is given to the pedestrian 84 | ped.follow(waypoints) 85 | 86 | # Simulation will run for 30 seconds 87 | sim.run(30) 88 | -------------------------------------------------------------------------------- /examples/SampleTestCases/random-traffic-local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2020 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from datetime import datetime 9 | from environs import Env 10 | import random 11 | import lgsvl 12 | 13 | 14 | ''' 15 | LGSVL__AUTOPILOT_0_HOST IP address of the computer running the bridge to connect to 16 | LGSVL__AUTOPILOT_0_PORT Port that the bridge listens on for messages 17 | LGSVL__AUTOPILOT_0_VEHICLE_CONFIG Vehicle configuration to be loaded in Dreamview (Capitalization and spacing must match the dropdown in Dreamview) 18 | LGSVL__AUTOPILOT_HD_MAP HD map to be loaded in Dreamview (Capitalization and spacing must match the dropdown in Dreamview) 19 | LGSVL__MAP ID of map to be loaded in Simulator 20 | LGSVL__RANDOM_SEED Simulation random seed 21 | LGSVL__SIMULATION_DURATION_SECS How long to run the simulation for 22 | LGSVL__SIMULATOR_HOST IP address of computer running simulator (Master node if a cluster) 23 | LGSVL__SIMULATOR_PORT Port that the simulator allows websocket connections over 24 | LGSVL__VEHICLE_0 ID of EGO vehicle to be loaded in Simulator 25 | ''' 26 | 27 | env = Env() 28 | 29 | SIMULATOR_HOST = env.str("LGSVL__SIMULATOR_HOST", "127.0.0.1") 30 | SIMULATOR_PORT = env.int("LGSVL__SIMULATOR_PORT", 8181) 31 | BRIDGE_HOST = env.str("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 32 | BRIDGE_PORT = env.int("LGSVL__AUTOPILOT_0_PORT", 9090) 33 | 34 | LGSVL__AUTOPILOT_HD_MAP = env.str("LGSVL__AUTOPILOT_HD_MAP", "SanFrancisco") 35 | LGSVL__AUTOPILOT_0_VEHICLE_CONFIG = env.str("LGSVL__AUTOPILOT_0_VEHICLE_CONFIG", 'Lincoln2017MKZ') 36 | LGSVL__SIMULATION_DURATION_SECS = 120.0 37 | LGSVL__RANDOM_SEED = env.int("LGSVL__RANDOM_SEED", 51472) 38 | 39 | vehicle_conf = env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_modular) 40 | scene_name = env.str("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_sanfrancisco) 41 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 42 | try: 43 | print("Loading map {}...".format(scene_name)) 44 | sim.load(scene_name, LGSVL__RANDOM_SEED) # laod map with random seed 45 | except Exception: 46 | if sim.current_scene == scene_name: 47 | sim.reset() 48 | else: 49 | sim.load(scene_name) 50 | 51 | 52 | # reset time of the day 53 | sim.set_date_time(datetime(2020, 7, 1, 15, 0, 0, 0), True) 54 | 55 | spawns = sim.get_spawn() 56 | # select spawn deterministically depending on the seed 57 | spawn_index = LGSVL__RANDOM_SEED % len(spawns) 58 | 59 | state = lgsvl.AgentState() 60 | state.transform = spawns[spawn_index] # TODO some sort of Env Variable so that user/wise can select from list 61 | print("Loading vehicle {}...".format(vehicle_conf)) 62 | ego = sim.add_agent(vehicle_conf, lgsvl.AgentType.EGO, state) 63 | 64 | print("Connecting to bridge...") 65 | # The EGO is now looking for a bridge at the specified IP and port 66 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 67 | 68 | def on_collision(agent1, agent2, contact): 69 | raise Exception("{} collided with {}".format(agent1, agent2)) 70 | sys.exit() 71 | 72 | ego.on_collision(on_collision) 73 | 74 | dv = lgsvl.dreamview.Connection(sim, ego, BRIDGE_HOST) 75 | dv.set_hd_map(LGSVL__AUTOPILOT_HD_MAP) 76 | dv.set_vehicle(LGSVL__AUTOPILOT_0_VEHICLE_CONFIG) 77 | 78 | destination_index = LGSVL__RANDOM_SEED % len(spawns[spawn_index].destinations) 79 | destination = spawns[spawn_index].destinations[destination_index] # TODO some sort of Env Variable so that user/wise can select from list 80 | 81 | default_modules = [ 82 | 'Localization', 83 | 'Transform', 84 | 'Routing', 85 | 'Prediction', 86 | 'Planning', 87 | 'Control', 88 | 'Recorder' 89 | ] 90 | 91 | dv.disable_apollo() 92 | dv.setup_apollo(destination.position.x, destination.position.z, default_modules) 93 | 94 | print("adding npcs") 95 | sim.add_random_agents(lgsvl.AgentType.NPC) 96 | sim.add_random_agents(lgsvl.AgentType.PEDESTRIAN) 97 | 98 | sim.run(LGSVL__SIMULATION_DURATION_SECS) 99 | -------------------------------------------------------------------------------- /examples/SampleTestCases/red-light-runner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # LGSVL__SIMULATOR_HOST and LGSVL__AUTOPILOT_0_HOST are environment variables 9 | # They can be set for the terminal instance with `export LGSVL__SIMULATOR_HOST=###` 10 | # which will use the set value for all future commands in that terminal. 11 | # To set the variable for only a particular execution, run the script in this way 12 | # `LGSVL__SIMULATOR_HOST=### LGSVL__AUTOPILOT_0_HOST=### python3 cut-in.py` 13 | 14 | # LGSVL__SIMULATOR_HOST is the IP of the computer running the simulator 15 | # LGSVL__AUTOPILOT_0_HOST is the IP of the computer running the bridge (from the perspective of the Simulator) 16 | # If the simulator and bridge are running on the same computer, then the default values will work. 17 | # Otherwise the variables must be set for in order to connect to the simulator and the bridge to receive data. 18 | # LGSVL__SIMULATOR_PORT and LGSVL__AUTOPILOT_0_HOST need to be set if non-default ports will be used 19 | 20 | import os 21 | import lgsvl 22 | 23 | import sys 24 | 25 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", 8181)) 27 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", 9090)) 29 | 30 | scene_name = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_borregasave) 31 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 32 | if sim.current_scene == scene_name: 33 | sim.reset() 34 | else: 35 | sim.load(scene_name, seed=0) 36 | 37 | # spawn EGO 38 | egoState = lgsvl.AgentState() 39 | egoState.transform = sim.get_spawn()[0] 40 | ego = sim.add_agent(os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 41 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 42 | 43 | forward = lgsvl.utils.transform_to_forward(egoState.transform) # Unit vector in the forward direction of the EGO 44 | right = lgsvl.utils.transform_to_right(egoState.transform) # Unit vector in the right direction of the EGO 45 | 46 | # spawn NPC 47 | npcState = lgsvl.AgentState() 48 | npcState.transform = sim.map_point_on_lane(egoState.position + 51.1 * forward + 29 * right) # NPC is 20m ahead of the EGO 49 | npc = sim.add_agent("SUV", lgsvl.AgentType.NPC, npcState) 50 | 51 | # This function will be called if a collision occurs 52 | def on_collision(agent1, agent2, contact): 53 | raise Exception("{} collided with {}".format(agent1, agent2)) 54 | 55 | ego.on_collision(on_collision) 56 | npc.on_collision(on_collision) 57 | 58 | controlReceived = False 59 | 60 | # This function will be called when the Simulator receives the first message on the topic defined in the CheckControlSensor configuration 61 | def on_control_received(agent, kind, context): 62 | global controlReceived 63 | # There can be multiple custom callbacks defined, this checks for the appropriate kind 64 | if kind == "checkControl": 65 | # Stops the Simulator running, this will only interrupt the first sim.run(30) call 66 | sim.stop() 67 | controlReceived = True 68 | 69 | ego.on_custom(on_control_received) 70 | 71 | # Run Simulator for at most 30 seconds for the AD stack to to initialize 72 | sim.run(30) 73 | 74 | # If a Control message was not received, then the AD stack is not ready and the scenario should not continue 75 | if not controlReceived: 76 | raise Exception("AD stack is not ready") 77 | sys.exit() 78 | 79 | # Create the list of waypoints for the npc to follow 80 | waypoints = [] 81 | # First waypoint is the same position that the npc is spawned. The npc will wait here until the EGO is within 50m 82 | waypoints.append(lgsvl.DriveWaypoint(position=npcState.position, speed=20.1168, angle=npcState.rotation, idle=0, deactivate=False, trigger_distance=35)) 83 | # Second waypoint is across the intersection 84 | endPoint = sim.map_point_on_lane(egoState.position + 51.1 * forward - 63.4 * right) 85 | waypoints.append(lgsvl.DriveWaypoint(position=endPoint.position, speed=0, angle=endPoint.rotation)) 86 | npc.follow(waypoints) 87 | 88 | # Set all the traffic lights to green. 89 | # It is possible to set only the lights visible by the EGO to green, but positions of the lights must be known 90 | signals = sim.get_controllables("signal") 91 | for signal in signals: 92 | signal.control("green=3") 93 | 94 | # Run the simulation for 30 seconds 95 | sim.run(30) 96 | -------------------------------------------------------------------------------- /examples/SampleTestCases/sudden-braking.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | # LGSVL__SIMULATOR_HOST and LGSVL__AUTOPILOT_0_HOST are environment variables 9 | # They can be set for the terminal instance with `export LGSVL__SIMULATOR_HOST=###` 10 | # which will use the set value for all future commands in that terminal. 11 | # To set the variable for only a particular execution, run the script in this way 12 | # `LGSVL__SIMULATOR_HOST=### LGSVL__AUTOPILOT_0_HOST=### python3 cut-in.py` 13 | 14 | # LGSVL__SIMULATOR_HOST is the IP of the computer running the simulator 15 | # LGSVL__AUTOPILOT_0_HOST is the IP of the computer running the bridge (from the perspective of the Simulator) 16 | # If the simulator and bridge are running on the same computer, then the default values will work. 17 | # Otherwise the variables must be set for in order to connect to the simulator and the bridge to receive data. 18 | # LGSVL__SIMULATOR_PORT and LGSVL__AUTOPILOT_0_HOST need to be set if non-default ports will be used 19 | 20 | import os 21 | import lgsvl 22 | 23 | import sys 24 | 25 | SIMULATOR_HOST = os.environ.get("LGSVL__SIMULATOR_HOST", "127.0.0.1") 26 | SIMULATOR_PORT = int(os.environ.get("LGSVL__SIMULATOR_PORT", 8181)) 27 | BRIDGE_HOST = os.environ.get("LGSVL__AUTOPILOT_0_HOST", "127.0.0.1") 28 | BRIDGE_PORT = int(os.environ.get("LGSVL__AUTOPILOT_0_PORT", 9090)) 29 | 30 | scene_name = os.environ.get("LGSVL__MAP", lgsvl.wise.DefaultAssets.map_singlelaneroad) 31 | sim = lgsvl.Simulator(SIMULATOR_HOST, SIMULATOR_PORT) 32 | if sim.current_scene == scene_name: 33 | sim.reset() 34 | else: 35 | sim.load(scene_name, seed=0) 36 | 37 | # spawn EGO 38 | egoState = lgsvl.AgentState() 39 | egoState.transform = sim.get_spawn()[0] 40 | ego = sim.add_agent(os.environ.get("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5_full_analysis), lgsvl.AgentType.EGO, egoState) 41 | ego.connect_bridge(BRIDGE_HOST, BRIDGE_PORT) 42 | 43 | forward = lgsvl.utils.transform_to_forward(egoState.transform) # Unit vector in the forward direction of the EGO 44 | 45 | # spawn NPC 46 | npcState = lgsvl.AgentState() 47 | npcState.transform = egoState.transform 48 | npcState.transform.position = egoState.position + 20 * forward # NPC is 20m ahead of the EGO 49 | npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, npcState) 50 | 51 | # This function will be called if a collision occurs 52 | def on_collision(agent1, agent2, contact): 53 | raise Exception("{} collided with {}".format(agent1, agent2)) 54 | 55 | ego.on_collision(on_collision) 56 | npc.on_collision(on_collision) 57 | 58 | controlReceived = False 59 | 60 | # This function will be called when the Simulator receives the first message on the topic defined in the CheckControlSensor configuration 61 | def on_control_received(agent, kind, context): 62 | global controlReceived 63 | # There can be multiple custom callbacks defined, this checks for the appropriate kind 64 | if kind == "checkControl": 65 | # Stops the Simulator running, this will only interrupt the first sim.run(30) call 66 | sim.stop() 67 | controlReceived = True 68 | 69 | ego.on_custom(on_control_received) 70 | 71 | # Run Simulator for at most 30 seconds for the AD stack to to initialize 72 | sim.run(30) 73 | 74 | # If a Control message was not received, then the AD stack is not ready and the scenario should not continue 75 | if not controlReceived: 76 | raise Exception("AD stack is not ready") 77 | sys.exit() 78 | 79 | # NPC will follow the HD map at a max speed of 11.176 m/s (25 mph) 80 | npc.follow_closest_lane(follow=True, max_speed=11.176) 81 | 82 | # Run Simulation for 10 seconds 83 | sim.run(10) 84 | 85 | # Force the NPC to come to a stop 86 | control = lgsvl.NPCControl() 87 | control.e_stop = True 88 | 89 | npc.apply_control(control) 90 | 91 | # Simulation will run for 10 seconds 92 | # NPC will be stopped for this time 93 | sim.run(10) 94 | 95 | # NPC told to resume following the HD map 96 | npc.follow_closest_lane(True, 11.176) 97 | 98 | # Simulation runs for another 10 seconds 99 | sim.run(10) 100 | -------------------------------------------------------------------------------- /lgsvl/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2021 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .geometry import Vector, BoundingBox, Transform, Quaternion 8 | from .simulator import Simulator, RaycastHit, WeatherState 9 | from .sensor import Sensor, CameraSensor, LidarSensor, ImuSensor 10 | from .agent import ( 11 | AgentType, 12 | AgentState, 13 | VehicleControl, 14 | Vehicle, 15 | EgoVehicle, 16 | NpcVehicle, 17 | Pedestrian, 18 | DriveWaypoint, 19 | WalkWaypoint, 20 | WaypointTrigger, 21 | TriggerEffector, 22 | NPCControl, 23 | ) 24 | from .controllable import Controllable 25 | from .utils import ObjectState 26 | 27 | # Subpackages 28 | import lgsvl.dreamview 29 | import lgsvl.evaluator 30 | import lgsvl.wise 31 | -------------------------------------------------------------------------------- /lgsvl/controllable.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2021 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .geometry import Transform 8 | from .utils import accepts, ObjectState 9 | 10 | 11 | class Controllable: 12 | def __init__(self, remote, j): 13 | self.remote = remote 14 | self.uid = j["uid"] 15 | self.type = j["type"] 16 | self.transform = Transform.from_json(j) 17 | self.valid_actions = j["valid_actions"] 18 | self.default_control_policy = j["default_control_policy"] 19 | 20 | @property 21 | def object_state(self): 22 | j = self.remote.command("controllable/object_state/get", {"uid": self.uid}) 23 | return ObjectState.from_json(j) 24 | 25 | @object_state.setter 26 | @accepts(ObjectState) 27 | def object_state(self, object_state): 28 | self.remote.command("controllable/object_state/set", { 29 | "uid": self.uid, 30 | "state": object_state.to_json() 31 | }) 32 | 33 | @property 34 | def current_state(self): 35 | j = self.remote.command("controllable/current_state/get", {"uid": self.uid}) 36 | return j["state"] 37 | 38 | @property 39 | def control_policy(self): 40 | j = self.remote.command("controllable/control_policy/get", {"uid": self.uid}) 41 | return j["control_policy"] 42 | 43 | @accepts((str, list)) 44 | def control(self, control_policy): 45 | self.remote.command("controllable/control_policy/set", { 46 | "uid": self.uid, 47 | "control_policy": control_policy, 48 | }) 49 | 50 | def __eq__(self, other): 51 | return self.uid == other.uid 52 | 53 | def __hash__(self): 54 | return hash(self.uid) 55 | 56 | def __repr__(self): 57 | return str({ 58 | "type": str(self.type), 59 | "transform": str(self.transform), 60 | "valid_actions": str(self.valid_actions), 61 | "default_control_policy": str(self.default_control_policy), 62 | }) 63 | -------------------------------------------------------------------------------- /lgsvl/dreamview/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .dreamview import Connection, CoordType 8 | -------------------------------------------------------------------------------- /lgsvl/evaluator/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .utils import TestException, right_lane_check, separation, almost_equal, in_parking_zone 8 | -------------------------------------------------------------------------------- /lgsvl/evaluator/utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | import lgsvl 8 | import numpy 9 | 10 | 11 | class TestException(Exception): 12 | pass 13 | 14 | 15 | def right_lane_check(simulator, ego_transform): 16 | egoLane = simulator.map_point_on_lane(ego_transform.position) 17 | right = lgsvl.utils.transform_to_right(ego_transform) 18 | rightLane = simulator.map_point_on_lane(ego_transform.position + 3.6 * right) 19 | 20 | return almost_equal(egoLane.position.x, rightLane.position.x) and \ 21 | almost_equal(egoLane.position.y, rightLane.position.y) and \ 22 | almost_equal(egoLane.position.z, rightLane.position.z) 23 | 24 | 25 | def in_parking_zone(beginning, end, ego_transform): 26 | forward = lgsvl.utils.transform_to_forward(ego_transform) 27 | b2e = ego_transform.position - beginning # Vector from beginning of parking zone to EGO's position 28 | b2e = b2e * (1 / b2e.magnitude()) # Make it a Unit vector to simplify dot product result 29 | e2e = end - ego_transform.position # Vector from EGO's position to end of parking zone 30 | e2e = e2e * (1 / e2e.magnitude()) 31 | return ( 32 | numpy.dot([forward.x, forward.y, forward.z], [b2e.x, b2e.y, b2e.z]) > 0.9 33 | and numpy.dot([forward.x, forward.y, forward.z], [e2e.x, e2e.y, e2e.z]) > 0.9 34 | ) 35 | 36 | 37 | def almost_equal(a, b, diff=0.5): 38 | return abs(a - b) <= diff 39 | 40 | 41 | def separation(V1, V2): 42 | return (V1 - V2).magnitude() 43 | -------------------------------------------------------------------------------- /lgsvl/geometry.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from math import sqrt 8 | 9 | 10 | class Vector: 11 | def __init__(self, x=0.0, y=0.0, z=0.0): 12 | self.x = x 13 | self.y = y 14 | self.z = z 15 | 16 | @staticmethod 17 | def from_json(j): 18 | return Vector(j["x"], j["y"], j["z"]) 19 | 20 | def to_json(self): 21 | return {"x": self.x, "y": self.y, "z": self.z} 22 | 23 | def __repr__(self): 24 | return "Vector({}, {}, {})".format(self.x, self.y, self.z) 25 | 26 | def __add__(self, v): 27 | if isinstance(v, Vector): 28 | return Vector(self.x + v.x, self.y + v.y, self.z + v.z) 29 | elif isinstance(v, (int, float)): 30 | return Vector(self.x + v, self.y + v, self.z + v) 31 | else: 32 | raise TypeError("Vector addition only allowed between Vectors and numbers") 33 | 34 | def __sub__(self, v): 35 | if isinstance(v, Vector): 36 | return Vector(self.x - v.x, self.y - v.y, self.z - v.z) 37 | elif isinstance(v, (int, float)): 38 | return Vector(self.x - v, self.y - v, self.z - v) 39 | else: 40 | raise TypeError("Vector subtraction only allowed between Vectors and numbers") 41 | 42 | def __mul__(self, v): 43 | if isinstance(v, Vector): 44 | return Vector(self.x * v.x, self.y * v.y, self.z * v.z) 45 | elif isinstance(v, (int, float)): 46 | return Vector(self.x * v, self.y * v, self.z * v) 47 | else: 48 | raise TypeError("Vector multiplication only allowed between Vectors and numbers") 49 | 50 | def __rmul__(self, v): 51 | return self * v 52 | 53 | def __neg__(self): 54 | return Vector(-self.x, -self.y, -self.z) 55 | 56 | def magnitude(self): 57 | return sqrt(self.x**2 + self.y**2 + self.z**2) 58 | 59 | 60 | class BoundingBox: 61 | def __init__(self, min, max): 62 | self.min = min 63 | self.max = max 64 | 65 | @staticmethod 66 | def from_json(j): 67 | return BoundingBox(Vector.from_json(j["min"]), Vector.from_json(j["max"])) 68 | 69 | def to_json(self): 70 | return {"min": self.min.to_json(), "max": self.max.to_json()} 71 | 72 | def __repr__(self): 73 | return "BoundingBox({}, {})".format(self.min, self.max) 74 | 75 | @property 76 | def center(self): 77 | return Vector( 78 | (self.max.x + self.min.x) * 0.5, 79 | (self.max.y + self.min.y) * 0.5, 80 | (self.max.z + self.min.z) * 0.5, 81 | ) 82 | 83 | @property 84 | def size(self): 85 | return Vector( 86 | self.max.x - self.min.x, 87 | self.max.y - self.min.y, 88 | self.max.z - self.min.z, 89 | ) 90 | 91 | 92 | class Transform: 93 | def __init__(self, position=None, rotation=None): 94 | if position is None: position = Vector() 95 | if rotation is None: rotation = Vector() 96 | self.position = position 97 | self.rotation = rotation 98 | 99 | @staticmethod 100 | def from_json(j): 101 | return Transform(Vector.from_json(j["position"]), Vector.from_json(j["rotation"])) 102 | 103 | def to_json(self): 104 | return {"position": self.position.to_json(), "rotation": self.rotation.to_json()} 105 | 106 | def __repr__(self): 107 | return "Transform(position={}, rotation={})".format(self.position, self.rotation) 108 | 109 | 110 | class Spawn: 111 | def __init__(self, transform=None, destinations=None): 112 | if transform is None: transform = Transform() 113 | if destinations is None: destinations = [] 114 | self.position = transform.position 115 | self.rotation = transform.rotation 116 | self.destinations = destinations 117 | 118 | @staticmethod 119 | def from_json(j): 120 | spawn_point = Transform.from_json(j) 121 | destinations = [] 122 | if "destinations" in j: 123 | for d in j["destinations"]: 124 | destinations.append(Transform.from_json(d)) 125 | 126 | return Spawn(spawn_point, destinations) 127 | 128 | def to_json(self): 129 | return {"position": self.position.to_json(), "rotation": self.rotation.to_json()} 130 | 131 | def __repr__(self): 132 | return "Spawn(position={}, rotation={}, destinations={})".format( 133 | self.position, self.rotation, self.destinations 134 | ) 135 | 136 | 137 | class Quaternion: 138 | def __init__(self, x=0.0, y=0.0, z=0.0, w=0.0): 139 | self.x = x 140 | self.y = y 141 | self.z = z 142 | self.w = w 143 | 144 | @staticmethod 145 | def from_json(j): 146 | return Quaternion(j["x"], j["y"], j["z"], j["w"]) 147 | 148 | def to_json(self): 149 | return {"x": self.x, "y": self.y, "z": self.z, "w": self.w} 150 | 151 | def __repr__(self): 152 | return "Quaternion({}, {}, {}, {})".format(self.x, self.y, self.z, self.w) 153 | -------------------------------------------------------------------------------- /lgsvl/remote.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | import threading 8 | import websockets 9 | import asyncio 10 | import json 11 | 12 | 13 | class Remote(threading.Thread): 14 | 15 | def __init__(self, host, port): 16 | super().__init__(daemon=True) 17 | self.endpoint = "ws://{}:{}".format(host, port) 18 | self.lock = threading.Lock() 19 | self.cv = threading.Condition() 20 | self.data = None 21 | self.sem = threading.Semaphore(0) 22 | self.running = True 23 | self.start() 24 | self.sem.acquire() 25 | 26 | def run(self): 27 | self.loop = asyncio.new_event_loop() 28 | asyncio.set_event_loop(self.loop) 29 | self.loop.run_until_complete(self.process()) 30 | 31 | def close(self): 32 | asyncio.run_coroutine_threadsafe(self.websocket.close(), self.loop) 33 | self.join() 34 | self.loop.close() 35 | 36 | async def process(self): 37 | self.websocket = await websockets.connect(self.endpoint, compression=None) 38 | self.sem.release() 39 | 40 | while True: 41 | try: 42 | data = await self.websocket.recv() 43 | except Exception as e: 44 | if isinstance(e, websockets.exceptions.ConnectionClosed): 45 | break 46 | with self.cv: 47 | self.data = {"error": str(e)} 48 | self.cv.notify() 49 | break 50 | with self.cv: 51 | self.data = json.loads(data) 52 | self.cv.notify() 53 | 54 | await self.websocket.close() 55 | 56 | def command(self, name, args={}): 57 | if not self.websocket: 58 | raise Exception("Not connected") 59 | 60 | data = json.dumps({"command": name, "arguments": args}) 61 | asyncio.run_coroutine_threadsafe(self.websocket.send(data), self.loop) 62 | 63 | with self.cv: 64 | self.cv.wait_for(lambda: self.data is not None) 65 | data = self.data 66 | self.data = None 67 | 68 | if "error" in data: 69 | raise Exception(data["error"]) 70 | return data["result"] 71 | -------------------------------------------------------------------------------- /lgsvl/sensor.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .geometry import Transform 8 | from .utils import accepts 9 | 10 | from collections import namedtuple 11 | 12 | GpsData = namedtuple("GpsData", "latitude longitude northing easting altitude orientation") 13 | 14 | 15 | class Sensor: 16 | def __init__(self, remote, uid, name): 17 | self.remote = remote 18 | self.uid = uid 19 | self.name = name 20 | 21 | @property 22 | def transform(self): 23 | j = self.remote.command("sensor/transform/get", {"uid": self.uid}) 24 | return Transform.from_json(j) 25 | 26 | @property 27 | def enabled(self): 28 | return self.remote.command("sensor/enabled/get", {"uid": self.uid}) 29 | 30 | @enabled.setter 31 | @accepts(bool) 32 | def enabled(self, value): 33 | self.remote.command("sensor/enabled/set", {"uid": self.uid, "enabled": value}) 34 | 35 | def __eq__(self, other): 36 | return self.uid == other.uid 37 | 38 | def __hash__(self): 39 | return hash(self.uid) 40 | 41 | @staticmethod 42 | def create(remote, j): 43 | if j["type"] == "camera": 44 | return CameraSensor(remote, j) 45 | if j["type"] == "lidar": 46 | return LidarSensor(remote, j) 47 | if j["type"] == "imu": 48 | return ImuSensor(remote, j) 49 | if j["type"] == "gps": 50 | return GpsSensor(remote, j) 51 | if j["type"] == "radar": 52 | return RadarSensor(remote, j) 53 | if j["type"] == "canbus": 54 | return CanBusSensor(remote, j) 55 | if j["type"] == "recorder": 56 | return VideoRecordingSensor(remote, j) 57 | if j["type"] == "analysis": 58 | return AnalysisSensor(remote, j) 59 | raise ValueError("Sensor type '{}' not supported".format(j["type"])) 60 | 61 | 62 | class CameraSensor(Sensor): 63 | def __init__(self, remote, j): 64 | super().__init__(remote, j["uid"], j["name"]) 65 | self.frequency = j["frequency"] 66 | self.width = j["width"] 67 | self.height = j["height"] 68 | self.fov = j["fov"] 69 | self.near_plane = j["near_plane"] 70 | self.far_plane = j["far_plane"] 71 | """ 72 | RGB - 24-bit color image 73 | DEPTH - 8-bit grayscale depth buffer 74 | SEMANTIC - 24-bit color image with semantic segmentation 75 | """ 76 | self.format = j["format"] 77 | 78 | @accepts(str, int, int) 79 | def save(self, path, quality=75, compression=6): 80 | success = self.remote.command("sensor/camera/save", { 81 | "uid": self.uid, 82 | "path": path, 83 | "quality": quality, 84 | "compression": compression, 85 | }) 86 | return success 87 | 88 | 89 | class LidarSensor(Sensor): 90 | def __init__(self, remote, j): 91 | super().__init__(remote, j["uid"], j["name"]) 92 | self.min_distance = j["min_distance"] 93 | self.max_distance = j["max_distance"] 94 | self.rays = j["rays"] 95 | self.rotations = j["rotations"] # rotation frequency, Hz 96 | self.measurements = j["measurements"] # how many measurements each ray does per one rotation 97 | self.fov = j["fov"] 98 | self.angle = j["angle"] 99 | self.compensated = j["compensated"] 100 | 101 | @accepts(str) 102 | def save(self, path): 103 | success = self.remote.command("sensor/lidar/save", { 104 | "uid": self.uid, 105 | "path": path, 106 | }) 107 | return success 108 | 109 | 110 | class ImuSensor(Sensor): 111 | def __init__(self, remote, j): 112 | super().__init__(remote, j["uid"], j["name"]) 113 | 114 | 115 | class GpsSensor(Sensor): 116 | def __init__(self, remote, j): 117 | super().__init__(remote, j["uid"], j["name"]) 118 | self.frequency = j["frequency"] 119 | 120 | @property 121 | def data(self): 122 | j = self.remote.command("sensor/gps/data", {"uid": self.uid}) 123 | return GpsData(j["latitude"], j["longitude"], j["northing"], j["easting"], j["altitude"], j["orientation"]) 124 | 125 | 126 | class RadarSensor(Sensor): 127 | def __init__(self, remote, j): 128 | super().__init__(remote, j["uid"], j["name"]) 129 | 130 | 131 | class CanBusSensor(Sensor): 132 | def __init__(self, remote, j): 133 | super().__init__(remote, j["uid"], j["name"]) 134 | self.frequency = j["frequency"] 135 | 136 | 137 | class VideoRecordingSensor(Sensor): 138 | def __init__(self, remote, j): 139 | super().__init__(remote, j["uid"], j["name"]) 140 | self.width = j["width"] 141 | self.height = j["height"] 142 | self.framerate = j["framerate"] 143 | self.min_distance = j["near_plane"] 144 | self.max_distance = j["far_plane"] 145 | self.fov = j["fov"] 146 | self.quality = j["quality"] 147 | self.bitrate = j["bitrate"] 148 | self.max_bitrate = j["max_bitrate"] 149 | 150 | 151 | class AnalysisSensor(Sensor): 152 | def __init__(self, remote, j): 153 | super().__init__(remote, j["uid"], j["name"]) 154 | self.stucktravelthreshold = j["stucktravelthreshold"] 155 | self.stucktimethreshold = j["stucktimethreshold"] 156 | self.stoplinethreshold = j["stoplinethreshold"] 157 | -------------------------------------------------------------------------------- /lgsvl/utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .geometry import Vector, Transform 8 | 9 | import math 10 | import inspect 11 | 12 | 13 | def accepts(*types): 14 | def check_accepts(f): 15 | assert len(types) + 1 == f.__code__.co_argcount 16 | 17 | def new_f(*args, **kwargs): 18 | names = inspect.getfullargspec(f)[0] 19 | it = zip(args[1:], types, names[1:]) 20 | for (a, t, n) in it: 21 | if not isinstance(a, t): 22 | raise TypeError("Argument '{}' should have '{}' type".format(n, t)) 23 | return f(*args, **kwargs) 24 | new_f.__name__ = f.__name__ 25 | return new_f 26 | return check_accepts 27 | 28 | 29 | class ObjectState: 30 | def __init__(self, transform=None, velocity=None, angular_velocity=None): 31 | if transform is None: 32 | transform = Transform() 33 | if velocity is None: 34 | velocity = Vector() 35 | if angular_velocity is None: 36 | angular_velocity = Vector() 37 | self.transform = transform 38 | self.velocity = velocity 39 | self.angular_velocity = angular_velocity 40 | 41 | @property 42 | def position(self): 43 | return self.transform.position 44 | 45 | @property 46 | def rotation(self): 47 | return self.transform.rotation 48 | 49 | @property 50 | def speed(self): 51 | return math.sqrt( 52 | self.velocity.x * self.velocity.x 53 | + self.velocity.y * self.velocity.y 54 | + self.velocity.z * self.velocity.z 55 | ) 56 | 57 | @staticmethod 58 | def from_json(j): 59 | return ObjectState( 60 | Transform.from_json(j["transform"]), 61 | Vector.from_json(j["velocity"]), 62 | Vector.from_json(j["angular_velocity"]), 63 | ) 64 | 65 | def to_json(self): 66 | return { 67 | "transform": self.transform.to_json(), 68 | "velocity": self.velocity.to_json(), 69 | "angular_velocity": self.angular_velocity.to_json(), 70 | } 71 | 72 | def __repr__(self): 73 | return str( 74 | { 75 | "transform": str(self.transform), 76 | "velocity": str(self.velocity), 77 | "angular_velocity": str(self.angular_velocity), 78 | } 79 | ) 80 | 81 | 82 | def transform_to_matrix(tr): 83 | px = tr.position.x 84 | py = tr.position.y 85 | pz = tr.position.z 86 | 87 | ax = tr.rotation.x * math.pi / 180.0 88 | ay = tr.rotation.y * math.pi / 180.0 89 | az = tr.rotation.z * math.pi / 180.0 90 | 91 | sx, cx = math.sin(ax), math.cos(ax) 92 | sy, cy = math.sin(ay), math.cos(ay) 93 | sz, cz = math.sin(az), math.cos(az) 94 | 95 | # Unity uses left-handed coordinate system, Rz * Rx * Ry order 96 | return [ 97 | [sx * sy * sz + cy * cz, cx * sz, sx * cy * sz - sy * cz, 0.0], 98 | [sx * sy * cz - cy * sz, cx * cz, sy * sz + sx * cy * cz, 0.0], 99 | [cx * sy, -sx, cx * cy, 0.0], 100 | [px, py, pz, 1.0], 101 | ] 102 | 103 | 104 | def transform_to_forward(tr): 105 | ax = tr.rotation.x * math.pi / 180.0 106 | sx, cx = math.sin(ax), math.cos(ax) 107 | 108 | ay = tr.rotation.y * math.pi / 180.0 109 | sy, cy = math.sin(ay), math.cos(ay) 110 | 111 | return Vector(cx * sy, -sx, cx * cy) 112 | 113 | 114 | def transform_to_up(tr): 115 | ax = tr.rotation.x * math.pi / 180.0 116 | ay = tr.rotation.y * math.pi / 180.0 117 | az = tr.rotation.z * math.pi / 180.0 118 | 119 | sx, cx = math.sin(ax), math.cos(ax) 120 | sy, cy = math.sin(ay), math.cos(ay) 121 | sz, cz = math.sin(az), math.cos(az) 122 | 123 | return Vector(sx * sy * cz - cy * sz, cx * cz, sy * sz + sx * cy * cz) 124 | 125 | 126 | def transform_to_right(tr): 127 | ax = tr.rotation.x * math.pi / 180.0 128 | ay = tr.rotation.y * math.pi / 180.0 129 | az = tr.rotation.z * math.pi / 180.0 130 | 131 | sx, cx = math.sin(ax), math.cos(ax) 132 | sy, cy = math.sin(ay), math.cos(ay) 133 | sz, cz = math.sin(az), math.cos(az) 134 | 135 | return Vector(sx * sy * sz + cy * cz, cx * sz, sx * cy * sz - sy * cz) 136 | 137 | 138 | def vector_dot(a, b): 139 | return a.x * b.x + a.y * b.y + a.z * b.z 140 | 141 | 142 | # this works only with transformation matrices (no scaling, no projection) 143 | def matrix_inverse(m): 144 | x = Vector(m[0][0], m[0][1], m[0][2]) 145 | y = Vector(m[1][0], m[1][1], m[1][2]) 146 | z = Vector(m[2][0], m[2][1], m[2][2]) 147 | v = Vector(m[3][0], m[3][1], m[3][2]) 148 | a = -vector_dot(v, x) 149 | b = -vector_dot(v, y) 150 | c = -vector_dot(v, z) 151 | return [ 152 | [x.x, y.x, z.x, 0.0], 153 | [x.y, y.y, z.y, 0.0], 154 | [x.z, y.z, z.z, 0.0], 155 | [a, b, c, 1.0], 156 | ] 157 | 158 | 159 | def matrix_multiply(a, b): 160 | r = [[0, 0, 0, 0] for t in range(4)] 161 | for i in range(4): 162 | for j in range(4): 163 | for k in range(4): 164 | r[i][j] += a[i][k] * b[k][j] 165 | return r 166 | 167 | 168 | def vector_multiply(v, m): 169 | tmp = [None] * 3 170 | for i in range(3): 171 | tmp[i] = v.x * m[0][i] + v.y * m[1][i] + v.z * m[2][i] + m[3][i] 172 | return Vector(tmp[0], tmp[1], tmp[2]) 173 | -------------------------------------------------------------------------------- /lgsvl/wise/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | from .wise import DefaultAssets, SimulatorSettings 8 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | lgsvl 5 | 2021.1.0 6 | A Python API for SVL Simulator 7 | Hadi Tabatabaee 8 | Other 9 | 10 | python3-environs-pip 11 | python3-numpy 12 | python3-websocket 13 | python3-websockets 14 | 15 | 16 | ament_python 17 | 18 | 19 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | # get_version() in setup.py requires GitPython. 3 | requires = ["setuptools", "wheel", "GitPython==3.1.14"] 4 | -------------------------------------------------------------------------------- /quickstart/01-connecting-to-simulator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #1: Connecting to the Simulator") 12 | env = Env() 13 | 14 | # Connects to the simulator instance at the ip defined by LGSVL__SIMULATOR_HOST, default is localhost or 127.0.0.1 15 | # env.str() is equivalent to os.environ.get() 16 | # env.int() is equivalent to int(os.environ.get()) 17 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 18 | 19 | print("Version =", sim.version) 20 | print("Current Time =", sim.current_time) 21 | print("Current Frame =", sim.current_frame) 22 | -------------------------------------------------------------------------------- /quickstart/02-loading-scene-show-spawns.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #2: Loading the scene spawn points") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | 16 | print("Current Scene = {}".format(sim.current_scene)) 17 | 18 | # Loads the named map in the connected simulator. The available maps can be set up in web interface 19 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 20 | sim.reset() 21 | else: 22 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 23 | 24 | print("Current Scene = {}".format(sim.current_scene)) 25 | print("Current Scene ID = {}".format(sim.current_scene_id)) 26 | 27 | # This will print out the position and rotation vectors for each of the spawn points in the loaded map 28 | spawns = sim.get_spawn() 29 | for spawn in sim.get_spawn(): 30 | print(spawn) 31 | -------------------------------------------------------------------------------- /quickstart/03-raycast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #3: Using raycasts in the Simulator") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | # The next few lines spawns an EGO vehicle in the map 21 | spawns = sim.get_spawn() 22 | 23 | state = lgsvl.AgentState() 24 | state.transform = spawns[0] 25 | forward = lgsvl.utils.transform_to_forward(state.transform) 26 | right = lgsvl.utils.transform_to_right(state.transform) 27 | up = lgsvl.utils.transform_to_up(state.transform) 28 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | # This is the point from which the rays will originate from. It is raised 1m from the ground 31 | p = spawns[0].position 32 | p.y += 1 33 | 34 | # use layers property to get all layers used in simulator 35 | # useful bits in layer mask 36 | # 0 - Default (road & ground) 37 | # 9 - EGO vehicles 38 | # 10 - NPC vehicles 39 | # 11 - Pedestrian 40 | # 12 - Obstacle 41 | layers = sim.layers 42 | print(layers) 43 | 44 | # Included layers can be hit by the rays. Otherwise the ray will go through the layer 45 | layer_mask = 0 46 | tohitlayers = ["Default", "NPC", "Pedestrian", "Obstacle"] 47 | for layer in tohitlayers: 48 | layer_mask |= 1 << layers[layer] 49 | 50 | # raycast returns None if the ray doesn't collide with anything 51 | # hit also has the point property which is the Unity position vector of where the ray collided with something 52 | hit = sim.raycast(p, right, layer_mask) 53 | if hit: 54 | print("Distance right:", hit.distance) 55 | 56 | hit = sim.raycast(p, -right, layer_mask) 57 | if hit: 58 | print("Distance left:", hit.distance) 59 | 60 | hit = sim.raycast(p, -forward, layer_mask) 61 | if hit: 62 | print("Distance back:", hit.distance) 63 | 64 | hit = sim.raycast(p, forward, layer_mask) 65 | if hit: 66 | print("Distance forward:", hit.distance) 67 | 68 | hit = sim.raycast(p, up, layer_mask) 69 | if hit: 70 | print("Distance up:", hit.distance) 71 | 72 | hit = sim.raycast(p, -up, layer_mask) 73 | if hit: 74 | print("Distance down:", hit.distance) 75 | -------------------------------------------------------------------------------- /quickstart/04-ego-drive-straight.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #4: Ego vehicle driving straight") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | 25 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 26 | 27 | # Agents can be spawned with a velocity. Default is to spawn with 0 velocity 28 | state.velocity = 20 * forward 29 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 30 | 31 | # The bounding box of an agent are 2 points (min and max) such that the box formed from those 2 points completely encases the agent 32 | print("Vehicle bounding box =", ego.bounding_box) 33 | 34 | print("Current time = ", sim.current_time) 35 | print("Current frame = ", sim.current_frame) 36 | 37 | input("Press Enter to drive forward for 2 seconds") 38 | 39 | # The simulator can be run for a set amount of time. time_limit is optional and if omitted or set to 0, then the simulator will run indefinitely 40 | sim.run(time_limit=2.0) 41 | 42 | print("Current time = ", sim.current_time) 43 | print("Current frame = ", sim.current_frame) 44 | 45 | input("Press Enter to continue driving for 2 seconds") 46 | 47 | sim.run(time_limit=2.0) 48 | 49 | print("Current time = ", sim.current_time) 50 | print("Current frame = ", sim.current_frame) 51 | -------------------------------------------------------------------------------- /quickstart/05-ego-drive-in-circle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #5: Ego vehicle driving in circle") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 25 | state.transform.position += 5 * forward # 5m forwards 26 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 27 | 28 | print("Current time = ", sim.current_time) 29 | print("Current frame = ", sim.current_frame) 30 | 31 | input("Press Enter to start driving for 30 seconds") 32 | 33 | # VehicleControl objects can only be applied to EGO vehicles 34 | # You can set the steering (-1 ... 1), throttle and braking (0 ... 1), handbrake and reverse (bool) 35 | c = lgsvl.VehicleControl() 36 | c.throttle = 0.3 37 | c.steering = -1.0 38 | # a True in apply_control means the control will be continuously applied ("sticky"). False means the control will be applied for 1 frame 39 | ego.apply_control(c, True) 40 | 41 | sim.run(30) 42 | -------------------------------------------------------------------------------- /quickstart/06-save-camera-image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #6: Saving an image from the Main Camera sensor") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 25 | 26 | # get_sensors returns a list of sensors on the EGO vehicle 27 | sensors = ego.get_sensors() 28 | for s in sensors: 29 | if s.name == "Main Camera": 30 | # Camera and LIDAR sensors can save data to the specified file path 31 | s.save("main-camera.png", compression=0) 32 | s.save("main-camera.jpg", quality=75) 33 | break 34 | -------------------------------------------------------------------------------- /quickstart/07-save-lidar-point-cloud.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #7: Saving a point cloud from the Lidar sensor") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 25 | 26 | sensors = ego.get_sensors() 27 | for s in sensors: 28 | if s.name == "Lidar": 29 | s.save("lidar.pcd") 30 | break 31 | -------------------------------------------------------------------------------- /quickstart/08-create-npc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #8: Creating various NPCs") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 25 | 26 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 27 | right = lgsvl.utils.transform_to_right(spawns[0]) 28 | 29 | # Spawns one of each of the listed types of NPCS 30 | # The first will be created in front of the EGO and then they will be created to the left 31 | # The available types of NPCs can be found in NPCManager prefab 32 | for i, name in enumerate(["Sedan", "SUV", "Jeep", "Hatchback"]): 33 | state = lgsvl.AgentState() 34 | 35 | # Spawn NPC vehicles 10 meters ahead of the EGO 36 | state.transform.position = spawns[0].position + (10 * forward) - (4.0 * i * right) 37 | state.transform.rotation = spawns[0].rotation 38 | sim.add_agent(name, lgsvl.AgentType.NPC, state) 39 | -------------------------------------------------------------------------------- /quickstart/09-reset-scene.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import random 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #9: Resetting the scene to it's initial state") 13 | env = Env() 14 | 15 | random.seed(0) 16 | 17 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 18 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 19 | sim.reset() 20 | else: 21 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 22 | 23 | spawns = sim.get_spawn() 24 | 25 | state = lgsvl.AgentState() 26 | state.transform = spawns[0] 27 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 28 | 29 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 30 | right = lgsvl.utils.transform_to_right(spawns[0]) 31 | 32 | for i, name in enumerate(["Sedan", "SUV", "Jeep", "Hatchback"]): 33 | state = lgsvl.AgentState() 34 | # 10 meters ahead 35 | state.transform.position = spawns[0].position + (10 * forward) - (4.0 * i * right) 36 | state.transform.rotation = spawns[0].rotation 37 | sim.add_agent(name, lgsvl.AgentType.NPC, state) 38 | 39 | input("Press Enter to reset") 40 | 41 | # Reset will remove any spawned vehicles and set the weather back to default, but will keep the scene loaded 42 | sim.reset() 43 | -------------------------------------------------------------------------------- /quickstart/10-npc-follow-the-lane.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #10: NPC following the lane") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 25 | 26 | state = lgsvl.AgentState() 27 | 28 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 29 | right = lgsvl.utils.transform_to_right(spawns[0]) 30 | 31 | # 10 meters ahead, on left lane 32 | state.transform.position = spawns[0].position + 10.0 * forward 33 | state.transform.rotation = spawns[0].rotation 34 | 35 | npc1 = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 36 | 37 | state = lgsvl.AgentState() 38 | 39 | # 10 meters ahead, on right lane 40 | state.transform.position = spawns[0].position + 4.0 * right + 10.0 * forward 41 | state.transform.rotation = spawns[0].rotation 42 | 43 | npc2 = sim.add_agent("SUV", lgsvl.AgentType.NPC, state, lgsvl.Vector(1, 1, 0)) 44 | 45 | # If the passed bool is False, then the NPC will not moved 46 | # The float passed is the maximum speed the NPC will drive 47 | # 11.1 m/s is ~40 km/h 48 | npc1.follow_closest_lane(True, 11.1) 49 | 50 | # 5.6 m/s is ~20 km/h 51 | npc2.follow_closest_lane(True, 5.6) 52 | 53 | input("Press Enter to run the simulation for 40 seconds") 54 | 55 | sim.run(40) 56 | -------------------------------------------------------------------------------- /quickstart/11-collision-callbacks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #11: Handling the collision callbacks") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 22 | right = lgsvl.utils.transform_to_right(spawns[0]) 23 | 24 | # ego vehicle 25 | state = lgsvl.AgentState() 26 | state.transform = spawns[0] 27 | state.velocity = 6 * forward 28 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | # school bus, 20m ahead, perpendicular to road, stopped 31 | state = lgsvl.AgentState() 32 | state.transform.position = spawns[0].position + 20.0 * forward 33 | state.transform.rotation.y = spawns[0].rotation.y + 90.0 34 | bus = sim.add_agent("SchoolBus", lgsvl.AgentType.NPC, state) 35 | 36 | # sedan, 10m ahead, driving forward 37 | state = lgsvl.AgentState() 38 | state.transform.position = spawns[0].position + 10.0 * forward 39 | state.transform.rotation = spawns[0].rotation 40 | sedan = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 41 | # Even though the sedan is commanded to follow the lane, obstacle avoidance takes precedence and it will not drive into the bus 42 | sedan.follow_closest_lane(True, 11.1) # 11.1 m/s is ~40 km/h 43 | 44 | vehicles = { 45 | ego: "EGO", 46 | bus: "SchoolBus", 47 | sedan: "Sedan", 48 | } 49 | 50 | 51 | # This function gets called whenever any of the 3 vehicles above collides with anything 52 | def on_collision(agent1, agent2, contact): 53 | name1 = vehicles[agent1] 54 | name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE" 55 | print("{} collided with {} at {}".format(name1, name2, contact)) 56 | 57 | 58 | # The above on_collision function needs to be added to the callback list of each vehicle 59 | ego.on_collision(on_collision) 60 | bus.on_collision(on_collision) 61 | sedan.on_collision(on_collision) 62 | 63 | input("Press Enter to run the simulation for 10 seconds") 64 | 65 | # Drive into the sedan, bus, or obstacle to get a callback 66 | sim.run(10) 67 | -------------------------------------------------------------------------------- /quickstart/12-create-npc-on-lane.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import math 9 | import random 10 | from environs import Env 11 | import lgsvl 12 | 13 | print("Python API Quickstart #12: Creating NPCs on lanes") 14 | env = Env() 15 | 16 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 17 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 18 | sim.reset() 19 | else: 20 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 21 | 22 | spawns = sim.get_spawn() 23 | 24 | state = lgsvl.AgentState() 25 | state.transform = spawns[0] 26 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 27 | 28 | sx = spawns[0].position.x 29 | sy = spawns[0].position.y 30 | sz = spawns[0].position.z 31 | 32 | mindist = 10.0 33 | maxdist = 40.0 34 | 35 | random.seed(0) 36 | 37 | print("Spawn 10 random NPCs on lanes") 38 | for i in range(10): 39 | input("Press Enter to spawn NPC ({})".format(i + 1)) 40 | 41 | # Creates a random point around the EGO 42 | angle = random.uniform(0.0, 2 * math.pi) 43 | dist = random.uniform(mindist, maxdist) 44 | 45 | point = lgsvl.Vector(sx + dist * math.cos(angle), sy, sz + dist * math.sin(angle)) 46 | 47 | # Creates an NPC on a lane that is closest to the random point 48 | state = lgsvl.AgentState() 49 | state.transform = sim.map_point_on_lane(point) 50 | sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 51 | -------------------------------------------------------------------------------- /quickstart/13-npc-follow-waypoints.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import copy 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #13: NPC following waypoints") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 17 | sim.reset() 18 | else: 19 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 20 | 21 | spawns = sim.get_spawn() 22 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 23 | right = lgsvl.utils.transform_to_right(spawns[0]) 24 | 25 | # Creating state object to define state for Ego and NPC 26 | state = lgsvl.AgentState() 27 | state.transform = spawns[0] 28 | 29 | # Ego 30 | ego_state = copy.deepcopy(state) 31 | ego_state.transform.position += 50 * forward 32 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 33 | 34 | # NPC 35 | npc_state = copy.deepcopy(state) 36 | npc_state.transform.position += 10 * forward 37 | npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, npc_state) 38 | 39 | vehicles = { 40 | ego: "EGO", 41 | npc: "Sedan", 42 | } 43 | 44 | 45 | # Executed upon receiving collision callback -- NPC is expected to drive through colliding objects 46 | def on_collision(agent1, agent2, contact): 47 | name1 = vehicles[agent1] 48 | name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE" 49 | print("{} collided with {}".format(name1, name2)) 50 | 51 | 52 | ego.on_collision(on_collision) 53 | npc.on_collision(on_collision) 54 | 55 | # This block creates the list of waypoints that the NPC will follow 56 | # Each waypoint is an position vector paired with the speed that the NPC will drive to it 57 | waypoints = [] 58 | x_max = 2 59 | z_delta = 12 60 | 61 | layer_mask = 0 62 | layer_mask |= 1 << 0 # 0 is the layer for the road (default) 63 | 64 | for i in range(20): 65 | speed = 24 # if i % 2 == 0 else 12 66 | px = 0 67 | pz = (i + 1) * z_delta 68 | # Waypoint angles are input as Euler angles (roll, pitch, yaw) 69 | angle = spawns[0].rotation 70 | # Raycast the points onto the ground because BorregasAve is not flat 71 | hit = sim.raycast( 72 | spawns[0].position + pz * forward, lgsvl.Vector(0, -1, 0), layer_mask 73 | ) 74 | 75 | # NPC will wait for 1 second at each waypoint 76 | wp = lgsvl.DriveWaypoint(hit.point, speed, angle=angle, idle=1) 77 | waypoints.append(wp) 78 | 79 | 80 | # When the NPC is within 0.5m of the waypoint, this will be called 81 | def on_waypoint(agent, index): 82 | print("waypoint {} reached".format(index)) 83 | 84 | 85 | # The above function needs to be added to the list of callbacks for the NPC 86 | npc.on_waypoint_reached(on_waypoint) 87 | 88 | # The NPC needs to be given the list of waypoints. 89 | # A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false) 90 | npc.follow(waypoints) 91 | 92 | input("Press Enter to run the simulation for 30 seconds") 93 | 94 | sim.run(30) 95 | -------------------------------------------------------------------------------- /quickstart/14-create-pedestrians.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import random 9 | import time 10 | from environs import Env 11 | import lgsvl 12 | 13 | print("Python API Quickstart #14: Creating pedestrians on the map") 14 | env = Env() 15 | 16 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 17 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 18 | sim.reset() 19 | else: 20 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 21 | 22 | spawns = sim.get_spawn() 23 | 24 | state = lgsvl.AgentState() 25 | state.transform = spawns[0] 26 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 27 | right = lgsvl.utils.transform_to_right(spawns[0]) 28 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | input("Press Enter to create 100 pedestrians") 31 | 32 | # The list of available pedestrians can be found in PedestrianManager prefab 33 | names = [ 34 | "Bob", 35 | "EntrepreneurFemale", 36 | "Howard", 37 | "Johny", 38 | "Pamela", 39 | "Presley", 40 | "Robin", 41 | "Stephen", 42 | "Zoe", 43 | ] 44 | 45 | i = 0 46 | while i < 100: 47 | state = lgsvl.AgentState() 48 | 49 | state.transform.position = ( 50 | spawns[0].position 51 | + (5 + (1.0 * (i // 16))) * forward 52 | + (5 - (1.0 * (i % 16))) * right 53 | ) 54 | state.transform.rotation = spawns[0].rotation 55 | name = random.choice(names) 56 | print("({}) adding {}".format(i + 1, name)) 57 | p = sim.add_agent(name, lgsvl.AgentType.PEDESTRIAN, state) 58 | time.sleep(0.1) 59 | i += 1 60 | -------------------------------------------------------------------------------- /quickstart/15-pedestrian-walk-randomly.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #15: Pedestrian walking randomly") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 22 | right = lgsvl.utils.transform_to_right(spawns[0]) 23 | 24 | state = lgsvl.AgentState() 25 | state.transform.position = spawns[0].position + 40 * forward 26 | state.transform.rotation = spawns[0].rotation 27 | 28 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | state = lgsvl.AgentState() 31 | # Spawn the pedestrian in front of car 32 | state.transform.position = spawns[0].position + 50 * forward 33 | state.transform.rotation = spawns[0].rotation 34 | 35 | p = sim.add_agent("Bob", lgsvl.AgentType.PEDESTRIAN, state) 36 | # Pedestrian will walk to a random point on sidewalk 37 | p.walk_randomly(True) 38 | 39 | input("Press Enter to walk") 40 | 41 | sim.run(10) 42 | 43 | input("Press Enter to stop") 44 | # With walk_randomly passed False, pedestrian will stop walking 45 | p.walk_randomly(False) 46 | 47 | sim.run(5) 48 | -------------------------------------------------------------------------------- /quickstart/16-pedestrian-follow-waypoints.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import math 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #16: Pedestrian following waypoints") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 17 | sim.reset() 18 | else: 19 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 20 | 21 | spawns = sim.get_spawn() 22 | forward = lgsvl.utils.transform_to_forward(spawns[1]) 23 | right = lgsvl.utils.transform_to_right(spawns[1]) 24 | 25 | state = lgsvl.AgentState() 26 | state.transform = spawns[1] 27 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 28 | 29 | # This will create waypoints in a circle for the pedestrian to follow 30 | radius = 4 31 | count = 8 32 | wp = [] 33 | for i in range(count): 34 | x = radius * math.cos(i * 2 * math.pi / count) 35 | z = radius * math.sin(i * 2 * math.pi / count) 36 | # idle is how much time the pedestrian will wait once it reaches the waypoint 37 | idle = 1 if i < count // 2 else 0 38 | wp.append( 39 | lgsvl.WalkWaypoint(spawns[1].position + x * right + (z + 8) * forward, idle) 40 | ) 41 | 42 | state = lgsvl.AgentState() 43 | state.transform = spawns[1] 44 | state.transform.position = wp[0].position 45 | 46 | p = sim.add_agent("Pamela", lgsvl.AgentType.PEDESTRIAN, state) 47 | 48 | 49 | def on_waypoint(agent, index): 50 | print("Waypoint {} reached".format(index)) 51 | 52 | 53 | p.on_waypoint_reached(on_waypoint) 54 | 55 | # This sends the list of waypoints to the pedestrian. The bool controls whether or not the pedestrian will continue walking (default false) 56 | p.follow(wp, True) 57 | 58 | input("Press Enter to walk in circle for 60 seconds") 59 | 60 | sim.run(60) 61 | -------------------------------------------------------------------------------- /quickstart/17-many-pedestrians-walking.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import random 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #17: Many pedestrians walking simultaneously") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 17 | sim.reset() 18 | else: 19 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 20 | 21 | spawns = sim.get_spawn() 22 | 23 | state = lgsvl.AgentState() 24 | state.transform = spawns[0] 25 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 26 | right = lgsvl.utils.transform_to_right(spawns[0]) 27 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 28 | 29 | names = [ 30 | "Bob", 31 | "EntrepreneurFemale", 32 | "Howard", 33 | "Johny", 34 | "Pamela", 35 | "Presley", 36 | "Robin", 37 | "Stephen", 38 | "Zoe", 39 | ] 40 | 41 | print("Creating 120 pedestrians") 42 | for i in range(20 * 6): 43 | # Create peds in a block 44 | start = ( 45 | spawns[0].position 46 | + (5 + (1.0 * (i // 6))) * forward 47 | - (2 + (1.0 * (i % 6))) * right 48 | ) 49 | end = start + 10 * forward 50 | 51 | # Give waypoints for the spawn location and 10m ahead 52 | wp = [lgsvl.WalkWaypoint(start, 0), lgsvl.WalkWaypoint(end, 0)] 53 | 54 | state = lgsvl.AgentState() 55 | state.transform.position = start 56 | state.transform.rotation = spawns[0].rotation 57 | name = random.choice(names) 58 | 59 | # Send the waypoints and make the pedestrian loop over the waypoints 60 | p = sim.add_agent(name, lgsvl.AgentType.PEDESTRIAN, state) 61 | p.follow(wp, True) 62 | 63 | input("Press Enter to start the simulation for 30 seconds") 64 | sim.run(30) 65 | -------------------------------------------------------------------------------- /quickstart/18-weather-effects.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #18: Changing the weather effects") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[0] 24 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 25 | 26 | print(sim.weather) 27 | 28 | input("Press Enter to set rain to 80%") 29 | 30 | # Each weather variable is a float from 0 to 1 31 | # There is no default value so each varible must be specified 32 | sim.weather = lgsvl.WeatherState(rain=0.8, fog=0, wetness=0, cloudiness=0, damage=0) 33 | print(sim.weather) 34 | 35 | sim.run(5) 36 | 37 | input("Press Enter to set fog to 50%") 38 | 39 | sim.weather = lgsvl.WeatherState(rain=0, fog=0.5, wetness=0, cloudiness=0, damage=0) 40 | print(sim.weather) 41 | 42 | sim.run(5) 43 | 44 | input("Press Enter to set wetness to 50%") 45 | 46 | sim.weather = lgsvl.WeatherState(rain=0, fog=0, wetness=0.5, cloudiness=0, damage=0) 47 | print(sim.weather) 48 | 49 | sim.run(5) 50 | 51 | input("Press Enter to reset to 0") 52 | 53 | sim.weather = lgsvl.WeatherState(rain=0, fog=0, wetness=0, cloudiness=0, damage=0) 54 | print(sim.weather) 55 | 56 | sim.run(5) 57 | -------------------------------------------------------------------------------- /quickstart/19-time-of-day.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | from datetime import datetime 11 | 12 | print("Python API Quickstart #19: Changing the time of day") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 17 | sim.reset() 18 | else: 19 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 20 | 21 | spawns = sim.get_spawn() 22 | 23 | state = lgsvl.AgentState() 24 | state.transform = spawns[0] 25 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 26 | 27 | print("Current time:", sim.time_of_day) 28 | 29 | input("Press Enter to set fixed time to 19:00") 30 | 31 | # Time of day can be set from 0 ... 24 32 | sim.set_time_of_day(19.0) 33 | print(sim.time_of_day) 34 | 35 | sim.run(5) 36 | 37 | input("Press Enter to set normal time to 10:30") 38 | # Normal time moves forward (at an accelerated rate). Pass False to set_time_of_day for this to happen 39 | sim.set_time_of_day(10.5, False) 40 | print(sim.time_of_day) 41 | 42 | sim.run(5) 43 | 44 | print(sim.time_of_day) 45 | 46 | input("Press Enter to set date to July 1 2020 and time to 19:00") 47 | dt = datetime(2020, 7, 1, 19, 0, 0, 0) 48 | sim.set_date_time(dt, False) 49 | print(sim.time_of_day) 50 | print(sim.current_datetime) 51 | 52 | sim.run(5) 53 | 54 | print(sim.time_of_day) 55 | print(sim.current_datetime) 56 | -------------------------------------------------------------------------------- /quickstart/20-enable-sensors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #20: Enabling and disabling sensors") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | state.transform = spawns[1] 24 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 25 | 26 | sensors = ego.get_sensors() 27 | 28 | # Sensors have an enabled/disabled state that can be set 29 | # By default all sensors are enabled 30 | # Disabling sensor will prevent it to send or receive messages to ROS or Cyber bridges 31 | lidarAvailable = False 32 | for s in sensors: 33 | print(type(s), s.enabled) 34 | if isinstance(s, lgsvl.LidarSensor): 35 | lidarAvailable = True 36 | 37 | if lidarAvailable: 38 | input("Press Enter to disable LiDAR") 39 | 40 | for s in sensors: 41 | if isinstance(s, lgsvl.LidarSensor): 42 | s.enabled = False 43 | 44 | for s in sensors: 45 | print(type(s), s.enabled) 46 | else: 47 | print("LiDAR sensor is not included in the selected sensor configuration. Please check the \"ego_lincoln2017mkz_apollo5\" sensor configuration in the default assets.") 48 | input("Press Enter to stop the simulation") 49 | -------------------------------------------------------------------------------- /quickstart/21-map-coordinates.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #21: Converting the map coordinates") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | tr = spawns[0] 23 | print("Default transform: {}".format(tr)) 24 | 25 | # There are functions to convert to and from GPS coordingates 26 | # This function takes position and rotation vectors and outputs the equivalent GPS coordinates 27 | gps = sim.map_to_gps(tr) 28 | print("GPS coordinates: {}".format(gps)) 29 | 30 | # This function can take either lat/long or northing/easting pairs as inputs and will provide equivalent position and rotation vectors 31 | # Altitude and orientation are optional 32 | t1 = sim.map_from_gps( 33 | northing=gps.northing, 34 | easting=gps.easting, 35 | altitude=gps.altitude, 36 | orientation=gps.orientation, 37 | ) 38 | print("Transform from northing/easting: {}".format(t1)) 39 | 40 | t2 = sim.map_from_gps(latitude=gps.latitude, longitude=gps.longitude) 41 | print("Transform from lat/long without altitude/orientation: {}".format(t2)) 42 | -------------------------------------------------------------------------------- /quickstart/22-connecting-bridge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import time 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #22: Connecting to a bridge") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 17 | sim.reset() 18 | else: 19 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 20 | 21 | spawns = sim.get_spawn() 22 | 23 | state = lgsvl.AgentState() 24 | state.transform = spawns[0] 25 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 26 | 27 | # An EGO will not connect to a bridge unless commanded to 28 | print("Bridge connected:", ego.bridge_connected) 29 | 30 | # The EGO is now looking for a bridge at the specified IP and port 31 | ego.connect_bridge(env.str("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host), env.int("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 32 | 33 | print("Waiting for connection...") 34 | 35 | while not ego.bridge_connected: 36 | time.sleep(1) 37 | 38 | print("Bridge connected:", ego.bridge_connected) 39 | print("Running the simulation for 30 seconds") 40 | 41 | sim.run(30) 42 | -------------------------------------------------------------------------------- /quickstart/23-npc-callbacks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import math 9 | import random 10 | from environs import Env 11 | import lgsvl 12 | 13 | print("Python API Quickstart #23: Handling NPCs callbacks") 14 | env = Env() 15 | 16 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 17 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 18 | sim.reset() 19 | else: 20 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 21 | 22 | spawns = sim.get_spawn() 23 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 24 | right = lgsvl.utils.transform_to_right(spawns[0]) 25 | 26 | state = lgsvl.AgentState() 27 | state.transform = sim.map_point_on_lane(spawns[0].position + 200 * forward) 28 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | mindist = 10.0 31 | maxdist = 40.0 32 | 33 | random.seed(0) 34 | 35 | 36 | # Along with collisions and waypoints, NPCs can send a callback when they change lanes and reach a stopline 37 | def on_stop_line(agent): 38 | print(agent.name, "reached stop line") 39 | 40 | 41 | # This will be called when an NPC begins to change lanes 42 | def on_lane_change(agent): 43 | print(agent.name, "is changing lanes") 44 | 45 | 46 | # This creates 4 NPCs randomly in an area around the EGO 47 | for name in ["Sedan", "SUV", "Jeep", "Hatchback"]: 48 | angle = random.uniform(0.0, 2 * math.pi) 49 | dist = random.uniform(mindist, maxdist) 50 | 51 | point = ( 52 | spawns[0].position 53 | + dist * math.sin(angle) * right 54 | + (225 + dist * math.cos(angle)) * forward 55 | ) 56 | 57 | state = lgsvl.AgentState() 58 | state.transform = sim.map_point_on_lane(point) 59 | npc = sim.add_agent(name, lgsvl.AgentType.NPC, state) 60 | npc.follow_closest_lane(True, 10) 61 | npc.on_lane_change(on_lane_change) 62 | npc.on_stop_line(on_stop_line) 63 | 64 | print("Running the simulation for 30 seconds.") 65 | sim.run(30) 66 | -------------------------------------------------------------------------------- /quickstart/24-ego-drive-straight-non-realtime.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import time 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #24: Changing the Simulator timescale") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 17 | sim.reset() 18 | else: 19 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 20 | 21 | spawns = sim.get_spawn() 22 | 23 | state = lgsvl.AgentState() 24 | state.transform = spawns[0] 25 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 26 | # Agents can be spawned with a velocity. Default is to spawn with 0 velocity 27 | state.velocity = 20 * forward 28 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | print("Real time elapsed =", 0) 31 | print("Simulation time =", sim.current_time) 32 | print("Simulation frames =", sim.current_frame) 33 | 34 | input("Press Enter to drive forward for 4 seconds (2x)") 35 | 36 | # The simulator can be run for a set amount of time. time_limit is optional and if omitted or set to 0, then the simulator will run indefinitely 37 | t0 = time.time() 38 | sim.run(time_limit=4, time_scale=2) 39 | t1 = time.time() 40 | print("Real time elapsed =", t1 - t0) 41 | print("Simulation time =", sim.current_time) 42 | print("Simulation frames =", sim.current_frame) 43 | 44 | current_sim_time = sim.current_time 45 | current_sim_frames = sim.current_frame 46 | 47 | input("Press Enter to continue driving for 2 more seconds (0.5x)") 48 | 49 | t2 = time.time() 50 | sim.run(time_limit=2, time_scale=0.5) 51 | t3 = time.time() 52 | 53 | print("Real time elapsed =", t3 - t2) 54 | print("Simulation time =", sim.current_time - current_sim_time) 55 | print("Simulation frames =", sim.current_frame - current_sim_frames) 56 | -------------------------------------------------------------------------------- /quickstart/25-waypoint-flying-npc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #25: NPC flying to waypoints") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | # EGO 23 | state = lgsvl.AgentState() 24 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 25 | right = lgsvl.utils.transform_to_right(spawns[0]) 26 | up = lgsvl.utils.transform_to_up(spawns[0]) 27 | state.transform = spawns[0] 28 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | # NPC 31 | state = lgsvl.AgentState() 32 | state.transform.position = spawns[0].position + 10 * forward 33 | state.transform.rotation = spawns[0].rotation 34 | npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 35 | 36 | # This block creates the list of waypoints that the NPC will follow 37 | # Each waypoint consists of a position vector, speed, and an angular orientation vector 38 | waypoints = [] 39 | z_delta = 12 40 | 41 | layer_mask = 0 42 | layer_mask |= 1 << 0 # 0 is the layer for the road (default) 43 | px = 0 44 | py = 0.5 45 | 46 | for i in range(75): 47 | speed = 6 48 | px = 0 49 | py = ((i + 1) * 0.05) if (i < 50) else (50 * 0.05 + (50 - i) * 0.05) 50 | pz = i * z_delta * 0.05 51 | 52 | angle = lgsvl.Vector(i, 0, 3 * i) 53 | 54 | # Raycast the points onto the ground because BorregasAve is not flat 55 | hit = sim.raycast( 56 | spawns[0].position + px * right + pz * forward, 57 | lgsvl.Vector(0, -1, 0), 58 | layer_mask, 59 | ) 60 | 61 | wp = lgsvl.DriveWaypoint( 62 | spawns[0].position + px * right + py * up + pz * forward, speed, angle, 0, 0 63 | ) 64 | waypoints.append(wp) 65 | 66 | 67 | # When the NPC is within 1m of the waypoint, this will be called 68 | def on_waypoint(agent, index): 69 | print("waypoint {} reached".format(index)) 70 | 71 | 72 | # The above function needs to be added to the list of callbacks for the NPC 73 | npc.on_waypoint_reached(on_waypoint) 74 | 75 | # The NPC needs to be given the list of waypoints. 76 | # A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false) 77 | npc.follow(waypoints) 78 | 79 | input("Press Enter to run the simulation for 12 seconds") 80 | 81 | sim.run(12) 82 | -------------------------------------------------------------------------------- /quickstart/26-npc-trigger-waypoints.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #26: NPC triggering the waypoints callbacks") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | # EGO 23 | state = lgsvl.AgentState() 24 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 25 | right = lgsvl.utils.transform_to_right(spawns[0]) 26 | state.transform = spawns[0] 27 | state.velocity = 12 * forward 28 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | # NPC 31 | state = lgsvl.AgentState() 32 | state.transform.position = spawns[0].position + 10 * forward 33 | state.transform.rotation = spawns[0].rotation 34 | npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 35 | 36 | vehicles = { 37 | ego: "EGO", 38 | npc: "Sedan", 39 | } 40 | 41 | 42 | # Executed upon receiving collision callback -- NPC is expected to drive through colliding objects 43 | def on_collision(agent1, agent2, contact): 44 | name1 = vehicles[agent1] 45 | name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE" 46 | print("{} collided with {}".format(name1, name2)) 47 | 48 | 49 | ego.on_collision(on_collision) 50 | npc.on_collision(on_collision) 51 | 52 | # This block creates the list of waypoints that the NPC will follow 53 | # Each waypoint is an position vector paired with the speed that the NPC will drive to it 54 | waypoints = [] 55 | z_delta = 12 56 | 57 | layer_mask = 0 58 | layer_mask |= 1 << 0 # 0 is the layer for the road (default) 59 | 60 | for i in range(20): 61 | speed = 24 # if i % 2 == 0 else 12 62 | px = 0 63 | pz = (i + 1) * z_delta 64 | # Waypoint angles are input as Euler angles (roll, pitch, yaw) 65 | angle = spawns[0].rotation 66 | # Raycast the points onto the ground because BorregasAve is not flat 67 | hit = sim.raycast( 68 | spawns[0].position + px * right + pz * forward, 69 | lgsvl.Vector(0, -1, 0), 70 | layer_mask, 71 | ) 72 | 73 | # Trigger is set to 10 meters for every other waypoint (0 means no trigger) 74 | tr = 0 75 | if i % 2: 76 | tr = 10 77 | wp = lgsvl.DriveWaypoint( 78 | position=hit.point, speed=speed, angle=angle, idle=0, trigger_distance=tr 79 | ) 80 | waypoints.append(wp) 81 | 82 | 83 | # When the NPC is within 0.5m of the waypoint, this will be called 84 | def on_waypoint(agent, index): 85 | print("waypoint {} reached, waiting for ego to get closer".format(index)) 86 | 87 | 88 | # The above function needs to be added to the list of callbacks for the NPC 89 | npc.on_waypoint_reached(on_waypoint) 90 | 91 | # The NPC needs to be given the list of waypoints. 92 | # A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false) 93 | npc.follow(waypoints) 94 | 95 | input("Press Enter to run simulation for 22 seconds") 96 | 97 | sim.run(22) 98 | -------------------------------------------------------------------------------- /quickstart/27-control-traffic-lights.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #27: How to Control Traffic Light") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave, 42) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 24 | state.transform = spawns[0] 25 | state.transform.position = spawns[0].position + 20 * forward 26 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 27 | 28 | # # Get a list of controllable objects 29 | controllables = sim.get_controllables("signal") 30 | print("\n# List of controllable objects in {} scene:".format(lgsvl.wise.DefaultAssets.map_borregasave)) 31 | for c in controllables: 32 | print(c) 33 | 34 | signal = sim.get_controllable(lgsvl.Vector(15.5, 4.7, -23.9), "signal") 35 | print("\n# Signal of interest:") 36 | print(signal) 37 | 38 | # Get current controllable states 39 | print("\n# Current control policy:") 40 | print(signal.control_policy) 41 | 42 | # Create a new control policy 43 | control_policy = "trigger=50;green=3;yellow=2;red=1;loop" 44 | 45 | # Control this traffic light with a new control policy 46 | signal.control(control_policy) 47 | 48 | print("\n# Updated control policy:") 49 | print(signal.control_policy) 50 | 51 | # Get current state of signal 52 | print("\n# Current signal state before simulation:") 53 | print(signal.current_state) 54 | 55 | seconds = 18 56 | input("\nPress Enter to run simulation for {} seconds".format(seconds)) 57 | print("\nRunning simulation for {} seconds...".format(seconds)) 58 | sim.run(seconds) 59 | 60 | print("\n# Current signal state after simulation:") 61 | print(signal.current_state) 62 | print("\nDone!") 63 | -------------------------------------------------------------------------------- /quickstart/28-control-traffic-cone.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2020-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #28: How to Add/Control Traffic Cone") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave, 42) 19 | 20 | spawns = sim.get_spawn() 21 | 22 | state = lgsvl.AgentState() 23 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 24 | right = lgsvl.utils.transform_to_right(spawns[0]) 25 | up = lgsvl.utils.transform_to_up(spawns[0]) 26 | state.transform = spawns[0] 27 | 28 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | for i in range(10 * 3): 31 | # Create controllables in a block 32 | start = ( 33 | spawns[0].position 34 | + (5 + (1.0 * (i // 6))) * forward 35 | - (2 + (1.0 * (i % 6))) * right 36 | ) 37 | end = start + 10 * forward 38 | 39 | state = lgsvl.ObjectState() 40 | state.transform.position = start 41 | state.transform.rotation = spawns[0].rotation 42 | # Set velocity and angular_velocity 43 | state.velocity = 10 * up 44 | state.angular_velocity = 6.5 * right 45 | 46 | # add controllable 47 | o = sim.controllable_add("TrafficCone", state) 48 | 49 | 50 | print("\nAdded {} Traffic Cones".format(i + 1)) 51 | 52 | seconds = 10 53 | input("\nPress Enter to run simulation for {} seconds".format(seconds)) 54 | print("\nRunning simulation for {} seconds...".format(seconds)) 55 | sim.run(seconds) 56 | 57 | print("\nDone!") 58 | -------------------------------------------------------------------------------- /quickstart/29-add-random-agents.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2020-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #29: Adding random agents to a simulation") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | spawns = sim.get_spawn() 21 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 22 | right = lgsvl.utils.transform_to_right(spawns[0]) 23 | 24 | state = lgsvl.AgentState() 25 | state.transform.position = spawns[0].position + 40 * forward 26 | state.transform.rotation = spawns[0].rotation 27 | 28 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 29 | 30 | sim.add_random_agents(lgsvl.AgentType.NPC) 31 | sim.add_random_agents(lgsvl.AgentType.PEDESTRIAN) 32 | 33 | input("Press Enter to start the simulation for 30 seconds") 34 | 35 | sim.run(30) 36 | -------------------------------------------------------------------------------- /quickstart/30-time-to-collision-trigger.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2020-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #30: Using the time to collision trigger") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave, 42) 19 | 20 | spawns = sim.get_spawn() 21 | layer_mask = 0 22 | layer_mask |= 1 << 0 # 0 is the layer for the road (default) 23 | 24 | # EGO 25 | state = lgsvl.AgentState() 26 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 27 | right = lgsvl.utils.transform_to_right(spawns[0]) 28 | spawn_state = spawns[0] 29 | hit = sim.raycast( 30 | spawn_state.position + forward * 40, lgsvl.Vector(0, -1, 0), layer_mask 31 | ) 32 | spawn_state.position = hit.point 33 | state.transform = spawn_state 34 | state.velocity = forward * 2 35 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 36 | 37 | # NPC 38 | state = lgsvl.AgentState() 39 | npc_position = lgsvl.Vector(-4, -1, -48) 40 | hit = sim.raycast(npc_position, lgsvl.Vector(0, -1, 0), layer_mask) 41 | npc_rotation = lgsvl.Vector(0, 16, 0) 42 | state.transform.position = hit.point 43 | state.transform.rotation = npc_rotation 44 | npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 45 | 46 | vehicles = { 47 | ego: "EGO", 48 | npc: "Sedan", 49 | } 50 | 51 | 52 | # Executed upon receiving collision callback -- NPC is expected to drive through colliding objects 53 | def on_collision(agent1, agent2, contact): 54 | name1 = vehicles[agent1] 55 | name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE" 56 | print("{} collided with {}".format(name1, name2)) 57 | 58 | 59 | ego.on_collision(on_collision) 60 | npc.on_collision(on_collision) 61 | 62 | # This block creates the list of waypoints that the NPC will follow 63 | # Each waypoint is an position vector paired with the speed that the NPC will drive to it 64 | waypoints = [] 65 | 66 | for i in range(2): 67 | speed = 8 68 | # Waypoint angles are input as Euler angles (roll, pitch, yaw) 69 | angle = npc_rotation 70 | # Raycast the points onto the ground because BorregasAve is not flat 71 | npc_position.x += 6 72 | npc_position.z += 21 73 | hit = sim.raycast(npc_position, lgsvl.Vector(0, -1, 0), layer_mask) 74 | 75 | trigger = None 76 | if i == 0: 77 | effector = lgsvl.TriggerEffector("TimeToCollision", {}) 78 | trigger = lgsvl.WaypointTrigger([effector]) 79 | wp = lgsvl.DriveWaypoint( 80 | position=hit.point, 81 | speed=speed, 82 | angle=angle, 83 | idle=0, 84 | trigger_distance=0, 85 | trigger=trigger, 86 | ) 87 | waypoints.append(wp) 88 | 89 | 90 | def on_waypoint(agent, index): 91 | print("waypoint {} reached".format(index)) 92 | 93 | 94 | def agents_traversed_waypoints(): 95 | print("All agents traversed their waypoints.") 96 | sim.stop() 97 | 98 | 99 | # The above function needs to be added to the list of callbacks for the NPC 100 | npc.on_waypoint_reached(on_waypoint) 101 | sim.agents_traversed_waypoints(agents_traversed_waypoints) 102 | 103 | # The NPC needs to be given the list of waypoints. 104 | # A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false) 105 | npc.follow(waypoints) 106 | 107 | input("Press Enter to run") 108 | 109 | sim.run() 110 | -------------------------------------------------------------------------------- /quickstart/31-wait-for-distance-trigger.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2020-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #31: Using the wait for distance trigger") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave, 42) 19 | 20 | spawns = sim.get_spawn() 21 | layer_mask = 0 22 | layer_mask |= 1 << 0 # 0 is the layer for the road (default) 23 | 24 | # EGO 25 | state = lgsvl.AgentState() 26 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 27 | right = lgsvl.utils.transform_to_right(spawns[0]) 28 | spawn_state = spawns[0] 29 | hit = sim.raycast( 30 | spawn_state.position + forward * 40, lgsvl.Vector(0, -1, 0), layer_mask 31 | ) 32 | spawn_state.position = hit.point 33 | state.transform = spawn_state 34 | state.velocity = forward * 2 35 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 36 | 37 | # NPC 38 | state = lgsvl.AgentState() 39 | npc_position = lgsvl.Vector(-4, -1, -48) 40 | hit = sim.raycast(npc_position, lgsvl.Vector(0, -1, 0), layer_mask) 41 | npc_rotation = lgsvl.Vector(0, 16, 0) 42 | state.transform.position = hit.point 43 | state.transform.rotation = npc_rotation 44 | npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state) 45 | 46 | vehicles = { 47 | ego: "EGO", 48 | npc: "Sedan", 49 | } 50 | 51 | 52 | # Executed upon receiving collision callback -- NPC is expected to drive through colliding objects 53 | def on_collision(agent1, agent2, contact): 54 | name1 = vehicles[agent1] 55 | name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE" 56 | print("{} collided with {}".format(name1, name2)) 57 | 58 | 59 | ego.on_collision(on_collision) 60 | npc.on_collision(on_collision) 61 | 62 | # This block creates the list of waypoints that the NPC will follow 63 | # Each waypoint is an position vector paired with the speed that the NPC will drive to it 64 | waypoints = [] 65 | 66 | for i in range(2): 67 | speed = 8 # if i % 2 == 0 else 12 68 | # Waypoint angles are input as Euler angles (roll, pitch, yaw) 69 | angle = npc_rotation 70 | # Raycast the points onto the ground because BorregasAve is not flat 71 | npc_position.x += 6 72 | npc_position.z += 21 73 | hit = sim.raycast(npc_position, lgsvl.Vector(0, -1, 0), layer_mask) 74 | 75 | trigger = None 76 | if i == 0: 77 | parameters = {"maxDistance": 4.0} 78 | effector = lgsvl.TriggerEffector("WaitForDistance", parameters) 79 | trigger = lgsvl.WaypointTrigger([effector]) 80 | wp = lgsvl.DriveWaypoint( 81 | position=hit.point, 82 | speed=speed, 83 | angle=angle, 84 | idle=0, 85 | trigger_distance=0, 86 | trigger=trigger, 87 | ) 88 | waypoints.append(wp) 89 | 90 | 91 | def on_waypoint(agent, index): 92 | print("waypoint {} reached".format(index)) 93 | 94 | 95 | def agents_traversed_waypoints(): 96 | print("All agents traversed their waypoints.") 97 | sim.stop() 98 | 99 | 100 | # The above function needs to be added to the list of callbacks for the NPC 101 | npc.on_waypoint_reached(on_waypoint) 102 | sim.agents_traversed_waypoints(agents_traversed_waypoints) 103 | 104 | # The NPC needs to be given the list of waypoints. 105 | # A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false) 106 | npc.follow(waypoints) 107 | 108 | input("Press Enter to run") 109 | 110 | sim.run() 111 | -------------------------------------------------------------------------------- /quickstart/32-pedestrian-time-to-collision.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #1: Using the time to collision trigger with a pedestrian") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave, 42) 19 | 20 | spawns = sim.get_spawn() 21 | layer_mask = 0 22 | layer_mask |= 1 << 0 # 0 is the layer for the road (default) 23 | 24 | # EGO 25 | state = lgsvl.AgentState() 26 | ego_position = lgsvl.Vector(342.0, 0.0, -87.7) 27 | hit = sim.raycast(ego_position, lgsvl.Vector(0, -1, 0), layer_mask) 28 | state.transform.position = hit.point 29 | state.transform.rotation = lgsvl.Vector(0.0, 15.0, 0.0) 30 | forward = lgsvl.Vector(0.2, 0.0, 0.8) 31 | state.velocity = forward * 15 32 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 33 | 34 | # Pedestrian 35 | state = lgsvl.AgentState() 36 | pedestrian_position = lgsvl.Vector(350.0, 0.0, -12) 37 | hit = sim.raycast(pedestrian_position, lgsvl.Vector(0, -1, 0), layer_mask) 38 | pedestrian_rotation = lgsvl.Vector(0.0, 105.0, 0.0) 39 | state.transform.position = hit.point 40 | state.transform.rotation = pedestrian_rotation 41 | pedestrian = sim.add_agent("Bob", lgsvl.AgentType.PEDESTRIAN, state) 42 | 43 | agents = {ego: "EGO", pedestrian: "Bob"} 44 | 45 | 46 | # Executed upon receiving collision callback -- pedestrian is expected to walk into colliding objects 47 | def on_collision(agent1, agent2, contact): 48 | name1 = agents[agent1] 49 | name2 = agents[agent2] if agent2 is not None else "OBSTACLE" 50 | print("{} collided with {}".format(name1, name2)) 51 | 52 | 53 | ego.on_collision(on_collision) 54 | pedestrian.on_collision(on_collision) 55 | 56 | # This block creates the list of waypoints that the pedestrian will follow 57 | # Each waypoint is an position vector paired with the speed that the pedestrian will walk to 58 | waypoints = [] 59 | 60 | trigger = None 61 | speed = 3 62 | hit = sim.raycast( 63 | pedestrian_position + lgsvl.Vector(7.4, 0.0, -2.2), 64 | lgsvl.Vector(0, -1, 0), 65 | layer_mask, 66 | ) 67 | effector = lgsvl.TriggerEffector("TimeToCollision", {}) 68 | trigger = lgsvl.WaypointTrigger([effector]) 69 | wp = lgsvl.WalkWaypoint( 70 | position=hit.point, speed=speed, idle=0, trigger_distance=0, trigger=trigger 71 | ) 72 | waypoints.append(wp) 73 | 74 | hit = sim.raycast( 75 | pedestrian_position + lgsvl.Vector(12.4, 0.0, -3.4), 76 | lgsvl.Vector(0, -1, 0), 77 | layer_mask, 78 | ) 79 | wp = lgsvl.WalkWaypoint( 80 | position=hit.point, speed=speed, idle=0, trigger_distance=0, trigger=None 81 | ) 82 | waypoints.append(wp) 83 | 84 | 85 | def on_waypoint(agent, index): 86 | print("waypoint {} reached".format(index)) 87 | 88 | 89 | def agents_traversed_waypoints(): 90 | print("All agents traversed their waypoints.") 91 | sim.stop() 92 | 93 | 94 | # The above function needs to be added to the list of callbacks for the pedestrian 95 | pedestrian.on_waypoint_reached(on_waypoint) 96 | sim.agents_traversed_waypoints(agents_traversed_waypoints) 97 | 98 | # The pedestrian needs to be given the list of waypoints. A bool can be passed as the 2nd argument that controls 99 | # whether or not the pedestrian loops over the waypoints (default false) 100 | pedestrian.follow(waypoints, False) 101 | 102 | input("Press Enter to run") 103 | 104 | sim.run() 105 | -------------------------------------------------------------------------------- /quickstart/33-ego-drive-stepped.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2020-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import os 9 | import lgsvl 10 | import time 11 | 12 | print("Python API Quickstart #33: Stepping a simulation") 13 | sim = lgsvl.Simulator(os.environ.get("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), lgsvl.wise.SimulatorSettings.simulator_port) 14 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 15 | sim.reset() 16 | # Re-load scene and set random seed 17 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave, seed=123) 18 | 19 | spawns = sim.get_spawn() 20 | 21 | state = lgsvl.AgentState() 22 | state.transform = spawns[0] 23 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 24 | 25 | # Agents can be spawned with a velocity. Default is to spawn with 0 velocity 26 | # state.velocity = 20 * forward 27 | 28 | # In order for Apollo to drive with stepped simulation we must add the clock sensor 29 | # and we must also set clock_mode to MODE_MOCK in Apollo's cyber/conf/cyber.pb.conf 30 | # Note that MODE_MOCK is only supported in Apollo master (6.0 or later)! 31 | # Refer to https://www.svlsimulator.com/docs/sensor-json-options/#clock 32 | 33 | # We can test Apollo with standard MKZ or MKZ with ground truth sensors 34 | # Refer to https://www.svlsimulator.com/docs/modular-testing/ 35 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5, lgsvl.AgentType.EGO, state) 36 | 37 | # An EGO will not connect to a bridge unless commanded to 38 | print("Bridge connected:", ego.bridge_connected) 39 | 40 | # The EGO looks for a (Cyber) bridge at the specified IP and port 41 | ego.connect_bridge(lgsvl.wise.SimulatorSettings.bridge_host, lgsvl.wise.SimulatorSettings.bridge_port) 42 | # uncomment to wait for bridge connection; script will drive ego if bridge not found 43 | # print("Waiting for connection...") 44 | # while not ego.bridge_connected: 45 | time.sleep(1) 46 | 47 | print("Bridge connected:", ego.bridge_connected) 48 | 49 | # spawn random NPCs 50 | sim.add_random_agents(lgsvl.AgentType.NPC) 51 | sim.add_random_agents(lgsvl.AgentType.PEDESTRIAN) 52 | 53 | t0 = time.time() 54 | s0 = sim.current_time 55 | print() 56 | print("Total real time elapsed = {:5.3f}".format(0)) 57 | print("Simulation time = {:5.1f}".format(s0)) 58 | print("Simulation frames =", sim.current_frame) 59 | 60 | # let simulator initialize and settle a bit before starting 61 | sim.run(time_limit=2) 62 | 63 | t1 = time.time() 64 | s1 = sim.current_time 65 | print() 66 | print("Total real time elapsed = {:5.3f}".format(t1 - t0)) 67 | print("Simulation settle time = {:5.1f}".format(s1 - s0)) 68 | print("Simulation settle frames =", sim.current_frame) 69 | 70 | # tell ego to drive forward, or not (if apollo is driving) 71 | if not ego.bridge_connected: 72 | state = ego.state 73 | forward = lgsvl.utils.transform_to_forward(state.transform) 74 | state.velocity = 20 * forward 75 | ego.state = state 76 | duration = 15 77 | else: 78 | duration = 45 79 | 80 | step_time = 0.10 81 | 82 | step_rate = int(1.0 / step_time) 83 | steps = duration * step_rate 84 | print() 85 | print("Stepping forward for {} steps of {}s per step" .format(steps, step_time)) 86 | input("Press Enter to start:") 87 | 88 | # The simulator can be run for a set amount of time. 89 | # time_limit is optional and if omitted or set to 0, then the simulator will run indefinitely 90 | t0 = time.time() 91 | for i in range(steps): 92 | t1 = time.time() 93 | sim.run(time_limit=step_time) 94 | t2 = time.time() 95 | s2 = sim.current_time 96 | 97 | state = ego.state 98 | pos = state.position 99 | speed = state.speed * 3.6 100 | 101 | # if Apollo is not driving 102 | if not ego.bridge_connected: 103 | state.velocity = 20 * forward 104 | ego.state = state 105 | 106 | print("Sim time = {:5.2f}".format(s2 - s1) + "; Real time elapsed = {:5.3f}; ".format(t2 - t1), end='') 107 | print("Speed = {:4.1f}; Position = {:5.3f},{:5.3f},{:5.3f}".format(speed, pos.x, pos.y, pos.z)) 108 | time.sleep(0.2) 109 | 110 | t3 = time.time() 111 | 112 | # Final statistics 113 | print("Total real time elapsed = {:5.3f}".format(t3 - t0)) 114 | print("Simulation time = {:5.1f}".format(sim.current_time)) 115 | print("Simulation frames =", sim.current_frame) 116 | -------------------------------------------------------------------------------- /quickstart/34-simulator-cam-set.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from environs import Env 9 | import lgsvl 10 | 11 | print("Python API Quickstart #34: Setting the fixed camera position") 12 | env = Env() 13 | 14 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 15 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave: 16 | sim.reset() 17 | else: 18 | sim.load(lgsvl.wise.DefaultAssets.map_borregasave) 19 | 20 | # This creates a transform in Unity world coordinates 21 | tr = lgsvl.Transform(lgsvl.Vector(10, 50, 0), lgsvl.Vector(90, 0, 0)) 22 | 23 | spawns = sim.get_spawn() 24 | 25 | state = lgsvl.AgentState() 26 | state.transform = spawns[0] 27 | forward = lgsvl.utils.transform_to_forward(spawns[0]) 28 | state.velocity = 20 * forward 29 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 30 | 31 | # This function sets the camera to free state and applies the transform to the camera rig 32 | sim.set_sim_camera(tr) 33 | print("Set transform: {}".format(tr)) 34 | 35 | input("Press Enter to drive forward for 4 seconds") 36 | sim.run(time_limit=4.0) 37 | -------------------------------------------------------------------------------- /quickstart/35-spawn-multi-robots.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import time 9 | from environs import Env 10 | import lgsvl 11 | 12 | print("Python API Quickstart #35: Spawning multi robots with bridge connections") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | 17 | map_seocho = lgsvl.wise.DefaultAssets.map_lgseocho 18 | robots = [ 19 | lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2_multi_robot1, 20 | lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2_multi_robot2, 21 | lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2_multi_robot3, 22 | ] 23 | 24 | if sim.current_scene == map_seocho: 25 | sim.reset() 26 | else: 27 | sim.load(map_seocho) 28 | 29 | spawns = sim.get_spawn() 30 | spawn = spawns[1] 31 | right = lgsvl.utils.transform_to_right(spawn) 32 | 33 | for i, robot in enumerate(robots): 34 | state = lgsvl.AgentState() 35 | state.transform.position = spawn.position + (1.0 * i * right) 36 | state.transform.rotation = spawn.rotation 37 | ego = sim.add_agent(robot, lgsvl.AgentType.EGO, state) 38 | print("Spawned a robot at:", state.transform.position) 39 | 40 | ego.connect_bridge(env.str("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host), env.int("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 41 | print("Waiting for connection...") 42 | while not ego.bridge_connected: 43 | time.sleep(1) 44 | 45 | print("Bridge connected:", ego.bridge_connected) 46 | 47 | print("Running the simulation...") 48 | sim.run() 49 | -------------------------------------------------------------------------------- /quickstart/36-send-destination-to-nav2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import lgsvl 9 | from environs import Env 10 | from lgsvl import Vector, Quaternion 11 | 12 | print("Python API Quickstart #36: Sending destinations to Navigation2") 13 | env = Env() 14 | 15 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 16 | 17 | map_seocho = lgsvl.wise.DefaultAssets.map_lgseocho 18 | ego_cloi = lgsvl.wise.DefaultAssets.ego_lgcloi_navigation2 19 | 20 | if sim.current_scene == map_seocho: 21 | sim.reset() 22 | else: 23 | sim.load(map_seocho) 24 | 25 | sim.set_time_of_day(0, fixed=True) 26 | spawns = sim.get_spawn() 27 | state = lgsvl.AgentState() 28 | state.transform = spawns[0] 29 | 30 | ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", ego_cloi), lgsvl.AgentType.EGO, state) 31 | ego.connect_bridge(env.str("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host), env.int("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port)) 32 | 33 | i = 0 34 | 35 | # List of destinations in Nav2 costmap coordinates 36 | ros_destinations = [ 37 | ((3.118, -0.016, 0), (0, 0, 0.0004, 0.999)), 38 | ((3.126, -10.025, 0), (0, 0, 0.006, 0.999)), 39 | ((11.171, -9.875, 0), (0, 0, 0.707, 0.707)), 40 | ((11.882, -0.057, 0), (0, 0, 0.699, 0.715)), 41 | ((12.351, 11.820, 0), (0, 0, -0.999, 0.0004)), 42 | ((2.965, 11.190, 0), (0, 0, -0.707, 0.707)), 43 | ((2.687, -0.399, 0), (0, 0, -0.0036, 0.999)), 44 | ] 45 | 46 | ego.set_initial_pose() 47 | sim.run(5) 48 | 49 | 50 | def send_next_destination(agent): 51 | global i 52 | print(f"{i}: {agent.name} reached destination") 53 | i += 1 54 | if i >= len(ros_destinations): 55 | print("Iterated all destinations successfully. Stopping...") 56 | sim.stop() 57 | return 58 | 59 | ros_dst = ros_destinations[i] 60 | next_dst = sim.map_from_nav(Vector(*ros_dst[0]), Quaternion(*ros_dst[1])) 61 | ego.set_destination(next_dst) 62 | 63 | 64 | ros_dst = ros_destinations[0] 65 | first_dst = sim.map_from_nav(Vector(*ros_dst[0]), Quaternion(*ros_dst[1])) 66 | ego.set_destination(first_dst) 67 | ego.on_destination_reached(send_next_destination) 68 | 69 | sim.run() 70 | 71 | print("Done!") 72 | -------------------------------------------------------------------------------- /quickstart/98-npc-behaviour.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | import math 9 | import random 10 | from environs import Env 11 | import lgsvl 12 | 13 | print("Python API Quickstart #98: Simulating different NPCs behaviours") 14 | env = Env() 15 | 16 | sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port)) 17 | 18 | drunkDriverAvailable = False 19 | trailerAvailable = 0 20 | 21 | print("Current Scene = {}".format(sim.current_scene)) 22 | # Loads the named map in the connected simulator. 23 | if sim.current_scene == lgsvl.wise.DefaultAssets.map_cubetown: 24 | sim.reset() 25 | else: 26 | print("Loading Scene = {}".format(lgsvl.wise.DefaultAssets.map_cubetown)) 27 | sim.load(lgsvl.wise.DefaultAssets.map_cubetown) 28 | 29 | agents = sim.available_agents 30 | print("agents:") 31 | for i in range(len(agents)): 32 | agent = agents[i] 33 | if agent["name"] == "TrailerTruckTest": 34 | trailerAvailable |= 1 35 | if agent["name"] == "MackAnthemStandupSleeperCab2018": 36 | trailerAvailable |= 2 37 | print( 38 | "#{:>2}: {} {:40} ({:9}) {}".format( 39 | i, 40 | ("✔️" if agent["loaded"] else "❌"), 41 | agent["name"], 42 | agent["NPCType"], 43 | agent["AssetGuid"], 44 | ) 45 | ) 46 | 47 | behaviours = sim.available_npc_behaviours 48 | 49 | 50 | print("behaviours:") 51 | for i in range(len(behaviours)): 52 | if behaviours[i]["name"] == "NPCDrunkDriverBehaviour": 53 | drunkDriverAvailable = True 54 | if behaviours[i]["name"] == "NPCTrailerBehaviour": 55 | trailerAvailable |= 4 56 | print("#{:>2}: {}".format(i, behaviours[i]["name"])) 57 | 58 | spawns = sim.get_spawn() 59 | 60 | state = lgsvl.AgentState() 61 | state.transform = spawns[0] 62 | sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state) 63 | 64 | mindist = 10.0 65 | maxdist = 40.0 66 | 67 | random.seed(0) 68 | trailerAvailable = trailerAvailable == (1 | 2 | 4) 69 | 70 | print( 71 | "Trailer support: {} Drunk Driver support: {}".format( 72 | "✔️" if trailerAvailable else "❌", "✔️" if drunkDriverAvailable else "❌" 73 | ) 74 | ) 75 | 76 | while True: 77 | if trailerAvailable: 78 | inp = input( 79 | "Enter index of Agent to spawn, t to spawn truck and trailer, r to run:" 80 | ) 81 | else: 82 | inp = input("Enter index of Agent to spawn, r to run:") 83 | 84 | angle = random.uniform(0.0, 2 * math.pi) 85 | dist = random.uniform(mindist, maxdist) 86 | spawn = random.choice(spawns) 87 | sx = spawn.position.x 88 | sy = spawn.position.y 89 | sz = spawn.position.z 90 | point = lgsvl.Vector(sx + dist * math.cos(angle), sy, sz + dist * math.sin(angle)) 91 | state = lgsvl.AgentState() 92 | state.transform = sim.map_point_on_lane(point) 93 | 94 | if inp == "r": 95 | print("running.") 96 | sim.run() 97 | 98 | if inp == "t" and trailerAvailable: 99 | truck = sim.add_agent( 100 | "MackAnthemStandupSleeperCab2018", lgsvl.AgentType.NPC, state 101 | ) 102 | truck.follow_closest_lane(True, 5.6) 103 | trailer = sim.add_agent("TrailerTruckTest", lgsvl.AgentType.NPC, state) 104 | trailer.set_behaviour("NPCTrailerBehaviour") 105 | sim.remote.command( 106 | "agent/trailer/attach", {"trailer_uid": trailer.uid, "truck_uid": truck.uid} 107 | ) 108 | 109 | else: 110 | try: 111 | agentIndex = int(inp) 112 | if agentIndex > len(agents): 113 | print("index out of range") 114 | continue 115 | 116 | agent = agents[agentIndex]["name"] 117 | print("Selected {}".format(agent)) 118 | npc = sim.add_agent(agent, lgsvl.AgentType.NPC, state) 119 | 120 | if drunkDriverAvailable: 121 | inp = input("make drunk driver? yN") 122 | if inp == "y" or inp == "Y": 123 | npc.set_behaviour("NPCDrunkDriverBehaviour") 124 | npc.remote.command( 125 | "agent/drunk/config", 126 | { 127 | "uid": npc.uid, 128 | "correctionMinTime": 0.0, 129 | "correctionMaxTime": 0.6, 130 | "steerDriftMin": 0.00, 131 | "steerDriftMax": 0.09, 132 | }, 133 | ) 134 | 135 | npc.follow_closest_lane(True, 5.6) 136 | print("spawned agent {}, uid {}".format(agent, npc.uid)) 137 | 138 | except ValueError: 139 | print("expected a number") 140 | -------------------------------------------------------------------------------- /quickstart/99-utils-examples.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2019-2021 LG Electronics, Inc. 4 | # 5 | # This software contains code licensed as described in LICENSE. 6 | # 7 | 8 | from lgsvl import Transform, Vector 9 | from lgsvl.utils import ( 10 | transform_to_matrix, 11 | matrix_inverse, 12 | matrix_multiply, 13 | vector_multiply, 14 | ) 15 | 16 | print("Python API Quickstart #99: Using the LGSVL utilities") 17 | # global "world" transform (for example, car position) 18 | world = Transform(Vector(10, 20, 30), Vector(11, 22, 33)) 19 | 20 | # "local" transform, relative to world transform (for example, Lidar sensor) 21 | local = Transform(Vector(0, 2, -0.5), Vector(0, 0, 0)) 22 | 23 | # combine them in one transform matrix 24 | mtx = matrix_multiply(transform_to_matrix(local), transform_to_matrix(world)) 25 | 26 | # compute inverse for transforming points 27 | mtx = matrix_inverse(mtx) 28 | 29 | # now transform some point from world position into coordinate system of local transform of Lidar 30 | pt = vector_multiply(Vector(15, 20, 30), mtx) 31 | print(pt) 32 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | # - PACKAGE >= PKG_VERSION ; python_version >= PYTHON_VERSION 3 | # PKG_VERSION is the first version of PACKAGE that supports PYTHON_VERSION 4 | # - PACKAGE < PKG_VERSION ; python_version < PYTHON_VERSION 5 | # PKG_VERSION is the first version of PACKAGE that no longer supports 6 | # PYTHON_VERSION; add entries for PYTHON_VERSION > "python_requires" of 7 | # lgsvl in setup.py 8 | # - Keep in alphabetical order. 9 | environs >= 8.1.0 ; python_version >= '3.9' 10 | numpy < 1.20 ; python_version < '3.7' 11 | numpy >= 1.20 ; python_version >= '3.7' 12 | websocket-client >= 0.58.0 ; python_version >= '3.8' 13 | websockets < 8.1 ; python_version < '3.6.1' 14 | websockets >= 8.1 ; python_version >= '3.8' 15 | websockets >= 9.0.1 ; python_version >= '3.9' 16 | -------------------------------------------------------------------------------- /resource/lgsvl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgsvl/PythonAPI/9bc29c9aee5e98d4d99e6a410c04b153b8f7feef/resource/lgsvl -------------------------------------------------------------------------------- /scripts/run_and_create_coverage_report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | ~/.local/bin/coverage run -m unittest discover -v -c 6 | ~/.local/bin/coverage html --omit "~/.local/*","tests/*" 7 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script_dir=$base/lib/lgsvl 3 | [install] 4 | install_scripts=$base/lib/lgsvl 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from setuptools import setup 4 | 5 | # Without enabling the user site, "python3 -m pip install --user -e ." fails 6 | # with: 7 | # 8 | # WARNING: The user site-packages directory is disabled. 9 | # error: can't create or remove files in install directory 10 | # ... 11 | # [Errno 13] Permission denied: '/usr/local/lib/python3.6/dist-packages/' 12 | # 13 | # Taken from https://github.com/pypa/pip/issues/7953#issuecomment-645133255. 14 | import site 15 | import sys 16 | site.ENABLE_USER_SITE = "--user" in sys.argv[1:] 17 | 18 | 19 | def get_version(git_tag): 20 | """ 21 | Returns a PEP 440 version identifier 22 | 23 | [+] 24 | 25 | derived from its parameter and the output from: 26 | 27 | git describe --match --tags 28 | 29 | which has the format: 30 | 31 | [--g] 32 | 33 | The public version identifier is formed from . PEP 440 versioning 34 | allows only digits without leading zeros in the release segments of public 35 | version identifiers, so they are dropped along with any "P"-s found in 36 | . And PEP 440 does not allow hyphens in pre-release segments, so 37 | any "-rc"-s are replaced with "rc". Fortunately, this mapping doesn't 38 | introduce any ambiguities when used for the tags that currently exist. 39 | 40 | The optional local version label is formed from the portion of the 41 | "git describe" output which follows with all hyphens converted to 42 | periods (except the first, which is dropped). This segment will be empty if: 43 | - Git is not available, or 44 | - the working tree is not a Git repository, or 45 | - the tag is not present or not on the currrent branch, or 46 | - the HEAD of the current branch is coincident with the tag . 47 | 48 | NB. - Not using https://pypi.org/project/setuptools-git-version/ because it 49 | passes "--long" to "git describe". 50 | - Not using https://pypi.org/project/setuptools-scm/ because it's way 51 | more complicated to configure it to do what is wanted. 52 | """ 53 | 54 | # ASSERT( has no more than one leading "0", no more than one "-rc", 55 | # and no more than one "P", which is expected to be at the end -- but 56 | # this is not checked) 57 | public_version_identifier = git_tag.replace(".0", ".", 1) \ 58 | .replace("P", "", 1) \ 59 | .replace("-rc", "rc", 1) 60 | from os import getenv 61 | try: 62 | from git import Repo 63 | # PWD is the directory from where we invoked "pip install", which is 64 | # the root of the Git repository; when setup() is 65 | # called, pip has changed the current directory to be under /tmp. 66 | repo = Repo(path=getenv('PWD')) 67 | val = repo.git.describe('--match', git_tag, '--tags') 68 | except Exception: 69 | val = "" 70 | 71 | # Remove and convert the first hyphen to a "+": 72 | local_version_label_with_plus = val.replace(git_tag, '', 1) \ 73 | .replace('-', '+', 1) \ 74 | .replace('-', '.') 75 | 76 | return public_version_identifier + local_version_label_with_plus 77 | 78 | 79 | package_name = 'lgsvl' 80 | 81 | setup( 82 | name=package_name, 83 | version=get_version('2021.1'), 84 | data_files=[ 85 | ('share/ament_index/resource_index/packages', 86 | ['resource/' + package_name]), 87 | ('share/' + package_name, ['package.xml']), 88 | ], 89 | description="Python API for SVL Simulator", 90 | author="LGSVL", 91 | author_email="contact@svlsimulator.com", 92 | python_requires=">=3.6.0", 93 | url="https://github.com/lgsvl/PythonAPI", 94 | packages=["lgsvl", "lgsvl.dreamview", "lgsvl.evaluator", "lgsvl.wise"], 95 | install_requires=[ 96 | "environs", 97 | "numpy", 98 | "setuptools", 99 | "websocket-client", 100 | "websockets" 101 | ], 102 | setup_requires=[ 103 | "GitPython==3.1.14" 104 | ], 105 | extras_require={ 106 | "ci": [ 107 | "flake8>=3.7.0" 108 | ], 109 | }, 110 | zip_safe=True, 111 | maintainer='Hadi Tabatabaee', 112 | maintainer_email='hadi.tabatabaee@lge.com', 113 | license='Other', 114 | classifiers=[ 115 | "License :: Other/Proprietary License", 116 | "Programming Language :: Python :: 3", 117 | "Programming Language :: Python :: 3.6", 118 | ], 119 | ) 120 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | import unittest 8 | from .test_collisions import TestCollisions 9 | from .test_simulator import TestSimulator 10 | from .test_EGO import TestEGO 11 | from .test_NPC import TestNPC 12 | from .test_sensors import TestSensors 13 | from .test_peds import TestPeds 14 | from .test_utils import TestUtils 15 | 16 | 17 | def load_tests(loader, standard_tests, pattern): 18 | suite = unittest.TestSuite() 19 | suite.addTests(loader.loadTestsFromTestCase(TestNPC)) # must be first 20 | suite.addTests(loader.loadTestsFromTestCase(TestCollisions)) 21 | suite.addTests(loader.loadTestsFromTestCase(TestEGO)) 22 | suite.addTests(loader.loadTestsFromTestCase(TestSensors)) 23 | suite.addTests(loader.loadTestsFromTestCase(TestPeds)) 24 | suite.addTests(loader.loadTestsFromTestCase(TestUtils)) 25 | suite.addTests(loader.loadTestsFromTestCase(TestSimulator)) #must be last 26 | return suite 27 | -------------------------------------------------------------------------------- /tests/common.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2021 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | import signal 8 | import lgsvl 9 | import os 10 | 11 | class TestTimeout(Exception): 12 | pass 13 | 14 | 15 | class TestException(Exception): 16 | pass 17 | 18 | 19 | class SimConnection: 20 | def __init__(self, seconds=30, scene=lgsvl.wise.DefaultAssets.map_borregasave, error_message=None, load_scene=True): 21 | if error_message is None: 22 | error_message = 'test timed out after {}s.'.format(seconds) 23 | self.seconds = seconds 24 | self.error_message = error_message 25 | self.scene = scene 26 | self.load_scene = load_scene 27 | 28 | def handle_timeout(self, signum, frame): 29 | raise TestTimeout(self.error_message) 30 | 31 | def __enter__(self): 32 | signal.signal(signal.SIGALRM, self.handle_timeout) 33 | signal.alarm(self.seconds) 34 | 35 | self.sim = lgsvl.Simulator(os.environ.get("LGSVL__SIMULATOR_HOST", "127.0.0.1"), 8181) 36 | if self.load_scene: 37 | if self.sim.current_scene == self.scene: 38 | self.sim.reset() 39 | signal.alarm(self.seconds - 20) 40 | else: 41 | self.sim.load(self.scene) 42 | return self.sim 43 | 44 | def __exit__(self, exc_type, exc_val, exc_tb): 45 | signal.alarm(0) 46 | # agents = self.sim.get_agents() 47 | # for a in agents: 48 | # self.sim.remove_agent(a) 49 | self.sim.close() 50 | 51 | 52 | def spawnState(sim, index=0): 53 | state = lgsvl.AgentState() 54 | state.transform = sim.get_spawn()[index] 55 | return state 56 | 57 | 58 | def cmEqual(self, a, b, msg): # Test vectors within 1cm 59 | self.assertAlmostEqual(a.x, b.x, 2, msg) 60 | self.assertAlmostEqual(a.y, b.y, 2, msg) 61 | self.assertAlmostEqual(a.z, b.z, 2, msg) 62 | 63 | 64 | def mEqual(self, a, b, msg): # Test vectors within 1cm 65 | self.assertAlmostEqual(a.x, b.x, delta=1.5, msg=msg) 66 | self.assertAlmostEqual(a.y, b.y, delta=1.5, msg=msg) 67 | self.assertAlmostEqual(a.z, b.z, delta=1.5, msg=msg) 68 | 69 | 70 | def notAlmostEqual(a,b): 71 | return round(a-b,7) != 0 72 | 73 | -------------------------------------------------------------------------------- /tests/test_manual_features.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2021 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | # DO NOT INCLUDE IN __init__.py 8 | 9 | import unittest 10 | 11 | import lgsvl 12 | from .common import SimConnection, spawnState, TestTimeout 13 | 14 | class TestManual(unittest.TestCase): 15 | @unittest.skip("Windshield wipers no longer supported") 16 | def test_wipers(self): 17 | try: 18 | with SimConnection() as sim: 19 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 20 | control = lgsvl.VehicleControl() 21 | control.windshield_wipers = 1 22 | ego.apply_control(control, True) 23 | sim.run(1) 24 | input("Press Enter if wipers are on low") 25 | 26 | control = lgsvl.VehicleControl() 27 | control.windshield_wipers = 2 28 | ego.apply_control(control, True) 29 | sim.run(1) 30 | input("Press Enter if wipers are on medium") 31 | 32 | control = lgsvl.VehicleControl() 33 | control.windshield_wipers = 3 34 | ego.apply_control(control, True) 35 | sim.run(1) 36 | input("Press Enter if wipers are on high") 37 | except TestTimeout: 38 | self.fail("Wipers were not on") 39 | 40 | def test_headlights(self): 41 | try: 42 | with SimConnection() as sim: 43 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 44 | control = lgsvl.VehicleControl() 45 | control.headlights = 1 46 | ego.apply_control(control, True) 47 | sim.run(1) 48 | input("Press Enter if headlights are on") 49 | 50 | control = lgsvl.VehicleControl() 51 | control.headlights = 2 52 | ego.apply_control(control, True) 53 | sim.run(1) 54 | input("Press Enter if high beams are on") 55 | except TestTimeout: 56 | self.fail("Headlights were not on") 57 | 58 | def test_blinkers(self): 59 | try: 60 | with SimConnection() as sim: 61 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 62 | control = lgsvl.VehicleControl() 63 | control.turn_signal_left = True 64 | ego.apply_control(control, True) 65 | sim.run(3) 66 | input("Press Enter if left turn signal is on") 67 | 68 | control = lgsvl.VehicleControl() 69 | control.turn_signal_right = True 70 | ego.apply_control(control, True) 71 | sim.run(3) 72 | input("Press Enter if right turn signal is on") 73 | except TestTimeout: 74 | self.fail("Turn signals were not on") 75 | 76 | @unittest.skip("Windshield wipers no longer supported") 77 | def test_wiper_large_value(self): 78 | try: 79 | with SimConnection() as sim: 80 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 81 | control = lgsvl.VehicleControl() 82 | control.windshield_wipers = 4 83 | ego.apply_control(control, True) 84 | sim.run(1) 85 | input("Press Enter if wipers are off") 86 | except TestTimeout: 87 | self.fail("Wipers were on") 88 | 89 | @unittest.skip("Windshield wipers no longer supported") 90 | def test_wiper_str(self): 91 | try: 92 | with SimConnection() as sim: 93 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 94 | control = lgsvl.VehicleControl() 95 | control.windshield_wipers = "on" 96 | ego.apply_control(control, True) 97 | sim.run(1) 98 | input("Press Enter if wipers are off") 99 | except TestTimeout: 100 | self.fail("Wipers were on") 101 | 102 | def test_headlights_large_value(self): 103 | try: 104 | with SimConnection() as sim: 105 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 106 | control = lgsvl.VehicleControl() 107 | control.headlights = 123 108 | ego.apply_control(control, True) 109 | sim.run(1) 110 | input("Press Enter if headlights are off") 111 | except TestTimeout: 112 | self.fail("Headlights were on") 113 | 114 | def test_headlights_str(self): 115 | try: 116 | with SimConnection() as sim: 117 | ego = sim.add_agent(lgsvl.wise.DefaultAssets.ego_jaguar2015xe_apollo5, lgsvl.AgentType.EGO, spawnState(sim)) 118 | control = lgsvl.VehicleControl() 119 | control.headlights = "123" 120 | ego.apply_control(control, True) 121 | sim.run(1) 122 | input("Press Enter if headlights are off") 123 | except TestTimeout: 124 | self.fail("Headlights were on") 125 | -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 LG Electronics, Inc. 3 | # 4 | # This software contains code licensed as described in LICENSE. 5 | # 6 | 7 | import unittest 8 | 9 | import lgsvl 10 | import lgsvl.utils 11 | 12 | 13 | class TestUtils(unittest.TestCase): # Check that transform_to_matrix calculates the right values 14 | def test_transform_to_matrix(self): 15 | transform = lgsvl.Transform(lgsvl.Vector(1, 2, 3), lgsvl.Vector(4, 5, 6)) 16 | expectedMatrix = [[0.9913729386253347, 0.10427383718471564, -0.07941450396586013, 0.0], 17 | [-0.0980843287345578, 0.9920992900156518, 0.07822060602635744, 0.0], 18 | [0.08694343573875718, -0.0697564737441253, 0.9937680178757644, 0.0], 19 | [1, 2, 3, 1.0]] 20 | 21 | matrix = lgsvl.utils.transform_to_matrix(transform) 22 | for i in range(4): 23 | for j in range(4): 24 | self.assertAlmostEqual(matrix[i][j], expectedMatrix[i][j]) 25 | 26 | def test_matrix_multiply(self): # Check that matrix_multiply calculates the right values 27 | inputMatrix = lgsvl.utils.transform_to_matrix(lgsvl.Transform(lgsvl.Vector(1, 2, 3), lgsvl.Vector(4, 5, 6))) 28 | expectedMatrix = [[0.9656881042915112, 0.21236393599051254, -0.1494926216255657, 0.0], 29 | [-0.18774677387638924, 0.9685769782741936, 0.1631250626244768, 0.0], 30 | [0.1794369920860106, -0.12946117505974142, 0.9752139098799174, 0.0], 31 | [2.0560345883724906, 3.8792029959836434, 6.058330761714148, 1.0]] 32 | 33 | matrix = lgsvl.utils.matrix_multiply(inputMatrix, inputMatrix) 34 | for i in range(4): 35 | for j in range(4): 36 | self.assertAlmostEqual(matrix[i][j], expectedMatrix[i][j]) 37 | 38 | def test_matrix_inverse(self): # Check that matrix_inverse calculates the right values 39 | inputMatrix = lgsvl.utils.transform_to_matrix(lgsvl.Transform(lgsvl.Vector(1, 2, 3), lgsvl.Vector(4, 5, 6))) 40 | expectedMatrix = [[0.9913729386253347, -0.0980843287345578, 0.08694343573875718, 0.0], 41 | [0.10427383718471564, 0.9920992900156518, -0.0697564737441253, 0.0], 42 | [-0.07941450396586013, 0.07822060602635744, 0.9937680178757644, 0.0], 43 | [-0.9616771010971856, -2.120776069375818, -2.9287345418778, 1.0]] 44 | 45 | matrix = lgsvl.utils.matrix_inverse(inputMatrix) 46 | for i in range(4): 47 | for j in range(4): 48 | self.assertAlmostEqual(matrix[i][j], expectedMatrix[i][j]) 49 | 50 | def test_vector_multiply(self): # Check that vector_multiply calculates the right values 51 | inputMatrix = lgsvl.utils.transform_to_matrix(lgsvl.Transform(lgsvl.Vector(1, 2, 3), lgsvl.Vector(4, 5, 6))) 52 | inputVector = lgsvl.Vector(10, 20, 30) 53 | expectedVector = lgsvl.Vector(11.560345883724906, 20.792029959836434, 33.58330761714148) 54 | 55 | vector = lgsvl.utils.vector_multiply(inputVector, inputMatrix) 56 | self.assertAlmostEqual(vector.x, expectedVector.x) 57 | self.assertAlmostEqual(vector.y, expectedVector.y) 58 | self.assertAlmostEqual(vector.z, expectedVector.z) 59 | 60 | def test_vector_dot(self): # Check that vector_dot calculates the right values 61 | result = lgsvl.utils.vector_dot(lgsvl.Vector(1, 2, 3), lgsvl.Vector(4, 5, 6)) 62 | self.assertAlmostEqual(result, 32) 63 | --------------------------------------------------------------------------------