1import random
2from typing import TYPE_CHECKING, Optional
3
4from agents.tools.logs import logger
5
6if TYPE_CHECKING:
7 import carla
8
9 from agents.lunatic_agent import LunaticAgent
10 from classes.constants import Hazard
11
12
[docs]
13def emergency_manager(self: "LunaticAgent", *, reasons: "set[Hazard]", control: Optional["carla.VehicleControl"] = None, force=False) -> "carla.VehicleControl":
14 """
15 Modifies the control values to perform an emergency stop.
16 The steering remains unchanged to avoid going out of the lane during turns.
17
18 Parameters:
19 reasons: set of :py:class:`.Hazard` that triggered the emergency stop.
20 If empty this function will do nothing. Normally :py:attr:`detected_hazards <.LunaticAgent.detected_hazards>`.
21 control: control to be modified in place.
22 If :code:`None` the control for the current step will be calculated.
23 force: if True, the emergency stop will be performed even if the **reasons** are empty.
24 """
25 control = control or self.get_control()
26 if control is None:
27 control = self._calculate_control(debug=self.debug)
28 if not reasons and not force:
29 return control
30 logger.debug("Emergency Manager: Hazards not cleared or forced stopping. Reason: %s", reasons)
31
32 # TODO, future: Can be turned into a rule. Problem here and with rule it will trigger each step -> new random value
33 # rule should return consistent result for a period of time
34 if self.config.emergency.ignore_percentage > 0.0 and self.config.emergency.ignore_percentage / 100 > random.random():
35 return control
36
37 control.throttle = 0.0
38 # negate the chosen default setting
39 if self.config.emergency.hand_brake_modify_chance > 0.0 and self.config.emergency.hand_brake_modify_chance / 100 > random.random():
40 control.hand_brake = not self.config.emergency.hand_brake
41 else:
42 control.hand_brake = self.config.emergency.hand_brake
43
44 # Enable random steering if flagged
45 if self.config.emergency.do_random_steering:
46 control.steer = random.uniform(*self.config.emergency.random_steering_range) # Randomly adjust steering
47
48 control.brake = self.config.controls.max_brake
49
50 # TODO: more sophisticated emergency behavior
51
52 return control