计算没有 getSpeed() 方法的导航应用程序的速度 [英] Calculating Speed for a navigation app without getSpeed() method

查看:21
本文介绍了计算没有 getSpeed() 方法的导航应用程序的速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款应用,它更像是您朋友之间的时移赛车.

I am developing an app which is more of a time-shift racing between your friends.

我需要计算移动车辆的速度,我不想使用 Location.getSpeed() 方法.(在底部详细说明为什么我不想使用它)

I need to calculate speed of a moving vehicle, and I don't want to use Location.getSpeed() method. (Explained in detail in the bottom why I don't want to use it)

我正在尝试借助可用的纬度和经度来计算速度,而这正是我需要帮助的地方.

I am trying to calculate speed with the help of Latitude and Longitude available to me, and this is where I need help.

需要的帮助:我想知道的是:

  • 如果算法正确
  • 我应该用厘米而不是米来计算
  • 如果有任何可用的代码/库可以做到这一点.

我正在使用以下代码:

这给了我两个 LatLng 点之间的距离:

long getDistanceBetweenPoints(double lat1, double lng1, double lat2, double lng2 ){
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lng2 - lng1);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1))
                * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
                * Math.sin(dLon / 2);
        double c = 2 * Math.asin(Math.sqrt(a));
        long distanceInMeters = Math.round(6371000 * c);
        return distanceInMeters;
    }

以下代码是它的使用方式:

if(lastLat == -1 && lastLng == -1){
    lastLat = location.getLatitude();
    lastLng = location.getLongitude();
    lastTimeStamp = location.getTime();
    return;
}
long distanceInMeters = getDistanceBetweenPointsAndSetTotal(lastLat, lastLng, location.getLatitude(), location.getLongitude());
long timeDelta = (location.getTime() - lastTimeStamp)/1000;
long speed = 0;
if(timeDelta > 0){
speed = (distanceInMeters/timeDelta);
}
Log.d("Calculations","Distance: "+distanceInMeters+", TimeDelta: "+timeDelta+" seconds"+",speed: "+speed+" Accuracy: "+location.getAccuracy());

lastLat = location.getLatitude();
lastLng = location.getLongitude();
lastTimeStamp = location.getTime();

当我运行它时,我从那个 LogCat 得到以下输出:

When I run it, I get following output from that LogCat:

Distance: 0, TimeDelta: 0 seconds,speed: 0 Accuracy: 5.0

详细原因
目标消费者不应该拥有带有高质量 GPS 芯片的高质量设备,因此在设备移动时始终获得非常准确的定位是不可能的.

Detailed Reasons
The target consumers are not supposed to have high quality devices with high-quality GPS chips, thus always getting a very accurate fix when the device is on the move is not possible.

因此我不想依赖 Location.getSpeed() 方法,因为我观察到它仅在精度在 5~8 米范围内时才给出速度值.

I thus don't want to depend on the Location.getSpeed() method, since I have observed it gives out speed values only when the accuracy is in the range of 5~8 metres.

我在一般情况下获得的正常精度范围是 10-15 米,而 getSpeed() 不提供任何速度.甚至 hasSpeed() 也开始返回 false.

The normal accuracy ranges I am getting in general circumstances is 10-15 metres, and getSpeed() doesn't give any speed. Even hasSpeed() starts returning false.

我已经在这件事上摸索了超过 3 天,对此的任何帮助将不胜感激.

I have been tinkering my head around this thing for more than 3 days, any help in this would be deeply appreciated.

非常感谢!

推荐答案

我开发了 MyTrails,一个 Android 映射和跟踪应用程序,和您一样,我一开始也遇到了 Google 认为适合包含在 Android 中的非常粗糙的位置 API.

I develop MyTrails, an Android mapping and tracking app, and like you I struggled at first with the very crude location APIs Google has seen fit to include in Android.

hasSpeed() 当 GPS 芯片没有足够好的修复来根据多普勒效应计算速度时为假.即使是这样,如果速度低于 5 公里/小时或左右,我通常也不相信速度.

hasSpeed() is false when the GPS chip doesn't have a good enough fix to compute speed based on dopler effect. Even when it does, I usually don't trust the speed if it's less than 5km/h or thereabouts.

我处理速度计算的方式是使用粗略的低通滤波器:我每秒记录一个轨迹点(基于 LocationManager.requestLocationUpdates(),并且至少间隔 5m,然后计算最近的速度,我返回几个样本以获得相距足够远的样本(但不超过 30 秒),然后执行您正在做的平均.

The way I handle speed calculations is by using a crude low-pass filter: I record a trackpoint every second (and a minimum of 5m apart, based on LocationManager.requestLocationUpdates(), and to calculate the recent speed, I go back a few samples to get one that is a sufficient distance apart (but no more than 30s prior), and perform the averaging you're doing.

我使用 Location.distanceBetween() 进行实际距离计算.请注意,它会在非常少(但不幸)数量的设备上失败,因此您拥有的半正弦方法可能是更好的选择.你可能想检查一下,我有的是

I'm using Location.distanceBetween() for the actual distance calculation. Beware that it fails on a very small (but unfortunate) number of devices, so the haversine method you have may be a better bet. You may want to check it though, what I have is

/**
 * Gets distance in meters, coordinates in RADIAN
 */
private static double getDistance(double lat1, double lon1, double lat2, double lon2) {
    double R = 6371000; // for haversine use R = 6372.8 km instead of 6371 km
    double dLat = lat2 - lat1;
    double dLon = lon2 - lon1;
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1) * Math.cos(lat2) *
                    Math.sin(dLon / 2) * Math.sin(dLon / 2);
    //double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return 2 * R * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    // simplify haversine:
    //return 2 * R * 1000 * Math.asin(Math.sqrt(a));
}

(注意 1000 因子)

(note the 1000 factor)

这篇关于计算没有 getSpeed() 方法的导航应用程序的速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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