follow_leading_vehicle.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #!/usr/bin/env python
  2. # Copyright (c) 2018-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. Follow leading vehicle scenario:
  8. The scenario realizes a common driving behavior, in which the
  9. user-controlled ego vehicle follows a leading car driving down
  10. a given road. At some point the leading car has to slow down and
  11. finally stop. The ego vehicle has to react accordingly to avoid
  12. a collision. The scenario ends either via a timeout, or if the ego
  13. vehicle stopped close enough to the leading vehicle
  14. """
  15. import random
  16. import py_trees
  17. import carla
  18. from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
  19. from srunner.scenariomanager.scenarioatomics.atomic_behaviors import (ActorTransformSetter,
  20. ActorDestroy,
  21. KeepVelocity,
  22. StopVehicle,
  23. WaypointFollower)
  24. from srunner.scenariomanager.scenarioatomics.atomic_criteria import CollisionTest
  25. from srunner.scenariomanager.scenarioatomics.atomic_trigger_conditions import (InTriggerDistanceToVehicle,
  26. InTriggerDistanceToNextIntersection,
  27. DriveDistance,
  28. StandStill)
  29. from srunner.scenariomanager.timer import TimeOut
  30. from srunner.scenarios.basic_scenario import BasicScenario
  31. from srunner.tools.scenario_helper import get_waypoint_in_distance
  32. class FollowLeadingVehicle(BasicScenario):
  33. """
  34. This class holds everything required for a simple "Follow a leading vehicle"
  35. scenario involving two vehicles. (Traffic Scenario 2)
  36. This is a single ego vehicle scenario
  37. """
  38. timeout = 120 # Timeout of scenario in seconds
  39. def __init__(self, world, ego_vehicles, config, randomize=False, debug_mode=False, criteria_enable=True,
  40. timeout=60):
  41. """
  42. Setup all relevant parameters and create scenario
  43. If randomize is True, the scenario parameters are randomized
  44. """
  45. self._map = CarlaDataProvider.get_map()
  46. self._first_vehicle_location = 25
  47. self._first_vehicle_speed = 10
  48. self._reference_waypoint = self._map.get_waypoint(config.trigger_points[0].location)
  49. self._other_actor_max_brake = 1.0
  50. self._other_actor_stop_in_front_intersection = 20
  51. self._other_actor_transform = None
  52. # Timeout of scenario in seconds
  53. self.timeout = timeout
  54. super(FollowLeadingVehicle, self).__init__("FollowVehicle",
  55. ego_vehicles,
  56. config,
  57. world,
  58. debug_mode,
  59. criteria_enable=criteria_enable)
  60. if randomize:
  61. self._ego_other_distance_start = random.randint(4, 8)
  62. # Example code how to randomize start location
  63. # distance = random.randint(20, 80)
  64. # new_location, _ = get_location_in_distance(self.ego_vehicles[0], distance)
  65. # waypoint = CarlaDataProvider.get_map().get_waypoint(new_location)
  66. # waypoint.transform.location.z += 39
  67. # self.other_actors[0].set_transform(waypoint.transform)
  68. def _initialize_actors(self, config):
  69. """
  70. Custom initialization
  71. """
  72. first_vehicle_waypoint, _ = get_waypoint_in_distance(self._reference_waypoint, self._first_vehicle_location)
  73. self._other_actor_transform = carla.Transform(
  74. carla.Location(first_vehicle_waypoint.transform.location.x,
  75. first_vehicle_waypoint.transform.location.y,
  76. first_vehicle_waypoint.transform.location.z + 1),
  77. first_vehicle_waypoint.transform.rotation)
  78. first_vehicle_transform = carla.Transform(
  79. carla.Location(self._other_actor_transform.location.x,
  80. self._other_actor_transform.location.y,
  81. self._other_actor_transform.location.z - 500),
  82. self._other_actor_transform.rotation)
  83. first_vehicle = CarlaDataProvider.request_new_actor('vehicle.nissan.patrol', first_vehicle_transform)
  84. first_vehicle.set_simulate_physics(enabled=False)
  85. self.other_actors.append(first_vehicle)
  86. def _create_behavior(self):
  87. """
  88. The scenario defined after is a "follow leading vehicle" scenario. After
  89. invoking this scenario, it will wait for the user controlled vehicle to
  90. enter the start region, then make the other actor to drive until reaching
  91. the next intersection. Finally, the user-controlled vehicle has to be close
  92. enough to the other actor to end the scenario.
  93. If this does not happen within 60 seconds, a timeout stops the scenario
  94. """
  95. # to avoid the other actor blocking traffic, it was spawed elsewhere
  96. # reset its pose to the required one
  97. start_transform = ActorTransformSetter(self.other_actors[0], self._other_actor_transform)
  98. # let the other actor drive until next intersection
  99. # @todo: We should add some feedback mechanism to respond to ego_vehicle behavior
  100. driving_to_next_intersection = py_trees.composites.Parallel(
  101. "DrivingTowardsIntersection",
  102. policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE)
  103. driving_to_next_intersection.add_child(WaypointFollower(self.other_actors[0], self._first_vehicle_speed))
  104. driving_to_next_intersection.add_child(InTriggerDistanceToNextIntersection(
  105. self.other_actors[0], self._other_actor_stop_in_front_intersection))
  106. # stop vehicle
  107. stop = StopVehicle(self.other_actors[0], self._other_actor_max_brake)
  108. # end condition
  109. endcondition = py_trees.composites.Parallel("Waiting for end position",
  110. policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL)
  111. endcondition_part1 = InTriggerDistanceToVehicle(self.other_actors[0],
  112. self.ego_vehicles[0],
  113. distance=20,
  114. name="FinalDistance")
  115. endcondition_part2 = StandStill(self.ego_vehicles[0], name="StandStill", duration=1)
  116. endcondition.add_child(endcondition_part1)
  117. endcondition.add_child(endcondition_part2)
  118. # Build behavior tree
  119. sequence = py_trees.composites.Sequence("Sequence Behavior")
  120. sequence.add_child(start_transform)
  121. sequence.add_child(driving_to_next_intersection)
  122. sequence.add_child(stop)
  123. sequence.add_child(endcondition)
  124. sequence.add_child(ActorDestroy(self.other_actors[0]))
  125. return sequence
  126. def _create_test_criteria(self):
  127. """
  128. A list of all test criteria will be created that is later used
  129. in parallel behavior tree.
  130. """
  131. criteria = []
  132. collision_criterion = CollisionTest(self.ego_vehicles[0])
  133. criteria.append(collision_criterion)
  134. return criteria
  135. def __del__(self):
  136. """
  137. Remove all actors upon deletion
  138. """
  139. self.remove_all_actors()
  140. class FollowLeadingVehicleWithObstacle(BasicScenario):
  141. """
  142. This class holds a scenario similar to FollowLeadingVehicle
  143. but there is an obstacle in front of the leading vehicle
  144. This is a single ego vehicle scenario
  145. """
  146. timeout = 120 # Timeout of scenario in seconds
  147. def __init__(self, world, ego_vehicles, config, randomize=False, debug_mode=False, criteria_enable=True):
  148. """
  149. Setup all relevant parameters and create scenario
  150. """
  151. self._map = CarlaDataProvider.get_map()
  152. self._first_actor_location = 25
  153. self._second_actor_location = self._first_actor_location + 41
  154. self._first_actor_speed = 10
  155. self._second_actor_speed = 1.5
  156. self._reference_waypoint = self._map.get_waypoint(config.trigger_points[0].location)
  157. self._other_actor_max_brake = 1.0
  158. self._first_actor_transform = None
  159. self._second_actor_transform = None
  160. super(FollowLeadingVehicleWithObstacle, self).__init__("FollowLeadingVehicleWithObstacle",
  161. ego_vehicles,
  162. config,
  163. world,
  164. debug_mode,
  165. criteria_enable=criteria_enable)
  166. if randomize:
  167. self._ego_other_distance_start = random.randint(4, 8)
  168. def _initialize_actors(self, config):
  169. """
  170. Custom initialization
  171. """
  172. first_actor_waypoint, _ = get_waypoint_in_distance(self._reference_waypoint, self._first_actor_location)
  173. second_actor_waypoint, _ = get_waypoint_in_distance(self._reference_waypoint, self._second_actor_location)
  174. first_actor_transform = carla.Transform(
  175. carla.Location(first_actor_waypoint.transform.location.x,
  176. first_actor_waypoint.transform.location.y,
  177. first_actor_waypoint.transform.location.z - 500),
  178. first_actor_waypoint.transform.rotation)
  179. self._first_actor_transform = carla.Transform(
  180. carla.Location(first_actor_waypoint.transform.location.x,
  181. first_actor_waypoint.transform.location.y,
  182. first_actor_waypoint.transform.location.z + 1),
  183. first_actor_waypoint.transform.rotation)
  184. yaw_1 = second_actor_waypoint.transform.rotation.yaw + 90
  185. second_actor_transform = carla.Transform(
  186. carla.Location(second_actor_waypoint.transform.location.x,
  187. second_actor_waypoint.transform.location.y,
  188. second_actor_waypoint.transform.location.z - 500),
  189. carla.Rotation(second_actor_waypoint.transform.rotation.pitch, yaw_1,
  190. second_actor_waypoint.transform.rotation.roll))
  191. self._second_actor_transform = carla.Transform(
  192. carla.Location(second_actor_waypoint.transform.location.x,
  193. second_actor_waypoint.transform.location.y,
  194. second_actor_waypoint.transform.location.z + 1),
  195. carla.Rotation(second_actor_waypoint.transform.rotation.pitch, yaw_1,
  196. second_actor_waypoint.transform.rotation.roll))
  197. first_actor = CarlaDataProvider.request_new_actor(
  198. 'vehicle.nissan.patrol', first_actor_transform)
  199. second_actor = CarlaDataProvider.request_new_actor(
  200. 'vehicle.diamondback.century', second_actor_transform)
  201. first_actor.set_simulate_physics(enabled=False)
  202. second_actor.set_simulate_physics(enabled=False)
  203. self.other_actors.append(first_actor)
  204. self.other_actors.append(second_actor)
  205. def _create_behavior(self):
  206. """
  207. The scenario defined after is a "follow leading vehicle" scenario. After
  208. invoking this scenario, it will wait for the user controlled vehicle to
  209. enter the start region, then make the other actor to drive towards obstacle.
  210. Once obstacle clears the road, make the other actor to drive towards the
  211. next intersection. Finally, the user-controlled vehicle has to be close
  212. enough to the other actor to end the scenario.
  213. If this does not happen within 60 seconds, a timeout stops the scenario
  214. """
  215. # let the other actor drive until next intersection
  216. driving_to_next_intersection = py_trees.composites.Parallel(
  217. "Driving towards Intersection",
  218. policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE)
  219. obstacle_clear_road = py_trees.composites.Parallel("Obstalce clearing road",
  220. policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE)
  221. obstacle_clear_road.add_child(DriveDistance(self.other_actors[1], 4))
  222. obstacle_clear_road.add_child(KeepVelocity(self.other_actors[1], self._second_actor_speed))
  223. stop_near_intersection = py_trees.composites.Parallel(
  224. "Waiting for end position near Intersection",
  225. policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE)
  226. stop_near_intersection.add_child(WaypointFollower(self.other_actors[0], 10))
  227. stop_near_intersection.add_child(InTriggerDistanceToNextIntersection(self.other_actors[0], 20))
  228. driving_to_next_intersection.add_child(WaypointFollower(self.other_actors[0], self._first_actor_speed))
  229. driving_to_next_intersection.add_child(InTriggerDistanceToVehicle(self.other_actors[1],
  230. self.other_actors[0], 15))
  231. # end condition
  232. endcondition = py_trees.composites.Parallel("Waiting for end position",
  233. policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL)
  234. endcondition_part1 = InTriggerDistanceToVehicle(self.other_actors[0],
  235. self.ego_vehicles[0],
  236. distance=20,
  237. name="FinalDistance")
  238. endcondition_part2 = StandStill(self.ego_vehicles[0], name="FinalSpeed", duration=1)
  239. endcondition.add_child(endcondition_part1)
  240. endcondition.add_child(endcondition_part2)
  241. # Build behavior tree
  242. sequence = py_trees.composites.Sequence("Sequence Behavior")
  243. sequence.add_child(ActorTransformSetter(self.other_actors[0], self._first_actor_transform))
  244. sequence.add_child(ActorTransformSetter(self.other_actors[1], self._second_actor_transform))
  245. sequence.add_child(driving_to_next_intersection)
  246. sequence.add_child(StopVehicle(self.other_actors[0], self._other_actor_max_brake))
  247. sequence.add_child(TimeOut(3))
  248. sequence.add_child(obstacle_clear_road)
  249. sequence.add_child(stop_near_intersection)
  250. sequence.add_child(StopVehicle(self.other_actors[0], self._other_actor_max_brake))
  251. sequence.add_child(endcondition)
  252. sequence.add_child(ActorDestroy(self.other_actors[0]))
  253. sequence.add_child(ActorDestroy(self.other_actors[1]))
  254. return sequence
  255. def _create_test_criteria(self):
  256. """
  257. A list of all test criteria will be created that is later used
  258. in parallel behavior tree.
  259. """
  260. criteria = []
  261. collision_criterion = CollisionTest(self.ego_vehicles[0])
  262. criteria.append(collision_criterion)
  263. return criteria
  264. def __del__(self):
  265. """
  266. Remove all actors upon deletion
  267. """
  268. self.remove_all_actors()