陆地车非完整性约束——INS/NHC组合导航

1 引言

陆地车在经过城市峡谷、隧道等严重遮挡环境时,GNSS定位精度较差。为了防止低精度的INS发散较快,可以通过非完整约束来进行约束。非完整约束不需要添加额外传感器,就可以抑制INS发散速度,被广泛采用。
本博文是在 INS/NHC/ODO组合导航 的基础上讨论的,没看的小伙伴可以先看这篇。

:为便于理解NHC原理,本文不考虑IMU和陆地车间的安装角(即,IMU和陆地车坐标系安装角为零)

2 原理

陆地车在不发生跳跃和侧滑时,其垂直于前进方向的后轮速度近似为零。

在这里插入图片描述

由博文 INS/NHC/ODO组合导航 可知:
在这里插入图片描述
NHC只有两个观测量,所以“前-右-下”和“右-前-上”坐标系在具体实施时,有一点区别。

2.1 北-东-地 前-右-下坐标系

2.2 东-北-天 右-前-上坐标系

3 结果

通过在严恭敏老师的PSINS平台中仿真,对比了INS和INS/NHC的定位精度。

** 3.1 仿真轨迹:**
仿真轨迹

图1 仿真轨迹

** 3.2 INS/NHC轨迹:**
在这里插入图片描述

图2 INS/NHC轨迹

** 3.3 纯INS轨迹**
在这里插入图片描述

图3 纯INS轨迹

从轨迹图中可以看出,INS/NHC的轨迹和仿真轨迹基本一致,而纯INS的轨迹已经面目全非,由此可以看出NHC对INS的约束效果还是十分明显的。

4 参考

[1] Wu Yuanxin. Versatile Land Navigation Using Inertial Sensors and Odometry Self-calibration, In-motion Alignment and Positioning.

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个基于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蓝牙模块的串口波特率需要和程序中设置的波特率一致,否则无法正常通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值