How Mapping Works

Creating a map within LVPS is essentially just projecting cartesian coordinate system (2d grid) onto an area.

The map does not need to know everything about the area. It doesn't even need to have special markers on the axis or at boundaries.

What it does need is visibility, at any given time, to at least two landmarks. The landmarks can be outside the boundaries, inside the boundaries, or any combination. The landmarks can be anywhere on the map, but they do need to be accurately described, in terms of their X,Y position and size.

The origin (0,0) can be anywhere on the map, or not even on the map at all. Notice there is no definition of where the origin is or where any axis is in the map definition. Both of those are automatically calculated during positioning, based on the landmarks you define in this map.

Map Items

Map Component Description
Landmark Any number of landmarks can exist on the map, but at least two are required for positioning to be possible. Each landmark will include the object type and the object detection model that knows how to recognize the object, a height and width, used for gauging distance by looking at the visual size vs known size, whether the object might be visible to LIDAR, a confidence value (0 to 1) indicating the minimum level of confidence required to consider the object a 'hit', and a priority, which helps the positioning system to decide which landmarks to use if many are visible.
Boundaries
The minimum and maximum (x,y) coordinates that are considered to be on-map, or in bounds.
Near Boundaries
A 'gray zone' that is considered out-of-bounds, but still within the realm of possibility that a robot may find itself there
Obstacles Blocked off areas within the map, where the robot should not travel. This enables route planning algorithms to know where they should avoid on the map.
Search A set of objects that are considered searchable on the current map. This helps the pilot ensure it has downloaded all the maps it needs for an assignment, prior to going off and doing its own thing.

Visual Example

Lets look at the example of my basement. The JSON below defines many landmarks that can currently be found in my basement (windmill, cat tree, various IR light patterns, etc).

You can see I've blocked of the pool table, as well as some other areas.

A visual representation of what that looks like can be seen in the Bot Captain screenshot to the right. The screenshot shows the session of a robot, with its path highlighted in red. The path is not part of the map, so you can ignore that, but the rest of what you see is part of the map.

You do not need to create the map graphic, just the JSON document. The positioning software does all the rest.

{
 "landmarks": {
    "w_windmill": {
            "pattern":"na",
            "type":"windmill",
            "model":"basement",
            "x":-133,
            "y":0,
            "height":12.0,
            "altitude":6.0,
            "confidence":0.6,
            "lidar_visible":true,
            "priority":6
    },
        "ne_tree": {
            "pattern":"na",
            "type":"cat_tree",
            "model":"basement",
            "x":100,
            "y":108,
            "height":24,
            "altitude":12,
            "confidence":0.6,
            "lidar_visible":true,
            "priority":7
        },
    "se_pineapple": {
            "pattern":"na",
            "type":"pineapple",
            "model":"basement",
            "x":100,
            "y":-78,
            "height":14.0,
            "altitude":7.0,
            "confidence":0.6,
            "lidar_visible":true,
            "priority":2
    },   
        "nw_house": {
            "pattern":"na",
            "type":"house",
            "model":"basement",
            "x":-67,
            "y":69,
            "height":7,
            "altitude":3.875,
            "confidence":0.6,
            "lidar_visible":false,
            "priority":1
        },
        "sw_light": {
            "pattern":"8",
            "type":"light",
            "model":"lights",
            "x":-136,
            "y":-80,
            "height":43,
            "altitude":39,
            "confidence":0.25,
            "lidar_visible":true,
            "priority":8
        },    
        "nw_light": {
            "pattern":"2",
            "type":"light",
            "model":"lights",
            "x":-155,
            "y":159,
            "height":25,
            "altitude":34.5,
            "confidence":0.25,
            "lidar_visible":true,
            "priority":9
        },
        "n_light": {
            "pattern":"3",
            "type":"light",
            "model":"lights",
            "x":-65,
            "y":287,
            "height":33,
            "altitude":50.5,
            "confidence":0.25,
            "lidar_visible":true,
            "priority":10
        }
    },
    "shape":"rectangle",
    "boundaries" : {
        "xmin":-150,
        "ymin":-50,
        "xmax":150,
        "ymax":250
    },
    "near_boundaries" : {
        "xmin":-170,
        "ymin":-100,
        "xmax":170,
        "ymax":270
    },
    "obstacles": {
        "christmas_tree": {
            "xmin":110,
            "ymin":-17,
            "xmax":150,
            "ymax":25
        },
        "old_stereo": {
            "xmin":136,
            "ymin":25,
            "xmax":150,
            "ymax":180
        },
        "pool_table": {
            "xmin":16,
            "ymin":180,
            "xmax":150,
            "ymax":250
        },
        "work_area": {
            "xmin":-150,
            "ymin":-50,
            "xmax":-130,
            "ymax":135
        },
        "fp_house": {
            "xmin":-74,
            "ymin":65,
            "xmax":-64,
            "ymax":74
        },
        "fp_tree": {
            "xmin":90,
            "ymin":99,
            "xmax":107,
            "ymax":116
        },
        "post_center": {
            "xmin":-3,
            "ymin":-3,
            "xmax":3,
            "ymax":3
        },
        "post_north": {
            "xmin":-3,
            "ymin":143,
            "xmax":3,
            "ymax":150
        }
    },
    "search": {
        "gazing_ball": {
                "pattern":"na",
                "model":"basement",
                "height":12.0,
                "confidence":0.6,
                "lidar_visible":false
        },
        "cone": {
                "pattern":"na",
                "model":"basement",
                "height":12.0,
                "confidence":0.6,
                "lidar_visible":true
        },
        "speaker": {
                "pattern":"na",
                "model":"basement",
                "height":8.5,
                "confidence":0.6,
                "lidar_visible":false
        }

    }
}