1

我面临着在 C 中实时计算回旋曲线值的问题。

首先,我尝试使用 Matlab 编码器为菲涅耳公式的 quadgk 积分器获取自动生成的 C 代码。这在我的测试场景中基本上很有效。唯一的问题是它运行得非常慢(在 Matlab 以及自动生成的代码中)。

另一种选择是对通过直线连接样本点的单位回旋曲线的数据表进行插值(线性插值)。在我发现曲率只有很小的变化(沿着回旋曲线的微小步骤)后,我放弃了,结果显然会退化为线条。多么惊喜……

我知道可以使用不同的公式绘制圆,但在实际场景中经常会遇到曲率的低变化,并且航向 0° 和 360° 之间的 30k 个采样点无法为我的问题提供足够的角分辨率。

然后我在 R = inf 点附近尝试了泰勒近似,希望在我想要的任何地方都有明显的曲率。我很快意识到我不能使用超过 4 个项(15 的幂),否则多项式会很快变得不稳定(可能是由于双精度 fp 计算中的数值不准确)。因此,很明显,对于大的 t 值,精度会迅速下降。通过“大 t 值”,我指的是回旋曲线上的每个点,它们代表一条相对于零曲率点超过 90° 的曲线。

例如,当评估一条从 R=150m 到 R=125m 并进行 90° 转弯的道路时,我就在有效近似区域之外。相反,我在 204.5° - 294.5° 的范围内,而我的泰勒极限在单位回旋曲线的 90° 左右。

我现在有点随机尝试了。我的意思是我可以试着花时间在一个关于该主题的几十篇论文上。或者我可以尝试改进或结合上述一些方法。也许Matlab中甚至存在与Coder兼容且速度足够快的集成功能。

这个问题是如此根本,我觉得我不应该有那么大的麻烦来解决它。有什么建议吗?

4

2 回答 2

1

关于泰勒级数中的 4 个术语 - 你应该可以使用更多。2pi 的总 theta 肯定是可行的,双打。

您可能根据完整公式单独计算每个术语,计算完整的阶乘和功率值。这就是精度损失极快的原因。

相反,逐步计算术语,从前一个计算下一个。找到系列中下一项与前一项之的公式,并使用它。

为了提高精度,不要按theta距离计算,s(以免失去缩放精度)。

你的例子是一个非常平坦的回旋曲线。如果我没记错的话,它会从(25/22) pi =~ 204.545°to (36/22) pi =~ 294.545° (为什么不在你的问题中包含这些细节?)。不过应该没问题。甚至2 pi = 360°,整个圆圈(以及两倍)应该没有问题。

given: r = 150 -> 125,  90 degrees turn :

  r s = A^2 = 150 s = 125 (s+x)  

  =>  1+(x/s) = 150/125 = 1 + 25/125       x/s = 1/5  

  theta = s^2/2A^2 = s^2 / (300 s) = s / 300  ;   = (pi/2) * (25/11)  = 204.545°
  theta2 = (s+x)^2/(300 s) = (6/5)^2 s / 300  ;   = (pi/2) * (36/11)  = 294.545°
  theta2 - theta = ( 36/25 - 1 ) s / 300 == pi/2

  =>  s = 300 * (pi/2) * (25/11) = 1070.99749554    x = s/5 = 214.1994991

      A^2 = 150 s = 150 * 300 * (pi/2) * (25/11) 

      a = sqrt (2 A^2) = 300 sqrt ( (pi/2) * (25/11) ) = 566.83264608

参考点位于 r = Infinity,其中 theta = 0。

我们有x = a INT[u=0..(s/a)] cos(u^2) d(u)wherea = sqrt(2 r s)theta = (s/a)^2. 写出 的泰勒级数cos,并将其逐项积分,以得到x作为距离函数 的泰勒近似值s,沿曲线,从 0 点开始。就这样。

接下来你必须决定用什么密度来计算你沿着回旋曲线的点。您可以从弦上方的所需公差值中找到它,最小半径为 125。因此,这些点将通过在连续点之间绘制的线段定义曲线的近似值。

于 2015-04-15T14:32:42.857 回答
0

我现在正在同一领域做我的论文。

我的方法如下。

  1. 在回旋曲线上的每个点,计算以下(航向变化/沿回旋曲线行进的距离),通过这个公式,您可以通过这个简单的方程计算每个点的曲率。

  2. 您将绘制每个曲率值,您的 x 轴将是沿回旋曲线的距离,y 轴将是曲率。通过绘制此图并应用非常简单的线性回归算法(以您选择的语言搜索 Peuker 算法实现)

  3. 您可以轻松识别值为 0 的曲线部分(直线没有曲率)、线性增加或减少(欧拉螺旋 CCW/CW)或恒定值!= 0(弧上所有点的曲率恒定) .

我希望这会对你有所帮助。

你可以在 github 上找到我的代码。我为此类问题实现了一些算法,例如 Peuker 算法。

于 2018-06-23T00:04:38.103 回答