question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add draw obstacles in map

See original GitHub issue

See my patch 😃

diff --git a/custom_components/xiaomi_cloud_map_extractor/camera.py b/custom_components/xiaomi_cloud_map_extractor/camera.py
index 16dd74e..958fe0d 100644
--- a/custom_components/xiaomi_cloud_map_extractor/camera.py
+++ b/custom_components/xiaomi_cloud_map_extractor/camera.py
@@ -26,6 +26,7 @@ DEFAULT_TRIMS = {
 
 DEFAULT_SIZES = {
     CONF_SIZE_VACUUM_RADIUS: 4,
+    CONF_SIZE_OBSTACLE_RADIUS: 3,
     CONF_SIZE_CHARGER_RADIUS: 4
 }
 
@@ -75,6 +76,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
             })]),
         vol.Optional(CONF_SIZES, default=DEFAULT_SIZES): vol.Schema({
             vol.Optional(CONF_SIZE_VACUUM_RADIUS, default=4): vol.All(vol.Coerce(float), vol.Range(min=0)),
+            vol.Optional(CONF_SIZE_OBSTACLE_RADIUS, default=3): vol.All(vol.Coerce(float), vol.Range(min=0)),
             vol.Optional(CONF_SIZE_CHARGER_RADIUS, default=4): vol.All(vol.Coerce(float), vol.Range(min=0))
         })
     })
diff --git a/custom_components/xiaomi_cloud_map_extractor/const.py b/custom_components/xiaomi_cloud_map_extractor/const.py
index 10a6883..6347f76 100644
--- a/custom_components/xiaomi_cloud_map_extractor/const.py
+++ b/custom_components/xiaomi_cloud_map_extractor/const.py
@@ -16,6 +16,7 @@ CONF_ROTATE = "rotate"
 CONF_SCALE = "scale"
 CONF_SIZES = "sizes"
 CONF_SIZE_CHARGER_RADIUS = "charger_radius"
+CONF_SIZE_OBSTACLE_RADIUS = "obstacle_radius"
 CONF_SIZE_VACUUM_RADIUS = "vacuum_radius"
 CONF_TEXT = "text"
 CONF_TEXTS = "texts"
@@ -81,6 +82,7 @@ ATTR_Y3 = "y3"
 DRAWABLE_ALL = "all"
 DRAWABLE_CHARGER = "charger"
 DRAWABLE_GOTO_PATH = "goto_path"
+DRAWABLE_OBSTACLES = "obstacles"
 DRAWABLE_NO_GO_AREAS = "no_go_zones"
 DRAWABLE_NO_MOPPING_AREAS = "no_mopping_zones"
 DRAWABLE_PATH = "path"
@@ -90,7 +92,7 @@ DRAWABLE_VIRTUAL_WALLS = "virtual_walls"
 DRAWABLE_ZONES = "zones"
 
 CONF_AVAILABLE_DRAWABLES = [DRAWABLE_ALL, DRAWABLE_NO_MOPPING_AREAS, DRAWABLE_NO_GO_AREAS, DRAWABLE_VIRTUAL_WALLS,
-                            DRAWABLE_CHARGER, DRAWABLE_ZONES, DRAWABLE_GOTO_PATH, DRAWABLE_PATH,
+                            DRAWABLE_CHARGER, DRAWABLE_ZONES, DRAWABLE_OBSTACLES, DRAWABLE_GOTO_PATH, DRAWABLE_PATH,
                             DRAWABLE_PREDICTED_PATH, DRAWABLE_VACUUM_POSITION]
 
 COLOR_ROOM_PREFIX = "color_room_"
@@ -106,6 +108,7 @@ COLOR_NO_GO_ZONES = "color_no_go_zones"
 COLOR_NO_GO_ZONES_OUTLINE = "color_no_go_zones_outline"
 COLOR_NO_MOPPING_ZONES = "color_no_mop_zones"
 COLOR_NO_MOPPING_ZONES_OUTLINE = "color_no_mop_zones_outline"
+COLOR_OBSTACLE = "color_obstacle"
 COLOR_PATH = "color_path"
 COLOR_PREDICTED_PATH = "color_predicted_path"
 COLOR_ROBO = "color_robo"
@@ -118,7 +121,8 @@ COLOR_ZONES_OUTLINE = "color_zones_outline"
 CONF_AVAILABLE_COLORS = [COLOR_CHARGER, COLOR_GOTO_PATH, COLOR_GREY_WALL, COLOR_MAP_INSIDE, COLOR_MAP_OUTSIDE,
                          COLOR_MAP_WALL, COLOR_MAP_WALL_V2, COLOR_NO_GO_ZONES, COLOR_NO_GO_ZONES_OUTLINE,
                          COLOR_NO_MOPPING_ZONES, COLOR_NO_MOPPING_ZONES_OUTLINE, COLOR_PATH, COLOR_PREDICTED_PATH,
-                         COLOR_ROBO, COLOR_SCAN, COLOR_UNKNOWN, COLOR_VIRTUAL_WALLS, COLOR_ZONES, COLOR_ZONES_OUTLINE]
+                         COLOR_ROBO, COLOR_SCAN, COLOR_UNKNOWN, COLOR_VIRTUAL_WALLS, COLOR_ZONES, COLOR_ZONES_OUTLINE,
+                         COLOR_OBSTACLE]
 
 COLOR_ROOM_1 = "color_room_1"
 COLOR_ROOM_2 = "color_room_2"
diff --git a/custom_components/xiaomi_cloud_map_extractor/image_handler.py b/custom_components/xiaomi_cloud_map_extractor/image_handler.py
index c6b9036..fdc1ac4 100644
--- a/custom_components/xiaomi_cloud_map_extractor/image_handler.py
+++ b/custom_components/xiaomi_cloud_map_extractor/image_handler.py
@@ -171,6 +171,12 @@ class ImageHandler:
         color = ImageHandler.__get_color__(COLOR_CHARGER, colors)
         ImageHandler.__draw_circle__(image, charger, radius, color, color)
 
+    @staticmethod
+    def draw_obstacles(image, obstacles, radius, colors):
+        color = ImageHandler.__get_color__(COLOR_OBSTACLE, colors)
+        for obstacle in obstacles:
+            ImageHandler.__draw_circle__(image, obstacle, radius, color, color)
+
     @staticmethod
     def draw_vacuum_position(image, vacuum_position, radius, colors):
         color = ImageHandler.__get_color__(COLOR_ROBO, colors)
diff --git a/custom_components/xiaomi_cloud_map_extractor/map_data_parser.py b/custom_components/xiaomi_cloud_map_extractor/map_data_parser.py
index 17df350..5b4ae65 100644
--- a/custom_components/xiaomi_cloud_map_extractor/map_data_parser.py
+++ b/custom_components/xiaomi_cloud_map_extractor/map_data_parser.py
@@ -18,6 +18,8 @@ class MapDataParser:
     BLOCKS = 11
     NO_MOPPING_AREAS = 12
     OBSTACLES = 13
+    OBSTACLES_WITH_TYPE = 14
+    OBSTACLES_WITH_TYPE_AND_PHOTO = 15
     DIGEST = 1024
     MM = 50
     SIZE = 1024
@@ -67,7 +69,7 @@ class MapDataParser:
                 map_data.no_go_areas = MapDataParser.parse_area(header, data)
             elif block_type == MapDataParser.NO_MOPPING_AREAS:
                 map_data.no_mopping_areas = MapDataParser.parse_area(header, data)
-            elif block_type == MapDataParser.OBSTACLES:
+            elif block_type == MapDataParser.OBSTACLES or block_type == MapDataParser.OBSTACLES_WITH_TYPE or block_type == MapDataParser.OBSTACLES_WITH_TYPE_AND_PHOTO:
                 map_data.obstacles = MapDataParser.parse_obstacles(data, header)
             elif block_type == MapDataParser.BLOCKS:
                 block_pairs = MapDataParser.get_int16(header, 0x08)
@@ -164,11 +166,26 @@ class MapDataParser:
     def parse_obstacles(data, header):
         obstacle_pairs = MapDataParser.get_int16(header, 0x08)
         obstacles = []
-        for obstacle_start in range(0, obstacle_pairs * 5, 5):
+        if obstacle_pairs == 0:
+            return obstacles
+        obstacle_size = int(len(data) / obstacle_pairs)
+        for obstacle_start in range(0, obstacle_pairs * obstacle_size, obstacle_size):
             x0 = MapDataParser.get_int16(data, obstacle_start + 0)
             y0 = MapDataParser.get_int16(data, obstacle_start + 2)
-            u = data[obstacle_start + 0] & 0xFF
-            obstacles.append({x0: x0, y0: y0, u: u})
+            u = None
+            if obstacle_size == 5:
+                u = {'type':  data[obstacle_start + 0] & 0xFF}
+            elif obstacle_size >= 6:
+                u = {'type':  MapDataParser.get_int16(data, obstacle_start + 4)}
+                if obstacle_size >= 10:
+                    u1 = MapDataParser.get_int16(data, obstacle_start + 6)
+                    u2 = MapDataParser.get_int16(data, obstacle_start + 8)
+                    u['confidence_level'] = u1 * 10.0 / u2
+                    if obstacle_size == 28 and (data[obstacle_start + 12] & 0xFF) > 0:
+                        txt = MapDataParser.get_bytes(data, obstacle_start + 12, 16)
+                        u['photo'] = txt.decode('ascii')
+            obstacles.append(Point(x0, y0, u))
+
         return obstacles
 
     @staticmethod
@@ -222,6 +239,8 @@ class MapDataParser:
             if DRAWABLE_VACUUM_POSITION == drawable and map_data.vacuum_position is not None:
                 ImageHandler.draw_vacuum_position(map_data.image, map_data.vacuum_position,
                                                   sizes[CONF_SIZE_VACUUM_RADIUS], colors)
+            if DRAWABLE_OBSTACLES == drawable and map_data.obstacles is not None:
+                ImageHandler.draw_obstacles(map_data.image, map_data.obstacles, sizes[CONF_SIZE_OBSTACLE_RADIUS], colors)
             if DRAWABLE_PATH == drawable and map_data.path is not None:
                 ImageHandler.draw_path(map_data.image, map_data.path, colors, scale)
             if DRAWABLE_GOTO_PATH == drawable and map_data.goto_path is not None:

This patch is tested on Roborock S6 MaxV / OBSTACLES_WITH_TYPE_AND_PHOTO 👍

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
PiotrMachowskicommented, Apr 18, 2021

Added in v1.1.0

1reaction
PiotrMachowskicommented, Apr 1, 2021

Nice!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Tile-based game Part 13: Map Obstacles - YouTube
Now that we have the map loading, we need to create obstacles for walls, trees, etc.Download Tiled:http://mapeditor.org/Download Kenney.nl ...
Read more >
c# - Create an obstacles inside the map - Stack Overflow
Right now i only be able to draw a obstacles during mouse down, but i am not able to generate a map that...
Read more >
Adding Obstacles - Navigine Docs
The Navigine CMS provides two obstacle drawing tools, which are Barriers and Walls. ... To add obstacles of such kind into your sub-location's...
Read more >
Creating Map Obstacles - Python Forum
[PyGame] Creating Map Obstacles · pygame.draw. · # Puts the fences on the screen for fence in fences: pygame.draw. · # Coordinates of...
Read more >
Create an obstacles inside the map - Unity Answers
Now i want to draw a obstacles within those grids, how do i do that? Right now i only be able to draw...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found