Unity3D - 使用GPS数据获得平稳的速度和加速度

时间:2016-04-25 07:06:17

标签: android unity3d gps location distance

我正在使用Unity3D,我使用最后位置的纬度和经度创建了简单的距离,速度和加速度计算器。我正在计算每次GPS更新中的最后距离,速度和加速度(大约每秒一次)。但有时(2-3秒间隔)纬度和经度值变化很快(晴朗天气,没有障碍物)。这就是速度和加速度值获得不真实结果的原因。例如,在稳定的40 km / h速度下,速度值变为60 km / h并在2-3秒内恢复到40 km / h。我在这里问我怎样才能避免这种不准确和快速的GPS数据变化?

我正在使用Nexus 5设备

有我的代码:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class Manager : MonoBehaviour
{
public Text longitude, latitude, lonAText, latAText, lonBText, latBText;
public Text result, overallResult, speedText, lastTimeText, timerText, accelerationText, speed0Text;

float lonA, lonB, latA, latB, overallDistance, lastDistance, timer, lastTime, speed, speed0, acceleration;
bool firstTime, allowTimer;

public AudioSource audio;

void Awake()
{
    overallDistance = 0;
    lastDistance = 0;
    timer = 0;
    lastTime = 0;
    speed = 0;
    speed0 = 0;

    firstTime = true;
    allowTimer = true;
}

IEnumerator Start()
{
    // First, check if user has location service enabled
    if (!Input.location.isEnabledByUser)
        yield break;

    // Start service before querying location
    Input.location.Start(1, 1);

    // Wait until service initializes
    int maxWait = 20;
    while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
    {
        yield return new WaitForSeconds(1);
        maxWait--;
    }

    // Service didn't initialize in 20 seconds
    if (maxWait < 1)
    {
        print("Timed out");
        yield break;
    }

    // Connection has failed
    if (Input.location.status == LocationServiceStatus.Failed)
    {
        print("Unable to determine device location");
        yield break;
    }
    else
    {
        // Access granted and location value could be retrieved
        print("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);

        longitude.text = Input.location.lastData.longitude.ToString();
        latitude.text = Input.location.lastData.latitude.ToString();

        lonA = Input.location.lastData.longitude;
        latA = Input.location.lastData.latitude;
    }

    // Stop service if there is no need to query location updates continuously
    //Input.location.Stop();
}

void Update()
{
    longitude.text = Input.location.lastData.longitude.ToString();
    latitude.text = Input.location.lastData.latitude.ToString();

    timer += Time.deltaTime;
    timerText.text = timer.ToString();


    if (lonA != Input.location.lastData.longitude || latA != Input.location.lastData.latitude)
    {
        audio.Play();

        CalculateDistances(lonA, latA, Input.location.lastData.longitude, Input.location.lastData.latitude);  // last distance and overall distanceS            
        lonA = Input.location.lastData.longitude;
        latA = Input.location.lastData.latitude;

        lastTime = timer;
        lastTimeText.text = lastTime.ToString();
        timer = 0;


        speed0 = speed;
        speed0Text.text = speed0.ToString();

        CalculateSpeed();

        CalculateAcceleration();
    }            
}   

public static float Radians(float x)
{
    return x * Mathf.PI / 180;
}

public void CalculateDistances(float firstLon, float firstLat, float secondLon, float secondLat)
{
    lonAText.text = firstLon.ToString();
    latAText.text = firstLat.ToString();

    lonBText.text = secondLon.ToString();
    latBText.text = secondLat.ToString();

    float dlon = Radians(secondLon - firstLon);
    float dlat = Radians(secondLat - firstLat);

    float distance = Mathf.Pow(Mathf.Sin(dlat / 2), 2) + Mathf.Cos(Radians(firstLat)) * Mathf.Cos(Radians(secondLat)) * Mathf.Pow(Mathf.Sin(dlon / 2), 2);

    float c = 2 * Mathf.Atan2(Mathf.Sqrt(distance), Mathf.Sqrt(1 - distance));

    lastDistance = 6371 * c * 1000; 

    result.text = lastDistance.ToString() + " meters";

    overallDistance += lastDistance;  // bu 1 anliq 6.000.000-dan boyuk qiymet ala biler

    StartCoroutine(Overall());
}

IEnumerator Overall()
{
    if (firstTime)
    {
        firstTime = false;

        yield return new WaitForSeconds(2);

        if (overallDistance > 6000000)
        {
            overallDistance = 0;
            lastDistance = 0;
        }
    }

    overallDistance += lastDistance;
    overallResult.text = overallDistance.ToString() + " meters";
}

void CalculateSpeed()
{
    speed = lastDistance / lastTime * 3.6f;

    speedText.text = speed.ToString();
}

void CalculateAcceleration()
{
    acceleration = (speed - speed0) / lastTime;
    accelerationText.text = acceleration.ToString();
}
}

感谢您的帮助和提示 PS。如果我犯了任何语法和逻辑错误,请编辑我的问题。

0 个答案:

没有答案