This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
mochapine64backup/MoCha/Assets/Pedometer/Plugins/Managed/Platforms/PedometerGPS.cs

103 lines
3.8 KiB
C#
Raw Normal View History

2018-04-10 12:44:50 -05:00
/*
* Pedometer
* Copyright (c) 2017 Yusuf Olokoba
*/
namespace PedometerU.Platforms {
using UnityEngine;
using System;
using System.Collections;
using Utilities;
public sealed class PedometerGPS : IPedometer {
#region --Properties--
public event StepCallback OnStep;
public bool IsSupported {get {return true;}}
public bool Running {get; private set;}
private const double
LocationTimeout = 20f,
EarthRadius = 6378.137d, // Meters
DegreesToRadians = Math.PI / 180d,
StepsToMeters = 0.715f;
#endregion
#region --Client API--
public IPedometer Initialize () {
// Check that the user has granted permissions
if (!Input.location.isEnabledByUser) Debug.LogError("Pedometer Error: GPS backend requires GPS permissions");
// Initialize location services
else PedometerHelper.Instance.Dispatch(Update());
// Log
Debug.Log("Pedometer: Initialized GPS backend");
return this;
}
public void Release () {
// Stop running
Running = false;
// Log
Debug.Log("Pedometer: Released GPS backend");
}
#endregion
#region --Operations--
private IEnumerator Update () {
// Start location service
Input.location.Start(0.5f, 3f);
// Wait until service initializes
var time = Time.realtimeSinceStartup;
yield return new WaitWhile(() => Input.location.status == LocationServiceStatus.Initializing && Time.realtimeSinceStartup - time < LocationTimeout);
// Check that service initialized
if (Input.location.status != LocationServiceStatus.Running) {
Debug.LogError("Pedometer Error: Failed to initialize location service with status: "+Input.location.status);
yield break;
}
// Get current location
var lastData = Input.location.lastData;
var distance = 0.0d;
Running = true;
// Update location
while (Running) {
// State checking
if (Input.location.status != LocationServiceStatus.Running) yield break;
// Check that the data was updated
if (Math.Abs(Input.location.lastData.timestamp - lastData.timestamp) < 1e-10) goto end;
// Accumulate haversine distance
var currentData = Input.location.lastData;
distance += Distance(lastData.latitude, lastData.longitude, currentData.latitude, currentData.longitude);
// Invoke event
if (OnStep != null) OnStep((int)(distance / StepsToMeters), distance);
// Update data
lastData = currentData;
// Next frame
end: yield return null;
}
// Stop location service
Input.location.Stop();
}
/// <summary>
/// Calculate the haversine distance between two latitude-longitude pairs
/// Implemented from: https://stackoverflow.com/questions/365826/calculate-distance-between-2-gps-coordinates
/// </summary>
private static double Distance (double lat1, double lon1, double lat2, double lon2) {
double
dlat = (lat2 - lat1) * DegreesToRadians,
dlong = (lon2 - lon1) * DegreesToRadians,
a = Math.Pow(Math.Sin(dlat / 2.0), 2) +
Math.Cos(lat1 * DegreesToRadians) *
Math.Cos(lat2 * DegreesToRadians) *
Math.Pow(Math.Sin(dlong / 2.0), 2),
c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a)),
distance = EarthRadius * c;
return distance;
}
#endregion
}
}