Managing Zones
A zone is a 2D polygonal region of space that changes how the vehicle navigates while it is inside that region, for example, a boundary it cannot cross or an area where it must slow down. Zones are always grouped into a zone set, a named collection of one or more zones. You provide a complete zone set, then load it to make it take effect.
Zone sets are handled as whole artifacts. You always send and receive a complete zone set, identified by its name in the URL. To edit/update a zone set, you replace it in full.
Zones cannot be loaded individually. They are always part of a zone set, and only one zone set can be loaded at a time.
This guide walks through creating a zone set, loading it, reading it back, and toggling zones at runtime.
Prerequisites
Set POLYMATH_ACCESS_TOKEN and POLYMATH_VEHICLE_ID as shown in Authentication and First Steps.
What makes up a zone set
A zone set needs a name and a list of one or more zones.
Zone set name
The zone set name is the identifier you pass in the URL, and it is how you refer to the set when reading, loading, or deleting it.
A zone set name is only considered valid if it:
- Is unique, and not already in use by another zone set
- Is not empty
- Does not start with a number or underscore
- Contains only letters, numbers, and underscores
All zone set names are case-insensitive, so "TestZoneSet" and "testzoneset" refer to the same zone set.
Zones
Each zone in the set has the following fields:
| Field | Notes |
|---|---|
name | Human-readable name, unique within the set. Duplicate names are rejected. |
type | The behavior type that the zone enforces. See Zone types. |
enabled | Whether the zone is enabled/disabled when the set is first loaded. This state can be toggled at runtime. |
coordinate_system | The frame the polygon is expressed in. Pass the integer value: 0 for WGS84, 1 for MAP. |
wgs84_polygon / map_polygon | The boundary vertices. Which field you provide depends on coordinate_system. See Coordinate systems. |
condition | Determines when the zone is active. See Conditions. |
params | Type-specific parameters as a list of {"key": ..., "value": ...} pairs. Type-specific parameters are mentioned in the respective Zone Type sections. |
Zone types
geofence- a containment boundary the vehicle cannot cross. The navigation planner will attempt to avoid crossing the boundary by rerouting around it. If the planner still tries to cross the boundary, the low-level velocity filters will stop the vehicle's movement. For a configurable distance before the boundary, the vehicle will slow down. For a configurable distance after the boundary, the vehicle will still allow backtracking to the boundary region. These distances can be configured for your application by a Polymath Engineer.- No additional
paramsare required for a geofence zone. - Only one geofence zone is allowed per zone set; additional geofence zones in the same set are rejected.
- No additional
speed_limit- enforces a maximum speed within the polygon.- Requires a
speed_limit_m_sentry inparams. The limit must be between0.2and20.0m/s, and is enforced in increments of0.2m/s. Where speed limit zones overlap, the strictest (lowest) limit wins.
- Requires a
keep_out- a region the vehicle cannot enter. The navigation planner will attempt to avoid entering the area by rerouting around it. If the planner still tries to enter the area, the low-level velocity filters will stop the vehicle's movement. For a configurable distance before the region boundary, the vehicle will slow down. For a configurable distance after the region boundary, the vehicle will still allow backtracking to leave the region. These distances can be configured for your application by a Polymath Engineer.- No additional
paramsare required for a keep-out zone.
- No additional
Coordinate systems & Polygons
Polygons are a list of at least 3 points (2-Dimensional). Do NOT repeat the first point as the last point, the polygon is closed automatically.
coordinate_system selects how the node's position is interpreted:
0(WGS84) - a GPS position inwgs84_positionaslat/lon. This is the system you will use most often, as Latitude and Longitude for a given location are always fixed.1(MAP) - a position in the vehicle's map frame inmap_positionasx/y. This system uses a reference point that defines the map origin, which may change over time, and is more suitable for indoor environments.
Conditions
A condition determines when an enabled zone is active. Each zone has exactly one condition.
Enabled vs. Active
It's worth understanding the difference:
- Enabled - the zone's condition will be evaluated. Just because a zone is enabled, doesn't mean the corresponding behavior is enforced by the vehicle.
- Active - the condition evaluated to
true, so the behavior is enforced when the vehicle is inside the polygon.
A zone can be enabled but not active if its condition currently evaluates to false.
Condition Types
always_on(integer value0) - the zone is active as long as it is enabled. This condition never evaluates to false.- More conditions coming soon...
Zone sets belong to a site
A site must be created and active before a zone set can be created.
All zone set management operations are scoped to the active site only.
If you create a zone set when site_A is active, the zone set will only be available for navigation when site_A is active.
If you activate site_B (by staging it and then restarting autonomy), the zone set from site_A will not be available.
This helps you clearly separate the artifacts for each site.
Read more about sites here.
Create a zone set
Send the complete zone set with POST, naming the set in the URL.
The example below creates a set with one geofence and one speed limit zone:
curl --request POST \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/zone_sets/site_zones" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN" \
--header "content-type: application/json" \
--data '{
"zones": [
{
"name": "site_boundary",
"type": "geofence",
"enabled": true,
"coordinate_system": 0,
"wgs84_polygon": [
{"latitude": 37.828258, "longitude": -122.425726},
{"latitude": 37.828385, "longitude": -122.420642},
{"latitude": 37.825124, "longitude": -122.420416},
{"latitude": 37.825183, "longitude": -122.425443}
],
"condition": {"type": 0, "params": []},
"params": []
},
{
"name": "slowdown_zone",
"type": "speed_limit",
"enabled": true,
"coordinate_system": 0,
"wgs84_polygon": [
{"latitude": 37.826800, "longitude": -122.423900},
{"latitude": 37.826900, "longitude": -122.422400},
{"latitude": 37.826100, "longitude": -122.422400},
{"latitude": 37.826100, "longitude": -122.423900}
],
"condition": {"type": 0, "params": []},
"params": [{"key": "speed_limit_m_s", "value": "5.0"}]
},
{
"name": "restricted_area_0",
"type": "keep_out",
"enabled": true,
"coordinate_system": 0,
"wgs84_polygon": [
{"latitude": 37.828021, "longitude": -122.424680},
{"latitude": 37.828029, "longitude": -122.424304},
{"latitude": 37.827885, "longitude": -122.424299},
{"latitude": 37.827898, "longitude": -122.424781},
],
"condition": {"type": 0, "params": []},
"params": []
}
]
}'
Load a zone set
Creating a zone set stores it. It does not take effect until you load it, which makes it available to the navigation system.
Only one zone set can be loaded at a time; loading a set replaces the previously loaded zone set.
curl --request POST \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/zone_sets/site_zones/load" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
Confirm which zone set is loaded
Read back the currently loaded set to confirm the vehicle is using the one you expect.
The loaded set also reports each zone's live runtime state:
curl "https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/loaded_zone_set" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
Each zone's state is one of:
UNINITIALIZED- the zone's state has not yet been established.DISABLED- the zone is disabled, so its condition is not evaluated.ENABLED_INACTIVE- enabled, but the condition currently evaluates to false, the behavior will not be enforced.ENABLED_ACTIVE- enabled and active, the behavior will be enforced.
Enable or disable zones at runtime
You can toggle individual zones within the loaded set without editing the stored artifact. This adjusts runtime state only, it does NOT modify the saved zone set. Using this endpoint, you can enable or disable multiple zones at once.
Send the zone names to enable and/or disable:
curl --request PATCH \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/loaded_zone_set/enabled" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN" \
--header "content-type: application/json" \
--data '{
"enable_zones": ["slowdown_zone"],
"disable_zones": ["site_boundary"]
}'
Clear the loaded zone set
Unload the current set so that no zones are in effect:
curl --request POST \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/loaded_zone_set/clear" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
Inspect zone sets
List all zone sets on the vehicle by name:
curl "https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/zone_sets" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
Read a previously created zone set in full by name:
curl "https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/zone_sets/site_zones" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
Update a zone set
Because zone sets are whole artifacts, editing one means replacing it in full.
Send the complete, updated set with PUT to the same name:
curl --request PUT \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/zone_sets/site_zones" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN" \
--header "content-type: application/json" \
--data '{ "zones": [ ... ] }'
Delete a zone set
Remove a zone set by name:
curl --request DELETE \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/zone_sets/site_zones" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
Handling errors
Failed requests come back with an HTTP status and a JSON body of the form {"status": "error", "message": "..."}.
The status tells you what happened:
400- the zone set was rejected as invalid by the vehicle.404- the named zone set does not exist, no zone set is currently loaded, or a named zone was not found in the active set.409- a zone set with that name already exists (on create).422- the request body was malformed or failed validation.
Next Steps
See the API Reference for the full request and response schema of every zone set endpoint.