在圆上找到任意弧长的长度

3

我有一个(对我来说)有趣的问题。我正在为V4的OpenServo.org工作,试图确定旅行弧长度及其方向。

我有一个磁编码器,返回轴的位置从0到4095。

伺服机有两个逻辑端点,称之为MAX和MIN,其在软件中设置并可随时更改,并且轴必须在MAX和MIN位置之间的一个弧线上旋转(即运动)。例如,在图片中,蓝色弧是有效的,但红色弧对于包括MIN和MAX之间的所有旅行都无效。

我正在尝试使用仅整数运算的简单算法,它可以告诉我在MIN和MAX限制下,任何两个点A和B之间的距离,其中A可以是当前位置,而B是目标位置,或者B是当前位置,而A是目标位置(这由从B到A的负距离表示)。请注意,允许旅行的一侧已知,它可能是“红色”或“蓝色”。

问题是当4095/0存在于ARC中时,计算变得有点有趣。

enter image description here


我们如何知道弧的哪一侧是有效的?即为什么是蓝色而不是红色? - viraptor
它被设置在软件中,以防止轴向不该转动的方向。例如,这可能是肘部关节,蓝色弧线是有效的,但红色弧线机械上不可能(或者红色弧线是允许的,A是3000,B是2500,A和B指示哪个弧线适用于移动)。 - user2836967
更改MIN和MAX时,是否保证A和B不会处于相反的位置? - Mark Ransom
当MIN和MAX被更改时,A和B也会被更改以指示您可以行驶的哪一侧,因此始终保持在MIN和MAX之间的正确弧线上。 - user2836967
感谢回复,其中两个算法可行,第三个我无法使其工作。我真的很喜欢Mark Ransom的非常简单的逻辑,但我也很欣赏Paul Griffith的程序。非常感谢。 - user2836967
我已经提出了一个补充问题,关于如何测试A和B是否在行程弧上=>http://stackoverflow.com/questions/19149498/find-the-length-of-any-arc-on-a-circle-confrim-limits-are-on-the-required-arc - user2836967
3个回答

2

您需要调整所有坐标,使它们都在限制点的同一侧。由于这是一个循环系统,因此可以添加4096而不影响绝对位置。

lowest = min(MIN, MAX);
if (A < lowest)
    A += 4096;
if (B < lowest)
    B += 4096;
distance = B - A;  /* or abs(B - A) */

在您的第一个例子中,A不会被调整,但B将被调整为5156。差异将是正1116。
在您的第二个例子中,当A=3000且B=2500时,它们都高于2000,因此都不需要调整。差异为-500。

非常好的算法,简洁明了! - user2836967

1
这是一个简单的算法:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int rotate_diff(int a, int b, bool * clockwise);

int main(void) {
    int degrees_rotated, a, b;
    bool clockwise;

    a = 4040;
    b = 1060;
    degrees_rotated = rotate_diff(a, b, &clockwise);
    printf("A = %d, B = %d, rotation = %d degrees, direction = %s\n",
            a, b, degrees_rotated,
            (clockwise ? "clockwise" : "counter-clockwise"));

    return EXIT_SUCCESS;
}

int rotate_diff(int a, int b, bool * clockwise) {
    static const int min = 2000;

    if ( a <= min ) {
        a += 4096;
    }
    if ( b <= min ) {
        b += 4096;
    }

    int degrees_rotated = b - a;
    if ( degrees_rotated > 0 ) {
        *clockwise = false;
    } else {
        degrees_rotated = -degrees_rotated;
        *clockwise = true;
    }

    return degrees_rotated * 360 / 4096;
}

请注意,这将给出您旋转的角度,但不会给出您旋转的距离,因为您没有告诉我们轴的尺寸。要获得旋转的距离,显然需要将周长乘以旋转的角度除以360。如果您的0到4095个点是某种已知单位,则只需跳过上述算法中的角度转换,并相应更改变量名称即可。

全面的解决方案 :-) - user2836967

0

除非我漏掉了什么,否则这应该会给你所需的结果:

if MIN < A,B < MAX
    distance = A - B
else
   if A > MAX and B < MIN
       distance = A - (B + 4096)
   else if B > MAX and A < MIN
       distance = (A + 4096) - B
   else
       distance = A - B

(如果您不需要方向,请获取距离的绝对值)


为了处理您的伪代码,如果2000 < 4040且1000 < 4000,则距离=4040-1060,得到2980,而不是55 + 1060 = 1115(我假设“,”是一个OR语句)? - user2836967
啊,应该使用一些正常的语法。我的意思是A和B都在(MIN,MAX)范围内。 - viraptor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接