mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
前言:
好久没更新博客了,这两个月真的是异常的忙,白天要忙着公司里的事,晚上还要忙着修改小论文,一点自己的时间都没有了,不过确确实实是学到了很多东西,对无人机的技术研究也更深了一些。不过好在小论文发出去了,公司的项目也有了进展,终于有一点时间来写博客。不由得感叹,无人机真是越学越觉得自己菜,越学越不明白,什么方面的知识都会涉及,软件、硬件、机械、理论、电路、各种通讯协议、以及较强的动手能力(组装,焊接,改线是真的累),更别提更上层的ros、SLAM、规划这些,感觉能学到老,哈哈,不过吐槽归吐槽,但是当取得一点点进展,就会觉得特别满足,所有的一切都源于对无人机的热爱。
项目需求:
因为目前公司的合作方提供的飞控并不是我所熟悉的pix飞控,而是他们自研的一款闭源飞控,因为飞控集成了一块算力还可以的板子当机载电脑,所以性价比比较高,但唯一让我头疼的就是这款飞控不是px4或者apm,不仅不熟悉,也没法做二次开发。不过,再三沟通后,飞控厂家提供了外部的通讯协议和部分内部的接口代码,让我惊喜的是,他们用的外部协议竟然就是mavlink2,且我看了他们提供的那部分代码后,估计这款飞控厂家应该是借鉴了PX4,因为我很明显看到了一些熟悉的头文件和uorb的痕迹。
知道了通讯协议后,事情就好办一些了,因为我需要将飞控的一些数据传到我们的服务器和传感器,并且能通过服务器和传感器反过来对无人机进行一些简单的控制,而不再用地面站做监测。先说简单点的,用单片机实现通讯。(后来我才发现服务器通讯更简单,嘿嘿,可能有同事的帮忙吧)
1.mavlink移植:
(1)移植说明
mavlink有两个版本,目前的飞控很多用的都是mavlink2,需要注意的一点是,mavlink2是可以兼容mavlink1的,但最好还是保持一致,如果你只是想要从飞控那接收一些姿态、速度、电池等数据,那mavlink1也可以,但如果你想要对飞控进行控制,发送指令,那就需要移植mavlink2。
MAVLink V1版:https://github.com/mavlink/c_library_v1
MAVLink V2版:https://github.com/mavlink/c_library_v1
(2)代码生成器
移植这部分我是直接在ubuntu下进行的,直接输入下面指令,将mavlink协议拷贝过来
git clone https://github.com/mavlink/mavlink

得到上面文件,一定要确保文件不要丢失,不要丢失,不要丢失,确保网络没问题,这里我踩过坑,有几个头文件没有,导致后面的工作一直出现问题。
更新子模块:git submodule update --init --recursive
生成代码:python mavgenerate.py
执行下面指令,会跳出一个代码生成器
python3 mavgenerate.py
XML选择:\message_definitions\v1.0\common.xml
out选择:mavlink(这个是生成文件的地方,随便选)

点击Generate你会得到下面这些文件

将这些文件打包好,从虚拟机里复制过来。
2.将mavlink文件加入到工程
这里需要用到一个串口的工程文件,基本上大家都有,我就不具体说了,可以看这篇参考博客。
打开正点原子例程:实验4 串口实验,其他的也可以,代码很简单,能通过串口1给串口助手传输数据就行。

将我们之前在ubuntu中生成的mavlink文件加入进来。
同时在keil5中也要将头文件路径加入进来,这些步骤就不详细说了,keil5大家也很熟悉。

这里记得把头文件路径加进来
因为我用的f103,这个串口例程是f4的,所以也要修改一下。

3.调试修改
这个过程是最痛苦的,因为动不动就是一堆报错,一堆警告,每个人的情况不一样,我只能网上搜教程,不过还是有收获的,之前mavros都是直接下载好用,对底层的这些函数没有去了解,但其实还是很有用的,毕竟这是直接和飞控对接,mavros毕竟还是隔了个ros,而且ros也是一堆问题,那不如一步到位。
建议先好好看看恒久力行的这几篇博客,真的受益匪浅,我看网上的基本都是在他的基础上进行的,很难想象这是8年前的工作,真的很佩服这些前辈,自愧不如。参考博客1 参考博客2 参考博客3
还有一些修改是我自己琢磨和参考网上其他人的。
替换代码:#define MAVPACKED( __Declaration__ ) __Declaration__

需要注意:keil中默认是不支持匿名结构体的,需要编译指令#pragma anon_unions指名。
还有mavlink_avoid_errors.h这个头文件,前辈在博客中有详细写这个,这里附上我修改后的。
#ifndef MAVLINK_AVOID_ERRORS_H
#define MAVLINK_AVOID_ERRORS_H
#include "stdio.h"
#include "stdint.h"
/*解决..\MAVLINK\common\../mavlink_types.h(53): error: #20: identifier "pack" is undefined*/
#define MAVPACKED( __Declaration__ ) __Declaration__
/*解决..\MAVLINK\common\../mavlink_types.h(53): error: #3092: anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions*/
#pragma anon_unions
#define inline __inline#include "mavlink.h"
#include "mavlink_helpers.h"
#endif //AVLINK_AVOID_ERRORS_H
main.c中的代码为:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "mavlink_avoid_errors.h"
#include "mavlink_usart_fifo.h"
#include "open_tel_mavlink.h"
#include "stdint.h"
mavlink_system_t mavlink_system;
#define UART_TX_BUFFER_SIZE 255
#define UART_RX_BUFFER_SIZE 255
extern fifo_t uart_rx_fifo, uart_tx_fifo;
extern uint8_t uart_tx_buf[UART_TX_BUFFER_SIZE], uart_rx_buf[UART_RX_BUFFER_SIZE];
int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168); //延时初始化 uart_init(115200); //串口初始化波特率为115200
// LED_Init(); //初始化与LED连接的硬件接口 fifo_init(&uart_tx_fifo, uart_tx_buf, UART_TX_BUFFER_SIZE); fifo_init(&uart_rx_fifo, uart_rx_buf, UART_RX_BUFFER_SIZE);mavlink_system.sysid = MAV_TYPE_GENERIC;mavlink_system.compid = MAV_AUTOPILOT_GENERIC;while(1) {mavlink_send_message(0, MSG_HEARTBEAT, 0);mavlink_send_message(0, MSG_LOCATION, 0);// while(1)
// {if(tranlTimer > 100) {tranlTimer = 0;
// delay_ms(1000);
// mavlink_send_message(0, MSG_HEARTBEAT, 0);
// mavlink_send_message(0, MSG_ATTITUDE, 0);
// mavlink_send_message(0, MSG_AHRS, 0);}update();
// }}
}
4.编译和测试
基本上按照前面的博客里修改,不会有什么报错,编译一下。

下载到开发板后,打开调试助手。
拿出这一组数据,来对照mavlink协议看看。
FE 03 1A 01 01 96 88 13 01 32 EC

至于接收数据,就不细说了,前面的博客里已经很详细了。后面有时间,我会记录一下怎么通过自己写网页的形式去控制无人机,突然间觉得地面站好像也没有那么神秘。
相关文章:
mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
前言: 好久没更新博客了,这两个月真的是异常的忙,白天要忙着公司里的事,晚上还要忙着修改小论文,一点自己的时间都没有了,不过确确实实是学到了很多东西,对无人机的技术研究也更深了一些。不过好…...
小程序基础 —— 08 文件和目录结构
文件和目录结构 一个完整的小程序项目由两部分组成:主体文件、页面文件: 主体文件:全局文件,能够作用于整个小程序,影响小程序的每个页面,主体文件必须放到项目的根目录下; 主体文件由三部分组…...
FIR数字滤波器设计——窗函数设计法——滤波器的时域截断
与IIR数字滤波器的设计类似,设计FIR数字滤波器也需要事先给出理想滤波器频率响应 H ideal ( e j ω ) H_{\text{ideal}}(e^{j\omega}) Hideal(ejω),用实际的频率响应 H ( e j ω ) H(e^{j\omega}) H(ejω)去逼近 H ideal ( e j ω ) H_{\text{ideal}}…...
MySQLOCP考试过了,题库很稳,经验分享。
前几天,本人参加了Oracle认证 MySQLOCP工程师认证考试 ,先说下考这个证书的初衷: 1、首先本人是从事数据库运维的,今年开始单位逐步要求DBA持证上岗。 2、本人的工作是涉及数据库维护,对这块的内容比较熟悉ÿ…...
WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)
在一个WPF项目中要用到样条曲线,必须过顶点,圆滑后还不能太走样,捣鼓一番,发现里面颇有玄机,于是把我多方抄来改造的方法发出来,方便新手: 如上图,看代码吧: ----------…...
Kafka 幂等性与事务
文章目录 幂等性实现机制配置使用局限性 事务使用场景配置使用实现机制事务过程事务初始化事务开始事务提交事务取消事务消费 幂等性 Producer 无论向 Broker 发送多少次重复的数据,Broker 端只会持久化一条,保证数据不丢失且不重复。 实现机制 通过引…...
day2 Linux操作系统指令
思维导图 在家目录下创建目录文件,dir 1、dir下创建dir1和dir2 2、把当前目录下的所有文件拷贝到dir1中, 3、把当前目录下的所有脚本文件拷贝到dir2中 4、把dir2打包并压缩为dir2.tar.xz 5、再把dir2.tar.xz移动到dir1中 6、解压dir1中的压缩包 7、使用…...
AI一周重要会议和活动概览
一、小模型的曙光和机会之思辨高峰论坛 会议介绍:小模型的曙光和机会之思辨”高峰论坛暨第32期CSIG图像图形学科前沿讲习班于2025年1月3—4日在杭州举办,会议由中国图象图形学学会主办,中国图象图形学学会前沿科技论坛委员会承办。本次论坛设…...
重启ubuntu服务器,如何让springboot服务自动运行
文章目录 1. 使用 systemd 服务步骤: 2. 使用 cron 的 reboot 任务步骤: 3. 使用 init.d 脚本(适用于较旧版本)步骤: 推荐方案 为了确保在重启Ubuntu服务器后,让springboot的服务test.jar象 nohup java -ja…...
python系列教程237——启动扩展功能
朋友们,如需转载请标明出处:https://blog.csdn.net/jiangjunshow 声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享…...
U盘格式化工具合集:6个免费的U盘格式化工具
在日常使用中,U盘可能会因为文件系统不兼容、数据损坏或使用需求发生改变而需要进行格式化。一个合适的格式化工具不仅可以清理存储空间,还能解决部分存储问题。本文为大家精选了6款免费的U盘格式化工具,并详细介绍它们的功能、使用方法、优缺…...
循环神经网络(RNN)入门指南:从原理到实践
目录 1. 循环神经网络的基本概念 2. 简单循环网络及其应用 3. 参数学习与优化 4. 基于门控的循环神经网络 4.1 长短期记忆网络(LSTM) 4.1.1 LSTM的核心组件: 4.2 门控循环单元(GRU) 5 实际应用中的优化技巧 5…...
马原复习笔记
文章目录 前言导论物质实践人类社会资本主义社会主义共产主义后记 前言 一月二号下午四点多考试,很友好,不是早八,哈哈哈。之前豪言壮语和朋友说这次马原要全对,多做了几次测试之后,发现总有一些知识点是自己不知道的…...
Android Room 框架的初步使用
一、简介 Room 是一个强大的对象关系映射库,它允许你将 SQLite 数据库中的表映射到 Java 或 Kotlin 的对象(称为实体)上。你可以使用简单的注解(如 Entity、Dao 和 Database)来定义数据库表、数据访问对象(…...
什么是过度拟合和欠拟合?
在机器学习中,当一个算法的预测非常接近或者直接等于它的训练数据,导致不能够准确预测除了训练数据以外的数据,我们把这种情况称为过度拟合。算法能够非常接近甚至就是训练的数据,是个非常好的事,但是它不能准确预测除…...
DotnetSpider实现网络爬虫
1. 使用DotnetSpider框架 DotnetSpider是一个开源的、轻量、灵活、高性能、跨平台的分布式网络爬虫框架,适用于.NET平台。它可以帮助开发者快速实现网页数据的抓取功能。 1.1 安装DotnetSpider NuGet包 首先,你需要在你的.NET项目中安装DotnetSpider NuGet包。你可以通过…...
锐捷WLAN产品出货量排名第一!
摘要:2024年Q3锐捷WLAN产品出货量排名第一!锐捷多形态Wi-Fi 7产品重磅出击! 近日, IT市场研究和咨询公司IDC发布《IDC中国企业级WLAN市场跟踪报告,2024年Q3》。报告显示,锐捷WLAN产品在2024年Q3出货量位居行业首位。至此,锐捷WLAN产品在2024年的Q1、Q2、Q3均实现了市场出货量的…...
win32汇编环境下,对话框程序中生成listview列表控件,点击标题栏自动排序的示例
;把代码抄进radasm里面,可以直接编译运行。重要的地方加了备注。 ;这个有点复杂,重要的地方加了备注 ;以下是ASM文件 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>…...
自动化文档处理:Azure AI Document Intelligence
Azure AI Document Intelligence支持多种文件格式,包括PDF、JPEG、PNG等。其核心功能是将这些文档按页进行内容提取,并转化为LangChain文档。其默认输出格式是Markdown,这使得文档可以通过MarkdownHeaderTextSplitter进行语义分片。您也可以使…...
【Maven】Maven打包机制详解
Maven打包的类型? 以下是几种常见的打包形式: 1、jar (Java Archive) 用途:用于包含 Java 类文件和其他资源(如属性文件、配置文件等)的库项目。特点: 可以被其他项目作为依赖引用。适合创建独立的应用程…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...
leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...
2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...
