Skip to content

Commit

Permalink
Add ScenarioRunner scenario for sensorlib integration test (#174)
Browse files Browse the repository at this point in the history
# PR Details
## Description

This PR adds a new ScenarioRunner scenario to facilitate with
`sensorlib` field of view integration testing.

## Related GitHub Issue

Closes #173 

## Related Jira Key

Progresses [CDAR-368](https://usdot-carma.atlassian.net/browse/CDAR-368)

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->

## How Has This Been Tested?

Manually verified

## Types of changes

- [x] New feature (non-breaking change that adds functionality)

## Checklist:

- [ ] I have added any new packages to the sonar-scanner.properties file
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the
[**CONTRIBUTING**](https://github.com/usdot-fhwa-stol/carma-platform/blob/develop/Contributing.md)
document.
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.


[CDAR-368]:
https://usdot-carma.atlassian.net/browse/CDAR-368?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
adamlm authored Nov 9, 2023
1 parent 32d0272 commit 36ec887
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 0 deletions.
30 changes: 30 additions & 0 deletions scenario-runner/examples/sensorlib_lidar_field_of_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0"?>

<!--
Copyright 2023 Leidos
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<scenarios>
<scenario name="SensorlibLidarFieldOfView_1" type="SensorlibLidarFieldOfView" town="Town04">
<ego_vehicle x="203.44" y="-230.0" z="2" yaw="-90.0" model="vehicle.audi.a2" rolename="ego_vehicle"/>

<other_actor x="214.79" y="-245.61" z="2" model="vehicle.carlamotors.carlacola" rolename="heavy_truck"/>
<other_actor x="216.58" y="-248.69" z="2" model="walker.pedestrian.0001" rolename="in_road_person"/>
<other_actor x="195.59" y="-254.18" z="2" yaw="90.0" model="walker.pedestrian.0002" rolename="crossing_person"/>
<other_actor x="208.58" y="-239.0" z="2" yaw="180.0" model="walker.pedestrian.0003" rolename="corner_person_01"/>
<other_actor x="208.58" y="-239.0" z="2" yaw="135.0" model="walker.pedestrian.0004" rolename="corner_person_02"/>
<other_actor x="207.88" y="-257.57" z="2" yaw="167.0" model="walker.pedestrian.0005" rolename="corner_person_03"/>
</scenario>
</scenarios>
176 changes: 176 additions & 0 deletions scenario-runner/scenarios/sensorlib_lidar_field_of_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Copyright 2023 Leidos
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from agents.navigation.global_route_planner import GlobalRoutePlanner
from agents.navigation.global_route_planner_dao import GlobalRoutePlannerDAO

import carla

import py_trees

from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
from srunner.scenariomanager.scenarioatomics.atomic_behaviors import (
Idle,
KeepVelocity,
WaypointFollower,
)
from srunner.scenariomanager.scenarioatomics.atomic_criteria import CollisionTest
from srunner.scenariomanager.scenarioatomics.atomic_trigger_conditions import (
DriveDistance,
)
from srunner.scenarios.basic_scenario import BasicScenario
from srunner.scenarioconfigs.scenario_configuration import ScenarioConfiguration


class SensorlibLidarFieldOfView(BasicScenario):
def __init__(
self,
world,
ego_vehicles,
config: ScenarioConfiguration,
randomize: bool = False,
debug_mode: bool = False,
criteria_enable: bool = True,
timeout=60,
) -> None:
"""
:param world: CARLA world in which the scenario is running
:param list[carla.Vehicle] ego_vehicles: CARLA vehicle objects created based on scenario XML configuration
:param ScenarioConfiguration config: Specifications from scenario XML configuration
:param bool randomize:
:param bool debug_mode:
:param bool criteria_enable:
:param float timeout: Threshold (in seconds) after which test automatically fails
:return: None
:rtype: None
"""
# Must be defined before super() call because BasicScenario
# references is in its __init__() function.
self.timeout = timeout

super(SensorlibLidarFieldOfView, self).__init__(
"SensorlibFieldOfView",
ego_vehicles,
config,
world,
debug_mode=debug_mode,
criteria_enable=criteria_enable,
)

self.world_map = CarlaDataProvider.get_map()

# This is where the action takes place
spectator = world.get_spectator()
spectator.set_transform(
carla.Transform(
carla.Location(187.8024, -227.3753, 16.9967),
carla.Rotation(-38.1110, -39.1415, 0.0),
)
)

self.carma_vehicle = ego_vehicles[0]
self.other_actors_dict = {}

def _initialize_actors(self, config: ScenarioConfiguration) -> None:
"""
Note: this function overrides the one in BasicScenario (parent
class), so this override is responsible for adding the actors
defined in the scenario XML configuration.
:param ScenarioConfiguration config: Specifications from
scenario XML configuration
:return: None
"""
actors = CarlaDataProvider.request_new_actors(config.other_actors)

self.other_actors_dict = {
actor_config.rolename: actor
for actor_config, actor in zip(config.other_actors, actors)
}

def _setup_scenario_trigger(self, _: ScenarioConfiguration) -> None:
"""
Set up the scenario start trigger
Note: this function overrides the abstract one in the
BasicScenario parent class. The base class's implementation adds
a trigger that prevents the scenario from starting until the
ego vehicle drives some distance. We don't want that trigger
for this scenario because the ego vehicle will not move. Override this
function to create custom scenario start triggers. Follow this link
for more information:
https://carla-scenariorunner.readthedocs.io/en/latest/creating_new_scenario/
:return: None
"""
pass

def _create_behavior(self):
"""
Setup the behavior for NewScenario
Note: this function overrides the abstract one in the
BasicScenario parent class.
:return: Behavior tree root
"""
start_condition = Idle(5, name="start_condition")

crossing_person = self.other_actors_dict["crossing_person"]
walk_across_street = KeepVelocity(
crossing_person, 2.0, 8.0, name="walk_across_street"
)

dao = GlobalRoutePlannerDAO(CarlaDataProvider.get_map(), 2)
global_route_planner = GlobalRoutePlanner(dao)
global_route_planner.setup()

carma_vehicle = self.ego_vehicles[0]
route = global_route_planner.trace_route(
carma_vehicle.get_location(),
carla.Location(x=205.044693, y=-298.390015, z=0.019592),
)

drive_through_intersection = WaypointFollower(carma_vehicle, 5, route)

actor_behaviors = py_trees.composites.Parallel(name="actor_behaviors")
actor_behaviors.add_child(walk_across_street)
actor_behaviors.add_child(drive_through_intersection)

end_condition = DriveDistance(carma_vehicle, 10)

root = py_trees.composites.Sequence(name="root_sequence")
root.add_child(start_condition)
root.add_child(actor_behaviors)
root.add_child(end_condition)

return root

def _create_test_criteria(self) -> list:
"""
Setup the evaluation criteria for NewScenario
Note: this function overrides the one in BasicScenario (parent class).
:return: List of test criteria
"""
return [
# This is an example usage for including test criteria in
# ScenarioRunner.
# CollisionTest(self.carma_vehicle)
]

def __del__(self):
self.remove_all_actors()

0 comments on commit 36ec887

Please sign in to comment.