OSCP GeoPose Protocol
Localize against MultiSet maps using Open AR Cloud's GeoPose Protocol, so an OSCP client needs no MultiSet-specific code.
Overview
POST /v1/vps/map/geopose speaks Open AR Cloud's GeoPose Protocol. An OSCP client can point at MultiSet and localize without knowing anything MultiSet-specific.
It answers with the same localization quality as Map Query, and meters against your plan the same way. What differs is the shape of the request and the response.
Not to be confused with GeoPose Support, which describes the GeoPose object returned inside a normal MultiSet localization response. That is a field on an existing API. This is a separate endpoint speaking the full protocol.
Protocol versions
Versions 1.0 and 2.0 are both accepted, and the two are detected by the shape of the request:
Version
sensorReadings
Camera intrinsics
1.0
Flat array
On the Sensor
2.0
Object of typed arrays
On the reading
The version travels in the Accept header and is echoed in the response Content-Type:
Accept: application/vnd.oscp+json;version=2.0It defaults to 2.0 when the header is absent. An unrecognised version is a 400.
Choosing which map to query
The GeoPose spec's body carries no map field, so there are two ways to scope a request.
By coordinate (spec-native)
Include a geolocationReading. The nearest map whose geo-fence is in range is resolved and queried.
Explicitly (MultiSet extension)
Pass mapCode or mapSetCode as a query parameter.
The query parameters take precedence over any geolocationReading. mapCode and mapSetCode are mutually exclusive.
The endpoint
Localize using Open AR Cloud's GeoPose Protocol, so an OSCP client can use MultiSet maps without MultiSet-specific code. Protocol versions 1.0 and 2.0 are both accepted and detected from the request. The version travels in the Accept header and is echoed in the response. The spec's body carries no map field. Supply a geolocationReading and the nearest map in range is used, or name one with the mapCode / mapSetCode query parameters, which take precedence. Images must be upright and non-mirrored.
Scope to one map. Takes precedence over any geolocationReading.
Scope to a map set. Mutually exclusive with mapCode.
vps-1Possible values: Protocol version negotiation. Supported - 1.0, 2.0. An unknown version is a 400.
application/vnd.oscp+json;version=2.0Milliseconds since the Unix epoch.
geoposev2 object of typed arrays, or the v1 flat array. Detected by shape.
Accepted by the spec; not consumed.
A GeoPoseResp. The quaternion is in the OGC LTP-ENU frame (+X east, +Y north, +Z up, right-handed).
geoposeMalformed payload, missing intrinsics, a rotated or mirrored image, or an unsupported protocol version
Unauthorized
No pose was found. reason is no_map_in_range when no map covered the coordinate supplied, or localization_failed when a map was queried but the image did not match.
POST /v1/vps/map/geopose HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 540
{
"id": "b8f1c2d4-0000-4000-8000-000000000000",
"timestamp": 1789557904000,
"type": "geopose",
"sensors": [
{
"id": "cam0",
"type": "camera"
},
{
"id": "gps0",
"type": "geolocation"
}
],
"sensorReadings": {
"cameraReadings": [
{
"timestamp": 1789557904000,
"sensorId": "cam0",
"size": [
1024,
1024
],
"imageBytes": "<base64 JPEG>",
"imageOrientation": {
"mirrored": false,
"rotation": 0
},
"params": {
"model": "PINHOLE",
"modelParams": [
512,
512,
512,
512
]
}
}
],
"geolocationReadings": [
{
"timestamp": 1789557904000,
"sensorId": "gps0",
"latitude": 37.794853,
"longitude": -122.394573,
"altitude": 5.74
}
]
}
}{
"id": "b8f1c2d4-0000-4000-8000-000000000000",
"timestamp": 1789557905123,
"accuracy": {
"position": 1,
"orientation": 5
},
"type": "geopose",
"geopose": {
"position": {
"lat": 37.7948528,
"lon": -122.3945734,
"h": 6.47
},
"quaternion": {
"x": -0.0127,
"y": -0.0007,
"z": -0.0539,
"w": 0.9985
}
}
}Image requirements
Images must be upright and non-mirrored. Send imageOrientation with rotation: 0 and mirrored: false, or rotate the image before encoding it.
This matches the requirement on the native query API. A rotated or mirrored frame does not fail loudly, it simply fails to localize, so it is worth asserting in your client rather than discovering in the field.
When no pose is found
A request that cannot be localized returns a 404 with a reason. The one worth handling separately is:
That means no geo-fence was within range of the coordinate you supplied, which is a different problem from a map being found and the image failing to match. The first is a coverage or geo-referencing issue, the second is an imagery issue. Treat them differently in your client.
Accuracy values
The response carries position and orientation accuracy. These are nominal values rather than a per-query estimate, so do not read them as a confidence score for an individual pose. Use the confidence field on Map Query when you need that.
Related
Map Query, the native equivalent.
GeoPose Support, the GeoPose object inside a normal response.
Geo-fence, which coordinate-scoped requests depend on.
Last updated
Was this helpful?

