Я пытался реализовать дополнительный фильтр C++ для IMU LSM9DS1, подключенного через I2C к плате mbed, но проблемы с синхронизацией не позволяют мне правильно интегрировать угловую скорость. Это связано с тем, что в моем коде я предполагаю, что моя частота дискретизации составляет 100 Гц, хотя это не совсем та частота, с которой отбираются данные из-за операторов printf(), которые я использую для отображения значений в реальном времени. Это приводит к тому, что мой фильтр выдает углы, которые дрейфуют/не возвращаются к исходному значению, когда IMU возвращается в исходное положение.
Мне было рекомендовано выполнить следующие шаги, чтобы избежать задержек в моем коде, которые могут нарушить работу моего чувствительного ко времени приложения:
- На каждой итерации программы добавляйте необработанные данные IMU в буфер.
- Когда буфер почти заполнен, используйте прерывание, чтобы записать все данные из буфера в файл .csv.
- Когда/если буфер переполняется, добавьте оставшиеся данные в новый «буфер переполнения».
- Очистите первый буфер и заполните его данными, хранящимися в буфере переполнения, и т. д.
- Выполняйте расчеты фильтрации отдельно, вручную обрабатывая данные из CSV-файла после того, как все они будут собраны, чтобы избежать проблем со временем и посмотреть, соответствует ли результат ожидаемому.
Весь этот буфер/буфер переполнения взад и вперед меня действительно смущает, может кто-нибудь, пожалуйста, помогите мне прояснить, как технически выполнить вышеуказанные шаги? Заранее спасибо!
Редактировать:
#include "LSM9DS1.h"
#define DT 1/100
void runFilter()
{
// calculate Euler angles from accelerometer and magnetometer (_roll,
// _pitch,_yaw)
calcAttitude(imu.ax, imu.ay, imu.az, -imu.my, -imu.mx, imu.mz);
_gyroAngleX += (_rateX*DT);
_gyroAngleY += (_rateY*DT);
_gyroAngleZ += (_rateZ*DT);
_xfilt = 0.98f*(_gyroAngleX) + 0.02f*_roll;
_yfilt = 0.98f*(_gyroAngleY) + 0.02f*_pitch;
_zfilt = 0.98f*(_gyroAngleZ) + 0.02f*_yaw;
printf("%.2f, %.2f, %.2f \n", _xfilt, _yfilt, _zfilt);
}
в main.cpp:
int main()
{
init(); // Initialise IMU
while(1) {
readValues(); // Read data from the IMUs
runFilter();
}
}