GPS running count of distance

anaylor01

Well-Known Member
Licensed User
Longtime User
I am using the example from the forum. I am trying to create a simple app to keep a running distance from a starting point. Below is the code I have. The problem is the distance calculation. getDistanceKM. I would also like to change this to MILES. Any help would be appreciated.
B4X:
Sub Process_Globals
    Dim GPS1 As GPS
End Sub

Sub Globals
    Dim lblLon As Label
    Dim lblLat As Label
    Dim lblSpeed As Label
    Dim lblSatellites As Label
    Dim btnTurnOnGps As Button
    Dim latstart,latstop,lonstart,lonstop As String
    Dim lblDistance As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        GPS1.Initialize("GPS")
    End If
    Activity.LoadLayout("GPSMain")
End Sub

Sub Activity_Resume
    If GPS1.GPSEnabled = False Then
        ToastMessageShow("Please enable the GPS device.", True)
        StartActivity(GPS1.LocationSettingsIntent) 'Will open the relevant settings screen.
    Else
        GPS1.Start(0, 0) 'Listen to GPS with no filters.
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    GPS1.Stop
End Sub

Sub GPS_LocationChanged (Location1 As Location)
    lblLat.Text = "Lat = " & Location1.ConvertToMinutes(Location1.Latitude)
    lblLon.Text = "Lon = " & Location1.ConvertToMinutes(Location1.Longitude)
    lblSpeed.Text = "Speed = " & Location1.Speed
    latstop = Location1.Latitude
    lonstop =Location1.Longitude
    getdistanceKM(latstart,lonstart,latstop,lonstop)
    latstart = latstop
    lonstart = lonstop

End Sub

Sub GPS_UserEnabled (Enabled As Boolean)
    ToastMessageShow("GPS device enabled = " & Enabled, True)
End Sub

Sub GPS_GpsStatus (Satellites As List)
lblsatellites.Initialize("")
    lblSatellites.Text = "Satellites:" & CRLF
    For i = 0 To Satellites.Size - 1
        Dim Satellite As GPSSatellite
        Satellite = Satellites.Get(i)
        lblSatellites.Text = lblSatellites.Text & CRLF & Satellite.Prn & _
            " " & Satellite.Snr & " " & Satellite.UsedInFix & " " & Satellite.Azimuth _ 
            & " " & Satellite.Elevation
    Next
    
End Sub
Sub btnTurnOnGps_click
Dim location1 As Location
Location1.Initialize
If btnturnongps.Text = "Start" Then
btnTurnOnGps.Text = "Stop"
latstart =  Location1.Latitude
lonstart = Location1.Longitude
Else
btnTurnOnGps.Text = "Start"
getdistanceKM(latstart,lonstart,latstop,lonstop)
End If

End Sub
Sub getDistanceKM(lat1, long1, lat2, long2)

    DEGREES_TO_RADIANS = (cPI / 180.0)
    EARTH_RADIUS = 6371.0
    
    rlat1 = DEGREES_TO_RADIANS * lat1
    rlong1 = DEGREES_TO_RADIANS * long1
    rlat2 = DEGREES_TO_RADIANS * lat2
    rlong2 = DEGREES_TO_RADIANS * long2
    
    '    There is no real reason To break this lot into 
    '    4 statements but I just feel it's a little more 
    '    readable.
    p1 = Cos(rlat1) * Cos(rlong1) * Cos(rlat2) * Cos(rlong2)
    p2 = Cos(rlat1) * Sin(rlong1) * Cos(rlat2) * Sin(rlong2)
    p3 = Sin(rlat1) * Sin(rlat2)

    ret = p1 + p2 + p3
    If ret = 1 Then Return 0
    
    ret = ACos(ret)
    ret = ret * EARTH_RADIUS
    lbldistance.text = ret
    Return ret
    
End Sub
 

anaylor01

Well-Known Member
Licensed User
Longtime User
Ok. It looks like this is the line that is causing NaN.But it is still returning 8.98383748374838484E-5.

B4X:
  Distance =  getdistanceKM(latstart,lonstart,latstop,lonstop) + distance
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Here you are.

There were several problems in your code:
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]latstop = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]NumberFormat[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2](Location1.Latitude,[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]8[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT]
[SIZE=2][FONT=Courier New]lonstop = [/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]NumberFormat[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2](Location1.Longitude,[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]8[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT][/SIZE][/FONT]
You shouldn't limit the number of digits of the latstop and longstop variabels. You should limit only for the display!
With the NumberFormat function you transformed the numbers to strings, that was the problem.

In the getDistanceKM routine you have changed the earth radius from km to miles, but you didn't remove the correction factor
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]EARTH_RADIUS = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]3959.0[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2].[/SIZE][/FONT]
[SIZE=2][FONT=Courier New].[/FONT][/SIZE]
[SIZE=2][FONT=Courier New]ret = (ret * EARTH_RADIUS) * [/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0.621[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]
* 0.621 must be removed !

As I don't have a device I added a timer to test the program.
You should remove all the lines with ' just for Test

Best regards.
 

Attachments

  • Pedometer.zip
    9.2 KB · Views: 320
Upvote 0

klaus

Expert
Licensed User
Longtime User
Did it work with the Timer ?
At what line exactly do you get the NaN error ?
The problem seems beeing related to the GPS.
It is not in the GetDistance routine.

You should set some breakpoints in the code and run the program step by step to find out where the problem happens.

As I have no device I can't test it with the GPS.

Best regards.
 
Upvote 0

anaylor01

Well-Known Member
Licensed User
Longtime User
Ok. It is in the return value. Please look at the attached screen print.
 

Attachments

  • Pedometer.jpg
    Pedometer.jpg
    28.6 KB · Views: 393
Upvote 0

klaus

Expert
Licensed User
Longtime User
Sorry, but it is impossible to read anything in the image.
The best way to see what happens is to set a breakpoint at the beginning of the GPS_LocationChanged routine to check the values of the variables transmitted. And perhaps also in the GetDistance routine.
Otherwise I can't help anymore, the sample program without a GPS is working well.

Best regards.
 
Upvote 0

anaylor01

Well-Known Member
Licensed User
Longtime User
the gps sub is returning 5.309249823E-4. You should be able to read the screen shot I attached.
 

Attachments

  • Pedometer.jpg
    Pedometer.jpg
    34.6 KB · Views: 316
Upvote 0

klaus

Expert
Licensed User
Longtime User
You need to be more precise how you did the test !
In the screenshot the values of lat1 and lat2 are the same and long1 and long2 are also the same so it's normal, the distance between two points with the same coordinates is zero. This happens at least with the first point because the program sets lat1 and lat2 the same and long1 and long2 also to the same. To get a disatance you need two points with different coordinates. If you make the test without moving the distance will reamin zero as it should be.

Best regards.
 
Upvote 0

anaylor01

Well-Known Member
Licensed User
Longtime User
I tested it on my device using the debug. If you look at the highlighted in blue value. That is the part that is returning NaN. I am testing it just sitting still. It should not display NaN. It should display 0.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Occasionally the variable ret contains a value very slightly greater than 1 and passes it to ACos for which it is an invalid value. Change the comparison to >=
B4X:
   If ret >= 1 Then 
      Return 0
   Else
      ret = ACos(ret)
      ret = (ret * EARTH_RADIUS)
      Return ret
   End If
@Klaus - I've not looked at the calc in any detail but can ret ever be -ve?
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Try to change these lines
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]GPS1.Start([/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2], [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]) [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000][FONT=Courier New][SIZE=2][COLOR=#008000][FONT=Courier New][SIZE=2][COLOR=#008000]'Listen to GPS with no filters.[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]latstart = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]lonstart = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]Distance = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]
to this
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]latstart = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]lonstart = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]Distance = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT]
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]GPS1.Start([/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2], [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]) [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000][FONT=Courier New][SIZE=2][COLOR=#008000][FONT=Courier New][SIZE=2][COLOR=#008000]'Listen to GPS with no filters.[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]

Are you shure you want to start directly when the program is started or only after clicking the Start button? Above lines are also in Activitys_Resume.

Best regards.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
That won't make any difference Klaus. The GPS event cannot occur until Activity_Resume returns because there is only a single thread so execution has to return to the message loop and then the message loop can process the event message from the GPS and call the event Sub.

It is probably the old "problem" that Floats and Doubles are not exact representations of numbers that causes ret to occasionally contain a value a teeny-weeny bit greater than 1 (I saw something like 1.0000000000002 when I looked at it) even if you think the maximum value can only ever be 1 or less - or it might be for a totally different reason. :)
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
@agraham,
I saw your post #32 after having posted mine.
Fully agree with with >=1 !

I proposed to set GPS1.Start(0, 0) 'Listen to GPS with no filters.
after Distance = 0 because in the last screenshot ret has a correct value but Distance has NaN.

@Klaus - I've not looked at the calc in any detail but can ret ever be -ve?
It shouldn't but I haven't checked it either. There exist different calculation routines, but with trigonometry same equations can be written in different manners.

Best regards.
 
Upvote 0

anaylor01

Well-Known Member
Licensed User
Longtime User
Got another question. I want to make this a service. I have added a service module. My question is how do I make this a serivce? Can I just call the GPS_LocationChanged sub routine from the Service?
 
Upvote 0
Top