cut_in.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python
  2. # Copyright (c) 2019-2020 Intel Corporation
  3. #
  4. # This work is licensed under the terms of the MIT license.
  5. # For a copy, see <https://opensource.org/licenses/MIT>.
  6. """
  7. Cut in scenario:
  8. The scenario realizes a driving behavior on the highway.
  9. The user-controlled ego vehicle is driving straight and keeping its velocity at a constant level.
  10. Another car is cutting just in front, coming from left or right lane.
  11. The ego vehicle may need to brake to avoid a collision.
  12. """
  13. import random
  14. import py_trees
  15. import carla
  16. from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
  17. from srunner.scenariomanager.scenarioatomics.atomic_behaviors import (ActorTransformSetter,
  18. LaneChange,
  19. WaypointFollower,
  20. AccelerateToCatchUp)
  21. from srunner.scenariomanager.scenarioatomics.atomic_criteria import CollisionTest
  22. from srunner.scenariomanager.scenarioatomics.atomic_trigger_conditions import InTriggerDistanceToVehicle, DriveDistance
  23. from srunner.scenarios.basic_scenario import BasicScenario
  24. class CutIn(BasicScenario):
  25. """
  26. The ego vehicle is driving on a highway and another car is cutting in just in front.
  27. This is a single ego vehicle scenario
  28. """
  29. timeout = 1200
  30. def __init__(self, world, ego_vehicles, config, randomize=False, debug_mode=False, criteria_enable=True,
  31. timeout=600):
  32. self.timeout = timeout
  33. self._map = CarlaDataProvider.get_map()
  34. self._reference_waypoint = self._map.get_waypoint(config.trigger_points[0].location)
  35. self._velocity = 40
  36. self._delta_velocity = 10
  37. self._trigger_distance = 30
  38. # get direction from config name
  39. self._config = config
  40. self._direction = None
  41. self._transform_visible = None
  42. super(CutIn, self).__init__("CutIn",
  43. ego_vehicles,
  44. config,
  45. world,
  46. debug_mode,
  47. criteria_enable=criteria_enable)
  48. if randomize:
  49. self._velocity = random.randint(20, 60)
  50. self._trigger_distance = random.randint(10, 40)
  51. def _initialize_actors(self, config):
  52. # direction of lane, on which other_actor is driving before lane change
  53. if 'LEFT' in self._config.name.upper():
  54. self._direction = 'left'
  55. if 'RIGHT' in self._config.name.upper():
  56. self._direction = 'right'
  57. # add actors from xml file
  58. for actor in config.other_actors:
  59. vehicle = CarlaDataProvider.request_new_actor(actor.model, actor.transform)
  60. self.other_actors.append(vehicle)
  61. vehicle.set_simulate_physics(enabled=False)
  62. # transform visible
  63. other_actor_transform = self.other_actors[0].get_transform()
  64. self._transform_visible = carla.Transform(
  65. carla.Location(other_actor_transform.location.x,
  66. other_actor_transform.location.y,
  67. other_actor_transform.location.z + 105),
  68. other_actor_transform.rotation)
  69. def _create_behavior(self):
  70. """
  71. Order of sequence:
  72. - car_visible: spawn car at a visible transform
  73. - just_drive: drive until in trigger distance to ego_vehicle
  74. - accelerate: accelerate to catch up distance to ego_vehicle
  75. - lane_change: change the lane
  76. - endcondition: drive for a defined distance
  77. """
  78. # car_visible
  79. behaviour = py_trees.composites.Sequence("CarOn_{}_Lane" .format(self._direction))
  80. car_visible = ActorTransformSetter(self.other_actors[0], self._transform_visible)
  81. behaviour.add_child(car_visible)
  82. # just_drive
  83. just_drive = py_trees.composites.Parallel(
  84. "DrivingStraight", policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE)
  85. car_driving = WaypointFollower(self.other_actors[0], self._velocity)
  86. just_drive.add_child(car_driving)
  87. trigger_distance = InTriggerDistanceToVehicle(
  88. self.other_actors[0], self.ego_vehicles[0], self._trigger_distance)
  89. just_drive.add_child(trigger_distance)
  90. behaviour.add_child(just_drive)
  91. # accelerate
  92. accelerate = AccelerateToCatchUp(self.other_actors[0], self.ego_vehicles[0], throttle_value=1,
  93. delta_velocity=self._delta_velocity, trigger_distance=5, max_distance=500)
  94. behaviour.add_child(accelerate)
  95. # lane_change
  96. if self._direction == 'left':
  97. lane_change = LaneChange(
  98. self.other_actors[0], speed=None, direction='right', distance_same_lane=5, distance_other_lane=300)
  99. behaviour.add_child(lane_change)
  100. else:
  101. lane_change = LaneChange(
  102. self.other_actors[0], speed=None, direction='left', distance_same_lane=5, distance_other_lane=300)
  103. behaviour.add_child(lane_change)
  104. # endcondition
  105. endcondition = DriveDistance(self.other_actors[0], 200)
  106. # build tree
  107. root = py_trees.composites.Sequence("Behavior", policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE)
  108. root.add_child(behaviour)
  109. root.add_child(endcondition)
  110. return root
  111. def _create_test_criteria(self):
  112. """
  113. A list of all test criteria is created, which is later used in the parallel behavior tree.
  114. """
  115. criteria = []
  116. collision_criterion = CollisionTest(self.ego_vehicles[0])
  117. criteria.append(collision_criterion)
  118. return criteria
  119. def __del__(self):
  120. """
  121. Remove all actors after deletion.
  122. """
  123. self.remove_all_actors()