Пожалуйста, предложите алгоритм для сравнения чисел Грея - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть абсолютный датчик, который выводит 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;
}

Второй Iсравнить два значения, которые были выбраны с интервалом в 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, даже если я физически двигаюсь в том же направлении, логика, которую я написал, неправильно фиксирует этоЕще один вариант - взять значение кода Грея как целое и сравнить два целых числа.

HКак я могу сравнить два значения кода Грея, которые были взяты на расстоянии 250 миллисекунд, и определить направление вращения, принимая во внимание аспект переворачивания энкодера?Если вы любезны помочь, не могли бы вы привести простой пример кода?

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Ответ Ришава верен, но его легче вычислить.

Пусть A и B будут двумя показаниями, разнесенными на 250 мсек и преобразованными из серого кода вдвоичное.

Разница в положении датчика составляет всего diff = ((1536 + B - A) & 1023) - 512 .Если вы предпочитаете не использовать побитовую математику, то diff = ((1536 + B - A)% 1024) - 512 .

Обратите внимание, что 1536 равно 1024 + 512, иОтвет diff определяется двумя ограничениями:

  1. diff = BA mod 1024
  2. diff находится вдиапазон [- 512, 511] , который был бы нормальным диапазоном для 10-разрядного числа со знаком.

Если ваш кодер может / должен работать быстрее в одном направлениичем другой, вы можете настроить диапазон в (2).

Чтобы разрешить ответы в диапазоне [MIN, MIN + 1023] , используйте diff = ((1024- MIN + B - A)% 1024) + MIN

Если MIN положительное, добавьте достаточно большое кратное 1024, чтобы убедиться, что оно положительное, прежде чем выполнять модульоперация, так как оператор модуля в большинстве языков ведет себя странно с отрицательными числами.

0 голосов
/ 16 сентября 2018

Предположим, что 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_forward и d_backward будет указывать направление движения энкодера.

Это не будет работать , если кодер будет перемещаться более 1023/2 единиц за 250 мс. В таком случае вам следует уменьшить интервалы между измерениями.

...