使用缓冲区和溢出缓冲区将 IMU 数据写入 csv 文件?

Posted

技术标签:

【中文标题】使用缓冲区和溢出缓冲区将 IMU 数据写入 csv 文件?【英文标题】:Write IMU data to csv file using buffer and overflow buffer? 【发布时间】:2019-08-13 20:31:32 【问题描述】:

我一直在尝试为通过 I2C 连接到 mbed 板的 LSM9DS1 IMU 实现 C++ 互补滤波器,但时序问题使我无法正确地获得角速率集成。这是因为在我的代码中,我假设我的采样率为 100Hz,而由于我用于实时显示值的 printf() 语句,这并不完全是采样数据的速率。这导致当 IM​​U 放回其原始位置时,我的过滤器输出的角度漂移/不回到原始值。

建议我按照以下步骤操作,以避免我的代码延迟可能会中断我对时间敏感的应用程序:

在程序的每次迭代中,将原始 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(); 
    
 

【问题讨论】:

您使用的是 Mbed OS2 还是 OS5? 这是 Mbed OS5... 有什么建议吗? 您可以在没有 printf() 的情况下以 100Hz 采样,对吗?如何确保 100Hz 采样率? (定时器中断?)是过滤计算还是 printf() 导致延迟?你的代码会很有帮助。 @KentaroOkuda 由于 LSM9DS1 库中的设置,确保了 100Hz 的采样率。我认为 printf() 语句和计算都导致了延迟,所以我想按照我上面提到的步骤来看看是否通过避免它们,数据是否按预期输出。我会用我的代码的相关部分更新帖子,谢谢! 您是否在等待 readValues() 中的数据就绪信号?如果没有,您将尝试尽可能快地进行采样。 【参考方案1】:

正如 Kentaro 在 cmets 中也提到的,为 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);

但是,您可能仍会遇到速度问题。一些一般提示:

    使用您的开发板可以处理的最高波特率。 在printf(使用Serial)之上使用RawSerial 对象以避免声明互斥体。 不要写入 UART,而是写入文件(例如,将 FATFileSystem 挂载到 SD 卡上)。这会更快。

【讨论】:

再次您好,感谢您的详细回答!你知道在 LPC1768 板上是否可以使用 EventQueue 和 Thread 吗?我在尝试时遇到错误 您确定您使用的是 Mbed OS 5 吗?见os.mbed.com/docs/mbed-os/v5.11/tutorials/…

以上是关于使用缓冲区和溢出缓冲区将 IMU 数据写入 csv 文件?的主要内容,如果未能解决你的问题,请参考以下文章

在 pandas 中读取 csv 文件时出错 [CParserError: 标记数据时出错。 C 错误:捕获缓冲区溢出 - 可能是格式错误的输入文件。]

使用 Visual C++ 的地址清理程序:忽略读取缓冲区溢出,同时仍捕获写入缓冲区溢出

缓冲区溢出及堆栈/堆操纵

单片机环形对接溢出如何处理

Netty源码之写入数据

20165315 缓冲区溢出漏洞实验