BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / smartcar / #447同步于 2024/1/28
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Smartcar机器人发帖

一个Rust写的运行于Linux上的飞控

Ncer
2024/1/28镜像同步16 回复
之前毕业之后,平时其实没有太多的时间,发誓不再手搓飞控,直接用开源方案。并且当时由于疫情导致的芯片荒,各种经典的STM单片机疯狂涨价,于是出现了风风火火的各大开源飞控移植到国产芯片的运动,影响最大的,最成功还是基于AT32的各种飞控: - atbetaflight(移植自betaflight) - inav(at32 已在主线支持) - ardupilot(听说已经支持,但不知道进入主线没有,我对AP兴趣不大,没咋关注) 移植运动风起云涌,虽然AT32与stm32都用的是cortex-m 核,但其实外设并不一致,这其中是有很多工作量在的,我十分敬佩大家这种为爱发电的精神,但也不仅担忧一个事情:就是现在从STM32 挪到 AT32,就要有这么多工作量,以后每出现一个好用的MCU,岂不是每次都得再做一次这个事情。 因此,基于这个担忧,我想着能不能基于linux的平台,在嵌入式linux上来跑飞控呢?在linux上跑,显然是有很多好处的: 1. 统一的驱动层 相比于单片机,虽然现在很多单片机厂家都提供了他们单片机的HAL包,但是对于具体的项目来说,大家用的驱动层API都不一样,免不了要做很多基于HAL重新封装成具体项目API的事情,这些其实都是体力活。 但linux不一样,每个可以跑linux的soc在进入市场前,soc公司至少都得提供一个能boot到linux,且各个外设都能用的SDK包吧(虽然我认为提供SDK而不是推动进入主线,仍旧会导致很多重复劳动,但至少这个重复劳动是soc公司承担了) 因此,基于这个驱动层,实际上飞控跑在linux上,基本上就不用关心外设了(当然在设备树上什么要做一下处理),从一个soc移植到另一个soc,只需要改改设备树,飞控层面的,只需要改改传感器连接定义等,甚至可以啥都不用改直接跑。 2. 性能 性能什么的当然不用多说,嵌入式linux soc主频至少是一般MCU的4、5倍,至少是arm v7a 的核。(arm9 的就不考虑了) 基于这个想法,我先尝试了PX4,因为PX4使用的RTOS是nuttx。而nuttx是所有rtos中,对Posix 支持得最好的,也就是跟linux最像的,如果要跑在Linux上,应该是最简单的。 事实上也正是如此,当然,我想到的PX4社区的大佬们也早就想到了。 PX4很早就支持在linux上运行,很早就支持基于树莓派的飞控 于是我也做了个板子,称作AutopilotPi,基于全志的V3s芯片(armv7 单核,64MB 内存,800MHz~1GHz) 当时在上面跑PX4的时候,就发现一个致命的问题,就是PX4线程(workqueue)调度的时候,有概率进入死锁,是线程调度加锁解锁的顺序导致的。这个我在V3s和另一个orangepi 上都复现过,但复现难度不一样 ,V3s上很容易复现,而orangepi复现难度则比较大,可能得跑一天才能出现。后来我改了线程调度里几句话的顺序,能够解决这个问题。但是问题和补丁提交到社区,社区的大佬们用的是树莓派,性能比V3s和orangepi高很多,一直复现不出来。再加上线程调度是个比较重要的东西,显然社区不会接收一个声称解决了一个复现都复现不了的问题的补丁,因此这个问题就一直搁置下来。 此外,就是linux在PX4,一直不算主流支持,而是“实验性”支持,这一实验都快十年了,而且进入主流支持仍然遥遥无期,社区里真的使用linux来跑飞机的,寥寥无几,更多的还是在linux上跑SIH仿真等等。 于是,在几个月前,在花了几天时间解决了一个Linux PX4和地面站的兼容性问题后(其实只是一个简单的路径问题,PX4的某些文件要放在linux的特定路径,但根本没有相关文档描述,社区里也没人遇到过),我实在忍不了了,开始想着能不能写一个纯粹的,在linux上运行的飞控。 于是便有了RustPilot 其中借鉴了PX4不少设计,比如使用hrt来手动维护一个调度队列、采用组件化的设计、线程间通信的实现等等。 其中有个比较大的改动,就是放弃了使用workqueue调度任务,而是采用thread + callback的方式来实现任务。PX4大量采用workqueue的一个好处省空间,可以好几个任务共用一个线程的内存资源,同时将用到同一个临界区资源的任务分配到同一个workqueue,这样这些任务天然就是互斥的。 而在linux上,首先不缺你一个线程的内存空间,而临界区资源维护的话,由于是基于linux的FIFO调度,因此可以将使用同一个临界区资源的任务设置为相同的优先级(当然如果是多核的情况,还得考虑各个线程跑在哪个核上)。这样的好处是不用再维护workqueue线程,每个任务还得实现为workitem。 至于为什么用Rust,一个很大的原因是实在不喜欢C++, 每次写PX4,里面一堆继承总是把我绕得晕头转向的。另外就是rust的crate质量都还可以,至少不会出现在github找半天找到某个开源库(还不支持cmake),下载下来编译一堆问题的情况(什么菜鸡发言 不过由于是第一次正儿八经写rust,以前看了挺多次语法,一直没有实践过,实际写起来发现确实很难,好在有编译器和AI教我写代码,磕磕绊绊地,总之现在程序基本上跑起来了(六角形的轮子也是轮子不是 当然,使用Linux来跑飞控,显然大家还是会有不少担忧,最经典的不外乎就是实时性了。不过这里写不下了,我就不多谈了,我直接留下一个暴论:微/小型无人机(大无人机我也没做过)的实时性要求实际上不高。比起实时性,我更担心的是linux soc一般没有MCU皮实耐操,对电源稳定性也有更高要求,不过这些都可以在电路层面解决。 关于强实时的linux,之前也做了一定的调研,RROS,居然是北邮的项目,了不起。不过后来发现如果用双内核的方式,实时内核里很难白嫖到linux的生态,而如果不放在实时内核跑,迁移到双内核的收益就不大了,因此目前暂时打消了迁移到强实时linux的打算,最多先打上preempt-rt的补丁
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
Dxes机器人#1 · 2024/1/28
看标题就猜到了是Ncer学长[ema21]
hujiangtao机器人#2 · 2024/1/28
太强了!!!不过我们RROS是包含了Linux哦,所有Linux应用无感迁移![ema3]欢迎尝试一下我们RROS
ruiqurm机器人#3 · 2024/1/28
bd
Ncer机器人#4 · 2024/1/28
是的,用户态程序是可以无感迁移,但我这个程序希望能在实时内核上跑,这就需要实时内核里再实现相应的外设驱动(如spi/i2c)等 【 在 hujiangtao 的大作中提到: 】 : 太强了!!!不过我们RROS是包含了Linux哦,所有Linux应用无感迁移!欢迎尝试一下我们RROS
Ncer机器人#5 · 2024/1/28
这都能猜到,不过北邮玩飞机的确实不多 【 在 Dxes 的大作中提到: 】 : 看标题就猜到了是Ncer学长
Po2020机器人#6 · 2024/1/28
哇,原来有智能车版,十八届小东西报道[ema3] 【 在 Ncer 的大作中提到: 】 : 之前毕业之后,平时其实没有太多的时间,发誓不再手搓飞控,直接用开源方案。并且当时由于疫情导致的芯片荒,各种经典的STM单片机疯狂涨价,于是出现了风风火火的各大开源飞控移植到国产芯片的运动,影响最大的,最成功还是基于AT32的各种飞控: : - atbetaflight(移植自betaflight) : ............
RainIsMe机器人#7 · 2024/1/28
牛逼 bd
bdyzhy9527机器人#8 · 2024/1/28
bd
Ncer机器人#9 · 2024/1/28
智能车版太冷清了,有空多来发点经验给十九届的年轻人 【 在 Po2020 的大作中提到: 】 : 哇,原来有智能车版,十八届小东西报道