valetudo-map-parser 0.1.7__py3-none-any.whl → 0.1.9a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- valetudo_map_parser/__init__.py +28 -13
- valetudo_map_parser/config/async_utils.py +93 -0
- valetudo_map_parser/config/auto_crop.py +312 -123
- valetudo_map_parser/config/color_utils.py +105 -0
- valetudo_map_parser/config/colors.py +662 -13
- valetudo_map_parser/config/drawable.py +613 -268
- valetudo_map_parser/config/drawable_elements.py +292 -0
- valetudo_map_parser/config/enhanced_drawable.py +324 -0
- valetudo_map_parser/config/optimized_element_map.py +406 -0
- valetudo_map_parser/config/rand256_parser.py +395 -0
- valetudo_map_parser/config/shared.py +94 -11
- valetudo_map_parser/config/types.py +105 -52
- valetudo_map_parser/config/utils.py +1025 -0
- valetudo_map_parser/hypfer_draw.py +464 -148
- valetudo_map_parser/hypfer_handler.py +366 -259
- valetudo_map_parser/hypfer_rooms_handler.py +599 -0
- valetudo_map_parser/map_data.py +56 -66
- valetudo_map_parser/rand256_handler.py +674 -0
- valetudo_map_parser/reimg_draw.py +68 -84
- valetudo_map_parser/rooms_handler.py +474 -0
- valetudo_map_parser-0.1.9a0.dist-info/METADATA +93 -0
- valetudo_map_parser-0.1.9a0.dist-info/RECORD +27 -0
- {valetudo_map_parser-0.1.7.dist-info → valetudo_map_parser-0.1.9a0.dist-info}/WHEEL +1 -1
- valetudo_map_parser/config/rand25_parser.py +0 -398
- valetudo_map_parser/images_utils.py +0 -398
- valetudo_map_parser/rand25_handler.py +0 -455
- valetudo_map_parser-0.1.7.dist-info/METADATA +0 -23
- valetudo_map_parser-0.1.7.dist-info/RECORD +0 -20
- {valetudo_map_parser-0.1.7.dist-info → valetudo_map_parser-0.1.9a0.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.7.dist-info → valetudo_map_parser-0.1.9a0.dist-info}/NOTICE.txt +0 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Image Draw Class for Valetudo Rand256 Image Handling.
|
|
3
3
|
This class is used to simplify the ImageHandler class.
|
|
4
|
-
Version:
|
|
4
|
+
Version: 0.1.9.b42
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import hashlib
|
|
10
|
-
import json
|
|
11
9
|
import logging
|
|
12
10
|
|
|
13
|
-
from .config.types import Color, JsonType, NumpyArray
|
|
14
11
|
from .config.drawable import Drawable
|
|
15
|
-
from
|
|
12
|
+
from .config.drawable_elements import DrawableElement
|
|
13
|
+
from .config.types import Color, JsonType, NumpyArray
|
|
14
|
+
from .map_data import ImageData, RandImageData
|
|
15
|
+
|
|
16
16
|
|
|
17
17
|
_LOGGER = logging.getLogger(__name__)
|
|
18
18
|
|
|
@@ -20,12 +20,11 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
20
20
|
class ImageDraw:
|
|
21
21
|
"""Class to handle the image creation."""
|
|
22
22
|
|
|
23
|
-
"""It Draws each elements of the images, like the walls, zones, paths, etc."""
|
|
24
|
-
|
|
25
23
|
def __init__(self, image_handler):
|
|
26
24
|
self.img_h = image_handler
|
|
27
25
|
self.file_name = self.img_h.shared.file_name
|
|
28
|
-
self.data =
|
|
26
|
+
self.data = RandImageData
|
|
27
|
+
self.data_sup = ImageData
|
|
29
28
|
self.draw = Drawable
|
|
30
29
|
self.color_grey = (128, 128, 128, 255)
|
|
31
30
|
|
|
@@ -47,12 +46,13 @@ class ImageDraw:
|
|
|
47
46
|
np_array = await self.draw.lines(
|
|
48
47
|
np_array, predicted_path, 3, self.color_grey
|
|
49
48
|
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return np_array
|
|
53
|
-
except Exception as e:
|
|
49
|
+
return np_array
|
|
50
|
+
except KeyError as e:
|
|
54
51
|
_LOGGER.warning(
|
|
55
|
-
|
|
52
|
+
"%s: Error in extraction of go-to target: %s",
|
|
53
|
+
self.file_name,
|
|
54
|
+
e,
|
|
55
|
+
exc_info=True,
|
|
56
56
|
)
|
|
57
57
|
return np_array
|
|
58
58
|
|
|
@@ -70,7 +70,7 @@ class ImageDraw:
|
|
|
70
70
|
)
|
|
71
71
|
except ValueError as e:
|
|
72
72
|
self.img_h.segment_data = None
|
|
73
|
-
_LOGGER.info(
|
|
73
|
+
_LOGGER.info("%s: No segments data found: %s", self.file_name, e)
|
|
74
74
|
|
|
75
75
|
async def async_draw_base_layer(
|
|
76
76
|
self,
|
|
@@ -87,13 +87,13 @@ class ImageDraw:
|
|
|
87
87
|
walls_data = self.data.get_rrm_walls(m_json)
|
|
88
88
|
floor_data = self.data.get_rrm_floor(m_json)
|
|
89
89
|
|
|
90
|
-
_LOGGER.info(
|
|
90
|
+
_LOGGER.info("%s: Empty image with background color", self.file_name)
|
|
91
91
|
img_np_array = await self.draw.create_empty_image(
|
|
92
92
|
self.img_h.img_size["x"], self.img_h.img_size["y"], color_background
|
|
93
93
|
)
|
|
94
94
|
room_id = 0
|
|
95
95
|
if self.img_h.frame_number == 0:
|
|
96
|
-
_LOGGER.info(
|
|
96
|
+
_LOGGER.info("%s: Overlapping Layers", self.file_name)
|
|
97
97
|
|
|
98
98
|
# checking if there are segments too (sorted pixels in the raw data).
|
|
99
99
|
await self.async_segment_data(m_json, size_x, size_y, pos_top, pos_left)
|
|
@@ -108,16 +108,18 @@ class ImageDraw:
|
|
|
108
108
|
color_wall,
|
|
109
109
|
color_zone_clean,
|
|
110
110
|
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
111
|
+
# Draw walls only if enabled in drawing config
|
|
112
|
+
if self.img_h.drawing_config.is_enabled(DrawableElement.WALL):
|
|
113
|
+
img_np_array = await self._draw_walls(
|
|
114
|
+
img_np_array,
|
|
115
|
+
walls_data,
|
|
116
|
+
size_x,
|
|
117
|
+
size_y,
|
|
118
|
+
pos_top,
|
|
119
|
+
pos_left,
|
|
120
|
+
pixel_size,
|
|
121
|
+
color_wall,
|
|
122
|
+
)
|
|
121
123
|
return room_id, img_np_array
|
|
122
124
|
|
|
123
125
|
async def _draw_floor(
|
|
@@ -146,31 +148,30 @@ class ImageDraw:
|
|
|
146
148
|
room_id = 0
|
|
147
149
|
rooms_list = [color_wall]
|
|
148
150
|
if not segment_data:
|
|
149
|
-
_LOGGER.info(
|
|
151
|
+
_LOGGER.info("%s: No segments data found.", self.file_name)
|
|
150
152
|
return room_id, img_np_array
|
|
151
153
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
room_color
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
((2 * room_color[3]) + color_zone_clean[3]) // 3,
|
|
167
|
-
)
|
|
168
|
-
img_np_array = await self.draw.from_json_to_image(
|
|
169
|
-
img_np_array, pixels, pixel_size, room_color
|
|
154
|
+
_LOGGER.info("%s: Drawing segments.", self.file_name)
|
|
155
|
+
for pixels in segment_data:
|
|
156
|
+
room_color = self.img_h.shared.rooms_colors[room_id]
|
|
157
|
+
rooms_list.append(room_color)
|
|
158
|
+
if (
|
|
159
|
+
self.img_h.active_zones
|
|
160
|
+
and len(self.img_h.active_zones) > room_id
|
|
161
|
+
and self.img_h.active_zones[room_id] == 1
|
|
162
|
+
):
|
|
163
|
+
room_color = (
|
|
164
|
+
((2 * room_color[0]) + color_zone_clean[0]) // 3,
|
|
165
|
+
((2 * room_color[1]) + color_zone_clean[1]) // 3,
|
|
166
|
+
((2 * room_color[2]) + color_zone_clean[2]) // 3,
|
|
167
|
+
((2 * room_color[3]) + color_zone_clean[3]) // 3,
|
|
170
168
|
)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
img_np_array = await self.draw.from_json_to_image(
|
|
170
|
+
img_np_array, pixels, pixel_size, room_color
|
|
171
|
+
)
|
|
172
|
+
room_id += 1
|
|
173
|
+
if room_id > 15:
|
|
174
|
+
room_id = 0
|
|
174
175
|
return room_id, img_np_array
|
|
175
176
|
|
|
176
177
|
async def _draw_walls(
|
|
@@ -209,10 +210,10 @@ class ImageDraw:
|
|
|
209
210
|
charger_pos = self.data.rrm_coordinates_to_valetudo(
|
|
210
211
|
self.data.get_rrm_charger_position(m_json)
|
|
211
212
|
)
|
|
212
|
-
except
|
|
213
|
-
_LOGGER.warning(
|
|
213
|
+
except KeyError as e:
|
|
214
|
+
_LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
|
|
214
215
|
else:
|
|
215
|
-
_LOGGER.debug("
|
|
216
|
+
_LOGGER.debug("Charger position: %s", charger_pos)
|
|
216
217
|
if charger_pos:
|
|
217
218
|
charger_pos_dictionary = {
|
|
218
219
|
"x": (charger_pos[0] * 10),
|
|
@@ -223,8 +224,7 @@ class ImageDraw:
|
|
|
223
224
|
np_array, charger_pos[0], charger_pos[1], color_charger
|
|
224
225
|
)
|
|
225
226
|
return np_array, charger_pos_dictionary
|
|
226
|
-
|
|
227
|
-
return np_array, {}
|
|
227
|
+
return np_array, {}
|
|
228
228
|
|
|
229
229
|
async def async_draw_zones(
|
|
230
230
|
self,
|
|
@@ -237,12 +237,11 @@ class ImageDraw:
|
|
|
237
237
|
zone_clean = self.data.get_rrm_currently_cleaned_zones(m_json)
|
|
238
238
|
except (ValueError, KeyError):
|
|
239
239
|
zone_clean = None
|
|
240
|
-
|
|
241
|
-
_LOGGER.info(f"{self.file_name}: Got zones.")
|
|
240
|
+
|
|
242
241
|
if zone_clean:
|
|
242
|
+
_LOGGER.info("%s: Got zones.", self.file_name)
|
|
243
243
|
return await self.draw.zones(np_array, zone_clean, color_zone_clean)
|
|
244
|
-
|
|
245
|
-
return np_array
|
|
244
|
+
return np_array
|
|
246
245
|
|
|
247
246
|
async def async_draw_virtual_restrictions(
|
|
248
247
|
self, m_json: JsonType, np_array: NumpyArray, color_no_go: Color
|
|
@@ -252,9 +251,9 @@ class ImageDraw:
|
|
|
252
251
|
virtual_walls = self.data.get_rrm_virtual_walls(m_json)
|
|
253
252
|
except (ValueError, KeyError):
|
|
254
253
|
virtual_walls = None
|
|
255
|
-
|
|
256
|
-
_LOGGER.info(f"{self.file_name}: Got virtual walls.")
|
|
254
|
+
|
|
257
255
|
if virtual_walls:
|
|
256
|
+
_LOGGER.info("%s: Got virtual walls.", self.file_name)
|
|
258
257
|
np_array = await self.draw.draw_virtual_walls(
|
|
259
258
|
np_array, virtual_walls, color_no_go
|
|
260
259
|
)
|
|
@@ -278,11 +277,13 @@ class ImageDraw:
|
|
|
278
277
|
# Extract the paths data from the JSON data.
|
|
279
278
|
try:
|
|
280
279
|
path_pixel = self.data.get_rrm_path(m_json)
|
|
281
|
-
path_pixel_formatted = self.
|
|
280
|
+
path_pixel_formatted = self.data_sup.sublist_join(
|
|
282
281
|
self.data.rrm_valetudo_path_array(path_pixel["points"]), 2
|
|
283
282
|
)
|
|
284
283
|
except KeyError as e:
|
|
285
|
-
_LOGGER.warning(
|
|
284
|
+
_LOGGER.warning(
|
|
285
|
+
"%s: Error extracting paths data: %s", self.file_name, str(e)
|
|
286
|
+
)
|
|
286
287
|
finally:
|
|
287
288
|
if path_pixel_formatted:
|
|
288
289
|
np_array = await self.draw.lines(
|
|
@@ -293,32 +294,13 @@ class ImageDraw:
|
|
|
293
294
|
async def async_get_entity_data(self, m_json: JsonType) -> dict or None:
|
|
294
295
|
"""Get the entity data from the JSON data."""
|
|
295
296
|
try:
|
|
296
|
-
entity_dict = self.
|
|
297
|
+
entity_dict = self.data_sup.find_points_entities(m_json)
|
|
297
298
|
except (ValueError, KeyError):
|
|
298
299
|
entity_dict = None
|
|
299
300
|
else:
|
|
300
|
-
_LOGGER.info(
|
|
301
|
+
_LOGGER.info("%s: Got the points in the json.", self.file_name)
|
|
301
302
|
return entity_dict
|
|
302
303
|
|
|
303
|
-
@staticmethod
|
|
304
|
-
async def async_copy_array(original_array: NumpyArray) -> NumpyArray:
|
|
305
|
-
"""Copy the array."""
|
|
306
|
-
return NumpyArray.copy(original_array)
|
|
307
|
-
|
|
308
|
-
async def calculate_array_hash(self, layers: dict, active: list[int] = None) -> str:
|
|
309
|
-
"""Calculate the hash of the image based on the layers and active segments walls."""
|
|
310
|
-
self.img_h.active_zones = active
|
|
311
|
-
if layers and active:
|
|
312
|
-
data_to_hash = {
|
|
313
|
-
"layers": len(layers["wall"][0]),
|
|
314
|
-
"active_segments": tuple(active),
|
|
315
|
-
}
|
|
316
|
-
data_json = json.dumps(data_to_hash, sort_keys=True)
|
|
317
|
-
hash_value = hashlib.sha256(data_json.encode()).hexdigest()
|
|
318
|
-
else:
|
|
319
|
-
hash_value = None
|
|
320
|
-
return hash_value
|
|
321
|
-
|
|
322
304
|
async def async_get_robot_position(self, m_json: JsonType) -> tuple | None:
|
|
323
305
|
"""Get the robot position from the entity data."""
|
|
324
306
|
robot_pos = None
|
|
@@ -329,14 +311,16 @@ class ImageDraw:
|
|
|
329
311
|
robot_pos = self.data.rrm_coordinates_to_valetudo(robot_pos_data)
|
|
330
312
|
angle = self.data.get_rrm_robot_angle(m_json)
|
|
331
313
|
except (ValueError, KeyError):
|
|
332
|
-
_LOGGER.warning(
|
|
314
|
+
_LOGGER.warning("%s No robot position found.", self.file_name)
|
|
333
315
|
return None, None, None
|
|
334
316
|
finally:
|
|
335
317
|
robot_position_angle = round(angle[0], 0)
|
|
336
318
|
if robot_pos and robot_position_angle:
|
|
337
319
|
robot_position = robot_pos
|
|
338
320
|
_LOGGER.debug(
|
|
339
|
-
|
|
321
|
+
"robot position: %s, robot angle: %s",
|
|
322
|
+
str(robot_pos),
|
|
323
|
+
str(robot_position_angle),
|
|
340
324
|
)
|
|
341
325
|
if self.img_h.rooms_pos is None:
|
|
342
326
|
self.img_h.robot_pos = {
|