环境配置
win10系统+STM32F103ZET6
步骤
参考MAVLINK官网
1.安装python3.6以上的版本
,我安装的是python3.8 Python3.8下载地址 详细安装步骤可参考:python3.8下载及安装步骤详解 安装完成后,使用win+R打开运行窗口,输入cmd命令,进入终端 使用python命令即可在终端打开python,使用exit() 命令可退出python环境
2.在终端中使用pip3 install future 命令安装future模块
这里是提示我已经安装过future模块了,警告是说我安装的不是最新版的future,无伤大雅
3.下载mavlinkgenerator
·在git 命令窗口中执行方式:git clone https://github.com/mavlink/mavlink
如果系统没有安装git包的可以参考Windows系统Git安装教程,超详细的安装过程!附软件资料~
如果下载失败的话可以考虑换个网再试一下
·进入文件夹:cd mavlink
此处我的mavlink下载到了C盘用户目录下,由于python安装在D盘,我就把mavlink文件夹复制到了D盘,和python在同一个目录下 在终端中切换到mavlink文件夹下 关于如何切换到D盘可参考:windows系统下使用cd命令切换到D盘的方法
·更新子模块:git submodule update --init --recursive
一定要更新子模块,不然后续运行会出错
4.执行mavgenerate.py,这是用Python语言编写的MAVLink的图形用户界面代码生成器。
python mavgenerate.py
如果没有更新子模块这一步就会出错 启动界面如下图所示 XML:选择\message_definitions\v1.0\common.xml Out :自己选择一个目录存储 Language:选择自己需要的语言 点击Generate则可.
5.在out目录下可看到文件夹mav,具体内容如下图所示
6.打开正点原子例程:实验4 串口实验
新建文件夹MAVLINK,将第五步mav文件夹下的内容复制进去
7. 打开工程新建分组,将所有拷贝过来的文件和头文件目录添加好
8.新建manlink_avoid_errors.h用来解决报错,尽量将更改添加到这个文件,方便以后移植。
后面内容主要参考[移植mavlink到stm32详细教程,后面附快速移植方法] 上面参考文章中提供的代码有部分缺少空格,如下图蓝色方框内代码 正确代码如下所示:
#ifndef MAVLINK_AVOID_ERRORS_H
#define MAVLINK_AVOID_ERRORS_H
#define MAVPACKED( __Declaration__ ) __Declaration__
#pragma anon_unions
#define inline __INLINE
#ifndef memset
static inline void*memset(void*dest,int data,size_t length)
{
uint32_t i;
int*point = dest;
for(i=0; i<length; i++) point[i]= data;
return dest;
}
#endif
#ifndef memcpy
void*memcpy(void*dest,const void*src,size_t n)
{
unsigned char*pout =(unsigned char*)dest;
unsigned char*pin =(unsigned char*)src;
while(n-->0)*pout++=*pin++;
return dest;
}
#include"mavlink_types.h"
#define MAVLINK_USE_CONVENIENCE_FUNCTIONS
#define MAVLINK_SEPARATE_HELPERS
mavlink_system_t mavlink_system ={1,1};
void comm_send_ch(mavlink_channel_t chan,uint8_t buf)
{
chan=chan;
USART_SendData(USART1, buf);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
#endif
#include"mavlink.h"
#include"mavlink_helpers.h"
#endif
9.修改main.c中代码为:
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include"mavlink_avoid_errors.h"
int main(void)
{
mavlink_heartbeat_t packet_in ={963497464,17,84,151,218,3};
mavlink_heartbeat_t packet1;
memset(&packet1,0,sizeof(packet1));
packet1.custom_mode = packet_in.custom_mode;
packet1.type = packet_in.type;
packet1.autopilot = packet_in.autopilot;
packet1.base_mode = packet_in.base_mode;
packet1.system_status = packet_in.system_status;
packet1.mavlink_version = packet_in.mavlink_version;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init();
uart_init(115200);
LED_Init();
while(1)
{
mavlink_msg_heartbeat_send(MAVLINK_COMM_1 , packet1.type , packet1.autopilot , packet1.base_mode , packet1.custom_mode , packet1.system_status );
delay_ms(1000);
}
}
10.将mavlink_conversions.h更改这一部分代码为:
可解决错误“declaration may not appear after executable statement in block”
MAVLINK_HELPER void mavlink_dcm_to_quaternion(const float dcm[3][3], float quaternion[4])
{
int i,dcm_i,dcm_j,dcm_k;
float s;
float tr = dcm[0][0] + dcm[1][1] + dcm[2][2];
if (tr > 0.0f) {
s = sqrtf(tr + 1.0f);
quaternion[0] = s * 0.5f;
s = 0.5f / s;
quaternion[1] = (dcm[2][1] - dcm[1][2]) * s;
quaternion[2] = (dcm[0][2] - dcm[2][0]) * s;
quaternion[3] = (dcm[1][0] - dcm[0][1]) * s;
} else {
dcm_i = 0;
for (i = 1; i < 3; i++) {
if (dcm[i][i] > dcm[dcm_i][dcm_i]) {
dcm_i = i;
}
}
dcm_j = (dcm_i + 1) % 3;
dcm_k = (dcm_i + 2) % 3;
s = sqrtf((dcm[dcm_i][dcm_i] - dcm[dcm_j][dcm_j] -
dcm[dcm_k][dcm_k]) + 1.0f);
quaternion[dcm_i + 1] = s * 0.5f;
s = 0.5f / s;
quaternion[dcm_j + 1] = (dcm[dcm_i][dcm_j] + dcm[dcm_j][dcm_i]) * s;
quaternion[dcm_k + 1] = (dcm[dcm_k][dcm_i] + dcm[dcm_i][dcm_k]) * s;
quaternion[0] = (dcm[dcm_k][dcm_j] - dcm[dcm_j][dcm_k]) * s;
}
}
11.将mavlink_helpers.h中更改这一部分代码为:
可解决错误“declaration may not appear after executable statement in block”
MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg)
{
uint8_t *ck;
memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
ck = buffer + (MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
ck[0] = (uint8_t)(msg->checksum & 0xFF);
ck[1] = (uint8_t)(msg->checksum >> 8);
return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len;
}
12.屏蔽mavlink_types.h中这一部分代码:
13.将common.h中更改这一部分代码为:
可解决错误literal treated as "long long"和“enumeration value is out of “int” range”
MAV_SYS_STATUS_EXTENSION_USED=(int)2147483648u,
MAV_SYS_STATUS_SENSOR_ENUM_END=(int)2147483649u,
HIL_SENSOR_UPDATED_RESET=(int)2147483648u,
HIL_SENSOR_UPDATED_FLAGS_ENUM_END=(int)2147483649u,
14.编译
15.下载到开发板打开串口调试助手
成功接收到数据,如图,表示移植成功 下图解释了每个数据位的含义
此处还有个小插曲:单片机通过usb连接到电脑后电脑无法试别,检查ch340驱动,无可卸载,预安装成功,正在束手无策之时,换了根usb线,电脑可识别了!
思考
mavlink作为一个非常可靠(至少两字节校验)、支持类型丰富(message ID、component ID等)的通信协议,每次通信时,除了payload以外,还要占用至少8个字节的冗余信息。因此在使用mavlink之前需要考虑,在硬件资源非常有限的情况下,是否有必要牺牲效率来换取可靠性?
|