Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Making GPS as accurate as possible
Started by patso Nov 21 2015 10:07 AM

16 replies to this topic
location gps
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

In my app I'm getting the GPS location and save it to the cloud. I simultaneously measure distance between points and sum them. The problem is that however I've set accuracy to 10 meters it is still very inaccurate. Once I start  the location tracker I get 0.6 miles and than 0.1 adds up every second. Having looked on the coordinate themselves I have seen that while the iPhone is in one place it records different coordinates nearby the actual location. 
How I make it more accurate. Maybe recording only certain coordinates or recording coordinates every 10 seconds. 
What would you recommend?



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,253 posts
  • Enterprise

I'm not sure I follow the problem here. Perhaps some code would help us understand.

 

Rob



[TOPIC: post.html]
#3

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

Ok, maybe I miss something fundamental. here is what I have
I have the location listener which records coordinates and adds them to a table. later coordinates are summed up (see function distanceBetween below ) and the degrees are then turned to miles and displayed as text. The problem is that I obtain 0.6 a;most immediately after the launch of the location service
 

local locationEnabled = false
system.setLocationAccuracy( 10 )

locationHandler = function( event )
  if locationEnabled == true then
    -- Check for error (user may have turned off location services)
    if ( event.errorCode ) then
        native.showAlert( "GPS Location Error", event.errorMessage, {"OK"} )
        print( "Location error: " .. tostring( event.errorMessage ) )
    else
        startLat, startLon = event.latitude, event.longitude
        print(event.latitude, event.longitude)
--- add coordinates to table
        counter = counter+1
        movementTable[counter] = {}
        movementTable[counter].lat, movementTable[counter].lng = event.latitude, event.longitude
        local table = json.encode(movementTable)
        
        if counter>1 then
         DD.distanceBetween( movementTable[counter-1],  movementTable[counter], counter,"current")
         currentTotalDistance = currentTotalDistance+ currentDistance[counter]

--turn degrees to miles
                  local distancekm = currentTotalDistance * ( 10000 / 90 )
                  
                  local distanceFeet = distancekm * 3280.84
                  local distancemi = distanceFeet/5280
---  display one digit after the dot
                  distancemi = math.round(distancemi*10)*0.1

            distanceText.text = distancemi.." mi"
  

             
        end
        
    end
  end
end

Here is distanceBetween function I'm referring to.
 

DD.distanceBetween = function( point1, point2, count, typeD )
    
    local dX = point2.lng - point1.lng
    local dY = point2.lat - point1.lat
if typeD == "total" then
    distance[count] = math.sqrt( ( dX^2 ) + ( dY^2 ) )
    --print("distance", distance[count] )
    return distance[count]
    elseif typeD == "week" then
      weekDistance[count] = math.sqrt( ( dX^2 ) + ( dY^2 ) )
    --print("distance", distance[count] )
    return weekDistance[count]
    elseif typeD == "current" then
      currentDistance[count] = math.sqrt( ( dX^2 ) + ( dY^2 ) )
      return currentDistance[count]
    end
end 

Hope this clarifies the question.



[TOPIC: post.html]
#4

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,253 posts
  • Enterprise

It's going to be real hard with out seeing the values of the print statements getting the lat and long to check the math in your distance calculation function.

 

I don't know how much you're moving between events, so its very likely your movement is working out to 0.1 per event. Remember lat and long are in degrees. There are 69 miles per degree so depending on your movement 0.1 might be very real.

 

Also, you do this:   local table = json.encode(movementTable)

while I don't see an use of the variable table afterwards or anything that would use the table object, you temporarily trash the internal table.* API's. Its not really safe to use "table" as a variable name.



[TOPIC: post.html]
#5

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

As for the table, you're completely right! I had used this json later on for a reason, but now I have no more need in it.

Here is what I'm geting(1 second of location handler sitting and not moving)
total distance(degrees): 5.2594401346301e-05
distancekm: 0.0058438223718227
distancefeet: 19.172646190371
distance miles(before rounding up): 0.0036311829906005

Does it make sense? If i continue using listener and up to moving it mounts up to 198 feet in 1 minute and then considerably slows down in adding distance. 2:30 and only 227 feet. 
 



[TOPIC: post.html]
#6

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

The 0.6 miles I initially stated was a remark for my client. He told me that he got 0.6 miles without yet leaving the parking lot. 



[TOPIC: post.html]
#7

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,253 posts
  • Enterprise

I think it's your rounding code.  There are 5280 feet in a mile. You're rounding off to 10ths of a mile (528 feet). Even if you round off to 100ths, its 52.8 feet.

 

Rob



[TOPIC: post.html]
#8

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

So my rounding code should look something like:
 

distancemi = math.round(distancemi)*0.1

Sorry, I'm bad at math.



[TOPIC: post.html]
#9

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,489 posts
  • Corona SDK

Hi.  I wanted to interject that you're working too hard.  Don't write the code to calculate delta distance yourself.  Let some else do it.

 

There is an equation called the "Haversine Distance".  I've borrowed someone else's code and you can now borrow it from me:

-- Calculate the distance from one decimal lat-long position to another.
-- Distance is a multiple of R (either kilometers or miles)
-- More accurate for short distances than long.
function math.haversine_dist( lat1, lng1, lat2, lng2, R )
   --[[ haversine formula
   dlon = lon2 - lon1 
   dlat = lat2 - lat1 
   a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2 
   c = 2 * atan2( sqrt(a), sqrt(1-a) ) 
   d = R * c (where R is the radius of the Earth;  radius of the Earth: 3961 miles and 6373 km) 
   --]]

   local mRad  = math.rad
   local mCos  = math.cos
   local mSin  = math.sin
   local mSqrt = math.sqrt
   local mAtan2 = math.atan2
	
   R = R or 6373 -- Default radius of earth in km
   local dlng = mRad(lng2 - lng1)
   local dlat = mRad(lat2 - lat1)

   lat1 = mRad(lat1)
   lat2 = mRad(lat2)

   local a = (mSin(dlat/2))^2 + mCos(lat1) * mCos(lat2) * (mSin(dlng/2))^2 
   local c = 2 * mAtan2( mSqrt(a), mSqrt(1-a) ) 
   local d = R * c --(where R is the radius of the Earth)

   return d
end

Now, if you have start lat-lng and current lat-lng you can get the delta distance like this:


print( "Delta Dist in kilometers: ", math.haversine_dist( startLat, startLng, curLat, curLng, 6373 ) )

print( "Delta Dist in miles: ", math.haversine_dist( startLat, startLng, curLat, curLng, 3961 ) )


[TOPIC: post.html]
#10

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

Thanks roaminggamer! output seems to be more accurate but again how do I round it up to one digit after dot correctly?

 



[TOPIC: post.html]
#11

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,253 posts
  • Enterprise

I don't think you should. 0.1 is 568 feet. It sounds like you need more resolution to this. 0.01 is 56.8 feet and 0.001 is 5.68 feet. You can't measure small movements without enough resolution.

 

Now what I would do is not round at all while you're doing your math, but output the visual like this:

 

distanceText.text = string.format("%0.1f", distancemi)

 

Rob



[TOPIC: post.html]
#12

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,489 posts
  • Corona SDK


-- ==
--    round(val, n) - Rounds a number to the nearest decimal places. (http://lua-users.org/wiki/FormattingNumbers)
--    val - The value to round.
--    n - Number of decimal places to round to.
-- ==
function math.round2(val, n)
  if (n) then
    return math.floor( (val * 10^n) + 0.5) / (10^n)
  else
    return math.floor(val+0.5)
  end
end

 Or use format as suggested by rob to get a string formatted number.



[TOPIC: post.html]
#13

patso

[GLOBAL: userInfoPane.html]
patso
  • Contributor

  • 135 posts
  • Corona SDK

Thanks guys for your help!

Any tips on how to reduce or eliminate this "garbage" location collecting (even if still, the phone receives different location coordinates)?
 



[TOPIC: post.html]
#14

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,253 posts
  • Enterprise

Not sure I follow. Can you explain better what is happening and what you want to do?

 

Thanks

Rob



[TOPIC: post.html]
#15

ikwilgeenreclame

[GLOBAL: userInfoPane.html]
ikwilgeenreclame
  • Observer

  • 16 posts
  • Corona SDK

Thanks guys for your help!

Any tips on how to reduce or eliminate this "garbage" location collecting (even if still, the phone receives different location coordinates)?
 

Hi, I am working on an app with gps as well. I have seen in my log data the first gps readings may come from cache on the device. So always ignore the two first readings, that already minimizes "garbage". I am not there yet with getting no garbage at all, but this helps.



[TOPIC: post.html]
#16

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,253 posts
  • Enterprise

Here's the way location services works. It first gets a location from WiFi if WiFi is enabled or from 3G/4G if it has support for that. 3G/4G is the least accurate, WiFi in the middle and GPS The most.

 

You have probably seen this behavior in the Maps app. It starts showing a big circle around you, then it gets smaller and smaller. With 3G/4G services as it contacts more towers the more accurate it gets up to a limit. If you are on WiFi, it's getting the location of the nearest WiFi hot spot or your home WiFi.

 

GPS can take a while to connect. If you're in a building, it may not even be able to see the GPS birds. It as to be able to get the signal from at least three satellites to triangulate your position. These don't sync up immediately.

 

These first few locations that you are throwing a way is just the device homing in on you. If you can't see the GPS satellites then those first few signals may be as accurate as you can get.

 

Next, the GPS has errors built in. Even with the Map app, if you zoom in, don't move, you will see your dot move around by a few meters. Without moving, I can be in my living room, then a few seconds later, I'm in my garage at my house. It's the nature of GPS.

 

Rob



[TOPIC: post.html]
#17

ikwilgeenreclame

[GLOBAL: userInfoPane.html]
ikwilgeenreclame
  • Observer

  • 16 posts
  • Corona SDK

Rob,

 

Thanks for the answer. I already saw that when driving the car the overall  accuracy of speed and also calculated distance is a lot better then when walking. I am still "tuning" to get more accurate readings when running, since I am working on a running app. The reported accuracy can be used I guess to determine how many decimals of the latitude and longitude can be considered valuable. When the accuracy is above 100 meters, you could choose to only use the first three decimals for calculating distance? And so on based on this table (http://gis.stackexchange.com/questions/8650/how-to-measure-the-accuracy-of-latitude-and-longitude).

Also based on this table I am ignoring everything from the 4th/5th decimal since that does explain the "moving around" when you are not moving :-).

decimal
places degrees distance
------- ------- --------
0 1 111  km
1 0.1 11.1 km
2 0.01 1.11 km
3 0.001 111 m
4 0.0001 11.1 m
5 0.00001 1.11 m
6 0.000001 11.1 cm
7 0.0000001 1.11 cm
8 0.00000001 1.11 mm



[topic_controls]
[/topic_controls]