wellenvogel / avnav

using the raspberry pi as a nav computer
MIT License
87 stars 27 forks source link

Feature Request: AIS relative motion vectors #323

Closed quantenschaum closed 5 months ago

quantenschaum commented 7 months ago

It would be nice to have the possibility to display relative motion vectors for AIS targets. The transformation is trivial and the usefulness for collision avoidance is great. All commercial radar/AIS systems support that.

There could be a shortcut for switching between true/relative. Or one could enable relative vectors additionally in the AIS settings and show them as dashed lines. Additionally there could be a marker on the relative motion vector at the location of the CPA.

wellenvogel commented 7 months ago

What exactly do you mean with "relative motion"?

quantenschaum commented 7 months ago

The motion vector of the other vessels (ais targets) relative to own ship.

relative motion vector = true motion vector - true motion vector of own ship

These are the vectors usually shown by a radar with ARPA that tracks contacts or as you would draw them on a maneuvering board to calculate CPA. Using them you immediately see when on collision course: the relative motion vector is pointing at you. And it tells you, how to change your course and speed to open up the CPA.

more on this topic and theory can be found here (page 59) https://msi.nga.mil/Publications/RNMB and https://www.youtube.com/watch?v=8YUic4LdWFg

image

There is no need for a separate view looking like a maneuvering board, the relative motion vectors could be displayed on the chart directly but visually distinguishable from true motion vectors (dashed). You just have to be aware of how to read these vectors, they do not show an actual track on the map. Switching to heap up mode is useful here as well (head up + range rings effectively give you a maneuvering board). RM vectors should be disabled by default to avoid confusion but can be activated by the user if they want to. A RM vector display is usually only available on commercial equipment and not on consumer products. So, it would be really nice, if AvNav supported this.

It could look something like this.

image

quantenschaum commented 7 months ago

If you could point me to the relevant sections in the code, I would try to implement it myself.

wellenvogel commented 7 months ago

For the computations: viewer/nav/aisdata.js viewer/nav/navcompute.js For the display: viewer/map/aislayer.js For the switch: viewer/util/keys.jsx viewer/gui/settingspage.jsx Potentially some more for the ais list and info page. Important to think about the error scenarios...

quantenschaum commented 7 months ago

Is there a way to load the sources directly into the browser without processing it through the gradle whatever thing? How can I change the code and immediately run and debug it in the browser?

quantenschaum commented 7 months ago

../gradlew debug -t in viewer/?

wellenvogel commented 7 months ago

No. At least you need to run the webpack build using npm run watch In the viever dir. Initially you need one run of npm install there. This requires nodejs being installed on your system. In parallel start the server from within the forked git ( cd into the base dir): linux/avnav -a . -v viewer/build/debug This requires python3 + some packages.... After any code change the webpack compiler will run and you can reload the page. And you have the debug build that you can easily debug with the browser developer tools.

quantenschaum commented 7 months ago

Thanks. OK, will try that. - It works, nice.

Why do you draw dashed lines by drawing every single dash and do not use context.setLineDash()?
And why does the dash size depend on the canvas width?

wellenvogel commented 7 months ago

In the beginning I was trying to remain independent of the context drawing API to be prepared for different back ends (like WebGL or something OpenLayers specific). Maybe this could be changed as I don't think I will still go for any other drawing back end. Finally some of the functions simply need some trial to get an impression what provides best visibility. We always have to consider poor visibility due to heavy sun light or other factors. So it's always a good idea to really try out things on a mobile device being outdoor.

quantenschaum commented 7 months ago

So, here is my take on it. Have a look, please.

It's a really cool project and nice to work and play with. Why didn't I find it earlier? Actually I had the idea of writing something like AvNav as well. It started with a server/proxy for tile based charts for use in OsmAnd, then I thought of adding own ship's position and other data to the map, but didn't have the time. Then I found AvNav. Someone already did the job. Very nice. Thank you.

https://github.com/wellenvogel/avnav/assets/3985599/8b8f58cb-d8d2-41b2-ba39-52b0abd4a731

wellenvogel commented 7 months ago

Thanks a lot. Will need some time as currently I'm busy with the o-charts stuff.

quantenschaum commented 7 months ago

Thoughts on AIS data, updating, CPA computation.

example

QM2 HDG=010 STW=0 SET=280 DFT=3 COG=280 SOG=3 both images show the same situation: left using COG, right using HDG

image

quantenschaum commented 7 months ago

drifting vessel with HDG!=COG displayed correctly

image

This is also helpful when you get visual contact with the target. You see how it is oriented (HDG) but you know how it actually moves over ground (COG). With HDG for COG this quickly gets confusing.

wellenvogel commented 7 months ago

For the HDG part: Refer to #272 For the update times: There is for sure some performance trade off. Just imagine very large number of AIS targets (>>100) - people reported such large numbers. This can really influence responsiveness a lot. Maybe it would be necessary to do some measurements - especially on rather slow devices (like a raspberry running the UI on a local screen).

quantenschaum commented 7 months ago

HDG stuff - What Aldebaran says is exactly what I said.

Am Schlepper sieht man auch schön, den Unterschied zwischen HDG und COG, er schaut nach Norden, aber fährt nach Süden, also rückwärts. Hier habe ich einen kleinen Dissens mit Andreas: die offizielle Empfehlung ist, dass das AIS Symbol immer in Richtung HDG schauen soll, nur wenn das HDG Signal fehlt, kann man auf COG zurückgreifen. In AVNAV ist dies einstellbar, aber man kann eben auch das Symbol nach COG ausrichten lassen, was dann anders ist als auf anderen Plottern. Dies finde ich unschön.

The problem in AvNav is, that both the target icon and the course vector use either HDG or COG (as selected in the settings) simultaneously. They always point into the same direction. This is wrong!

The true motion vector is the estimated track over ground for the selected time span, it is not related to HDG at all. Using HDG for its direction as in the example above yields a completely meaningless line that suggests a movement of the target that actually does not exist. This is why this is dangerous. It does not make sense to have a useHDGasCOG setting.

Please think about it and look at the images I posted carefully.

wellenvogel commented 7 months ago

Will just have a look... Anyway if I remember correctly (I had a lot of discussions with him offline) - one of the issues is that COG can be completely wrong if your speed is very low (close to 0) as it is computed from GPS position differences. So at least this also has to be considered for the course vector. And what he says in your excerpt is slightly different - he does not like the option to let the symbol point to COG - it's not about the course vector. Remaining problem: Breaking changes is something I always try to avoid as much as possible. So at least we need to consider the potential consequences.

quantenschaum commented 7 months ago

one of the issues is that COG can be completely wrong if your speed is very low

Yes and no, but this is no problem because you always have to see (COG,SOG) as vector. A zero length (or very short) vector has effectively no orientation, the value of COG with SOG=0 does not matter. This nonsense COG is an artifact of the polar coordinates. It's actually not wrong, it's just meaningless because SOG=0. The true motion vector displayed will be very short in this case, so the direction does not matter.

he does not like the option to let the symbol point to COG

Yes, because it doesn't make sense, but COG as fallback would be ok.

it's not about the course vector

It is, but indirectly. If the tug he describes goes astern, having the true motion vector point ahead is wrong. Ask him about it, I know what his answer will be. He focused on the orientation of the icon because it was aligned to COG, that was his complaint. The true motion vector was also using COG which is correct. He never wanted the TMV to be aligned with HDG. After introducing the useHDGasCOG switch and enabling it, not only the icon was aligned with HDG but also the TMV. This is wrong and doesn't match the situation he describes. He doesn't talk about the orientation of the TMV because it was correct before the HDG=COG option was introduced.

Breaking changes is something I always try to avoid as much as possible.

Can understand that, but what AvNav displays as true motion vector when using HDG for COG is rubbish and dangerous. Consider the consequences of this. I would not hesitate to fix this and already did. It's not a breaking change, it's broken. ;)

You want to make AvNav as useful as possible with the data that is available. Superb! But it doesn't make sense do display data, just to display something even if it is wrong. IMHO it's better display nothing at all, than to display wrong data.

Computing true motion vector from HDG is only correct if HDG=COG

These assumptions are almost never satisfied, especially not

I cannot think of any convincing argument for computing the true motion vector from HDG, it's just wrong. If you don't have a (COG,SOG) vector, you cannot display a true motion vector, end of story. Better don't show a TMV at all than a wrong one that suggests a movement of the target that is not the case and may lead to a collision.

It's a bit like the problem with the SailInstrument. Here the calculations were also wrong, COG/SOG/HDG/STW were carelessly mixed. If you don't have HDG/STW one can fallback to COG/SOG to compute ground wind instead of true wind, assuming COG=HDG (otherwise TWD wrong). That is somehow ok, and first of all it is less dangerous because wind speed is not used for collision avoidance.

quantenschaum commented 7 months ago

It's a pretty interesting experience to see how different people implement these calculations, but no one gets it completely right. There's also a plugin for SK that computes derived data, it also contains errors. I would really like to test products from B&G, Raymarine, Garmin..., feed them with test data and see what they show. Here the power of open source comes into play and many people can check and contribute to the code. This is great.

The root cause of these errors seems to be the common misconception that a ship moves over ground into the direction of it's heading. This is almost never the case and furthermore it is not the general case. There is current and leeway. Everyone holding a yacht master or the like knows how to work out a course to steer, usually graphically on paper. You calculate the (true) heading you have to hold to reach your destination at a certain bearing. This heading is usually not equal to the bearing, this is the reason for performing these vector gymnastics in the first place. So, it should be obvious that a ship doesn't move over ground into the direction of it's heading, but still it is commonly assumed.

A graphic like in https://github.com/wellenvogel/avnav/issues/323#issuecomment-1948833696 is what you actually want the chartplotter to show to you and this is nothing special or uncommon, this what happens in reality all the time.

quantenschaum commented 7 months ago

Here an example of AvNav (with TMV from HDG) vs OpenCPN (has no such option), both fed with the same data.

image

quantenschaum commented 7 months ago

It even gets more confusing if you look at the DR position ("ghost" :ghost: ) that is displayed by AvNav (right) compared to OpenCPN (left).

image

quantenschaum commented 7 months ago

I hope all of this in convincing enough to remove the use-HDG-as-COG-option.

wellenvogel commented 7 months ago

I just checked again in the code. Maybe I missed some points... For AIS targets the course vector is always computed from COG. For the Icon rotation (i.e. symbol direction you can select HDG or COG, HDG falls back to COG if not available). For the own ship we have the course vector (solid line) - always computed from COG. And we have the ship direction vector (dotted line, optional) that is based on the ship direction. The intention for this one is to easier align the chart view with what you see in reality if you look right ahead on the ship. CPA computation is always based on GPS data (i.e. SOG/COG). So what do you think is wrong?

Would be helpful to have some testing data available that shows a situation where AvNav does not compute it like this.

wellenvogel commented 7 months ago

Additional remark: I compared your PR code (aislayer) with the original code. Except for the relative motion vectors you are now back to the original handling - only you cannot switch back to use COG for the ais target direction (what is there to maintain compatibility...).

quantenschaum commented 7 months ago

For AIS targets the course vector is always computed from COG. For the Icon rotation (i.e. symbol direction you can select HDG or COG, HDG falls back to COG if not available).

Does this describe how it currently is or how it should be?

I observed (examples above) and found in the code that the course vector (aka true motion vector) is computed using HDG if this is selected in the settings.

So what do you think is wrong?

That the course vector of ais targets is computed using HDG. That's what I want to point out all the time.

Or did I talk rubbish and got confused between your original code and my changes? That's possible.

quantenschaum commented 7 months ago

Maybe I really mixed your and my changed code. Sorry for the noise then, but then this is clarified for sure now.

quantenschaum commented 7 months ago

I readded the HDG/COG setting but added a fallback to COG if there is no HDG.

Sorry for the confusion, but now this is topic has been discussed thoroughly. So, if someone asks...

wellenvogel commented 7 months ago

I made some tests with your pr code. For me the view now looks rather confusing... Screenshot_2024-02-18_17-38-35

What I see: (1) rot indicator is very dominant (and cannot be styled). And I do not really understand the formula for computing it. (2) For me all the relative motion vectors (really far away from my current position) are at best confusing. Maybe it would make sense to limit them to selected/nearest/warning target - or to targets in a close range to me. (3) for the dashed lines yellow is maybe not the best initial color (you can adapt this of course...)

quantenschaum commented 7 months ago

Thanks for testing and looking into it.

For me the view now looks rather confusing

Yes, it appears confusing at first, when you are not used to the concept of RMVs. Did you watch the YT video? :point_up_2: If you understand the idea and know how to read them, they are very helpful to spot CBDR situations right away. They are optional and disabled by default, not to confuse anyone, but they are there for those how know how to use them.

To read them the following helps.

  1. the ROT indicator is optional and still work in progress. ROT is not displayed anywhere in avnav so far. opencpn shows it as little black line at the end of the TMV, so I copied that. One could show a curved line. Which formula do you mean? (rot/4.733))^2? This is in the AIS specs (search for "rate of turn").
  2. A range threshold to only display RMVs on targets in proximity does make sense. I will add that.
  3. Yellow in general is hard to read, but it's configurable.
wellenvogel commented 7 months ago

Sorry I was not clear. The concept of the relative motion vectors is clear. And I like it. But the problem (for me) was just with all the targets being far away from my own pos. So I guess the solution with a range would really address this.

For the rot I'm not really sure if we should like to have it like this. Maybe a small indicator close to the ship symbol would be better. The problem will all AIS stuff is the to find a balance between displaying a lot of information and making the chart unreadable if we have many AIS targets. I know about the value in the spec.But I could not really get the point for: rot/300*target_sog*courseVectorTime as length of the vector.

quantenschaum commented 7 months ago

rot/300*target_sog*courseVectorTime = length of TMV scaled by rate of turn, 300 is just for normalization, was just a try to make the black line longer when the ship is turning faster

quantenschaum commented 7 months ago

I added optionally curved TMVs and RMVs. The estimated true and relative track is drawn including the rate of turn information and shows up as a curved line if the target is turning. This is very valuable information in situations when a big ship is turning slowly. This is currently not possible to see in avnav since there is neither a turn indicator nor is the rate of turn displayed in the AIS data. You would have to observe how a target changes its course between AIS updates. The curved paths can show you potentially dangerous situations right away long before a CPA warning is displayed (CPA computation doesn't consider ROT).

example

image

on the right you see how the vessel is changing course, but keep in mind that it is played back 20 times faster :point_up:

https://github.com/wellenvogel/avnav/assets/3985599/7450167e-b7a4-4044-a82c-b1e723473390

quantenschaum commented 5 months ago

is implemented