From 32b16fbaa5b9066e31031d94ea25028bafa4cb89 Mon Sep 17 00:00:00 2001 From: Valentina-Gol Date: Fri, 14 Apr 2023 17:02:11 +0300 Subject: [PATCH] added new layers --- requirements.txt | 1 - src/dt_maps/Map.py | 21 ++- src/dt_maps/types/citizens.py | 57 ++++++++ src/dt_maps/types/ground_tags.py | 63 +++++++++ src/dt_maps/types/map.py | 20 +++ src/dt_maps/types/traffic_signs.py | 90 +++++++++++++ src/dt_maps/types/vehicles.py | 96 ++++++++++++++ src/dt_maps/types/watchtowers.py | 2 +- src/dt_maps_tests/test_layer_citizens.py | 74 +++++++++++ src/dt_maps_tests/test_layer_ground_tags.py | 120 +++++++++++++++++ src/dt_maps_tests/test_layer_traffic_signs.py | 122 ++++++++++++++++++ src/dt_maps_tests/test_layer_vehicles.py | 99 ++++++++++++++ tests/maps/minimal_autolab/citizens.yaml | 7 + tests/maps/minimal_autolab/frames.yaml | 37 +++++- tests/maps/minimal_autolab/ground_tags.yaml | 13 ++ tests/maps/minimal_autolab/traffic_signs.yaml | 13 ++ tests/maps/minimal_autolab/vehicles.yaml | 10 ++ 17 files changed, 838 insertions(+), 7 deletions(-) create mode 100644 src/dt_maps/types/citizens.py create mode 100644 src/dt_maps/types/ground_tags.py create mode 100644 src/dt_maps/types/traffic_signs.py create mode 100644 src/dt_maps/types/vehicles.py create mode 100644 src/dt_maps_tests/test_layer_citizens.py create mode 100644 src/dt_maps_tests/test_layer_ground_tags.py create mode 100644 src/dt_maps_tests/test_layer_traffic_signs.py create mode 100644 src/dt_maps_tests/test_layer_vehicles.py create mode 100644 tests/maps/minimal_autolab/citizens.yaml create mode 100644 tests/maps/minimal_autolab/ground_tags.yaml create mode 100644 tests/maps/minimal_autolab/traffic_signs.yaml create mode 100644 tests/maps/minimal_autolab/vehicles.yaml diff --git a/requirements.txt b/requirements.txt index 99ef6cf..f3dd47e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,6 @@ rednose==1.3.0 numpy==1.19.5 networkx==2.6.3 coverage==5.0.3 -codecov==2.0.16 sphinx sphinx-rtd-theme diff --git a/src/dt_maps/Map.py b/src/dt_maps/Map.py index b14fb10..b29fa5e 100644 --- a/src/dt_maps/Map.py +++ b/src/dt_maps/Map.py @@ -15,9 +15,24 @@ from dt_maps.types.frames import Frame from dt_maps.types.tile_maps import TileMap from dt_maps.types.watchtowers import Watchtower +from dt_maps.types.vehicles import Vehicle +from dt_maps.types.citizens import Citizen +from dt_maps.types.traffic_signs import TrafficSign +from dt_maps.types.ground_tags import GroundTag logging.basicConfig() +REGISTER = { + "frames": Frame, + "tiles": Tile, + "watchtowers": Watchtower, + "tile_maps": TileMap, + "citizens": Citizen, + "vehicles": Vehicle, + "traffic_signs": TrafficSign, + "ground_tags": GroundTag +} + class Map: """ @@ -145,9 +160,7 @@ def from_disk(cls, name: str, map_dir: str) -> 'Map': # register type converters for known layers register = lambda l, t: m.layers.get(l).register_entity_helper(t) if m.layers.has(l) else 0 - register("frames", Frame) - register("tile_maps", TileMap) - register("tiles", Tile) - register("watchtowers", Watchtower) + for layer_name in REGISTER: + register(layer_name, REGISTER[layer_name]) # --- return m diff --git a/src/dt_maps/types/citizens.py b/src/dt_maps/types/citizens.py new file mode 100644 index 0000000..04b3d69 --- /dev/null +++ b/src/dt_maps/types/citizens.py @@ -0,0 +1,57 @@ +from enum import Enum +from typing import Union, Iterable, Optional, Any + +from dt_maps.types.commons import EntityHelper, FieldPath +from dt_maps.types.frames import Frame + +COLOR = "color" + + +class CitizenType(Enum): + YELLOW = "yellow" + RED = "red" + GREEN = "green" + GRAY = "grey" + + +class Citizen(EntityHelper): + + def _get_property_values(self, name: str) -> Optional[Iterable[Any]]: + return { + COLOR: [w.value for w in CitizenType] + }[name] + + def _get_property_types(self, name: str) -> Union[type, Iterable[type]]: + return { + COLOR: str + }[name] + + def _get_layer_name(self) -> str: + return "citizens" + + def _set_property(self, name: FieldPath, types: Union[type, Iterable[type]], value: Any): + # CitizenType -> str + if name == COLOR and isinstance(value, CitizenType): + value = value.value + # --- + super(Citizen, self)._set_property(name, types, value) + + def _get_property(self, name: FieldPath) -> Any: + value = super(Citizen, self)._get_property(name) + # str -> CitizenType + if name == COLOR: + value = CitizenType(value) + # --- + return value + + @property + def frame(self) -> Frame: + return Frame.create(self._map, self._key) + + @property + def color(self) -> CitizenType: + return CitizenType(self._get_property(COLOR)) + + @color.setter + def color(self, value: Union[str, CitizenType]): + self._set_property(COLOR, str, value) diff --git a/src/dt_maps/types/ground_tags.py b/src/dt_maps/types/ground_tags.py new file mode 100644 index 0000000..9859fb1 --- /dev/null +++ b/src/dt_maps/types/ground_tags.py @@ -0,0 +1,63 @@ +from typing import Union, Iterable, Optional, Any + +from dt_maps.types.commons import EntityHelper, FieldPath +from dt_maps.types.frames import Frame + +SIZE = "size" +ID = "id" +FAMILY = "family" + + +class GroundTag(EntityHelper): + + def _get_property_values(self, name: str) -> Optional[Iterable[Any]]: + return { + SIZE: None, + ID: None, + FAMILY: None + }[name] + + def _get_property_types(self, name: str) -> Union[type, Iterable[type]]: + return { + SIZE: float, + ID: int, + FAMILY: str + }[name] + + def _get_layer_name(self) -> str: + return "ground_tags" + + def _set_property(self, name: FieldPath, types: Union[type, Iterable[type]], value: Any): + super(GroundTag, self)._set_property(name, types, value) + + def _get_property(self, name: FieldPath) -> Any: + value = super(GroundTag, self)._get_property(name) + return value + + @property + def frame(self) -> Frame: + return Frame.create(self._map, self._key) + + @property + def size(self) -> float: + return self._get_property(SIZE) + + @property + def id(self) -> int: + return self._get_property(ID) + + @property + def family(self) -> str: + return self._get_property(FAMILY) + + @size.setter + def size(self, value: float): + self._set_property(SIZE, float, value) + + @id.setter + def id(self, value: int): + self._set_property(ID, int, value) + + @family.setter + def family(self, value: str): + self._set_property(FAMILY, str, value) diff --git a/src/dt_maps/types/map.py b/src/dt_maps/types/map.py index 85eb8dd..f2daa8b 100644 --- a/src/dt_maps/types/map.py +++ b/src/dt_maps/types/map.py @@ -21,6 +21,10 @@ from dt_maps.types.tile_maps import TileMap from dt_maps.types.tiles import Tile from dt_maps.types.watchtowers import Watchtower +from dt_maps.types.traffic_signs import TrafficSign +from dt_maps.types.vehicles import Vehicle +from dt_maps.types.citizens import Citizen +from dt_maps.types.ground_tags import GroundTag class MapAsset: @@ -256,6 +260,22 @@ def tiles(self) -> MapLayer[Tile]: @property def watchtowers(self) -> MapLayer[Watchtower]: return self.__getitem__("watchtowers") + + @property + def traffic_signs(self) -> MapLayer[TrafficSign]: + return self.__getitem__("traffic_signs") + + @property + def ground_tags(self) -> MapLayer[GroundTag]: + return self.__getitem__("ground_tags") + + @property + def vehicles(self) -> MapLayer[Vehicle]: + return self.__getitem__("vehicles") + + @property + def citizens(self) -> MapLayer[Citizen]: + return self.__getitem__("citizens") # known layers <== diff --git a/src/dt_maps/types/traffic_signs.py b/src/dt_maps/types/traffic_signs.py new file mode 100644 index 0000000..56927e9 --- /dev/null +++ b/src/dt_maps/types/traffic_signs.py @@ -0,0 +1,90 @@ +from enum import Enum +from typing import Union, Iterable, Optional, Any + +from dt_maps.types.commons import EntityHelper, FieldPath +from dt_maps.types.frames import Frame + +TYPE = "type" +ID = "id" +FAMILY = "family" + + +class TrafficSignType(Enum): + FOUR_WAY_INTERSECT = "four_way_intersect" + DO_NOT_ENTER = "do_not_enter" + DUCK_CROSSING = "duck_crossing" + LEFT_T_INTERSECT = "left_t_intersect" + NO_LEFT_TURN = "no_left_turn" + NO_RIGHT_TURN = "no_right_turn" + ONEWAY_LEFT = "oneway_left" + ONEWAY_RIGHT = "oneway_right" + PARKING = "parking" + PEDESTRIAN = "pedestrian" + RIGHT_T_INTERSECT = "right_t_intersect" + STOP = "stop" + T_INTERSECTION = "t_intersection" + T_LIGHT_AHEAD = "t_light_ahead" + YIELD = "yield" + + +class TrafficSign(EntityHelper): + + def _get_property_values(self, name: str) -> Optional[Iterable[Any]]: + return { + TYPE: [w.value for w in TrafficSignType], + ID: None, + FAMILY: None + }[name] + + def _get_property_types(self, name: str) -> Union[type, Iterable[type]]: + return { + TYPE: str, + ID: int, + FAMILY: str + }[name] + + def _get_layer_name(self) -> str: + return "traffic_signs" + + def _set_property(self, name: FieldPath, types: Union[type, Iterable[type]], value: Any): + # TrafficSignType -> str + if name == TYPE and isinstance(value, TrafficSignType): + value = value.value + # --- + super(TrafficSign, self)._set_property(name, types, value) + + def _get_property(self, name: FieldPath) -> Any: + value = super(TrafficSign, self)._get_property(name) + # str -> TrafficSignType + if name == TYPE: + value = TrafficSignType(value) + # --- + return value + + @property + def frame(self) -> Frame: + return Frame.create(self._map, self._key) + + @property + def type(self) -> TrafficSignType: + return TrafficSignType(self._get_property(TYPE)) + + @property + def id(self) -> int: + return self._get_property(ID) + + @property + def family(self) -> str: + return self._get_property(FAMILY) + + @type.setter + def type(self, value: Union[str, TrafficSignType]): + self._set_property(TYPE, str, value) + + @id.setter + def id(self, value: int): + self._set_property(ID, int, value) + + @family.setter + def family(self, value: str): + self._set_property(FAMILY, str, value) diff --git a/src/dt_maps/types/vehicles.py b/src/dt_maps/types/vehicles.py new file mode 100644 index 0000000..7ac64d9 --- /dev/null +++ b/src/dt_maps/types/vehicles.py @@ -0,0 +1,96 @@ +from enum import Enum +from typing import Union, Iterable, Optional, Any + +from dt_maps.types.commons import EntityHelper, FieldPath +from dt_maps.types.frames import Frame + +CONFIGURATION = "configuration" +ID = "id" +COLOR = "color" + + +class ColorType(Enum): + BLUE = "blue" + RED = "red" + GREEN = "green" + GRAY = "grey" + + +class VehicleType(Enum): + # duckie-bot + DB18: str = "DB18" + DB19: str = "DB19" + DB20: str = "DB20" + DB21M: str = "DB21M" + DB21J: str = "DB21J" + DB21R: str = "DB21R" + # duckie-drone + DD18: str = "DD18" + DD21: str = "DD21" + + +class Vehicle(EntityHelper): + + def _get_property_values(self, name: str) -> Optional[Iterable[Any]]: + return { + CONFIGURATION: [w.value for w in VehicleType], + ID: None, + COLOR: [w.value for w in ColorType] + }[name] + + def _get_property_types(self, name: str) -> Union[type, Iterable[type]]: + return { + CONFIGURATION: str, + ID: (type(None), str), + COLOR: str + }[name] + + def _get_layer_name(self) -> str: + return "vehicles" + + def _set_property(self, name: FieldPath, types: Union[type, Iterable[type]], value: Any): + # VehicleType -> str or ColorType -> str + if (name == CONFIGURATION and isinstance(value, VehicleType)) or \ + (name == COLOR and isinstance(value, ColorType)): + value = value.value + # --- + super(Vehicle, self)._set_property(name, types, value) + + def _get_property(self, name: FieldPath) -> Any: + value = super(Vehicle, self)._get_property(name) + # str -> VehicleType + if name == CONFIGURATION: + value = VehicleType(value) + # str -> ColorType + if name == COLOR: + value = ColorType(value) + # --- + return value + + @property + def frame(self) -> Frame: + return Frame.create(self._map, self._key) + + @property + def configuration(self) -> VehicleType: + return VehicleType(self._get_property(CONFIGURATION)) + + @property + def id(self) -> Optional[str]: + return self._get_property(ID) + + @property + def color(self) -> ColorType: + return ColorType(self._get_property(COLOR)) + + @configuration.setter + def configuration(self, value: Union[str, VehicleType]): + self._set_property(CONFIGURATION, str, value) + + @id.setter + def id(self, value: Optional[str]): + self._set_property(ID, (type(None), str), value) + + @color.setter + def color(self, value: Union[str, ColorType]): + self._set_property(COLOR, str, value) diff --git a/src/dt_maps/types/watchtowers.py b/src/dt_maps/types/watchtowers.py index 48a1315..8160fd0 100644 --- a/src/dt_maps/types/watchtowers.py +++ b/src/dt_maps/types/watchtowers.py @@ -63,4 +63,4 @@ def configuration(self, value: Union[str, WatchtowerType]): @id.setter def id(self, value: Optional[str]): - self._set_property(ID, Optional[str], value) + self._set_property(ID, (type(None), str), value) diff --git a/src/dt_maps_tests/test_layer_citizens.py b/src/dt_maps_tests/test_layer_citizens.py new file mode 100644 index 0000000..07711a8 --- /dev/null +++ b/src/dt_maps_tests/test_layer_citizens.py @@ -0,0 +1,74 @@ +from dt_maps import Map +from dt_maps.types.citizens import CitizenType + +from . import get_asset_path + + +def _load_map() -> Map: + map_dir = get_asset_path("maps/minimal_autolab") + return Map.from_disk("minimal_autolab", map_dir) + + +def test_citizens_num_citizens(): + m = _load_map() + assert len(m.layers.citizens) == 3 + + +def test_citizens_citizen1(): + m = _load_map() + citizen = "map_0/duckie1" + assert m.layers.citizens[citizen].color == CitizenType.YELLOW + # TODO: id is optional, but we catch exception: `layer 'citizens' does not have field 'id'`... + # assert m.layers.citizens[citizen].id is None + + +def test_citizens_set_raw(): + m = _load_map() + citizen = "map_0/duckie1" + m.layers.citizens[citizen].color = "red" + try: + test_citizens_citizen1() + assert False + except AssertionError: + pass + assert m.layers.citizens[citizen].color == CitizenType.RED + + +def test_citizens_set_wrong_raw(): + m = _load_map() + citizen = "map_0/duckie1" + try: + m.layers.citizens[citizen].color = "wrong" + assert False + except ValueError: + pass + + +def test_citizens_set_setitem_raw(): + m = _load_map() + citizen = "map_0/duckie1" + m.layers.citizens[citizen]["color"] = CitizenType.GREEN + try: + test_citizens_citizen1() + assert False + except AssertionError: + pass + assert m.layers.citizens[citizen]["color"] == CitizenType.GREEN + + +def test_citizens_set_wrong_setitem_raw(): + m = _load_map() + citizen = "map_0/duckie1" + try: + m.layers.citizens[citizen]["color"] = "wrong" + assert False + except ValueError: + pass + + +def test_citizens_frames(): + m = _load_map() + citizen1 = "map_0/duckie1" + citizen2 = citizen1 + "/duckie2" + assert m.layers.citizens[citizen1].frame.relative_to == "map_0" + assert m.layers.citizens[citizen2].frame.relative_to == citizen1 diff --git a/src/dt_maps_tests/test_layer_ground_tags.py b/src/dt_maps_tests/test_layer_ground_tags.py new file mode 100644 index 0000000..ec5176d --- /dev/null +++ b/src/dt_maps_tests/test_layer_ground_tags.py @@ -0,0 +1,120 @@ +from dt_maps import Map +from . import get_asset_path + + +def _load_map() -> Map: + map_dir = get_asset_path("maps/minimal_autolab") + return Map.from_disk("minimal_autolab", map_dir) + + +def test_ground_tags_num_ground_tags(): + m = _load_map() + assert len(m.layers.ground_tags) == 3 + + +def test_ground_tags_ground_tag1(): + m = _load_map() + ground_tag = "map_0/tag1" + assert m.layers.ground_tags[ground_tag].size == 0.1 + assert m.layers.ground_tags[ground_tag].id == 1 + assert m.layers.ground_tags[ground_tag].family == "36h11" + + +def test_ground_tags_set_raw(): + m = _load_map() + ground_tag = "map_0/tag1" + m.layers.ground_tags[ground_tag].size = 0.15 + m.layers.ground_tags[ground_tag].id = 2 + m.layers.ground_tags[ground_tag].family = "36h12" + try: + test_ground_tags_ground_tag1() + assert False + except AssertionError: + pass + assert m.layers.ground_tags[ground_tag].size == 0.15 + assert m.layers.ground_tags[ground_tag].id == 2 + assert m.layers.ground_tags[ground_tag].family == "36h12" + + +def test_ground_tags_set_wrong_raw_size(): + m = _load_map() + ground_tag = "map_0/tag1" + try: + m.layers.ground_tags[ground_tag].size = "wrong" + assert False + except ValueError: + pass + + +def test_ground_tags_set_wrong_raw_id(): + m = _load_map() + ground_tag = "map_0/tag1" + try: + m.layers.ground_tags[ground_tag].id = "wrong" + assert False + except ValueError: + pass + + +def test_ground_tags_set_wrong_raw_family(): + m = _load_map() + ground_tag = "map_0/tag1" + try: + m.layers.ground_tags[ground_tag].family = 1 + assert False + except ValueError: + pass + + +def test_ground_tags_set_setitem_raw(): + m = _load_map() + ground_tag = "map_0/tag1" + m.layers.ground_tags[ground_tag]["size"] = 0.15 + m.layers.ground_tags[ground_tag]["id"] = 2 + m.layers.ground_tags[ground_tag]["family"] = "36h12" + try: + test_ground_tags_ground_tag1() + assert False + except AssertionError: + pass + assert m.layers.ground_tags[ground_tag]["size"] == 0.15 + assert m.layers.ground_tags[ground_tag]["id"] == 2 + assert m.layers.ground_tags[ground_tag]["family"] == "36h12" + + +def test_ground_tags_set_wrong_setitem_raw_size(): + m = _load_map() + ground_tag = "map_0/tag1" + try: + m.layers.ground_tags[ground_tag]["size"] = "wrong" + assert False + except ValueError: + pass + + +def test_ground_tags_set_wrong_setitem_raw_id(): + m = _load_map() + ground_tag = "map_0/tag1" + try: + m.layers.ground_tags[ground_tag]["id"] = "wrong" + assert False + except ValueError: + pass + + +def test_ground_tags_set_wrong_setitem_raw_family(): + m = _load_map() + ground_tag = "map_0/tag1" + try: + m.layers.ground_tags[ground_tag]["family"] = 1 + assert False + except ValueError: + pass + + +def test_ground_tags_frames(): + m = _load_map() + ground_tag1 = "map_0/tag1" + ground_tag2 = ground_tag1 + "/tag2" + assert m.layers.ground_tags[ground_tag1].frame.relative_to == "map_0" + assert m.layers.ground_tags[ground_tag2].frame.relative_to == ground_tag1 diff --git a/src/dt_maps_tests/test_layer_traffic_signs.py b/src/dt_maps_tests/test_layer_traffic_signs.py new file mode 100644 index 0000000..33d824f --- /dev/null +++ b/src/dt_maps_tests/test_layer_traffic_signs.py @@ -0,0 +1,122 @@ +from dt_maps import Map +from dt_maps.types.traffic_signs import TrafficSignType + +from . import get_asset_path + + +def _load_map() -> Map: + map_dir = get_asset_path("maps/minimal_autolab") + return Map.from_disk("minimal_autolab", map_dir) + + +def test_traffic_signs_num_traffic_signs(): + m = _load_map() + assert len(m.layers.traffic_signs) == 3 + + +def test_traffic_signs_traffic_sign1(): + m = _load_map() + traffic_sign = "map_0/sign1" + assert m.layers.traffic_signs[traffic_sign].type == TrafficSignType.STOP + assert m.layers.traffic_signs[traffic_sign].id == 1 + assert m.layers.traffic_signs[traffic_sign].family == "36h11" + + +def test_traffic_signs_set_raw(): + m = _load_map() + traffic_sign = "map_0/sign1" + m.layers.traffic_signs[traffic_sign].type = "yield" + m.layers.traffic_signs[traffic_sign].id = 2 + m.layers.traffic_signs[traffic_sign].family = "36h12" + try: + test_traffic_signs_traffic_sign1() + assert False + except AssertionError: + pass + assert m.layers.traffic_signs[traffic_sign].type == TrafficSignType.YIELD + assert m.layers.traffic_signs[traffic_sign].id == 2 + assert m.layers.traffic_signs[traffic_sign].family == "36h12" + + +def test_traffic_signs_set_wrong_raw_type(): + m = _load_map() + traffic_sign = "map_0/sign1" + try: + m.layers.traffic_signs[traffic_sign].type = "wrong" + assert False + except ValueError: + pass + + +def test_traffic_signs_set_wrong_raw_id(): + m = _load_map() + traffic_sign = "map_0/sign1" + try: + m.layers.traffic_signs[traffic_sign].id = "wrong" + assert False + except ValueError: + pass + + +def test_traffic_signs_set_wrong_raw_family(): + m = _load_map() + traffic_sign = "map_0/sign1" + try: + m.layers.traffic_signs[traffic_sign].family = 1 + assert False + except ValueError: + pass + + +def test_traffic_signs_set_setitem_raw(): + m = _load_map() + traffic_sign = "map_0/sign1" + m.layers.traffic_signs[traffic_sign]["type"] = TrafficSignType.YIELD + m.layers.traffic_signs[traffic_sign]["id"] = 2 + m.layers.traffic_signs[traffic_sign]["family"] = "36h12" + try: + test_traffic_signs_traffic_sign1() + assert False + except AssertionError: + pass + assert m.layers.traffic_signs[traffic_sign]["type"] == TrafficSignType.YIELD + assert m.layers.traffic_signs[traffic_sign]["id"] == 2 + assert m.layers.traffic_signs[traffic_sign]["family"] == "36h12" + + +def test_traffic_signs_set_wrong_setitem_raw_type(): + m = _load_map() + traffic_sign = "map_0/sign1" + try: + m.layers.traffic_signs[traffic_sign]["type"] = "wrong" + assert False + except ValueError: + pass + + +def test_traffic_signs_set_wrong_setitem_raw_id(): + m = _load_map() + traffic_sign = "map_0/sign1" + try: + m.layers.traffic_signs[traffic_sign]["id"] = "wrong" + assert False + except ValueError: + pass + + +def test_traffic_signs_set_wrong_setitem_raw_family(): + m = _load_map() + traffic_sign = "map_0/sign1" + try: + m.layers.traffic_signs[traffic_sign]["family"] = 1 + assert False + except ValueError: + pass + + +def test_traffic_signs_frames(): + m = _load_map() + traffic_sign1 = "map_0/sign1" + traffic_sign2 = traffic_sign1 + "/sign2" + assert m.layers.traffic_signs[traffic_sign1].frame.relative_to == "map_0" + assert m.layers.traffic_signs[traffic_sign2].frame.relative_to == traffic_sign1 diff --git a/src/dt_maps_tests/test_layer_vehicles.py b/src/dt_maps_tests/test_layer_vehicles.py new file mode 100644 index 0000000..d930580 --- /dev/null +++ b/src/dt_maps_tests/test_layer_vehicles.py @@ -0,0 +1,99 @@ +from dt_maps import Map +from dt_maps.types.vehicles import VehicleType, ColorType + +from . import get_asset_path + + +def _load_map() -> Map: + map_dir = get_asset_path("maps/minimal_autolab") + return Map.from_disk("minimal_autolab", map_dir) + + +def test_vehicles_num_vehicles(): + m = _load_map() + assert len(m.layers.vehicles) == 3 + + +def test_vehicles_vehicle1(): + m = _load_map() + vehicle = "map_0/duckiebot1" + assert m.layers.vehicles[vehicle].configuration == VehicleType.DB18 + assert m.layers.vehicles[vehicle].color == ColorType.GREEN + # TODO: id is optional, but we catch exception: `layer 'vehicles' does not have field 'id'`... + # assert m.layers.vehicles[vehicle].id is None + + +def test_vehicles_set_raw(): + m = _load_map() + vehicle = "map_0/duckiebot1" + m.layers.vehicles[vehicle].configuration = "DB19" + m.layers.vehicles[vehicle].color = "red" + try: + test_vehicles_vehicle1() + assert False + except AssertionError: + pass + assert m.layers.vehicles[vehicle].configuration == VehicleType.DB19 + assert m.layers.vehicles[vehicle].color == ColorType.RED + + +def test_vehicles_set_wrong_raw_configuration(): + m = _load_map() + vehicle = "map_0/duckiebot1" + try: + m.layers.vehicles[vehicle].configuration = "wrong" + assert False + except ValueError: + pass + + +def test_vehicles_set_wrong_raw_color(): + m = _load_map() + vehicle = "map_0/duckiebot1" + try: + m.layers.vehicles[vehicle].color = "wrong" + assert False + except ValueError: + pass + + +def test_vehicles_set_setitem_raw(): + m = _load_map() + vehicle = "map_0/duckiebot1" + m.layers.vehicles[vehicle]["configuration"] = VehicleType.DB19 + m.layers.vehicles[vehicle]["color"] = ColorType.RED + try: + test_vehicles_vehicle1() + assert False + except AssertionError: + pass + assert m.layers.vehicles[vehicle]["configuration"] == VehicleType.DB19 + assert m.layers.vehicles[vehicle]["color"] == ColorType.RED + + +def test_vehicles_set_wrong_setitem_raw_configuration(): + m = _load_map() + vehicle = "map_0/duckiebot1" + try: + m.layers.vehicles[vehicle]["configuration"] = "wrong" + assert False + except ValueError: + pass + + +def test_vehicles_set_wrong_setitem_raw_color(): + m = _load_map() + vehicle = "map_0/duckiebot1" + try: + m.layers.vehicles[vehicle]["color"] = "wrong" + assert False + except ValueError: + pass + + +def test_vehicles_frames(): + m = _load_map() + vehicle1 = "map_0/duckiebot1" + vehicle2 = vehicle1 + "/duckiebot2" + assert m.layers.vehicles[vehicle1].frame.relative_to == "map_0" + assert m.layers.vehicles[vehicle2].frame.relative_to == vehicle1 diff --git a/tests/maps/minimal_autolab/citizens.yaml b/tests/maps/minimal_autolab/citizens.yaml new file mode 100644 index 0000000..6f79aca --- /dev/null +++ b/tests/maps/minimal_autolab/citizens.yaml @@ -0,0 +1,7 @@ +citizens: + map_0/duckie1: + color: yellow + map_0/duckie3: + color: red + map_0/duckie1/duckie2: + color: red diff --git a/tests/maps/minimal_autolab/frames.yaml b/tests/maps/minimal_autolab/frames.yaml index 9040ca8..3d5837c 100644 --- a/tests/maps/minimal_autolab/frames.yaml +++ b/tests/maps/minimal_autolab/frames.yaml @@ -98,4 +98,39 @@ frames: relative_to: map_0/watchtower1 pose: y: 0.9 - \ No newline at end of file + map_0/duckie1: + relative_to: map_0 + pose: + x: 1.6 + y: 1.6 + map_0/duckie1/duckie2: + relative_to: map_0/duckie1 + pose: + y: 0.9 + map_0/duckiebot1: + relative_to: map_0 + pose: + x: 1.6 + y: 1.6 + map_0/duckiebot1/duckiebot2: + relative_to: map_0/duckiebot1 + pose: + y: 0.9 + map_0/sign1: + relative_to: map_0 + pose: + x: 1.6 + y: 1.6 + map_0/sign1/sign2: + relative_to: map_0/sign1 + pose: + y: 0.9 + map_0/tag1: + relative_to: map_0 + pose: + x: 1.6 + y: 1.6 + map_0/tag1/tag2: + relative_to: map_0/tag1 + pose: + y: 0.9 diff --git a/tests/maps/minimal_autolab/ground_tags.yaml b/tests/maps/minimal_autolab/ground_tags.yaml new file mode 100644 index 0000000..5e31fc6 --- /dev/null +++ b/tests/maps/minimal_autolab/ground_tags.yaml @@ -0,0 +1,13 @@ +ground_tags: + map_0/tag1: + size: 0.1 + id: 1 + family: 36h11 + map_0/tag3: + size: 0.15 + id: 2 + family: 36h11 + map_0/tag1/tag2: + size: 0.15 + id: 3 + family: 36h11 diff --git a/tests/maps/minimal_autolab/traffic_signs.yaml b/tests/maps/minimal_autolab/traffic_signs.yaml new file mode 100644 index 0000000..91e7ec2 --- /dev/null +++ b/tests/maps/minimal_autolab/traffic_signs.yaml @@ -0,0 +1,13 @@ +traffic_signs: + map_0/sign1: + type: stop + id: 1 + family: 36h11 + map_0/sign3: + type: yield + id: 2 + family: 36h11 + map_0/sign1/sign2: + type: yield + id: 3 + family: 36h11 diff --git a/tests/maps/minimal_autolab/vehicles.yaml b/tests/maps/minimal_autolab/vehicles.yaml new file mode 100644 index 0000000..7f39bcb --- /dev/null +++ b/tests/maps/minimal_autolab/vehicles.yaml @@ -0,0 +1,10 @@ +vehicles: + map_0/duckiebot1: + configuration: DB18 + color: green + map_0/duckiebot3: + configuration: DB19 + color: red + map_0/duckiebot1/duckiebot2: + configuration: DB19 + color: red