【问题标题】:Please suggest an algorithm to compare Gray code numbers请建议一种算法来比较格雷码数
【发布时间】:2019-02-20 18:19:56
【问题描述】:

我有一个绝对编码器,它以格雷码输出 10 位值(0 到 1023)。我要解决的问题是如何确定编码器是向前还是向后移动。

我认为“最佳”算法如下: 首先,我将格雷码转换为常规二进制(完全归功于:https://www.daniweb.com/programming/software-development/code/216355/gray-code-conversion 中的最后一个答案):

int grayCodeToBinaryConversion(int bits)
{
  bits ^= bits >> 16; // remove if word is 16 bits or less
  bits ^= bits >>  8; // remove if word is 8 bits or less
  bits ^= bits >>  4;
  bits ^= bits >>  2;
  bits ^= bits >>  1;
  return bits;
}

其次,我比较了两个相隔 250 毫秒的采样值。我认为比较两个值会让我知道我是向前还是向后。例如:

if((SampleTwo – SampleOne) > 1)
{
  //forward motion actions
}

if((SampleTwo – SampleOne) < 1)
{
  //reverse motion actions
}

if(SampleTwo == SampleOne)
{
  //no motion action
}

就在我开始觉得自己很聪明的时候,令我失望的是,我意识到这个算法有一个致命的缺陷。当我将二进制值 824 与 1015 进行比较时,此解决方案效果很好。此时我知道编码器的移动方式。然而在某些时候,编码器会从 1023 翻转到 0 并爬升,然后当我去比较 1015 的第一个采样值和 44 的第二个采样值时,即使我在物理上朝同一个方向移动,我写的逻辑没有正确捕捉到这一点。另一个不行的是将格雷码值作为一个 int,并比较两个 int。

如何比较两个相隔 250 毫秒的格雷码值,并在考虑编码器翻转方面的情况下确定旋转方向?如果您愿意提供帮助,能否提供一个简单的代码示例?

【问题讨论】:

  • 您希望编码器在 250 毫秒间隔内移动多少?
  • 不超过 400 个脉冲(球场)。但是当它从 950 变为 250 时,我的算法就不起作用了。
  • 一种方法是计算读数之间的差异,假设您要“向前”然后“向后”。然后,您假设编码器正朝着较小值的方向行进。当然,如果您的编码器要在 250 毫秒内移动超过一半的时间间隔,这将失败;在这种情况下,您将增加采样频率。
  • S2-S1的结果在-1023到+1023的范围内;在该范围内,-1023 ~ -512 和 +1 ~ +511 是向前的,-511 ~ -1 和 512 ~ 1023 是向后的。
  • @m69,没有负数范围。这些值限制在 0 到 1023 之间的范围内。根据值的差异,我试图找出旋转方向。

标签: algorithm gray-code


【解决方案1】:

假设 A 是您的初始读数,B 是 250 毫秒后的读数。
让我们以 A = 950 和 B = 250 为例。

让我们假设编码器正在向前移动(它的值随着时间的推移而增加)。

那么,覆盖的距离是(B - A + 1024) % 1024。我们称之为d_forward

对于这个例子,d_forward(250 - 950 + 1024) % 1024 = 324

向后覆盖的距离 (d_backward) 将是 1024 - d_forward;这是700

d_forwardd_backward 的最小值将给出编码器的行进方向。

如果编码器要在 250 毫秒内移动超过 1023/2 个单位,这将不起作用。在这种情况下,您应该缩短读数的间隔。

【讨论】:

  • 我很惊讶这是正确的答案。我原以为弗兰克格雷先生也会创建一些数学运算符来配合他的系统。我向你致敬,Rishav....谢谢!
【解决方案2】:

Rishav 的答案是正确的,但计算起来更容易。

AB 为相隔 250 毫秒并从格雷码转换为二进制的两个读数。

编码器位置的差异只是 diff = ((1536 + B - A) & 1023) - 512。如果您不想使用按位数学,则 diff = ((1536 + B - A) % 1024) - 512

注意1536是1024+512,答案diff由两个约束决定:

  1. diff = B-A mod 1024
  2. diff[-512, 511] 范围内,这是 10 位有符号数的正常范围。

如果您的编码器被允许/预期在一个方向上比另一个方向更快,那么您可以调整 (2) 中的范围。

要允许 [MIN,MIN+1023] 范围内的答案,请使用 diff = ((1024 - MIN + B - A) % 1024) + MIN

如果 MIN 为正数,请在进行取模运算之前添加足够大的 1024 倍数以确保它为正数,因为大多数语言中的取模运算符在处理负数时表现异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多