Unity3d - 使用GPS数据获得平稳的速度和加速度 [英] Unity3d - get smooth speed and acceleration with GPS data

查看:569
本文介绍了Unity3d - 使用GPS数据获得平稳的速度和加速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我正在使用Nexus 5设备



感谢您的帮助和提示

PS。如果我犯了任何语法和逻辑错误,请编辑我的问题。



我尝试过:



有我的代码:



I'm using Unity3D and I created simple distance, speed and acceleration calculator using latitude and longitude of last position. I'm calculating last distance, speed and acceleration in each GPS update (approximately once per second). But sometimes (2-3 second interval) latitude and longitude values changes rapidly (in clear weather and no obstacles). That's why speed and acceleration values gets unreal results. For example, at stable 40 km/h speed, speed value becomes 60 km/h and returns to 40 km/h within 2-3 second. I'm here to ask how can I avoid this inaccurate and rapid GPS data changes?

I'm using Nexus 5 device

Thanks for any help and tip
PS. Please edit my question if I made any grammar and logical mistake.

What I have tried:

There is my code:

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();
}
}

推荐答案

Google用于GPS位置平滑。您将获得一个不太准确的位置和对速度变化的响应速度较慢,但​​您不会几乎同样跳跃。



消费者GPS不是由于军方拥有系统,准确开始死亡,准确性有限制。我认为它目前接收器限制在4米水平精度,而垂直更差。许多因素会影响卫星信号的准确性,包括手机可以看到的卫星数量,信号需要通过多少气氛,卫星距离多远......等等。所有这些都会影响准确性。



您的位置将实时从一帧跳到另一帧。没有什么办法可以让你在准确的位置上获得可靠的实时信息。您必须对该位置进行过滤才能获得更稳定的平均位置。这样做的缺点是对位置的实际变化反应较慢。
Google for "GPS location smoothing". You're going to get a less accurate location and slower response to your speed changes but you wont' get the jumping around nearly as much.

Consumer GPS isn't dead on accurate to begin with because the military owns the system, there are restrictions on the accuracy. I think it's currently receiver-limited to 4 meter horizontal accuracy and worse for vertical. A number of factors affect the accuracy of the signal from the satellites, including the number of satellites the phone can "see", how much atmosphere the signal has to go through, how far away the satellite is, ... and more. All of this affects the accuracy.

Your location will jump around from one frame to another in real time. There's nothing you can do to get a solid real-time dead on accurate location. You have to do filtering on the location to get an "average" location that's more stable. The downside to this is slower response to actual changes in location.


你需要考虑GPS喜欢的问题。



首先是准确性还是缺乏。实际位置和GPS位置之间的任何差异都会影响表观速度。



理想情况下,您必须从GPS读取计算的位置和时间才能获得最佳数据。

否则,你累积不准确。

第二好的是当新的位置可用时有GPS触发事件。通过这种方式,您可以保持新位置和时间之间的链接。



然后最糟糕的情况是,您在常规时间读取GPS,而不是测量时间。阅读速度太快,你不止一次得到相同的测量值(这可能意味着你不会移动。读得有点太慢了,速度变化取决于测量的年龄。读取真正的慢将减少移位问题,但你的应用程序反应较慢。
You need to take into account the problems liked with GPS.

First is accuracy or lack of. Any difference between real location and GPS location have impact on apparent speed.

Ideally, you must read position and time of calculation from GPS in order to get best data.
Otherwise, you are cumulating inaccuracies.
second best is to have the GPS triggering events when new location is available. This way you maintain a link between new location and and time.

Then worst case, you read the GPS at regular timing which don't march the timing of measure. Read a little too fast and you get the same measure more than once (which can mean you don't move. Read a little too slow a,d the speed shift depending of how old is the measure. reading real slow will reduce shifting problem, but your app will be less responsive.


这篇关于Unity3d - 使用GPS数据获得平稳的速度和加速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆