使用位置查找运动转角

Posted

技术标签:

【中文标题】使用位置查找运动转角【英文标题】:Find movement turn angle using Location 【发布时间】:2015-06-23 14:40:43 【问题描述】:

我需要找到以度为单位的车辆转弯角度。

位置点更新间隔相等(1 秒)。因此,设备在转弯时会获得 4-5 分。我在图片上示意性地显示了这一点。

是否可以使用Location计算转弯角度?如果可以,如何计算?


我尝试了什么:

    分别从点 3、4 和 1、2 创建两个几何向量,并找出这些向量之间的角度。我计算的向量坐标如Vector1 (lat2 - lat1; lon2 - lon2)。不确定这种方法是否适用于位置坐标。 使用location1.bearingTo(location2)。但这并没有给出预期的结果。似乎它给出了“指南针”的结果。也许我可以以某种方式使用它,但不确定。 还尝试了一些三角公式,例如here 或here 或here。他们没有给出预期的角度。

编辑:解决方案 接受的答案效果很好。但要完成答案,我必须展示angleDifference 的方法。这个对我有用:

public int getAngleDifference(int currentAngle)
    int r = 0;
    angleList.add(currentAngle);
    if (angleList.size() == 4) 
        int d = Math.abs(angleList.get(0) - angleList.get(3)) % 360;
        r = d > 180 ? 360 - d : d;

        angleList.clear();
    
    return r;

我将点添加到列表中,直到其中有 4 个,然后计算第 1 点和第 4 点之间的角度差以获得更好的结果。

希望对某人有所帮助!

【问题讨论】:

【参考方案1】:
vect1 = LatLon2 - LatLon1; // vector subtraction

vect2 = LatLon4 - LatLon3;

根据点积的定义有以下性质:

vect1.vect2 = ||vect1||*||vect2||*Cos(theta)

这里是符号的分解

术语vect1.vect2vect1vect2 的点积。

点积的一般形式可以分解为组件明智的让v1 = <x1,y1>v2=<x2,y2> 对于两个任意向量v1v2 点积将是:

v1.v2 = x1*x2 + y1*y2 

某个任意向量v的大小为:

||v|| = sqrt(v.v); which is a scalar.

上面等价于欧几里得距离公式,分量x和y:

||v|| = sqrt(x^2 + y^2)

获取角度

在给定两个向量vect1vect2 的情况下找到theta 的值:

theta = Math.ArcCos(vect1.vect2/(||vect1||*||vect2||))

【讨论】:

ArcCos 对小角度在数值上是病态的,这将在连续的 gps 修复中发生。(这就是存在半正弦公式的原因,它避免了 arccocos())你有没有为他实现过一个可行的解决方案任务? @AlexWien 小角度掉头?点积给出了他正在寻找的角度,是的,任何坐标几何类都可以让您实现这一点。唯一不会做的就是给出该人正在旅行的方向,无论是向右还是向左。它总是给出两个向量之间的最小角度。 谁在谈论掉头?它只是一个转弯。您的公式结果的范围是多少:[0 - 90) 或 [0 - 180) ?掉头是否返回 179.99?直行不转弯时返回0吗? OP 没有要求这样做。他画了一张图片,表明他正在寻找的角度。请参阅Dot Product... 在几何定义下阅读。我假设坐标可以近似为欧几里得,因为球体比转弯的距离大得多,所以不需要半正弦函数。 对不起,如果我没有提到它,但是是的,我也对 U 形转弯感兴趣。当我直线移动时,角度应该为 0。角度越精确,解决方案就越好。【参考方案2】:

方法 1 不像您描述的那样工作:纬度,经度不是笛卡尔坐标(以米表示的经度度不是纬度度,这仅在赤道有效)。您必须首先转换为(本地)笛卡尔系统。

绘图中有错误:标有“?”的角度放置在错误的一侧。你很可能想要角度:180 - ? 在您的示例中,汽车转弯小于 90°,尽管您的角度显示超过 90°。 为了更好地理解,请绘制另一张图,其中汽车仅左转 10 度。在您的绘图中,这将是 170°,这是错误的。

方法 2) 效果更好,但您需要总结角度差异。 你必须给自己写一个方法

double angleDifference(double angle1, double angle2);

虽然代码只有几行,但看起来比实际简单。 确保您有一些测试用例来测试跨越 360° 限制时的行为。 示例

(从轴承 10 转到轴承 350),应该给出 20 或 -20,这取决于您是否希望该方法给出绝对值或相对角度

【讨论】:

我已经实现了这种方法。即使我不动,角度也每次都会改变。这可能是由位置坐标的分散引起的(其精度为 10 米)。无论如何,我会对此进行测试并让您知道结果。 bearingTo 工作得很好,它指向正确的方向,虽然我真的不明白如何将那些 (-180; 180) 度转换为汽车转弯角度。您能否对angleDifference() 方法提供更多解释或一些示例(更可取)? 您需要在站立时过滤掉这些动作。对于角度差异只需搜索互联网,并编写一些单元测试用例。如果您将角度差相加,您将得到一个转向角度。

以上是关于使用位置查找运动转角的主要内容,如果未能解决你的问题,请参考以下文章

单舵轮(叉车)AGV里程计数据解算

如何用python实现运动目标位置的简单预测

双足机器人简单步态生成

运动及运动封装swiper插件

基于.NET的机械运动模拟应用开发

模拟位置,玩运动世界校园