получение правильных значений IMU

#python #imu

#python #imu

Вопрос:

Я считываю данные с датчика AHRS / IMU через USB с помощью Python 2.7. Для получения ускорения, указанного производителем, в соответствии с изображением ниже:

описание IMU от поставщика

Мой код на python выглядит следующим образом, но когда ускорение отрицательное, значения неверны. Я считаю, что мне нужно проверить первый бит MSB (в данном случае поле AxH), если 1 отрицательное, если 0 положительное.

     #....
    #data = serial.read(size=11)
    #....
    #

    #Acceleration
    elif data[1] == b'x51':
        AxL=int(data[2:3].encode('hex'), 16)
        AxH=int(data[3:4].encode('hex'), 16)
        AyL=int(data[4:5].encode('hex'), 16)
        AyH=int(data[5:6].encode('hex'), 16)
        AzL=int(data[6:7].encode('hex'), 16)
        AzH=int(data[7:8].encode('hex'), 16)

        x = (AxH<<8|AxL)/32768.0*16.0
        y = (AyH<<8|AyL)/32768.0*16.0
        z = (AzH<<8|AzL)/32768.0*16.0
  

У кого-нибудь есть какие-либо предложения?

Полное руководство по датчику IMU таково: http://wiki.wit-motion.com/english/lib/exe/fetch.php?media=module:wt901:docs:jy901usermanualv4.pdf

Комментарии:

1. Нет необходимости преобразовывать данные в шестнадцатеричную строку, а затем преобразовывать их обратно в int. Если вы индексируете bytes объект в Python3, вы получаете (беззнаковый) байт в виде int напрямую, поэтому вы можете просто использовать AxL = data[2] . В Python2 вам пришлось бы сделать AxL = ord(data[2]) .

2. Смотрите мой ответ, знаковое числовое представление сокращений в данных, вероятно, является дополнением двух , поэтому просто использовать MSB в качестве знакового бита некорректно.

Ответ №1:

Использование struct

Данные axes хранятся в виде коротких целых чисел со знаком младшего порядка со знаком (2 байта) struct , поэтому мы можем использовать их для распаковки данных. struct Модуль позаботится о правильной интерпретации bytes как коротких целых чисел.

 import struct

g = 9.81
conv = 16.0 / 32768.0 * g

# ...

    elif data[1] == b'x51':
        axes = struct.unpack("<hhh", data[2:8])
        x, y, z = [a*conv for a in axes]
  

Преобразование вручную

Если вы хотите выполнить преобразование самостоятельно, я бы предположил, что представление числа со знаком является дополнением двух:

 def twos_complement(x, bytes=2):
    maxnum = 2**(bytes*8) - 1
    msb = 1 << (bytes*8 - 1) 
    return -((x^maxnum)   1) if xamp;msb else x

AxL = data[2]
AxH = data[3]
Ax_unsigned = AxH << 8 | AxL
Ax = twos_complement(Ax_unsigned, 2)
  

Ответ №2:

Немного поздно, но все еще может кому-то помочь.

Мы также должны проверить длину полученных данных и правильность суммы. Рекомендуется убедиться, что сигнал получен полностью.

Как указано в документации, Checksum: Sum=0x55 0x51 AxH AxL AyH AyL AzH AzL TH TL . Оно должно быть равно последнему значению в данных. Итак, не забудьте проверить это: (sum(data) - data[10]) amp; 0xFF) .