Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

GPS Data Not Giving Correct Speed #1855

Open
tpitman opened this issue Jul 19, 2021 · 0 comments
Open

GPS Data Not Giving Correct Speed #1855

tpitman opened this issue Jul 19, 2021 · 0 comments
Labels
bug Something isn't working

Comments

@tpitman
Copy link

tpitman commented Jul 19, 2021

Description

I am using the Geolocation.GetLocationAsync to get coordinates and the using those to find the speed. I am driving in a car, so expect values greater than when walking.

Steps to Reproduce

  1. Use code below to get GPS coordinates
  2. Use Location.CalculateDistance as shown below to get the distance
  3. Use the distance and Location.Timestamp as shown below to get the speed

Expected Behavior

Get an actual speed compared to the vehicles speedometer that matches

Actual Behavior

Calculated speed is between 2 and 10 MPH higher than vehicle speed. This is double checked against a GPS speed app found on the app store that matches the vehicle's speedometer.

Basic Information

  • Version with issue: 1.6.1

  • Last known good version?:

  • IDE: VSMac 2019

  • Platform Target Frameworks:

    • iOS: 14.6
  • Affected Devices:
    iPhone XSMax, iPhone 8

                  while (CurrentState == States.Adjusting)
                  {
                      try
                      {
                          var request = new GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(10));
                          var location = await Geolocation.GetLocationAsync(request);
                          if (location != null)
                          {
                              GPSAccuracy = location.Accuracy.Value;
                              if (location.Speed != null)
                              {
                                  GPSSpeed = location.Speed.Value;
                              }
                              else
                              {
                                  if (_gpsCalculator == null)
                                      _gpsCalculator = new GPSCalculator();
    
                                  double distance = 0;
                                  double time = 0;
                                  GPSSpeed = _gpsCalculator.Speed(location, out distance, out time);
                                  if (distance > 0 && time > 0)
                                  {
                                      GPSDistance = distance;
                                      GPSTime = time;
                                  }
                              }
                          }
                          await Task.Delay(100);
                      }
                      catch (FeatureNotSupportedException fnsEx)
                      {
                          StatusMessage = fnsEx.Message;
                          await MainPageViewModel.Instance.MessageBoxAsync("Error", "GPS Location is not available on your phone.", "", "OK");
                          CurrentState = States.None;
                      }
                      catch (FeatureNotEnabledException fneEx)
                      {
                          StatusMessage = fneEx.Message;
                          await MainPageViewModel.Instance.MessageBoxAsync("Error", "GPS Location is not enabled on your phone.", "", "OK");
                          CurrentState = States.None;
                      }
                      catch (PermissionException pEx)
                      {
                          StatusMessage = pEx.Message;
                          await MainPageViewModel.Instance.MessageBoxAsync("Error", "GPS Location permission is required.", "", "OK");
                          CurrentState = States.None;
                      }
                      catch (Exception ex)
                      {
                          StatusMessage = ex.Message;
                          await MainPageViewModel.Instance.MessageBoxAsync("Error", "GPS Location error encountered.", "", "OK");
                          CurrentState = States.None;
                      }
                  }
    

Here is my GPSCalculator class:

using System;
using System.Collections.Generic;
using System.Linq;
using Flashsynq.ViewModels;
using Xamarin.Essentials;

namespace Flashsynq.Models
{
    public class GPSCalculator
    {
        private Location _previousLatLong;
        private double _previousSpeed;
        private List<double> _speedList;
        public double Speed(Location newLatLong, out double distance, out double time)
        {
            distance = time = 0;

            if (_previousLatLong == null)
            {
                _previousLatLong = new Location(newLatLong);
                return 0;
            }

            time = (newLatLong.Timestamp - _previousLatLong.Timestamp).TotalHours;

            // because of the way GPS jitter occurs 2 reading can't possibly be exactly the same
            // so throw it out
            // also throw it out if the time is 0 or the accuracy is > 10 meters.
            if ((newLatLong.Latitude == _previousLatLong.Latitude && newLatLong.Longitude == _previousLatLong.Longitude) || time == 0 || newLatLong.Accuracy.Value > 10)
            {
                //MainPageViewModel.Instance.StatusMessage = $"Same position, 0 time or bad accuracy detected: Time: {time} Accuracy: {newLatLong.Accuracy.Value}";
                return _previousSpeed;
            }

            distance = _previousLatLong.CalculateDistance(newLatLong, DistanceUnits.Miles);

            _previousLatLong = new Location(newLatLong);

            var speed = Math.Round((distance / time), 0);

            if (_speedList == null)
                _speedList = new List<double>();

            if (_speedList.Count > 0)
            {
                _speedList.Add(speed);
                if (_speedList.Count > 10)
                    _speedList.RemoveAt(0);

                _previousSpeed = _speedList.Average();
            }
            else
                _speedList.Add(speed);

            MainPageViewModel.Instance.StatusMessage = $",{distance},{time},{speed},{_previousSpeed},{newLatLong.Latitude},{newLatLong.Longitude}";

            return _previousSpeed;
        }
    }
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant