Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 07:11 02 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Updated Boat Computer

     Page 2 of 3    
Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 05:17am 06 May 2016
Copy link to clipboard 
Print this post

  Quote  To be honest I cannot remember where I got the calculations from but I thought it was from there.


If you are using the flat earth approximations (which use sqrt) it may be worth using the full versions (which don't)
 
davematt
Regular Member

Joined: 27/09/2011
Location: Australia
Posts: 55
Posted: 04:07pm 06 May 2016
Copy link to clipboard 
Print this post

Geoff: Yes, version 2 uses the same 'Distance to POI' equation, which I believe is the problem. If my Excel sheet is correct, my location needs the POIs to be initialised to something more than 8 deg (lat and lon) and this will work for most of Australia.
By the way, I shouldn't have called it a crash, the program actually exits gracefully with a useful error message and an automatic restart. Pretty impressive...
Oh, and I hope others have as much fun as I have, chasing this tiny insect!
Dave.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:56pm 06 May 2016
Copy link to clipboard 
Print this post

The problem appears if the difference in Latitude between the GPS location and the POI is greater than 39.5 degrees.

Thats a long way to go to get a feed of fish.

This replacement function has a simple sanity check to catch the SQR(neg) problem.
variable a becomes greater than 1 so (1-a) is the problem.

I added "IF a>1 THEN a = 1 'sanity check"


FUNCTION POIDistance(POIlat AS INTEGER, POIlon AS INTEGER) AS STRING
LOCAL FLOAT y, x, lat1, lat2, n, m, a
'if abs(POIlat-lat)<0.000001 then POIlat=lat
lat1 = RAD(lat / 36000)
lat2 = RAD(POIlat / 36000)
n = RAD((POIlat / 36000) - (lat / 36000))
m = RAD((POIlon / 36000) - (lon / 36000))
a = SIN(m/2) * SIN(m/2) + COS(lat1) * COS(lat2) * SIN(n/2) * SIN(n/2)
IF a>1 THEN a = 1 'sanity check
n = (2 * atan2(SQR(a), SQR(1 - a)))

' convert the distance to the current units (nautical miles, kilometers, etc)
SELECT CASE SpeedMode
CASE 0
n = 3440 * n
CASE 1
n = 6371 * n
CASE 2
n = 3958 * n
END SELECT

' convert the distance to a four digit string
SELECT CASE n
CASE >= 1000
POIDistance = STR$(n, 1, 0)
CASE >= 100
POIDistance = STR$(n, 4, 0)
CASE >= 10
POIDistance = STR$(n, 1, 1)
CASE ELSE
POIDistance = STR$(n, 1, 2)
END SELECT
END FUNCTION


The function used for bearing and distance are really only valid for near distances.
If you want to navigate to the other side of the world, other formulas are needed.

If Geoff had used his Boat Computer when he visited Tasmania, he would have discovered the problem himself!

I don't have a GPS (or boat) handy so my mod needs testing.

Jim

VK7JH
MMedit
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 04:57pm 06 May 2016
Copy link to clipboard 
Print this post

I have only entered one POI so far and the distance works OK but the Port/Starboard
heading was varying all over the place, it certainly was not directing me to my POI. I will enter some more POIs and do further checking.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
davematt
Regular Member

Joined: 27/09/2011
Location: Australia
Posts: 55
Posted: 05:41pm 06 May 2016
Copy link to clipboard 
Print this post

Jim, I should have thought of that...

Paul, the bouncing is due to the gps calculating a direction traveled in the previous second, which for a stationary or slowly moving unit, does swing wildly. For a plane or car, no problem, but for a yacht or walking, annoying. My project this weekend is to add a rolling average function to the speed and direction result for exactly that reason...
Dave
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 05:45pm 06 May 2016
Copy link to clipboard 
Print this post

Paul,
If your GPS is stationary, the natural movement of the GPS readings will make the 'mite think you are wandering about in all directions.
That might explain the strange directions you are getting.

Jim

VK7JH
MMedit
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 09:02pm 06 May 2016
Copy link to clipboard 
Print this post

  Quote  rolling average function to the speed and direction result for exactly that reason

Rolling average of directions is hard because of going through from 359 to 0

Here is the way I do it - may save you some time

'
'
'rolling average of angles (0-359)
'
const MA=10 'number of elements in moving average array
dim float angleSMAcos(MA-1),angleSMAsine(MA-1)
dim integer temp%=0
'
'rolling average of angles (0-359)
'
ctemp=cos(rad(angle))
stemp=SIN(rad(angle))
angleMAc=angleMAc-angleSMAcos(temp%)/MA
angleMAs=angleMAs-angleSMAsine(temp%)/MA
angleMAc=angleMAc+ctemp/MA
angleMAs=angleMAs+stemp/MA
angleSMAcos(temp%)=ctemp
angleSMAsine(temp%)=stemp
angleMA=deg(atan2(angleMAs,angleMAc))
temp%= (temp% +1) mod MA
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 11:01pm 06 May 2016
Copy link to clipboard 
Print this post

I was travelling at about 20Kph.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
davematt
Regular Member

Joined: 27/09/2011
Location: Australia
Posts: 55
Posted: 12:26am 07 May 2016
Copy link to clipboard 
Print this post

Hi Peter, many thanks for this, it would save me time if I could understand it. I believe you're creating separate arrays of sin and cos, averaging them and then using atan2 to get the new average angle. But the exact process is a bit beyond me. I've met the zero crossing problem before. My brute force approach would have been to add something (eg 500deg) to each element, average them, and then correct. I'm sure your solution is a lot more elegant. Could I ask you (time permitting of course) to add some comments to your code? Oh, and wish me luck...
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 07:36am 07 May 2016
Copy link to clipboard 
Print this post

  Quote  Could I ask you (time permitting of course) to add some comments to your code?


Hope this helps

'
'
'rolling average of angles (0-359)
'
const MA=10 'number of elements in moving average array
dim float angleSMAcos(MA-1),angleSMAsine(MA-1) 'set up 10 element arrays to hold the sine and cosine values
dim integer temp%=0 'set the index to the next element to write
dim float angleMAc 'variable to hold the moving average of the cosines
dim float angleMAs 'variable to hold the moving average of the sines
'
' This section called each time the angle is updated
'
'
'rolling average of angles (0-359)
'
ctemp=cos(rad(angle)) 'get the cosine of the new angle into a temporary variable
stemp=SIN(rad(angle)) 'get the sine of the new angle into a temporary variable

' Now we remove from the rolling average of the sines and cosines the value in the array positions to be updated.
' In the example we have 10 readings in the moving average so we do this by subtracting 1/10th of the oldest value from each average
angleMAc=angleMAc-angleSMAcos(temp%)/MA
angleMAs=angleMAs-angleSMAsine(temp%)/MA

' Now we add into the two rolling averages 1/10th of the new value
angleMAc=angleMAc+ctemp/MA
angleMAs=angleMAs+stemp/MA

' Next we put the new values into the arrays so that in 10 loops time we can use them to remove from the avarages
angleSMAcos(temp%)=ctemp
angleSMAsine(temp%)=stemp

' We now convert the newly updated moving average sine and cosine values back to an angle
' Note we must use atan2 not atan in order not to lose information

angleMA=deg(atan2(angleMAs,angleMAc))

' Finally we update the index value for the next write, modulus the number of elements in the array
temp%= (temp% +1) mod MA


AFAIK this is the only completely robust mechanism of averaging angles such that the number of rotations is completely unconstrainedEdited by matherp 2016-05-08
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 02:38pm 07 May 2016
Copy link to clipboard 
Print this post

  palcal said   I was travelling at about 20Kph.
Paul.


20k is certainly fast enough to minimise errors due to jitter.
20k/h is 5.5 metres second. GPS readings can drift up to 10 metres but rarely will they move more that a metre between readings.

Geoff has code in place to detect very slow speeds but you are well above that threshold.

Does the heading change much while you are traveling with the display in 'heading' mode?

What is the location of your POI and what is your (approx) location?

I wrote a Windows program to do much the same as the boat computer but gave up on it because I found it too risky, playing with computers while driving.
I hope you are using a navigator....

JimEdited by TassyJim 2016-05-09
VK7JH
MMedit
 
davematt
Regular Member

Joined: 27/09/2011
Location: Australia
Posts: 55
Posted: 05:09pm 07 May 2016
Copy link to clipboard 
Print this post


Peter, I think I'm getting there... The attached is thanks to your help in several different areas, I'm sure you'll recognise the derivation.
And yes, I would have completely missed the GPS solution. Back to work...


 
rogersan
Regular Member

Joined: 10/04/2015
Location: Australia
Posts: 79
Posted: 09:18pm 07 May 2016
Copy link to clipboard 
Print this post

Hi Geoff

Have you considered the option of displaying Grid References (Eastings and Northings) as an alternative to Lats and Longs to make the Boat Computer more useful on land?

Roger Sanderson
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 09:30pm 07 May 2016
Copy link to clipboard 
Print this post

@ TassyJim
Heading is OK in Heading mode. My location is 19.0277° S, 146.4167° E
and I am heading to a POI only about one Km. away.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 01:29am 08 May 2016
Copy link to clipboard 
Print this post

  rogersan said  Have you considered the option of displaying Grid References (Eastings and Northings) as an alternative to Lats and Longs to make the Boat Computer more useful on land?

Well no, this is a boat computer.

As I understand it Grid References are referenced to some point - and there are lots of possible points. It sounds very complicated to me.

One of the important features of these Micromite based projects is that you can get in there and change the code to suit your requirements. Now please don't misunderstand, I'm not trying to be cute here, but this sounds like a perfect opportunity for you to get in there and modify the code yourself and come up with a land specific computer. In fact I invite anyone, please feel free to improve the device and post the code here.

GeoffEdited by Geoffg 2016-05-09
Geoff Graham - http://geoffg.net
 
CircuitGizmos

Guru

Joined: 08/09/2011
Location: United States
Posts: 1427
Posted: 10:01am 08 May 2016
Copy link to clipboard 
Print this post

  matherp said  
Rolling average of directions is hard because of going through from 359 to 0


Don't average the absolute angles, average the deltas/changes.


Micromites and Maximites! - Beginning Maximite
 
davematt
Regular Member

Joined: 27/09/2011
Location: Australia
Posts: 55
Posted: 03:33pm 08 May 2016
Copy link to clipboard 
Print this post

This can't be right!
With a bit of smoothing the heading values settled down nicely at walking speed, but the compass needle behaved very strangely. So as a test, I disabled the GPS stuff, and set the main loop to increment the heading by one. The compass needle started pointed West, and then rotated smoothly a full circle in 60 degrees. As I say, this can't be right! Either I've made a silly mistake (v possible) or there is something amiss with the needle drawing routine. Please can someone smarter than me take a look?
DavidEdited by davematt 2016-05-10
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 05:22pm 08 May 2016
Copy link to clipboard 
Print this post

In the Function GetX(),
change
GetX = 250 + Cos(Rad(t * 6)) * r
to
GetX = 250 + Cos(Rad(t)) * r

The same for GetY()
change
GetY = 160 + Sin(Rad(t * 6)) * r
to
GetY = 160 + Sin(Rad(t)) * r

These Functions were use for a clock and still assumed 60 ticks per circle.

In the Sub DrawCompassNeedle
change
ldeg = 90 - deg
to
ldeg = deg - 90

This puts the compass display in step with the bearing.

I haven't tried to simulate the bearing to POI yet.

Jim

VK7JH
MMedit
 
davematt
Regular Member

Joined: 27/09/2011
Location: Australia
Posts: 55
Posted: 07:17pm 08 May 2016
Copy link to clipboard 
Print this post

Bingo!!
Many thanks Jim
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 07:18pm 09 May 2016
Copy link to clipboard 
Print this post

@ TassyJim
You asked if heading needle was steady in heading mode, I replied that it was but that was before I updated the code.
When I was using Geoff's original Boat Computer Code I was running MM.V5.0 and the heading was good and steady both in heading mode and in POI mode.
However I had the problem that the POI would not save. I updated to the new Boat Computer Code and also updated to MM.V5.1 and now I have the problem of the heading needle jumping all over the place. The actual heading readout in degrees is rock solid.
I don't still have a copy of the original Boat Computer Code but maybe I can get it from Silicon Chip. I would like to reload it and see how it behaves with MM.V5.1

Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
     Page 2 of 3    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025