惯性导航算法_自动驾驶关键技术报告:惯性导航和背后的芯片大战

3b8b9107f99e8af5e98e68a763a26122.png

▲短期看算法长远看惯性传感器芯片

惯性导航系统在自动驾驶中的应用属于起步阶段,短期内竞争力主要体现在算法上。算法包括了惯性传感器的标定等硬件信息的处理,速度、加速度、航向及姿态的确定,以及与其他传感器信息、车身信息的融合等主要模块。算法的优劣决定传感器是否能发挥其最佳性能,也决定了惯性导航系统的稳定性和可靠性。从长远看,惯性导航系统的竞争力在惯性传感器芯片。随着自动驾驶技术级别的提升,对惯性传感器芯片的性能要求将持续提高;同时随着惯性导航系统算法的不断成熟,通过算法优化来提升系统性能的空间越来越小,而对惯性传感器芯片硬件性能的依赖程度则会相应提高。惯性传感器芯片的设计、制造、封测及标定将成为惯性导航系统中比较关键的环节。

6e0e5457d9b830bf9069648a15298f86.png

▲自动驾驶对惯性传感器芯片的基本要求

自动驾驶是汽车产业与人工智能(AI)、物联网、云计算等新一代信息技术深度融合的产物,自动驾驶是一个庞大而且复杂的工程,涉及的技术很多,它也是当前汽车行业与出行领域智能化和网联化发展的主要方向,已成为各国争抢的战略制高点及热点。高精度行车定位技术以及高精度地图技术是自动驾驶汽车的两项核心技术,也是自动驾驶破局的关键点。在定位系统中,所有需要用到GPS的地方都需要使用惯性导航系统,例如车辆定位、激光雷达的GPS接口等。在GPS信号丢失的时候,惯性导航能够将定位信号模拟出来。但惯性导航系统成本昂贵,如何攻克惯导技术难关,如何生产大批量车规级惯性导航装置一直是业界难题。这些年随着各种利好,国产惯性导航也有了突破惯性导航产品芯片化,也正是原子机器人在做的事。

b7942dc8f31c4422dd78b6549349bb6f.gif

▲原子机器人在惯性导航上持续发力

原子机器人自成立之初,就在惯性导航技术上持续发力。目前我们已经拥有全部自主知识产权的高性能算法引擎。这个引擎可以在高动态和低动态的情况下,自动去适应用户的环境,从而保证数据输出的精度。而且,我们的引擎可以把底层传感器芯片的精度,通过算法提升一个数量级,这意味着,我们惯导产品正在向高集成度,高性能算法,以及低成本的方向发展。目前我们的Saber系列已实现量产,可以提供更高级别的可扩展GNSS高精度技术,这将为新的导航应用铺平道路,如增强现实、无人驾驶车辆导航和机器人技术(无人机和机器人割草机等应用)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的imu惯性导航和GPS融合的代码示例(使用C语言): ``` #include <stdio.h> #include <math.h> #define PI 3.14159265358979323846 // 定义常量 const double a = 6378137.0; // 地球长半轴 const double b = 6356752.3142; // 地球短半轴 const double e = sqrt(1.0 - (b / a) * (b / a)); // 地球第一偏心率 const double f = 1.0 / 298.257223563; // 地球扁率 // 定义向量结构体 typedef struct { double x; double y; double z; } Vector; // 定义四元数结构体 typedef struct { double w; double x; double y; double z; } Quaternion; // 姿态估计函数 void attitudeEstimation(Vector *accel, Vector *gyro, Quaternion *q, double timeInterval) { // 计算角加速度 Vector gyroRate = {gyro->x * PI / 180, gyro->y * PI / 180, gyro->z * PI / 180}; Vector gyroRateScaled = {gyroRate.x * timeInterval / 2.0, gyroRate.y * timeInterval / 2.0, gyroRate.z * timeInterval / 2.0}; double gyroRateScaledNorm = sqrt(gyroRateScaled.x * gyroRateScaled.x + gyroRateScaled.y * gyroRateScaled.y + gyroRateScaled.z * gyroRateScaled.z); Quaternion dq = {cos(gyroRateScaledNorm), gyroRateScaled.x / gyroRateScaledNorm * sin(gyroRateScaledNorm), gyroRateScaled.y / gyroRateScaledNorm * sin(gyroRateScaledNorm), gyroRateScaled.z / gyroRateScaledNorm * sin(gyroRateScaledNorm)}; // 更新四元数 Quaternion qNew; qNew.w = q->w * dq.w - q->x * dq.x - q->y * dq.y - q->z * dq.z; qNew.x = q->w * dq.x + q->x * dq.w + q->y * dq.z - q->z * dq.y; qNew.y = q->w * dq.y - q->x * dq.z + q->y * dq.w + q->z * dq.x; qNew.z = q->w * dq.z + q->x * dq.y - q->y * dq.x + q->z * dq.w; *q = qNew; // 计算重力向量 Vector gravity = {2.0 * (q->x * q->z - q->w * q->y), 2.0 * (q->w * q->x + q->y * q->z), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z}; double gravityNorm = sqrt(gravity.x * gravity.x + gravity.y * gravity.y + gravity.z * gravity.z); gravity.x /= gravityNorm; gravity.y /= gravityNorm; gravity.z /= gravityNorm; // 计算加速度向量 Vector accelScaled = {accel->x * timeInterval, accel->y * timeInterval, accel->z * timeInterval}; Vector accelCorrected = {accelScaled.x - gravity.x, accelScaled.y - gravity.y, accelScaled.z - gravity.z}; double accelCorrectedNorm = sqrt(accelCorrected.x * accelCorrected.x + accelCorrected.y * accelCorrected.y + accelCorrected.z * accelCorrected.z); accelCorrected.x /= accelCorrectedNorm; accelCorrected.y /= accelCorrectedNorm; accelCorrected.z /= accelCorrectedNorm; // 计算航向角 double roll = atan2(accelCorrected.y, accelCorrected.z); double pitch = atan2(-accelCorrected.x, sqrt(accelCorrected.y * accelCorrected.y + accelCorrected.z * accelCorrected.z)); double yaw = atan2(sin(-gyroRate.x * timeInterval) * cos(pitch) * cos(yaw) + cos(-gyroRate.x * timeInterval) * sin(pitch) * cos(yaw) - sin(-gyroRate.y * timeInterval) * sin(yaw) + cos(-gyroRate.y * timeInterval) * sin(pitch) * sin(yaw) + sin(-gyroRate.z * timeInterval) * cos(pitch) * sin(yaw) + cos(-gyroRate.z * timeInterval) * cos(yaw), sin(-gyroRate.x * timeInterval) * cos(pitch) * sin(yaw) + cos(-gyroRate.x * timeInterval) * sin(pitch) * sin(yaw) + sin(-gyroRate.y * timeInterval) * cos(yaw) + cos(-gyroRate.y * timeInterval) * sin(pitch) * cos(yaw) + sin(-gyroRate.z * timeInterval) * cos(pitch) * cos(yaw) - cos(-gyroRate.z * timeInterval) * sin(yaw)); } // GPS解算函数 void GPSPositioning(double lati, double longi, double *x, double *y) { double latiRad = lati * PI / 180; double longiRad = longi * PI / 180; double N = a / sqrt(1.0 - e * e * sin(latiRad) * sin(latiRad)); *x = (N + 1.0) * cos(latiRad) * cos(longiRad); *y = (N + 1.0) * cos(latiRad) * sin(longiRad); } int main() { Vector accel = {0.0, 0.0, 0.0}; // 加速度向量 Vector gyro = {0.0, 0.0, 0.0}; // 陀螺仪输出向量 Quaternion q = {1.0, 0.0, 0.0, 0.0}; // 四元数 double timeInterval = 0.0; // 采样时间间隔 double lati = 0.0; // 纬度 double longi = 0.0; // 经度 double x = 0.0; // GPS解算得到的X坐标 double y = 0.0; // GPS解算得到的Y坐标 // 获取传感器数据和GPS数据并进行姿态估计和GPS解算 // ... // 输出姿态和位置信息 printf("Roll: %f, Pitch: %f, Yaw: %f\n", q.x, q.y, q.z); printf("X: %f, Y: %f\n", x, y); return 0; } ``` 需要注意的是,在实际应用中,需要根据具体的传感器和GPS模块进行代码的修改和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值