-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Course API #629
base: master
Are you sure you want to change the base?
Proposal: Course API #629
Conversation
This is really commendable work! I think we should also include what deltas are sent. For example if I am running several UIs, like multiple instances of Freeboard, I want to keep them in sync. A practical use case would be setting the course down below in the use navigation station and the settings reflected at the helm. Do we want to keep somehow track of who set the course? For example the user, or a course computer advancing the route as the vessel makes way along the route (in the latter case it would be useful to know who originally set the route to follow). Is it useful to have the irrelevant fields as ´null` or should they be just undefined / not there at all? How about advance/go back one waypoint? What about the sequence
I am not sure if we have really used hrefs anywhere in anger yet. As the SK http paths are mounted at /signalk/v1/api should there be a mechanism to indicate that the path in href is relative to that, or should there be something in the begining of the path, denoting that this is the case and the path does not start at the http server's root? Or should the hrefs be relative? |
Agreed. |
Have added a |
The convention to date seems to have been:
This convention seems to work quite well currently. |
Was covered in
Have separated this out to two APIs:
Both of these APIs will consider the value of the |
My understanding is that XTE works on What does this mean for autopilot operation, etc? |
From the relevant part of the specification the implication is that it's relative to Extract from
|
https://www.manualsdir.com/manuals/199085/raymarine-chartplotter.html?page=48&original=1 Relevant features:
|
Re: XTE: forget my example of being near or far from the waypoint. If we are navigating a route imho XTE would be the perpendicular distance between current position and the route leg, defined by two waypoints of the route, that we (or the autopilot) has set to be nextPoint and previousPoint. Does not really matter what our position is - XTE can be calculated even when we are behind previousPosition. The only exception would be "restart XTE" case. |
Added |
Added |
Do we want to include specifying the notifications for entering arrival circle and passing waypoint perpendicular, or is that going into autopilot functionality? |
I don't love the "PUT" or "POST". I think these should all be PUT, or at least pick one. |
I think that it's worth specifiying at least the path of the notification that would be raised. |
I'm OK with just PUT. |
Updated OpenAPI definition to remove POST operatrions. |
This is more in the realm of implementation, but the frequency at which deltas are sent and whether the course values are persisted, so they survive a server restart, all contribute to expected behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am adding a bunch of comments, see what you make of them.
I am starting to think that it would be useful to create the server implementation and a UI to exercise this API before merging this. While this sounds pretty straightforward the devils in the details and they are hard to get right just working in the abstract.
apis/course/README.md
Outdated
- Select the point within the route to be the current destination | ||
- Increment / decrement the point in the route to be the current destination. | ||
- Clear / cancel the course | ||
- Query the current course details. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Course restart is missing?
Do we want to iterate all the methods here exhaustivelu or is the list further below enough, as everything is there? Should this be rewritten as summary, not a list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can just be a summary and let the openapi document detail the methods.
I will reword to make them a summary and not sound like an exhaustive list.
apis/course/README.md
Outdated
|
||
__Action:__ `PUT` | ||
|
||
__Path:__ `/navigation/course/activeRoute/setPoint` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Should this be activeRoute/nextPoint/pointIndex and the payload just value? None of the other paths are setX, just X.
And the payload could support absolute and relative operations "value": 3
or"changeWaypoint": "next"
or previous.
The way increment/decrement are now with 1 and -1 can be confusing: if the route is reversed is "switch to next point in this reversed route" +1 or -1?
And add that property to the data model, so that it can be queried and is available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Should this be activeRoute/nextPoint/pointIndex and the payload just value? None of the other paths are setX, just X.
I have no problem with changing setPont
to pointIndex
and the value body being {value: 3}
I will update the document to refelct that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way increment/decrement are now with 1 and -1 can be confusing: if the route is reversed is "switch to next point in this reversed route" +1 or -1?
My thinking here is that indexes used and returned via query are relative to the route direction and the api manages the adjustment whether route is being navigated in forward or reverse.
So for example a route with 8 points activated in:
Normal (forward) mode:
- Index values reflect the order as defined within the route data 0= point at index 0.... 7= point at index 7.
- +1 next point of e.g. 0->1, 1->2,.....6->7
- -1 previous point e.g. 7->6, 6->5,.....1->0
Reverse mode:
- Start, previous and next operations reflect the sequence relative to the start of the journey... so in this case, 0= point at index 7, 1= point at index 6.... 7=point at index 0
- +1 go to next point e.g. 7->6, 6->5,.....1->0
- -1 go to previous point e.g. 7->6, 6->5,.....1->0
Doing it this way means the UI is not having to worry about number sequencing... start index is always 0 and end index is (length-1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me. So the way pointIndex
property works needs to be documented.
Should there be a way to retrieve activeRoute
's points as an array in one call, instead of fetching the href and reverse property and then fetching the points and accounting for the order in the client?
I just noticed that this PR uses both current
and active
route wording, we probably should use just active
.
apis/course/README.md
Outdated
|
||
### __3.API Methods:__ | ||
|
||
The following endpoints under the path `navigation/course` make up the Course API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think: should/could all this be in the openapi spec, and .md generated from that for humans? I think we should be moving towards openapi specs being the master here.
There is already a "build step" to generate the paths lists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The README.md really just to capture the proposal so if we are on the road to acceptance I would expect it will need to be "worded" and "formatted" appropriately.
So yes I agree that the desriptions of the methods belong in the openapi doc.
I am happy to create / update the documents.
If the location where I have placed these files is OK then I can structure them as agreed.
So is the structure apis/course
OK?
If so should the README.md document be renamed to something else?
I would assume that all future apis will follow the same structure: folder with name of the API containing a description document and an openapi.json file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apis/course is good enough for now.
I think we'd want to have the api documentation (readme.md and openapi) included in https://signalk.org/specification/ as well as available on a local server's Swagger ui, discoverable/navigable from the admin UI.
I have been mocking this up by extending the As far as embedding the course API into the server it will first require the resource path handling functionality to enable the courseAPI to retrieve route details. I have working skeleton of the If it is the correct protocol I can push this branch to |
Please do. I had already trouble looking for PR 1351 and then realised it was an issue, not a PR. Collaboration is easier when working off the same repo: a bit less work with checking out work locally and at least trivial corrections like typos need not go via comments. Can also collaborate on stuff where we are not stepping on each other's toes. |
Feature: Course API
Description:
Define an API for Signal K client applications that provides methods to set a destination or navigate a route.
These methods manage the setting of values in the relevant Signal K paths under both
navigation.courseGreatCircle
andnavigation.courseRhumbline
to enable a course computer to generate additional navigation information (XTE, DTG, etc) as well as facilitate display on a chart plotter.The API will facilitate operations such as:
/resources/waypoints
as a destination/resources/routes
Motivation:
Currently Signal K makes available paths to store navigation data but it is largely left up to implementors of client applications to determine how they are used.
This is can cause interoperability issues and inconsistency in application (e.g. calculations in
signalk-derived-data
plugin will use a mixture of pathsnavigation.courseGreatCircle
andnavigation.courseRhumbline
) so depending on an individual implementation results may vary.Defining and implementing an API will provide reliability in how the values in these paths are populated ensuring confidence in the source data used in course calculations.
By clearly defining and managing the use of specific
course
paths within the Signal K schema, this will ensure consistency in the values they contain and engender confidence in their use.Maintaining quality data in these paths enables the reliable operation of other navigation equipment such as:
by providing a trusted source of data for use in calculating navigation information for steering a course.
The paths within the Signal K schema pertaining to other navigation operations will be maintained by the relevant equipment or Signal K API.
1. Signal K Paths in Scope:
Note: All paths outlined below are relative to
/signalk/v1/api/vessels/self
.The Signal K specification contains a
navigation.course
schema definition which is applied to both thenavigation/courseGreatCircle
andnavigation/courseRhumbline
paths.The following properties under both these paths are in scope for management by this API:
This API will provide endpoints under the path
navigation/course
in order to set a course as well as query the current course information.2.API Operation:
While the intended use of the
in scope
Signal K paths are defined in the specification, the actual use of these paths in practise determines the success of an implementation.2.1 Use of
previousPoint
.To facilitate course calculations such as XTE where the source position is required, the
previousPoint.position
attribute will be set (at the time the destination is set) as follows:When a position (lat, lon) is supplied as a destination: Set the value of
previousPoint.position
to the location of the vessel.When a reference to a waypoint resource is supplied as a destination: Set the value of
previousPoint.position
to the location of the vessel.When a reference to a route resource is is supplied:
If the supplied route
pointIndex
is0
(point at start of the route) then set the value ofpreviousPoint.position
to the location of the vessel.If the supplied route
pointIndex
is not0
then set the value ofpreviousPoint.position
to that of the preceding point in the route.When a "Course Restart" is requested: Set the value of
previousPoint.position
to the location of the vessel.When a destination or active route is "Cancelled": then set the value of
previousPoint.position
tonull
.3.API Methods:
The following endpoints under the path
navigation/course
make up the Course API.3.1 Set a position (lat, lon) as a destination
Use case: Provide "navigate to here" operation.
Action:
PUT
Path:
<self>/navigation/course/destination
Request body:
where:
position
: The destination lat, lon (as per Signal K schema)type
(optional): A string describing the destination (as per Signal K schema).arrivalCircle
(optional): Radius of circle centered at destination indicating arrival.This will result in the following Signal K path values being set:
3.2 Set a Waypoint as a destination
Use case: Provide "navigate to selected waypoint resource" operation.
Action:
PUT
Path:
<self>/navigation/course/destination
Request body:
where:
href
: The path to the target waypoint in/resources/waypoints/
.arrivalCircle
(optional): Radius of circle centered at destination indicating arrival.This will result in the following Signal K path values being set:
3.3 Clear / Cancel a destination or Activated Route.
Use case: Provide "stop navigating to destination" or "deactivate as route" operation.
Action:
DELETE
Path:
<self>/navigation/course/destination
or<self>/navigation/course/activeRoute
Request body:
empty
This will result in the following Signal K path values being set:
3.4 Activate a Route to follow.
Use case: Provide "activate / follow a route" operation.
Action:
PUT
Path:
<self>/navigation/course/activeRoute
Request body:
where:
href
: The path to the target route in/resources/routes/
.pointIndex
(optional): Zero based index of the point within the route to use as the initial destination (defaults to 0 if not supplied or if value is larger than index of last point in the route).reverse
(optional): Iftrue
performs operations on route points in reverse order (defaults to false).arrivalCircle
(optional): Radius of circle centered at destination indicating arrival.This will result in the following Signal K path values being set:
3.5 Select point in the active Route as destination.
Use case: Provide "go to point in route" operation.
Action:
PUT
Path:
<self>/navigation/course/activeRoute/pointIndex
Request body:
where:
value
: Zero based index of the point within the route to use as the initial destination (if value is larger than index of last point in the route then destination is not changed).This will result in the following Signal K path values being set:
3.6 Increment / decrement point in the active Route as destination.
Use case: Provide "previous / next point" operation.
Action:
PUT
Path:
<self>/navigation/course/activeRoute/nextPoint
Request body:
where:
value
: Is either1
(next point) or-1
(previous point).This will result in the following Signal K path values being set:
3.7 Restart course calculations.
Use case: Provide "restart XTE" operation.
Action:
PUT
Path:
<self>/navigation/course/activeRoute/restart
Request body:
empty
3.8 Set arrival circle.
Use case: Provide ability to set the radius of a circle centered at destination indicating arrival.
Action:
PUT
Path:
<self>/navigation/course/arrivalCircle
Request body:
where:
value
: Is the radius of the circle in meters.This will result in the following Signal K path values being set:
3.9 Query current course details.
Use case: Provide "get current course", "get course details" operation.
Action:
GET
Path:
<self>/navigation/course
Response: JSON formatted object containing the current course details as per the following example:
4. Signal K Stream Deltas
The implementation of the Course API requires that the relevant delta messages are sent for the in-scope Signal K paths when:
The absence of a delta for a specific Signal K path indicates that the path has never had a value assigned to it.
Where a delta value is
null
, this indicates that a previous value is no longer valid (i.e. there is a provider for this path but there is no current value available).Delta messages for in-scope paths are as follows: