非完整性约束NHC

原理:

非完整性约束NHC是指在车辆行驶过程中假定车辆不出现侧滑、漂移、弹跳等,车辆的侧向和垂向速度为0,构造虚拟观测量,进行运动约束的过程。其效果与虚拟观测量方差的设置息息相关。

我们假定车辆(载体)坐标系和IMU坐标系重合,载体的前向、侧向、垂向速度可表示为:

                                                          

 

​​​​​​对上式进行全微分,可得:

但是另外一些论文中,观测矩阵不同,如下

                                             

这一块我就没看懂了。

研究内容:

现有的研究主要是在方差域调整NHC观测噪声改变其约束的松紧程度,其本质是通过方差膨胀使得以零为中心的协方差椭球能够包住真实的侧向/垂向速度,但在一定程度上损失了约束信息。在实际车辆导航中,车辆运动状态(直行或转弯)、车身振动、惯导安装位置以及安置角度等影响因素,使得车辆侧向和垂向速度为零的这一假设条件无法满足,导致 NHC 虚拟观测值存在误差,从而影响惯性误差推算的抑制效果。

非完整约束的 OD/SINS自适应组合导航方法》中针对这一问题构建了一种基于车辆运动状态的NHC噪声自适应方法。文中发现NHC横向速度噪声 受车辆前向速度和车辆转弯的共同影响,其中车辆前向速度 可由车辆CAN总线获取(里程计),车辆转弯可参考文献《利用 MEMS-IMU 检测车辆运动状态的 自适应方法》,文中车辆转弯的判定条件为:

 

;文中,也针对车辆变道和小角度弧段等,针对不同车速设置不同阈值,详细可看论文。

《非完整约束的 OD/SINS自适应组合导航方法》中提出当车辆存在转弯运动时,根据车辆行驶速度和转弯角度的大小,动态调整NHC噪声项 :

                                                

  为设定的自适应比例因子。为减少过松或过紧的噪声约束导致滤波结果异常,在进行滤波更新时,首先根据上式计算噪声项 ,再进行自适应调整

参数自主学习的车辆运动约束新模型及其惯性推算误差抑制分析》针对NHC观测噪声不适应的问题基于参数自主学习来构建参数运动约束模型,其基本思路是当GNSS观测条件良好时,训练车辆侧向/垂向速度与影响因子(车辆前向速度、转弯角速度)之间的映射关系;当GNSS不可用时,通过学习得到的映射模型推断车辆侧向/垂向速度,形成NHC约束信息。

 参数学习主要采用了两种方法:多元回归方法和深度学习方法。

多元回归方法考虑了侧向速度,文中给出了两类回归模型:

 深度学习方法使用历史数据作为训练集,当GNSS可用时,由GNSS/SINS 融合解算可以得到侧向/垂向速度真值,同时与相应的惯导六轴输出打包形成标签数据。构造的损失函数即为训练输出的侧向/垂向速度与真值之间差值向量的二范数。在训练过程中,若反向传播后的相关计算值小于阈值,则对神经网络进行参数更新,否则就直接开始下一次训练,直到训练次数达到设定值。

实验结果:相比于方差域调参的传统方法,采用多元回归模型的惯性推算误差RMS在水平位置上减小了69.6%~81.2%,而利用深度学习则减小了 60.0%~77.3%。同时,水平相对定位精度分别提升了75.2%和65.0%,能有效提高GNSS失效时车载定位精度维持能力。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,这里是一个基于L432KC单片机和降压模块和tt电动机和L298N和HC05的蓝牙控制小车行驶的程序示例: ```c #include "mbed.h" // 定义蓝牙串口对象 Serial bt(PA_9, PA_10); // TX, RX // 定义电机控制引脚对象 DigitalOut motor1A(PB_3); DigitalOut motor1B(PB_5); DigitalOut motor2A(PB_4); DigitalOut motor2B(PB_10); // 定义电压检测引脚对象 AnalogIn voltageIn(PC_4); // 定义电池电压值 float voltage = 0; // 定义电机控制函数 void motorControl(int leftSpeed, int rightSpeed) { // 控制左边电机 if (leftSpeed > 0) { motor1A = 1; motor1B = 0; leftSpeed = (leftSpeed > 100) ? 100 : leftSpeed; leftSpeed = (leftSpeed < 0) ? 0 : leftSpeed; motor1A.write((float)leftSpeed / 100.0f); } else if (leftSpeed < 0) { motor1A = 0; motor1B = 1; leftSpeed = (leftSpeed < -100) ? -100 : leftSpeed; leftSpeed = (leftSpeed > 0) ? 0 : leftSpeed; motor1B.write((float)(-leftSpeed) / 100.0f); } else { motor1A = 0; motor1B = 0; } // 控制右边电机 if (rightSpeed > 0) { motor2A = 1; motor2B = 0; rightSpeed = (rightSpeed > 100) ? 100 : rightSpeed; rightSpeed = (rightSpeed < 0) ? 0 : rightSpeed; motor2A.write((float)rightSpeed / 100.0f); } else if (rightSpeed < 0) { motor2A = 0; motor2B = 1; rightSpeed = (rightSpeed < -100) ? -100 : rightSpeed; rightSpeed = (rightSpeed > 0) ? 0 : rightSpeed; motor2B.write((float)(-rightSpeed) / 100.0f); } else { motor2A = 0; motor2B = 0; } } int main() { // 设置蓝牙串口波特率为9600 bt.baud(9600); while(1) { // 如果接收到了蓝牙数据,将电机速度设置为接收到的数据 if (bt.readable()) { char c = bt.getc(); if (c == 'W') { motorControl(50, 50); } else if (c == 'S') { motorControl(-50, -50); } else if (c == 'A') { motorControl(-50, 50); } else if (c == 'D') { motorControl(50, -50); } else if (c == 'Q') { motorControl(0, 0); } } // 每隔一段时间检测电池电压 if (voltageIn.read() < 0.1) { // 电池电压低于3.3V,停止电机 motorControl(0, 0); } else { // 读取电池电压值 voltage = voltageIn.read() * 3.3f * 2.0f; } } } ``` 在这个程序中,我们首先定义了一个Serial对象bt,用于和HC05蓝牙模块进行通信。然后定义了四个DigitalOut对象,分别用于控制左右两个电机的正反转。再定义了一个AnalogIn对象voltageIn,用于监测电池电压。在主循环中,我们不断地检查蓝牙串口是否有数据可读,如果有数据,就读取数据并判断其值。根据不同的值,我们调用motorControl函数控制电机的速度和方向。同时,我们还每隔一段时间检测一次电池电压,如果电池电压过低,就停止电机的运行。 需要注意的是,tt电动机通常需要使用电子调速器(例如L298N)进行控制,这里我们使用DigitalOut对象模拟PWM控制电机速度。另外,由于电动机的工作电压一般比单片机的工作电压高,因此还需要使用降压模块将电源电压降至适合单片机和电子调速器的电压范围。同时,HC05蓝牙模块的串口波特率需要和程序中设置的波特率一致,否则无法正常通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值