#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)
.