我有一个有趣的(对我来说)问题。我正在使用OpenServo.org for V4,我正在尝试确定行程弧的长度及其方向。
我有一个磁力编码器,可以将轴的位置从0恢复到4095.
伺服有两个逻辑端点,称为MAX和MIN,它们在软件中设置并且可以随时更改,并且轴必须在MAX和MIN位置之间的一个弧上旋转(即行进)。例如,在图片中,蓝色弧有效,但红色不适用于MIN和MAX之间的所有行程。
我正在尝试使用整数数学计算出一个简单的算法,可以告诉我任意两个点A和B之间的距离,它们可以是圆周上的任何位置,以MIN和MAX为界,并且A作为当前位置B是目标位置,或B是当前位置,A是目标(由B到A的负距离表示)。请注意,我允许旅行的一侧是已知的,它可以是“红色”或“蓝色”。
问题是当ARC中存在4095/0时,计算会有点兴趣。
答案 0 :(得分: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。
答案 1 :(得分: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是某种已知单位,那么只需跳过上述算法中的转换为度数,并相应地更改变量名称。
答案 2 :(得分: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
(如果您不需要方向,请获取距离的绝对值)