Share My Creation Touchstone - GPS compass

Hi, my first foray into the world of Android app development... here's my contribution

Touchstone - a GPS compass

Until a touchstone has been set (by pressing SET) and after it has been released (by pressing RESET), the compass arrow will point to the North.

When a touchstone has been set, the app records your current GPS location and the arrow points here, until the touchstone is released.
 

Attachments

  • screenshot.jpg
    screenshot.jpg
    8.1 KB · Views: 15,633
  • touchstone.zip
    268.1 KB · Views: 1,761

timo

Active Member
Licensed User
Longtime User
Great job.
Could you please explain me the following piece of code:

....
x = ((2880 + values(0) * 4) Mod 2880) - 1440

If CompassBearing <> x/4.0 Then
CompassBearing = x/4.0
....
Thanks!
 

novaseer

Member
Licensed User
Longtime User
Great job.
Could you please explain me the following piece of code:

....
x = ((2880 + values(0) * 4) Mod 2880) - 1440

If CompassBearing <> x/4.0 Then
CompassBearing = x/4.0
....
Thanks!

I was trying to limit the compass reading to +/- 360 in quarter degrees units
by using an integer value for x where x is the value of the compass bearing * 4

in the If statement, it checks if the stored value for the bearing has changed (that is, has the bearing changed by more than a ¼ degree); if so, it updates the stored value and does some other work too.

I could have just used the raw compass bearing, but I thought it would would use less of the processor if I limited it, smoothing out for some minor movements.
 

netchicken

Active Member
Licensed User
Longtime User
What an amazing program!!!!!

Just what I wanted to learn about. Thanks so much for gifting us your code!
 

timo

Active Member
Licensed User
Longtime User
I've soved in this 'unprofessional' way the problem.
Misteriously it works.:)

B4X:
Sub DegFromGps

Dim f As Float
f=(loc.BearingTo(loc2))
DegToImg (f)

end sub

Sub DegToImg(dir As Float)

'converts GPS deg to compass img Deg

Dim x As Float

x=dir
x=Floor (x)

If x=360 Then
   x=0 'to north
End If
If x >= 0 Then
   x= 0+x 
End If
If x < 0 Then
   x=Abs(x)'too much... 
   x= 360-x
End If

GPSDeg=x 'global
End Sub

Sub Orientation_SensorChanged(Values() As Float)
   
   
   Dim valore As Int
   SensDeg=Values(0)'ok, mi da nuovo orientamento del tel
   SensDeg=Floor(SEnsDeg)
      
   valore= GPSDeg-SensDeg
   If valore > 360 Then
   valore= valore - 360
   End If
   
   'Log ("Sens " & SensDeg &" GPS " & GPSDeg & " Val " & valore)'apparentemente funziona
   
      Canvas1.DrawBitmap(Bitmap1, Null, Rect1)
      Canvas1.DrawBitmapRotated(imgArrow, Null, Rect1,valore)
      Activity.Invalidate()
   
   
End Sub

I see now a mistake that does not invalidate the sub "if valore >360" was written when I additionned GPSDeg and SensDeg. Here it has now no sense.
 
Last edited:

netchicken

Active Member
Licensed User
Longtime User
Has anyone had trouble with the program not releasing its data when you exit and restart it?

Sometimes when I turn it off, and when I turn it back on the same GPS data automatically appears. Can it be cleared?
 

novaseer

Member
Licensed User
Longtime User
if you tap "reset" it releases any earlier data - tapping "set" will replace the current GPS waypoint with the current location (assuming the GPS unit has connected - if not, tapping the "set" is the same as tapping "reset")
 

latcc

Banned
I assume you are using the GPS track as your 'bearing'. How have you got over the difference between a track and a bearing (it is called Heading in UK aviation)?

Is there any chance of directly using the inbuilt compass that many phones have? This would give you a genuine heading rather than a GPS track.
 

novaseer

Member
Licensed User
Longtime User
actually, it uses a combination of gps and internal compass

the heading between the current gps location and the set one (or the north pole, should a point not be set) AND the compass angle is used to calculate the angle to rotate the arrow-canvas.

should the gps not function, it still works quite well as a compass :D
 

BarrySumpter

Active Member
Licensed User
Longtime User
I've created my own example with your script.

I'm in Australia.
South of the equator.

I've had to change this:
B4X:
' east and west are backwards.
degrees = GPSbearing - Compassbearing
tothis:
B4X:
' east and west are correct.
degrees = GPSbearing + Compassbearing


Would this be because the I'm running the app north or south of the equator?





B4X:
'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

      
            Dim GPS1 As GPS

        Dim cntRotate As Int    
    Dim TSloc As Location
    Dim OldLoc As Location
    Dim NPloc As Location


    Dim GPSbearing As Float    
    Dim Compassbearing As Float
        Dim Compass As PhoneSensors

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
   
        
        Dim imgView As ImageView
    Dim bmpDirectionArrow As Bitmap
       Dim bmpExtended As BitmapExtended


End Sub

Sub Activity_Create(FirstTime As Boolean)

    If FirstTime Then
                NPloc.Initialize2( "90:00:00", "00:00:00") 'North Pole
        TSloc = NPloc
        OldLoc.Initialize
bmpExtended.Initialize("BitmapExtended")
        GPS1.Initialize("GPS")
        Compass.Initialize(Compass.TYPE_ORIENTATION)
    End If

        Activity.LoadLayout("Main")
        
    bmpDirectionArrow.Initialize(File.DirAssets,"direction_arrow.png") '300 x 172 pix

        imgView.Bitmap=bmpDirectionArrow

End Sub

Sub Activity_Resume
    If GPS1.GPSEnabled = False Then
        ToastMessageShow("Please enable the GPS device.", True)
        StartActivity(GPS1.LocationSettingsIntent)
    Else
        GPS1.Start(0,0)
    End If
    Compass.StartListening("Orientation")

End Sub

Sub Activity_Pause (UserClosed As Boolean)
    'GPS1.Stop
    Compass.StopListening

End Sub


Sub GPS_LocationChanged (Loc As Location)
    Dim degrees As Float
    OldLoc = Loc
    If GPSbearing <> Loc.BearingTo(TSloc) Then
        GPSbearing = Loc.BearingTo(TSloc)
        degrees = (GPSbearing - Compassbearing)
        'Canvas1.DrawBitmap(Bitmap1, Null, Rect1)
        'Canvas1.DrawBitmapRotated(imgArrow, Null, Rect1, degrees)
        imgView.Bitmap = bmpExtended.rotateBitmap(bmpDirectionArrow, degrees)
        Activity.Invalidate()
    End If
End Sub


Sub Orientation_SensorChanged(Values() As Float)
    Dim degrees As Float, x As Int
    x = ((2880 + Values(0) * 4) Mod 2880) - 1440
    If Compassbearing <> x/4.0 Then
        Compassbearing = x/4.0
        degrees = GPSbearing + Compassbearing
        
        imgView.Bitmap = bmpExtended.rotateBitmap(bmpDirectionArrow, degrees)
        
        Activity.Invalidate()
        
    End If
End Sub
Sub GPS_UserEnabled (Enabled As Boolean)
    ToastMessageShow("GPS device enabled = " & Enabled, True)
End Sub

Sub imgView_Click

  Dim dgrs As Int
  cntRotate = cntRotate + 1
    
    If cntRotate = 37 Then
        cntRotate = 1
    End If
    
    dgrs = cntRotate * 10
    
    imgView.Bitmap = bmpExtended.rotateBitmap(bmpDirectionArrow, dgrs)
    
End Sub
 

novaseer

Member
Licensed User
Longtime User
I'm also downunder, it could be that I got the maths wrong, if that correction works for you, it's probably the case :signOops:
 

Takeru17

Member
Licensed User
Longtime User
North and GPS Compass Touchstone

Hi,
I'm used your example (Great Thanks for that)
but the North is not for the North.
There is a deviation of 20 ° approximately.
How to have the real magnetic North?
 
Top