Skip to content

Extending autopilot related paths 2020

AdrianP edited this page Jan 11, 2023 · 24 revisions

This doc is a draft for extending Signal K autopilot related paths to improve integration with different autopilots.

Autopilot paths:

List of relevant paths, proposed extensions in italic

  • autopilot/state
    • enum: enabled disabled error
  • autopilot/mode
    • current mode: e.g. compass
  • autopilot/availableModes
    • array of modes supported by the Auto-pilot e.g. [compass, gps, windApparent, windTrue]
  • autopilot/target/windAngleApparent (Q: should the path just be _autopilot/target_ which is a numeric value (-179 -> 359) as the mode will dtermine what the value represents?)
  • autopilot/target/windAngleTrue
  • autopilot/target/headingTrue
  • autopilot/target/headingMagnetic
  • autopilot/target/courseTrue
  • autopilot/target/courseMagnetic (not really relevant?)
  • autopilot/deadZone
  • autopilot/backlash
  • autopilot/gain
    • what subkeys should we have here?
  • autopilot/maxDriveCurrent
  • autopilot/maxDriveRate
  • autopilot/portLock
  • autopilot/starboardLock
  • _ slew speeds ??_

Course paths:

V1 specification:

  • navigation/courseGreatCircle/crossTrackError
  • navigation/courseGreatCircle/bearingTrackTrue
  • navigation/courseGreatCircle/bearingTrackMagnetic
  • navigation/courseGreatCircle/activeRoute
  • navigation/courseGreatCircle/activeRoute/estimatedTimeOfArrival
  • navigation/courseGreatCircle/activeRoute/startTime
  • navigation/courseGreatCircle/nextPoint {type + href}
  • navigation/courseGreatCircle/nextPoint/distance (tkurki: no idea why these are missing)
  • navigation/courseGreatCircle/nextPoint/position
  • navigation/courseGreatCircle/nextPoint/arrivalCircle (size in m)
  • navigation/courseGreatCircle/previousPoint {type + href}
  • navigation/courseGreatCircle/previousPoint/distance
  • navigation/courseGreatCircle/previousPoint/position

V2 specification:

  • navigation/course/calcValues/calcMethod {great circle | rhumbline}
  • navigation/course/calcValues/crossTrackError
  • navigation/course/calcValues/bearingTrackTrue
  • navigation/course/calcValues/bearingTrackMagnetic
  • navigation/course/calcValues/estimatedTimeOfArrival
  • navigation/course/calcValues/distance
  • navigation/course/calcValues/bearingTrue
  • navigation/course/calcValues/bearingMagnetic
  • navigation/course/calcValues/velocityMadeGood
  • navigation/course/calcValues/timeToGo

Autopilot API:

Implement an Autopilot API to handle requests for performing common operations and provide a common interface for AutopilotProvider plugins using a similar approach to ResourceProvider plugins.

The server handles AutoPilot API requests, validates the supplied data and then calls the registered AutopilotProvider plugin which manages communication with the autopilot device.

Proposed API endpoints:

  • GET /steering/autopilot/config (retrieve autopilot settings and configuration option values)

example:

{
    options: {
      state: ['enabled', 'disabled'],    // valid values for state
      mode: ['gps', 'compass', 'wind']   // valid values for mode
    },
    state: 'disabled',
    mode: 'gps',
    target: 0
}
  • PUT /steering/autopilot/engage (engage / activate the autopilot by setting the appropriate state)

Using the example above: state would be set to 'enabled'.

  • PUT /steering/autopilot/disengage (disengage / deactivate the autopilot by setting the appropriate state)

Using the example above: state would be set to 'disabled'.

  • GET /steering/autopilot/state (get autopilot state)

  • PUT /steering/autopilot/state (set autopilot state to one of the valid values)

  • GET /steering/autopilot/mode (get autopilot mode)

  • PUT /steering/autopilot/mode (set autopilot mode to one of the valid values)

  • GET /steering/autopilot/target (get currrent target value [-179 - 359])

  • PUT /steering/autopilot/target (set heading / wind angle by supplied value [-179 - 359])

  • PUT /steering/autopilot/target/adjust (increment heading / wind angle by supplied +/- value )

  • PUT /steering/autopilot/tack/port (perform a port tack)

  • PUT /steering/autopilot/tack/starboard (perform a starboard tack)

Todo

  • Dodging - what does it mean in real life?
  • More than one autopilot? Marking as active / standby?

Example: Path for each autopilot device with reference to path of active device.

/steering/autopilot/
    href: "pypilot"
    ...
    pypilot/
            ...
    raymarine/
              ...
  • Tacking
  • +/- adjustments
  • Internal autopilot operation values (gain, deadZone, backLash, etc.) in designated path? e.g. autopilot/internal/deadZone, autopilot/internal/backlash, autopilot/gain
  • What well defined notification/* paths should there be?

Control vs informing about a state

In Signal K control/command is usually separate from "sensor data", eg. data about the current value of something. Control messages are HTTP PUTs or (ws) messages with put syntax: https://github.com/SignalK/specification/blob/master/gitbook-docs/put.md

SK Server Network Plugin CAN / serial / IP Autopilot
/stream
HTTP GET
<------------ status ----------------------
steering.autopilot.state
steering.autopilot.mode
N2K to SK

websocket
<------

<------
NMEA Pilot

SK aware pilot
/stream
HTTP GET
<------------ target details ------------
autopilot.target.xxx
N2K to SK

websocket
<------

<------
NMEA Pilot

SK aware pilot
/stream --------------- course data ------------>
navigation.course.nextPoint
navigation.course.calcValues
SK to 0183

SK to N2K

websocket
---------->
RMB, APB, XTE
---------->
PGN 12928x
---------->
NMEA0183 Pilot

NMEA2000 Pilot

SK aware pilot
/stream
HTTP GET
<---------------- options -------------------
steering.autopilot.availableModes
AP Plugin

websocket
<------

<------
NMEA Pilot

SK aware pilot
HTTP PUT --------------- set state ------------>
PUT steering.autopilot.state {value: string}
AP Plugin ------>
HTTP PUT --------------- set mode ------------>
PUT steering.autopilot.mode {value: string}
AP Plugin ------>
HTTP PUT --------------- set target ------------>
PUT steering.autopilot.target {value: number}
AP Plugin ------>

Operation / Usage:

Assumption: Autopilot is a standalone device operating autonomously. It can accept commands and course settings via:

  • Direct input on the device / built-in UI
  • NMEA0183, NMEA200, SeaTalk messages
  • Signal K delta messages

Signal K Course API: signalk-server PR #1381 implements a course API that provides operations for setting an active route or destination point and facilitates the setting of navigation.course path values.

Assumption: navigation.courseGreatCircle and/or navigation.courseRhumbline (v1 specification), navigation.course.calculations (v2 specification) path values are populated through the use of a course data provider plugin.

Action Signal K aware Autopilot Plugin/Provider
1. SK Server startup Send status in steering/autopilot/mode path(s) to server. Connect to autopilot and retrieve status. Send steering/autopilotdeltas with retrieved values.
2. Autopilot engaged (autopilot UI) Send deltas containing updated autopilot path values. Detect change in autopilot status, retrieve status from autopilot, send deltas containing updated autopilot path values.
3. Changes to Autopilot status (autopilot UI) Send deltas containing updated autopilot path values. Detect change in autopilot status, retrieve status from autopilot, send deltas containing updated autopilot path values.
4. Destination set via Signal K Course API Receives course/nextPoint, course/calcValues deltas and uses values to set course to steer. Receives course/nextPoint, course/calcValues deltas and sends values to autopilot to set course to steer.
5. Send command to autopilot via Signal K Autopilot API Receives steering/autopilot deltas and adjusts operation based on received values. Receives steering/autopilot deltas and sends values to autopilot to adjust operation based on values supplied.

Real World setups

How about describing some real world setups to get context and depth.

A start point would be current NMEA0183 and N2K systems and OpenCpn & pypilot, then we could construct a "pure" Signal K system.

Related resources: