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"
}