基础知识回顾,在这篇文章中我提到了可以采用四元数作为EKF的状态量实现扩展Kalman滤波。借此机会动手编写完整的姿态解算,验证上述理论的实际效果
原理
在如何理解Kalman滤波中已经指出过典型的Kalman滤波的过程如下
预测过程
更新过程
基础知识回顾,在这篇文章中我提到了可以采用四元数作为EKF的状态量实现扩展Kalman滤波。借此机会动手编写完整的姿态解算,验证上述理论的实际效果
在如何理解Kalman滤波中已经指出过典型的Kalman滤波的过程如下
预测过程
更新过程
按照现实来看,市场中大部分大功率MOSFET都是N沟道增强型,因此在下文中没有特别指明的情况下都以N沟道增强型为模型讨论。
理想状态下,功率MOSFET的模型是非常简单的。栅极呈高阻态(等同于浮空),当在源极和栅极之间加上大于阈值电压Vgs的电压,MOSFET将完全导通。若该电压小于阈值电压Vgs,那么MOSFET将完全截止。因此这种模型等效于电压控制的开关。
但是实际上现实中MOSFET远比上述模型复杂得多,带寄生参数的MOSFET的电路模型应该是这样的
一个明显不同的地方是在三个输入极间均存在电容,在源漏之间还有一个体二极管。单论静态特性特性而言栅极到其他极间也有漏电电阻,关断后存在极小的漏电流,而导通后也存在较小的源漏导通电阻,这些具体参数可以在数据手册上查到。
人一般都有十个手指因而产生了最熟悉的十进制记数,计算机的结构先天性决定了它只能用二进制的记数。于是在此基础上总有一些运算方式和数字表示与2^n挂上钩,下面将尝试解释其中某些现象背后的机理
不论是串口缓冲区还是网络通信的缓冲区,似乎总是随便设的一个大小总是对2^n情有独钟,究其原因其实还是有的(当然不排除真的是随便给的缓冲区长度)。如256或者1024等长度写成二进制其最高位总是为1,这就可以让擅长二进制位判断的硬件去根据缓冲区元素索引判断是否溢出。
当然最典型的还是利用其特性简化运算。例如在环形缓冲区中通常会有求余的操作,因为这样可以让指针在到达末尾处返回0。不巧的是,在早期的平台中指令集里面是没有求余操作的单个指令(当然现在都有)。即使不考虑性能这种为了求余而多增加一段程序也是不太优雅的,于是有人提出了替代求余的方案:如果我们将缓冲区的长度设定为256,那么索引值对256求余实际上等价于把索引值的第9个二进制位置零,于是我们可以采用一条与指令完成求余。这种巧妙的处理方法被作为一种习惯流传,至今在很多缓冲区的设计中都有出现。
原本C板官方例程里已经带了用SPI读取BMI088的例程项目,但是细看数据手册后发现许多代码其实真的只是勉强能用,不论是速度还是代码风格都让我不太满意,故重新移植BMI088官方给出的驱动库。在折腾了一番之后,只能说BMI088性能上是个好东西,但是开发体验非常不好。
按照项目下的README给出的指引,实际上我们只是需要编写读写SPI的函数与微秒延时函数即可。延时可以直接用Systick当计数器完成,而SPI通信的移植实际上比较复杂
Parameters | Details |
---|---|
intf_ptr_accel | Interface pointer that can hold Accel device address |
intf_ptr_gyro | Interface pointer that can hold Gyro device address |
intf | I2C or SPI |
read | read through I2C/SPI interface |
write | write through I2C/SPI interface |
delay_us | delay in microseconds |
variant | BMI085_VARIANT |
当我们划分滤波器时通常会将其划分为至少两类,一类是经典滤波器,即针对频域滤波的滤波器,而后一类则是现代滤波器,利用信号的统计特性进行滤波,Kalman滤波则是这种滤波中的典型代表。
Kalman滤波的基本思想是构造一个使得信号测量值与预测值误差的方差值最小的滤波器,它同时考虑了信号测量中的高斯噪声,利用给定模型进行预测并修正输出。以单个变量的滤波器为例
通过调节K的大小可以调节输出中本次和上一次值所占的比例,当K的值固定时可等效为一个简单的FIR的滤波器。但Kalman滤波器的做法是,根据前后两个量的方差大小确定其不确定性,据此可以动态调节K的值,即更加相信哪一个变量
最终目的最小化预测与实际之间的方差,在上面这个例子中预测值相当于是上一次的x值
在Kalman滤波器中,根据模型获取信号值的过程称为预测(Predict),更新方差以及a(增益)的过程称为更新(Update)。由于预测模型不符合实际过程而产生的误差噪声被称为过程噪声(Process Noise),由于测量本身产生的噪声被称为测量噪声(Measurement Noise)
所谓滤波是指再输入信号中提取期望有效的信号,消除不期望的出现的信号即噪声。经典的数字滤波器主要利用信号的频域特性处理噪声,即滤除指定频率分量的滤波器。而现代滤波器利用的是信号的统计特性,即根据某个信号出现的概率进行滤波。这里主要讨论如何设计经典滤波器。
经典滤波器按照结构可以分为IIR(无限冲激响应)和FIR(有限冲激响应)两大类,前者存在输出反馈回路,可以用较低的阶数获得较高的选择性,但是相位是非线性的,并且在设计上存在不稳定的可能,而后者则恰好相反,无输出反馈回路,在同样的选择性下FIR滤波器需要较IIR更高阶数,但其相位是严格线性的并且滤波器总是稳定的。例如在对于控制反馈量的滤波,宜采用FIR确保其输入波形不发生失真。
之前在Memfault的博客上发现了一个很有意思的日志库Trice。它专为嵌入式设备设计输出日志体积小型且可以以极高速率输出日志。作者号称在不输出时间戳的情况下可以用四条指令即可完成打日志,原因在于它并不会直接输出某个字符串,而是给每个字符串预先分配一个独一无二的ID(当然这部分在代码生成的时候完成),在打日志时候真正输出的是ID,通过上位机的程序解析输出。同样也具有printf格式化字符串的功能。
作为测试在这里也稍微提一下串口的使用方式。在代码配置中作者给出了阻塞非阻塞输出,前者直接等待输出完成,后者则是将输出内容写在缓冲区内等待空闲时输出,而硬件上目前只有串口和RTT,具体可以在triceConfig.h
中修改TRICE_MODE
完成