1# pyright: reportUnusedImport=information, reportInvalidStringEscapeSequence=false
2"""
3In this module defines enums and constants that are used throughout the project.
4
5.. Comment "#: :meta hide-value:" hides the value in the documentation.
6"""
7
8import operator
9import os
10from enum import Enum, Flag, IntEnum, auto
11from functools import lru_cache, reduce
12from typing import TYPE_CHECKING, ClassVar, Dict, Union
13
14import carla
15from typing_extensions import Self, TypeAlias
16
17AD_RSS_AVAILABLE: bool
18"""
19Indicator if the :py:mod:`carla.ad` module is available, i.e. if the current carla version was build
20with RSS support. As a rule of thumb: On Windows this will be always false.
21If this is false some objects will be missing in the :py:mod:`carla` module, for example
22the :py:class:`carla.RssSensor`, likewise are some utilities of this project involving RSS not be
23available.
24
25See Also:
26 - https://carla.readthedocs.io/en/latest/adv_rss/
27 - https://github.com/intel/ad-rss-lib
28
29:meta hide-value:
30"""
31try:
32 from carla import ad # pyright: ignore # noqa
33 AD_RSS_AVAILABLE = True
34except ImportError:
35 AD_RSS_AVAILABLE = False # pyright: ignore[reportConstantRedefinition]
36
37
38READTHEDOCS = os.environ.get("READTHEDOCS", False)
39"""
40Whether the code is currently used to build the docs:
41
42Values:
43 - False: Normal Runtime
44 - 'local' : Local build
45 - other: ReadTheDocs build
46
47:meta hide-value:
48:meta private:
49"""
50
51
[docs]
52class AgentState(Flag):
53 """
54 High-level states that the agent currently can be in.
55
56 Used with :py:attr:`.LunaticAgent.current_states`
57 and :py:attr:`.InformationManager.state_counter`.
58 """
59
60 DRIVING = auto() #: :meta hide-value:
61 STOPPED = auto() #: :meta hide-value:
62 _parked = auto() # hidden it to avoid confusion, used further down for PARKED
63
64 BLOCKED_BY_VEHICLE = auto() #: :meta hide-value:
65 BLOCKED_RED_LIGHT = auto() #: :meta hide-value:
66 BLOCKED_BY_STATIC = auto()
67 """
68 Static obstacle.
69
70 Attention:
71 Not updated by the information manager
72 but in the :py:attr:`Phase.DETECT_STATIC_OBSTACLES` phase.
73
74 :meta hide-value:
75 """
76
77 BLOCKED_OTHER = auto() #: :meta hide-value:
78
79 REVERSE = auto() #: :meta hide-value:
80
81 OVERTAKING = auto() #: :meta hide-value:
82
83 AGAINST_LANE_DIRECTION = auto() #: :meta hide-value:
84
85 PARKED = _parked | STOPPED # we want this to be a combination of the two
86 """Includes :py:attr:`STOPPED`"""
87
88 BLOCKED = BLOCKED_OTHER | BLOCKED_BY_VEHICLE | BLOCKED_RED_LIGHT | BLOCKED_BY_STATIC
89 """
90 Combination of :python:`BLOCKED_OTHER | BLOCKED_BY_VEHICLE | BLOCKED_RED_LIGHT | BLOCKED_BY_STATIC`
91
92 :meta hide-value:
93 """
94
95 # Maybe more states like CAR_IN_FRONT <- detection matrix
96
97
[docs]
98class RulePriority(IntEnum):
99 """
100 Priority of a :py:class:`Rule <classes.rule.Rule>`.
101 The higher a value, the higher the priority.
102 Rules are sorted by their priority before being applied.
103 """
104 NULL = 0
105 LOWEST = 1
106 LOW = 2
107 NORMAL = 4
108 HIGH = 8
109 HIGHEST = 16
110
111
[docs]
112class Phase(Flag):
113 """
114 A rough order of the looped through states of the agent is:
115
116 .. code-block:: python
117
118 <Phases.NONE: 0>,
119 <Phases.UPDATE_INFORMATION|BEGIN: 5>,
120 <Phases.UPDATE_INFORMATION|END: 6>,
121 <Phases.PLAN_PATH|BEGIN: 9>,
122 <Phases.PLAN_PATH|END: 10>,
123 <Phases.DETECT_TRAFFIC_LIGHTS|BEGIN: 17>,
124 <Phases.DETECT_TRAFFIC_LIGHTS|END: 18>,
125 <Phases.DETECT_PEDESTRIANS|BEGIN: 33>,
126 <Phases.DETECT_PEDESTRIANS|END: 34>,
127 <Phases.DETECT_CARS|BEGIN: 65>,
128 <Phases.DETECT_CARS|END: 66>,
129 <Phases.POST_DETECTION_PHASE|BEGIN: 129>,
130 <Phases.POST_DETECTION_PHASE|END: 130>,
131 <Phases.EXECUTION|BEGIN: 1025>,
132 <Phases.EXECUTION|END: 1026>
133
134 Note:
135 The above cycle list is not up to date.
136
137 A complete list of all the main phases can be obtained by calling
138 - :py:func:`Phase.get_main_phases`
139 - :py:func:`Phase.get_phases`
140 """
141
142 # NOTE: # CRITICAL : Alias creation should be done >after< all the phases are created.
143 # see https://github.com/python/cpython/issues/91456
144 # Before python version (3.12+?) auto() DOES NOT WORK AS EXPECTED when using ALIASES
145
146 NONE = 0
147
148 # These can be combined with any of the other Phases
149 BEGIN = auto()
150 """
151 Indicates the beginning of a phase. Should always
152 be combined with another phase.
153
154 :meta hide-value:
155 """
156
157 END = auto()
158 """
159 Indicates the end of a phase. Should always
160 be combined with another phase.
161
162 :meta hide-value:
163 """
164
165 UPDATE_INFORMATION = auto()
166 """
167 Indicates the execution of the agents
168 :py:meth:`~.LunaticAgent.update_information` method
169
170 This is the first Phase of the agent and executed every
171 step.
172
173 :meta hide-value:
174 """
175
176 PLAN_PATH = auto()
177 """
178 Indicates that the planning of a new path has started.
179
180 Attention:
181 If the the path is replanned a :py:exc:`UpdatedPathException`
182 should be raised.
183
184 :meta hide-value:
185 """
186
187 DETECT_TRAFFIC_LIGHTS = auto()
188 """
189 Executed during the agents :py:meth:`~.LunaticAgent.detect_hazard`
190 method. Can add :py:attr:`.Hazard.TRAFFIC_LIGHT_RED` or
191 :py:attr:`.Hazard.TRAFFIC_LIGHT_YELLOW` to the agents
192 `.LunaticAgent.detected_hazards`:py:attr:.
193
194 :meta hide-value:
195 """
196
197 DETECT_PEDESTRIANS = auto()
198 """
199 Executed during the agents :py:meth:`~.LunaticAgent.detect_hazard`
200 method. Can add :py:attr:`.Hazard.PEDESTRIAN` to the agents
201 `.LunaticAgent.detected_hazards`:py:attr:.
202
203 :meta hide-value:
204 """
205
206 DETECT_STATIC_OBSTACLES = auto()
207 """
208 | Checks for static obstacles in the agents path with
209 | :py:attr:`.detect_obstacles_in_path` (:py:attr:`.LunaticAgent.static_obstacles_nearby`)
210
211 :meta hide-value:
212 """
213 # TODO: exchange LunaticAgent -> InformationManager when documented
214
215 DETECT_CARS = auto()
216 """
217 | Checks for vehicles in the agents path with
218 | :py:attr:`.detect_obstacles_in_path` (:py:attr:`.LunaticAgent.vehicles_nearby`)
219
220 Note:
221 If a car was detected executes :python:`Phase.CAR_DETECTED | BEGIN`,
222 :python:`Phase.DETECT_CARS | BEGIN` is **only** executed if no car was detected.
223
224 :meta hide-value:
225 """
226
227 TAKE_NORMAL_STEP = auto()
228 r"""
229 During this phase the :external-icon-parse:`:py:class:\`carla.VehicleControl\``
230 is calculated by the local planner.
231
232 :meta hide-value:
233 """
234
235 RSS_EVALUATION = auto()
236 """
237
238 See Also:
239 - :py:meth:`agents.lunatic_agent.LunaticAgent.parse_keyboard_input`
240 - :py:meth:`classes.keyboard_controls.RssKeyboardControls.parse_events`
241
242 :meta hide-value:
243 """
244
245 APPLY_MANUAL_CONTROLS = auto()
246 """Applied manually via human user interface.
247
248 :meta hide-value:
249 """
250
251 EXECUTION = auto()
252 """
253 Executed when the control is applied to the agent.
254
255 See Also:
256 :py:meth:`LunaticAgent.apply_control() <agents.lunatic_agent.LunaticAgent.parse_keyboard_input>`
257
258 :meta hide-value:
259 """
260
261 # --- Special situations ---
262 CAR_DETECTED = auto()
263 """
264 The :python:`Phase.CAR_DETECTED | BEGIN` is executed when a car is detected
265 and follows the :python:`Phase.DETECT_CARS | BEGIN` phase. If no car is detected
266 the :python:`Phase.DETECT_CARS | END` phase is executed.
267
268 :meta hide-value:
269 """
270
271 TURNING_AT_JUNCTION = auto()
272 """
273 Indicates that the agent is turning at a junction.
274
275 Warning:
276 This Phase might become obsolete.
277
278 :meta hide-value:
279 """
280
281 HAZARD = auto()
282 """
283 Not implemented. Refer to EMERGENCY | BEGIN
284
285 :meta hide-value:
286 """
287
288 EMERGENCY = auto()
289 """
290 Special Phase
291
292 See Also:
293 - `Emergency Phases`__
294
295 __ docs/Rules.html#emergency-phase
296 """
297
298 COLLISION = auto()
299 r"""
300 Special phase that is executed out-of-order when a
301 :external-icon-parse:`:py:class:\`carla.Sensor\`` detects a collision.
302
303 See Also:
304 - :external-icon-parse:`:py:class:\`carla.CollisionEvent\``
305 - https://carla.readthedocs.io/en/latest/ref_sensors/#collision-detector
306
307 :meta hide-value:
308 """
309
310 DONE = auto()
311 """
312 Indicates that the agent is at the end of its path and
313 :py:meth:`agent.done() <.LunaticAgent.done>` is :python:`True`.
314
315 :meta hide-value:
316 """
317
318 TERMINATING = auto()
319 """
320 Can be called when the agent is terminating. Must be executed by the user.
321
322 :meta hide-value:
323 """
324
325 CUSTOM_CYCLE = auto()
326 """
327 **experimental**
328
329 Can be used to indicate that the phase change is currently handled by the user.
330
331 Warning:
332 :any:`LunaticAgent.execute_phase` checks for exact match,
333 i.e. a phase :python:`UPDATE_INFORMATION | BEGIN | END`
334 will not be executed in the normal loop.
335
336 See Also:
337 Executed in :py:meth:`BlockingRule.loop_agent <classes.rule.BlockingRule.loop_agent>`
338
339 :meta hide-value:
340 """
341 # States which the agent can be in outside of a normal Phase0-5 loop
342
343 # --- Aliases & Combination Phases ---
344 # NOTE: # CRITICAL : Alias creation should be done after all the phases are created.!!!
345
346 DETECT_NON_CARS = DETECT_STATIC_OBSTACLES | DETECT_TRAFFIC_LIGHTS | DETECT_PEDESTRIANS
347 """
348 Combination of :python:`DETECT_STATIC_OBSTACLES | DETECT_TRAFFIC_LIGHTS | DETECT_PEDESTRIANS`
349
350 :meta hide-value:
351 """
352
353 DETECTION_PHASE = DETECT_NON_CARS | DETECT_CARS
354 """
355 Combination of :python:`DETECT_STATIC_OBSTACLES | DETECT_TRAFFIC_LIGHTS | DETECT_PEDESTRIANS | DETECT_CARS`
356
357 :meta hide-value:
358 """
359
360 EXCEPTIONS = HAZARD | EMERGENCY | COLLISION | TURNING_AT_JUNCTION \
361 | CAR_DETECTED | DONE | TERMINATING
362 """
363 Combination of :python:`HAZARD | EMERGENCY | COLLISION | TURNING_AT_JUNCTION | CAR_DETECTED | DONE | TERMINATING`
364
365 :meta hide-value:
366 """
367
368 USER_CONTROLLED = APPLY_MANUAL_CONTROLS | EXECUTION | TERMINATING | CUSTOM_CYCLE
369 """
370 Phases that might or not be went through as they must be implemented manually by the user.
371
372 Combination of :python:`APPLY_MANUAL_CONTROLS | EXECUTION | TERMINATING | CUSTOM_CYCLE`
373
374 :meta hide-value:
375 """
376
377 NORMAL_LOOP = UPDATE_INFORMATION | PLAN_PATH | DETECTION_PHASE | TAKE_NORMAL_STEP
378 """
379 Combination of :python:`UPDATE_INFORMATION | PLAN_PATH | DETECTION_PHASE | TAKE_NORMAL_STEP`
380
381 :meta hide-value:
382 """
383
384 IN_LOOP = NORMAL_LOOP | EMERGENCY | COLLISION
385 """
386 Phases that are executed in or before the inner step, EMERGENCY is executed,
387 right after the inner step.
388
389 Combination of :python:`NORMAL_LOOP | EMERGENCY | COLLISION`
390
391 See Also:
392 - :py:meth:`LunaticAgent.run_step <agents.lunatic_agent.LunaticAgent.run_step>`
393 - :py:mod:`agents.substep_managers.collision_manager`
394
395 :meta hide-value:
396 """
397
398 """
399 def __eq__(self, other):
400 # Makes sure that we can use current_phase == Phases.UPDATE_INFORMATION
401 if not isinstance(other, Phase):
402 return False
403 # Check None
404 if self is Phase.NONE or other is Phase.NONE:
405 return self is other
406 return self in other or other in self
407 """
408
409 def next_phase(self):
410 """
411 Note:
412 This function is more for >>debugging<< and testing purposes,
413 because of different control flows in the agent, the next phase
414 might not be accurate.
415
416 :meta private:
417 """
418 # Hardcoded transitions
419 if self in (Phase.NONE, Phase.EXECUTION | Phase.END): # Begin loop
420 return Phase.BEGIN | Phase.UPDATE_INFORMATION
421 #if self in (Phase.EXECUTION|Phase.END, Phase.DONE| Phase.END) : # End loop
422 # return Phase.NONE
423 if self == Phase.EXECUTION | Phase.BEGIN:
424 return Phase.USER_CONTROLLED # Cannot know what the next phase is
425 if Phase.BEGIN in self:
426 return (self & ~Phase.BEGIN) | Phase.END
427 # Note these should all be END phases
428 if Phase.DONE in self:
429 return Phase.BEGIN | Phase.UPDATE_INFORMATION
430 if Phase.EXCEPTIONS & self:
431 #return Phase.EXECUTION | Phase.BEGIN
432 return Phase.RSS_EVALUATION | Phase.BEGIN
433 if Phase.USER_CONTROLLED & self:
434 # cannot know what the next phase is
435 return Phase.USER_CONTROLLED | Phase.BEGIN # assure that is a BEGIN or END phase
436 if Phase.TERMINATING in self:
437 return Phase.NONE
438 if Phase.END in self: # Safeguard
439 return Phase.BEGIN | Phase((self & ~Phase.END).value * 2)
440 raise ValueError(f"Phase {self} is not a valid phase")
441 return Phase(self.value * 2)
442
443 def validate_next_phase(current_phase, next_phase: "Phase") -> None: # type: ignore
444 """
445 :meta private:
446 """
447 ...
448 #assumed_next = current_phase.next_phase()
449 # NotImplemented # Currently done in agent.execute_phase
450
451 @classmethod
452 def get_user_controlled_phases(cls):
453 """
454 :meta private:
455 """
456 user_phases = cls.APPLY_MANUAL_CONTROLS, cls.EXECUTION, cls.TERMINATING, cls.CUSTOM_CYCLE
457 assert all(p & cls.USER_CONTROLLED for p in user_phases)
458 return user_phases
459
[docs]
460 @classmethod
461 def get_phases(cls):
462 """Get all BEGIN and END phases combination."""
463 return cls.get_main_phases() + cls.get_exceptions() + [p for phase in cls.get_user_controlled_phases() for p in (phase | cls.BEGIN, phase | cls.END)] + [cls.TERMINATING | cls.BEGIN, cls.TERMINATING | cls.END]
464
465 @classmethod
466 @lru_cache(1) # < Python3.8
467 def get_main_phases(cls):
468 """
469 Phases which are not exceptions or user controlled.
470
471 :meta private:
472 """
473 main_phases = [cls.NONE, cls.UPDATE_INFORMATION | cls.BEGIN]
474 p = main_phases[1].next_phase()
475 while p != main_phases[1] and not (p & cls.USER_CONTROLLED):
476 if p & cls.USER_CONTROLLED:
477 raise ValueError(f"User controlled phase should not be in main phases {p}")
478 main_phases.append(p)
479 p = p.next_phase()
480 return main_phases
481
482 @classmethod
483 @lru_cache(1) # < Python3.8
484 def get_exceptions(cls) -> "list[Phase]":
485 """
486 Returns the :py:attr:`BEGIN` and :py:attr:`END` combinations of the exceptions that
487 do not follow the normal loop.
488
489 :meta private:
490 """
491 # TODO: Get this from EXCEPTIONS
492 exceptions = [cls.TURNING_AT_JUNCTION, cls.HAZARD, cls.EMERGENCY, cls.COLLISION, cls.CAR_DETECTED, cls.DONE]
493 exception_phases: "list[Phase]" = []
494 for e in exceptions: # improve with itertools
495 exception_phases.append(e | cls.BEGIN)
496 exception_phases.append(e | cls.END)
497 return exception_phases
498
[docs]
499 @classmethod
500 def from_string(cls, string: str) -> "Phase":
501 """
502 Utility method that turns a string like :code:`Phase.NAME | BEGIN | ...` into a Phase.
503
504 Note:
505 Only supports the operator :code:`|`. :code:`NAME` must be a valid Phase name.
506 """
507 elements = string.split("|") # Phase.NAME
508 elements = [cls[e.split(".")[-1].strip()] for e in elements]
509 return reduce(operator.or_, elements) # build union -> Phase
510
511
[docs]
512class Hazard(Flag):
513 """
514 Values currently stored in the agent's :py:attr:`~.LunaticAgent.detected_hazards`.
515 attribute.
516 """
517
518 # Type
519 TRAFFIC_LIGHT_RED = auto() #: :meta hide-value:
520 TRAFFIC_LIGHT_YELLOW = auto() #: :meta hide-value:
521
522 PEDESTRIAN = auto() #: :meta hide-value:
523 CAR = auto() #: :meta hide-value:
524 STATIC_OBSTACLE = auto()
525 """
526 Note:
527 These refer to actors and not the environment barriers.
528
529 :meta hide-value:
530 """
531
532 OTHER = auto() #: :meta hide-value:
533
534 JUNCTION = auto() #: :meta hide-value:
535
536 OBSTACLE = PEDESTRIAN | CAR | STATIC_OBSTACLE
537 """
538 Combination of :python:`PEDESTRIAN | CAR | STATIC_OBSTACLE`
539
540 :meta hide-value:
541 """
542
543 TRAFFIC_LIGHT = TRAFFIC_LIGHT_RED | TRAFFIC_LIGHT_YELLOW
544 """
545 Combination of :python:`TRAFFIC_LIGHT_RED | TRAFFIC_LIGHT_YELLOW`
546
547 :meta hide-value:
548 """
549
550
[docs]
551class HazardSeverity(Flag):
552 """
553 High level descriptions to further weight :py:class:`Hazard`.
554 The :py:class:`HazardSeverity` flags are stored in :py:attr:`~.LunaticAgent.detected_hazards_info`.
555 """
556
557 UNKNOWN = -1
558
559 NONE = 0
560 """
561 Initial values for :py:attr:`.LunaticAgent.detected_hazards_info`
562 """
563
564 # Severity
565 WARNING = auto() # Level 1
566 CRITICAL_ONLY = auto() #: :meta private:
567 EMERGENCY_ONLY = auto() #: :meta private:
568
569 COLLISION = auto()
570 """
571 Special case for collision.
572
573 :meta hide-value:
574 """
575
576 # Aliases - Always register at the end!
577 CRITICAL = WARNING | CRITICAL_ONLY # Level 2
578 """
579 Includes :py:attr:`WARNING`
580 """
581
582 EMERGENCY = CRITICAL | EMERGENCY_ONLY # Level 3
583 """
584 Includes :py:attr:`WARNING` and :py:attr:`CRITICAL`
585 """
586
587# ----------------- RoadOptions -----------------
588
589
590if TYPE_CHECKING:
591 # For type-checkers these classes should be the same.
592 # Prevent circular imports
593 from agents.navigation.local_planner import RoadOption
594else:
[docs]
595 class RoadOption(IntEnum):
596 """
597 RoadOption represents the possible topological configurations when moving from a segment of lane to other.
598
599 See Also:
600 :py:class:`RoadOptionColor` for the color representation of the road options.
601 """
602
603 VOID = -1
604 """
605 Indicated by green
606 """
607
608 LEFT = 1
609 """
610 Indicated by yellow
611
612 :meta hide-value:
613 """
614
615 RIGHT = 2
616 """
617 Indicated by cyan
618
619 :meta hide-value:
620 """
621
622 STRAIGHT = 3
623 """
624 Indicated by gray
625
626 :meta hide-value:
627 """
628
629 LANEFOLLOW = 4
630 """
631 Indicated by green
632
633 :meta hide-value:
634 """
635
636 CHANGELANELEFT = 5
637 """
638 Indicated by orange
639
640 :meta hide-value:
641 """
642
643 CHANGELANERIGHT = 6
644 """
645 Indicated by dark cyan
646
647 :meta hide-value:
648 """
649
650
651class __ItemAccessMeta(type):
652 """Class that allows item access on the class."""
653 def __getitem__(cls, key: str) -> carla.Color:
654 return getattr(cls, key)
655
656 def __call__(cls, option: "RoadOption") -> carla.Color:
657 return getattr(cls, option.name)
658
659
[docs]
660class RoadOptionColor(metaclass=__ItemAccessMeta):
661 """
662 Points to a :py:class:`carla.Color` object that represents the color of the road option.
663
664 Supports :python:`__getitem__(name)` and :python:`__call__(RoadOption)` for easy access.
665 """
666
667 VOID = carla.Color(0, 128, 0) # Green
668 """
669 Green
670
671 :meta hide-value:
672 """
673
674 LEFT = carla.Color(128, 128, 0) # Yellow
675 """
676 Yellow
677
678 :meta hide-value:
679 """
680
681 RIGHT = carla.Color(0, 128, 128) # Cyan
682 """
683 Cyan
684
685 :meta hide-value:
686 """
687
688 STRAIGHT = carla.Color(64, 64, 64) # Gray
689 """
690 Gray
691
692 :meta hide-value:
693 """
694
695 LANEFOLLOW = carla.Color(0, 128, 0) # Green
696 """
697 Green
698
699 :meta hide-value:
700 """
701
702 CHANGELANELEFT = carla.Color(128, 32, 0) # Orange
703 """
704 Orange
705
706 :meta hide-value:
707 """
708
709 CHANGELANERIGHT = carla.Color(0, 32, 128) # Dark Cyan
710 """
711 Dark Cyan
712
713 :meta hide-value:
714 """
715
716
717# ----------------- RSS -----------------
718# depending on availability of the carla.ad module
719
720# Stub classes that are alike
721class _CarlaIntEnum(IntEnum):
722 """
723 CARLA's Enums have a `values` entry that is not part of the python enum.Enum class.
724 This abstract class adds this method.
725 """
726
727 values: ClassVar[Dict[int, Self]]
728 names: ClassVar[Dict[str, Self]]
729
730 def __init_subclass__(cls):
731 # TODO: as this is runtime create it correctly.
732 cls.values: dict[int, cls] # noqa: B032
733 cls.names: dict[str, cls] # noqa: B032
734
735
745
746
756
757
758# assert that the stubs are correct
759if AD_RSS_AVAILABLE:
760 for value, name in carla.RssRoadBoundariesMode.values.items():
761 assert RssRoadBoundariesModeStub[str(name)] == value
762
763 for value, name in carla.RssLogLevel.values.items():
764 assert RssLogLevelStub[str(name)] == value
765
766if TYPE_CHECKING:
767 RssLogLevelAlias: TypeAlias = Union[carla.RssLogLevel, RssLogLevelStub]
768 RssRoadBoundariesModeAlias: TypeAlias = Union[carla.RssRoadBoundariesMode, RssRoadBoundariesModeStub]
769# Correct at Runtime, correct time needed for OmegaConf
770elif AD_RSS_AVAILABLE:
771 RssLogLevelAlias = carla.RssLogLevel
772 RssRoadBoundariesModeAlias = carla.RssRoadBoundariesMode
773else:
774 RssLogLevelAlias = RssLogLevelStub
775 RssRoadBoundariesModeAlias = RssRoadBoundariesModeStub
776
777# Non type variant
778if AD_RSS_AVAILABLE:
779 RssLogLevel = carla.RssLogLevel
780 RssRoadBoundariesMode = carla.RssRoadBoundariesMode
781else:
782 RssLogLevel = RssLogLevelStub
783 RssRoadBoundariesMode = RssRoadBoundariesModeStub
784
785# ----------------- RuleResult -----------------
786
787
[docs]
788class RuleResult(Enum):
789 """Special :python:`objects` that indicate special return values a :py:class:`.Rule`"""
790
791 NO_RESULT = object()
792 """
793 Indicates the the rule returned no result, e.g. because an exception was raised.
794
795 :meta hide-value:
796 """
797
798 NOT_APPLICABLE = object() # noqa: PIE796
799 """
800 Object that indicates that no action was executed, e.g. because the rule is on cooldown or blocked.
801
802 :meta hide-value:
803 """
804
805# ----------------- DetectionMatrix -----------------
806
807
[docs]
808class StreetType(str, Enum):
809 """Used by the :py:class:`.DetectionMatrix` to interpret the street type."""
810
811 ON_HIGHWAY = "On highway"
812 NON_HIGHWAY_STREET = "Non highway street"
813 ON_JUNCTION = "On junction"
814 ON_HIGHWAY_ENTRY = "On highway entry"
815 ON_HIGHWAY_EXIT = "On highway exit"
816 JUNCTION_AHEAD = "Junction ahead"
817 HIGHWAY_TRAFFIC_LIGHT = "Highway traffic light"
818 HIGHWAY_WITH_ENTRY_AND_EXIT = "Highway with entry/exit"
819
820
[docs]
821class StreetOccupation(IntEnum):
822 """
823 Enum to interpret the results of the :py:class:`DetectionMatrix`
824 """
825 NO_CAR = 0
826 EGO = 1
827 CAR = 2
828 NO_ROAD = 3
829
830 def __str__(self) -> str:
831 s = super().__str__()
832 return f"{s:^7}" # center the word