我一直在尝试为通过I2C连接到mbed板的LSM9DS1 IMU实现C ++互补滤波器,但是时序问题使我无法正确获得角速率集成。这是因为在我的代码中,我假设我的采样率为100Hz,但由于我要实时显示值所使用的printf()语句,这并不是精确的数据采样率。这导致我的滤波器的输出角度在将IMU放回其原始位置时漂移/不回到原始值。
建议我按照以下步骤进行操作,以避免代码中的延迟可能破坏我的时间敏感应用程序:
整个缓冲区/溢出缓冲区的来回交互确实使我感到困惑,有人可以帮助我阐明如何从技术上实现上述步骤吗?预先感谢!
编辑:
#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();
}
}
答案 0 :(得分:1)
正如Kentaro在评论中还提到的那样,请为printf
使用一个单独的线程,并使用Mbed OS EventQueue将printf语句延迟到该线程。
EventQueue queue;
Thread event_thread(osPriorityLow);
int main() {
event_thread.start(callback(&queue, &EventQueue::dispatch_forever));
// after sampling
queue.call(&printf, "%.2f, %.2f, %.2f \n", _xfilt, _yfilt, _zfilt);
但是,您可能仍然会遇到速度问题。一些一般性提示:
RawSerial
(使用printf
)上使用Serial
对象,以避免声明互斥体。FATFileSystem
挂载到SD卡)。这样会更快。