基于RT-Thread和i.MX RT1052的开源AutoQuad飞控 RTThread物联网操作系统

2018 年 8 月 2 日 无人机

本文为jiezhi320参与RT-Thread应用作品征集赛作品原创。只要你采用RT-Thread操作系统设计开发,不限硬件(每人可提交作品数不限)就有机会获得2000元现金大奖哦!投稿:andychen@rt-thread.com

【背景描述】

AutoQuad是德国的一款老牌开源飞控(硬件闭源),其旨在提供稳定、动态飞行和自动驾驶功能的飞控控制器。

由于AutoQuad硬件闭源的特性,国内的玩家很少,但AutoQuad 的ukf算法“独步天下”,绝对是一绝,我对其垂涎已久。15年时我自己做出了Autoquad的M4版本硬件(基于stm32f405rgt6),可以运行官方源码。

17年时我将Autoquad移植到mdk环境下并且将其rtos替换为RT-Thread。后续玩这个玩了蛮久时间,这个版本的AutoQuad有一个问题:由于UKF算法占用了很多cpu资源使得整个系统cpu占用率太高,再者就是片内ram资源捉襟见肘。

对于这个版本的AutoQuad目前有挺多模友想继续深入的开发,比如网名为“我的世界观”的网友想将L1自适应控制算法加入到其中,但这个L1自适应算法也是极耗费cpu资源的。在这个背景下我开始着手AutoQuad在imx-rt1052上的实现,以期留出足够的资源给大家来给模友们深入开发,同时我也借机熟悉下RT-Thread的3.x版本。

另外参加这个作品征集活动只是这个项目的开始,我后续会将成果放在github,欢迎大家一起来加入这个项目,继续延续AutoQuad的传奇。

【所用物料】

主控:

iMX-RT1052DVL6B

传感器:

ICM20602、SPL06、HMC5983

编译环境:

WIN10、MDK5.25

RT-Thread 版本:

3.0.4

实物图:

硬件板子目前基于野火1052 mini开发板,传感器是从马家买的现成模块,采用飞线的形式固定在开发板上(后期会重新设计一款小的适合飞控的板子)

主控+传感器

全部的连接都使用飞线(感谢火哥不杀之恩)

为了上盖能盖的下,将底板上的usb座和网络接口座去掉了(感谢火哥不杀之恩)

勉强能扣好

【硬件设计】

系统框图

硬件设计解析

A、传感器部分:

各个传感器接到IMX-RT1052的SPI3上,进行分时操作。

B、SBUS输入

由于SBUS信号是一个反向电平的串口信号,这里使用一个三级管搭了一个简单的反向电路,从而将信号正确到接入到处理器的串口输入端。

C、PWM 信号输出

用于控制ESC的PWM信号,使用主控上PWM1和PWM2中的AB通道,这里3的意思是使用submode3。

D、GPS

GPS模块是一个独立的单元,通过串口接到主控的串口5上,上图中的原理图是我早期时候设计的基于Ublox M8N的GPS模块,这里刚好用到。

【软件设计】

软件设计流程

整个AutoQuad源码是一个较大的系统,我这里抽丝剥茧,将其中的主脉络流程贴出来:

关键代码解析

此版和之前在stm32f405上的版本最大的区别在于加速度+陀螺仪传感器、磁力计、高度计的数据读取上。原版直接使用spi进行驱动,这个版本我使用了RT-Thread的SPI设备驱动框架来进行数据读取。

这里将加速度传感器&陀螺仪驱动源码列出来,进行一个简单解析:

1、将总线设备挂到总线上(配置CS引脚)

rt1050_spi_bus_attach_device("spi3", "spi32", 64); 

此段代码表示将icm20602作为spi3上的第三个设备和spi总线进行关联,并使用 GPIO_AD_B1_05 作为其cs引脚(其中64代表 GPIO_AD_B1_05 ,即icm20602的cs引脚是 GPIO_AD_B1_05 )。

2、配置SPI总线相关参数

struct rt_spi_configuration cfg;


    cfg.data_width = 8;

    cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */

    cfg.max_hz = MPU6000_SPI_BAUD; /* 1M */

rt_spi_configure(spi_acc_gyro_device->rt_spi_device, &cfg);

3、对总线的互斥操作

为保证多个设备对spi3的互斥使用,需要对icm20602加入互斥锁操作:

static void sensor_lock(struct spi_acc_gyro_device * sensor_device)

{

    rt_mutex_take(sensor_device->lock, RT_WAITING_FOREVER);

}


static void sensor_unlock(struct spi_acc_gyro_device * sensor_device)

{

    rt_mutex_release(sensor_device->lock);

}


4、寄存器的读写操作

static void icm20602_write_reg(uint8_t reg, uint8_t value)

{

    uint8_t send_buffer[2];

    send_buffer[0] = reg&0x7f;

    send_buffer[1] = value;

    rt_spi_send(spi_acc_gyro_device->rt_spi_device, send_buffer, 2);

}
 

static uint8_t icm20602_read_reg(uint8_t reg)

{

    uint8_t rxBuf[2];

    uint8_t txBuf[2];

    txBuf[0] = reg|0x80;

    rt_spi_send_then_recv(spi_acc_gyro_device->rt_spi_device, txBuf, 1, rxBuf, 2);

    return rxBuf[0];

}


static uint8_t icm20602_read_buffer(uint8_t reg, uint8_t *buffer, uint16_t len)

{

    uint8_t txBuf[2];

    uint8_t rxBuf[20];

    sensor_lock(spi_acc_gyro_device);

    txBuf[0] = reg|0x80;

    rt_spi_send_then_recv(spi_acc_gyro_device->rt_spi_device, txBuf, 1, rxBuf, len);

    rt_memcpy(buffer, rxBuf, len);

    sensor_unlock(spi_acc_gyro_device);

    return 0;

}

因为使用SPI总线驱动架构,SPI部分的相关操作使用 rt_spi_send rt_spi_send_then_recv 这两个API。

5、读取加速度和陀螺仪数据

static uint8_t icm20602_get_accel(int16_t *accel, int16_t *temp)

{

    uint8_t buf[10];

    icm20602_read_buffer(ICM20_ACCEL_XOUT_H,buf,8);

    accel[0] = ((int16_t)buf[0]<<8) + buf[1];

    accel[1] = ((int16_t)buf[2]<<8) + buf[3];

    accel[2] = ((int16_t)buf[4]<<8) + buf[5];

    *temp     = ((int16_t)buf[6]<<8) + buf[7];

    //ICM_TRACE("acc0=%d, acc1=%d, acc2=%d\r\n",accel[0],accel[1],accel[2]);

    return 0;
}

 

static uint8_t icm20602_get_gyro(int16_t *gyro)

{

    uint8_t buf[8];

    icm20602_read_buffer(ICM20_GYRO_XOUT_H,buf,8);

 

    gyro[0] = (buf[0]<<8) + buf[1];

    gyro[1] = (buf[2]<<8) + buf[3];

    gyro[2] = (buf[4]<<8) + buf[5];

 

    // ICM_TRACE("gyro0=%d, gyro1=%d, gyro2=%d\r\n",gyro[0],gyro[1],gyro[2]);

 

    return 0;

}

因为 icm20602_read_buffer 函数内部已经加入了互斥,所以读取时不再需要互斥操作。

RT-Thread 使用情况

1、动态内存管理;

2、GPIO设备驱动架构;

3、RTC设备驱动架构;

4、SPI设备驱动架构;

5、SDIO设备驱动架构;

6、串口设备驱动架构;

7、MSH命令行;

8、FatFs文件系统。

【演示视频】

由于大西安最近一直下雨,之前都是在家里进行飞行测试。今天阴天,雨基本停了,出来进行试飞,顺便测试一下定点功能,虽然有风,但整个测试还是比较顺利的,感谢媳妇帮我录视频,因为媳妇不会用单反,录的不是很好,硬是录的比手机录质量还差。


转自丨RTThread物联网操作系统


点击下面链接 查看历史文章



无人机飞控技术最详细解读

飞控中的一阶RC低通滤波算法

是什么毁灭了无人机行业?

无人机应用新思路丨吊挂无人机

美国DARPA“分布式作战管理”项目阶段性成果

八百米真牛!木牛科技二代无人机定高方案


登录查看更多
1

相关内容

传感器(英文名称:transducer/sensor)是一种检测装置,能感受到被测量的信息,并能将感受到的信息,按一定规律变换成为电信号或其他所需形式的信息输出,以满足信息的传输、处理、存储、显示、记录和控制等要求。
FPGA加速系统开发工具设计:综述与实践
专知会员服务
63+阅读 · 2020年6月24日
Python计算导论,560页pdf,Introduction to Computing Using Python
专知会员服务
70+阅读 · 2020年5月5日
【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
深度神经网络实时物联网图像处理,241页pdf
专知会员服务
76+阅读 · 2020年3月15日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
用 Python 开发 Excel 宏脚本的神器
私募工场
26+阅读 · 2019年9月8日
目标检测:Anchor-Free时代
极市平台
42+阅读 · 2019年4月17日
阿里云发布机器学习平台PAI v3.0
雷锋网
12+阅读 · 2019年3月22日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
48+阅读 · 2018年12月20日
【机器人】机器人PID控制
产业智能官
10+阅读 · 2018年11月25日
Python3.7中一种懒加载的方式
Python程序员
3+阅读 · 2018年4月27日
基于 Storm 的实时数据处理方案
开源中国
4+阅读 · 2018年3月15日
Arxiv
34+阅读 · 2019年11月7日
Knowledge Based Machine Reading Comprehension
Arxiv
4+阅读 · 2018年9月12日
Feature Selection Library (MATLAB Toolbox)
Arxiv
7+阅读 · 2018年8月6日
VIP会员
相关资讯
用 Python 开发 Excel 宏脚本的神器
私募工场
26+阅读 · 2019年9月8日
目标检测:Anchor-Free时代
极市平台
42+阅读 · 2019年4月17日
阿里云发布机器学习平台PAI v3.0
雷锋网
12+阅读 · 2019年3月22日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
48+阅读 · 2018年12月20日
【机器人】机器人PID控制
产业智能官
10+阅读 · 2018年11月25日
Python3.7中一种懒加载的方式
Python程序员
3+阅读 · 2018年4月27日
基于 Storm 的实时数据处理方案
开源中国
4+阅读 · 2018年3月15日
Top
微信扫码咨询专知VIP会员