Developer Programming Guide - directedmachines/customer-support GitHub Wiki
Overview
Work in progress, summary of HTTP APIs for integrators
Services
General
Please review at least the example core runtime tutorial to get an understanding of the HTTP/REST service model for all robot services. You just need to pay attention to how you interact with a service, from a remote agent. General communication protocol is HTTP framing with JSON payloads (set content-type to application/json). Login using basic authentication header and supply xenon auth token as a request header on every request after login. Please review core runtime tutorial on basic auth
External agent state machine
An external agent will need to track a state machine, with the following states at its level:
- IDLE - dont send any messages, to anyone. Our stack will do the right thing
- TRANSITION_TO_ACTIVE - set the graph, set your destination to AGT (autonomous ground task), enable
- LCR_ACTIVE - if AGT sample reports ACTIVE and ENABLED just monitor it until ...
- SERVO (non LCR agent is active) -> AGT has transitioned to IDLE, start sending 5Hz velocity update to Navigation service to perform custom motion required by your application. Obstacle avoidance will be used with the velocity request sent to the navigation service.
In general, it is not a good idea to send any requests to the AGT unless you want to patch it to a new destination, route, or toggle enable. For safety reasons, you enable / disable autonomy essentially at very long time scales compared to fine nav velocity requests.
There is no single API / component representing the robot, just a collection of cooperating planners that can be used at the right level of abstraction depending on the time scale and space complexity of the task. The closest to a single entry point is the Autonomous Ground Task, explained later.
LCR Idle determination
There is a set of services, and you decide what services to send requests to and collect data samples from, to determine the overall state.
- Autonomous Ground Task (AGT) service - Tells you if autonomy is enabled / Active, configures waypoint destination, route, etc
- Navigation Service - Gives the active velocity, safety flags, all active planner velocities and allows you to micro control motion if you send it POST with velocity requests.
you determine if the robot planners are idle if
- navigation service data sample reports IDLE
- navigation service data sample defaultVelocity magnitude is zero
- AGT service data sample reports IDLE
Data stream vs configuration
Every service has an associated data stream where it publishes its data. Planners consume streams from each other and from other key services. The service parameters can be adjusted through its configuration URI and the associated JSON state (configuration) file on disk, loaded on runtime start.
There is a deterministic way to derive the data stream URI from the configuration URI and vice versa, append /data-streams/ to the configuration URI
Pose Estimation Service
Sensor fusion and aggregator for inertial and position sensors. Its data stream will report GPS position, if available, and magnetic heading, compensated for errors.
URI Paths
/sensors/pose-estimators/default
/data-streams/sensors/pose-estimators/default
HTTP Verbs
Updates to the pose estimator configuration are not recommended so not yet documented.
Data Stream Discussion
The pose estimator data sample will contain a "flags":["UNSAFE"]
array field if any of the required sensors is not reporting data or is late. Other key key fields:
- defaultPose - Latest GPS pose, with accuracy meters reflecting the HDOP (dilution of precision) and GPS accuracy
- defaultVelocity - latest commanded velocity to the drive service
- defaultPose.angle - filtered heading, a combination of magnetic heading and learned adjustment from GPS moving baseline
- pitchDeg, rollDeg - unfiltered pitch and roll. Negative pitch is looking towards ground, negative roll is rolling to the right
- estRotationDPS, estTranslationMPS - open loop estimation of rotation and translation used to enable stall correction
- rotationDPS, translationMPS - rotation and translation derived from sensors (IMU, GPS)
GET /data-streams/sensors/pose-estimators/default
{
"timeMicros": 1592947918960001,
"scalars": {
"gpsMagCorrectionDeg": 0.0,
"estRotationDPS": 0.0,
"gpsHeadingDeg": 0.0,
"pitchAvgDeg": 1.6171555145416325,
"translationMPS": 0.0,
"estTranslationMPS": 0.0,
"rollDeg": 1.4319562858659216,
"rotationDPS": 0.0,
"pitchDeg": 4.75633974865186,
"headingDeg": 0.0,
"magHeadingDeg": 0.0,
"rollAvgDeg": 0.4868651371944133,
"qual": 4.0,
"inMotion": 0.0
},
"vectors": {
"magXYZ": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"rawMagXYZ": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"angVel": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"accel": {
"x": -0.03,
"y": -0.99,
"z": 0.1
}
},
"tags": {
"id": "SIMEDGS0-64181017690acc661"
},
"defaultPose": {
"options": [
"GLOBAL"
],
"accuracyMeters": 1.0,
"x": -120.78081982209017,
"y": 47.19631873166257,
"z": 0.0,
"angle": 0.0,
"axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
}
},
"defaultVelocity": {
"x": 0.0,
"y": 0.0,
"z": 0.0
}
}
Navigation Service
Top level motion controller, fusing velocity vectors from planners and external users. Accessible through its UI front end or programmatically.
URI Paths
/actuators/navigators/default
/data-streams/actuators/navigators/default
HTTP Verbs
POST
Velocity suggestion integrated with planners (from user, external agents). Example code in navClient.js (line 921)
{
"kind": "DriveRequest",
"velocity": {
"x": 0,
"z": 0
},
"version": 20,
"gains": {
"obsAvoid": {
"x": 0.25,
"y": 0,
"z": 1
}
}
}
- version - must be incremented on every request, use a counter on the sender side, millisecond timestamp, etc
Data Stream discussion
The navigation service data stream is a key indicator of robot behavior. In particular, the "flags"
field and the defaultVelocity
fields will indicate if the robot is in motion, idle or an UNSAFE condition is detected. Notice that the navigation service will flow through stream data from the pose estimators and any active planner samples, to its sample, acting as an aggregator.
Example data sample from a GET to the data stream, when robot is idle
GET /data-streams/actuators/navigators/default
{
"timeMicros": 1593037213189020,
"flags": [
"IDLE",
"ENABLED",
"INTERNAL"
],
"scalars": {
"XDeltaDeg": 0.0,
"pitchDeg": 5.765260301396192,
"freqHz": 6.9948657685259015,
"estDeltaXDeg": 0.0,
"ZDeltaMeters": 0.0,
"estDeltaZMeters": 0.0,
"rollDeg": 1.73570458892839
},
"vectors": {
"angVel": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"accel": {
"x": -0.03,
"y": -0.99,
"z": 0.1
}
},
"tags": {
"id": "SIMEDGS0-64181017690acc661"
},
"defaultPose": {
"options": [
"GLOBAL"
],
"accuracyMeters": 1.0,
"x": -120.78081982209017,
"y": 47.19631873166257,
"z": 0.0,
"angle": 0.0,
"axis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
}
},
"defaultVelocity": {
"x": 0.0,
"y": 0.0,
"z": 0.0
}
}
PATCH
- toggle global enable
- various options (obstacle avoidance, zero turn, active pose)
Enable / disable toggle
{
"isEnabled": false
}
Option Toggle
Supply the list of active options. To disable OBSTACLE_AVOIDANCE, for example, send a body with out it. See navClient.js patchNavOptions (line 799)
{
"navOptions": [
"USER_INPUT",
"PATH_PLANNING",
"ZERO_TURN"
]
}
Autonomous Ground Task Service
Top level autonomous task planner integrating topological, area coverage, obstacle avoidance planner outputs. Relies on selected navigation graph instance to inform planner what waypoints / areas to use for path planning
URI Paths
/navigation/autonomous-ground-tasks/default
/data-streams/navigation/autonomous-ground-tasks/default
HTTP Verbs
PATCH
- Enable / disable autonomous task
- global task speed
- set destination and route
- Set active navigation graph
Example code in agtClient.js patchRoute(), patchEnable()
To enable AGT two PATCH requests must be sent, in sequence
- toggle isEnable to true
- Upon successful completion, change subStage to NAVIGATING
Enable / Disable toggle (Step 1)
If destination and/or route is set, toggle to true to enable autonomous motion
PATCH /navigation/autonomous-ground-tasks/default
{
"isEnabled": true,
"velocityGains": {
"x": 0.2,
"y": 1,
"z": 0.2
}
}
Set navigation subStage toggle (Step 2)
PATCH /navigation/autonomous-ground-tasks/default
{
"subStage": "NAVIGATING"
}
Route and Destination update
Send list of waypoint labels, in order you want them to be visited. Do so when task is disabled, but can be done when enabled as well. Example below uses the labels w2 and w4 from two waypoints on the active graph.
{
"route": [
"w2",
"w4"
]
}
Set active navigation graph
Example code in ngClient.js createGraph() and agtClient.js patchNavigationGraphReference()
{
"navigationGraphReference": "http://54.213.97.10:8001/navigation/graphs/north-south"
}
Data Stream discussion
The AGT data stream should be used to determine the state of autonomous planning. Below are examples of stream samples in various states. Most fields have been removed for clarity
Idle state
GET /data-streams/navigation/autonomous-ground-tasks/default
{
....
....
"flags": [
"IDLE",
"ENABLED"
],
....
....
"tags": {
"stage": "IDLE",
"id": "SIMEDGS0-64181017690acc661"
}
}
Active state (autonomous navigation in progress)
GET /data-streams/navigation/autonomous-ground-tasks/default
{
....
....
"flags": [
"ACTIVE",
"ENABLED"
],
....
....
"tags": {
"stage": "NAVIGATING",
"destination": "w4",
"action": "NAVIGATE_ON_EDGE",
"driveDirection": "AXLE_FWD",
"id": "SIMEDGS0-64181017690acc661",
"graph": "default"
},
....
....
}
Navigation Graph Service
Data structure representing a topology of waypoints, paths between them and work areas (plus other markers, such as obstacle markers).
URI Path
/navigation/graphs/default
Note that each robot can have multiple graphs, which you can create dynamically by doing a POST to the factory path /navigation/graphs/
Each graph instance supports the following requests. The active graph is set by doing a PATCH to the the autonomous ground task instance.
HTTP Verbs
PATCH
- Add/Update/Remove graph elements (Nodes, Edges, Markers)
- global graph settings and tags
Example code in ngClient.js which is most of the graph manipulation client code.
Upsert waypoint (graph node)
You can add, remove or update an existing node. The service will look at the label tag, and if the node exists, it will update it, otherwise it will add a new one
{
"kind": "UpsertNodeRequest",
"node": {
"scalars": {
"widthMM": 1828.5
},
"tags": {
"label": "west",
"reqGenerateEdgeSamples": "true"
},
"defaultPose": {
"x": -120.78049108226247,
"y": 47.196856539364724,
"options": [
"GLOBAL"
]
}
}
}
Upsert path (graph edge)
The source and destination tags must already exist as nodes in the graph. You will need to issue two PATCH requests if you want a bi-direction path enabled between waypoints.
{
"kind": "UpsertEdgeRequest",
"edge": {
"tags": {
"label": "west:north",
"source": "west",
"target": "north"
},
"scalars": {
"widthMM": 1828.5
},
"poses": []
}
}
Charge Control Service
Charge control service is a I/O integration service. It communicates with the solar charge control board (SCC) which provides battery cell telemetry, solar telemetry and allows control of multiple aux DC12V outputs.
URI Paths
/actuators/dcentralized-charge-controllers/default
/data-streams/actuators/dcentralized-charge-controllers/default
HTTP Verbs
POST
DC output control (on / off)
{
"body": {
"outputs": {
"DCOUT12V1": 1.0,
"DCOUT12V2": 0.0,
"DCOUT12V3": 1.0,
"USB_DCOUT5V": 0.0
}
}
}
Data Stream discussion
The charge service data stream is a key indicator of battery health, state of charge and solar telemetry. It also reports power use across all aux and logic outputs
Example data sample from a GET to the data stream, when robot is idle
GET /data-streams/actuators/dcentralized-charge-controllers/default
{
"timeMicros": 1627520801616000,
"scalars": {
"chargeState": 1.0
},
"scalarMaps": {
"volts": {
"SOLAR_PANEL": 41.96,
"12V4": 13.349999999999994,
"12V3": 13.300000000000004,
"12V2": 13.929999999999998,
"12V1": 13.15,
"BATTERIES": 53.73
},
"amps": {
"SOLAR_PANEL": 4.15,
"USB_HUB": 1.2,
"BATTERIES": 2.51
}
},
"tags": {
"id": "LCR24ZS0-template"
},
"documentVersion": 22399,
"documentKind": "cap-ds",
"documentSelfLink": "/data-streams/actuators/dcentralized-charge-controllers/default",
"documentUpdateTimeMicros": 1627520801616005,
"documentUpdateAction": "PATCH",
"documentExpirationTimeMicros": 0,
"documentAuthPrincipalLink": "/core/authz/system-user"
}