首页 > 解决方案 > 请建议一种算法来比较格雷码数

问题描述

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

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

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 的第二个采样值时,即使我在物理上朝同一个方向移动,我写的逻辑没有正确捕捉到这一点。另一个不行是将格雷码值作为一个整数,并比较两个整数。

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

标签: algorithmgray-code

解决方案


假设 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 个单位,这将不起作用。在这种情况下,您应该缩短读数之间的间隔。


推荐阅读