本文是这篇文章的复现:http://www.sohu.com/a/213599378_175233
Mavlink 的全称是Micro Air Vehicle link,pixhawk把它作为与地面站通信的手段。有了它通信变的有序且简洁。使用需要花些心思,这里给出pixhawk飞控中arducopter代码是如何利用mavlink发送消息,并且更新xml文件通过mavlink generator生成新的消息并发送出来。
这里给出arducopter是如何发送mavlink消息的。
首先在arducopter代码上层会通过时间片管理调用多个任务,其中就包括mavlink消息的发送。
其中SCHED_TASK(gcs_data_stream_send, 50, 550)为主要的数据流发送部分
跟踪其函数到GCS_Mavlink.cpp中
void Copter::gcs_data_stream_send(void)
num_gcs为第几条数据链路,在各链路里调用函数data_stream_send()
该函数在GCS_Mavlink.cpp中,其中主要包含两个函数
一个是bool GCS_MAVLINK::stream_trigger(enum streams stream_num)这个函数作用主要是决定是否发生当前的消息的,可以理解为消息发生的管理函数,这里不做讲解了,可以看下,逻辑很好。
另一个函数void GCS_MAVLINK::send_message(enum ap_message id)这个函数就是发送消息的函数,其中的逻辑也很多,这里直接跳到最主要的部分,就是调用的try_send_message(id)函数。这个函数在/arducopter/GCS_Mavlink.cpp中,根据形参id来决定跳转到发送哪条消息。例如ahrs消息。
当形参id=MSG_AHRS时,即会调用 send_ahrs(copter.ahrs)函数,这个函数的实体在GCS_Common.cpp中
在里面调用了另一个函数mavlink_msg_ahrs_send,这个就有些特殊了,可以看它的实体在一个头文件Mavlink_msg_ahrs_send.h中,说它特殊是因为它不是开发者自己编写的,是通过xml文件自动生成的,所以会在头文件当中。
之后的事情不用我们管了,到这一步已够了,下面的简单看下。
mavlink_msg_ahrs_send()会把要传输的变量生成buf或者pack,然后通过
_mav_finalize_message_chan_send()把消息buf或pack通过串口传出去,怎么传的咱就不管了。
到这里基本就清楚了arducopter是怎么把一条mavlink消息传出来的。首先要生成mavlink消息库,库里会把变量安相应协议生成mavlink消息,然后通过时间片管理与函数调用直到把消息库里的函数调用。
原有的xml文件在
ardupilotmodulesmavlinkmessage_definitionsv1.0文件夹下有ardupilotmega.xml与common.xml文件,两个文件是互补的,可以看里面的id号是不冲突的,再哪个里面加新的消息都可以。下面我们来添加一条新的mavlink消息。
想添加自定义mavlink消息首先需要生成一个新的mavlink库。
打开/modules/mavlink/message_definitions/v1.0/ardupilotmega.xml文件,找到没有使用的id号,添加自定义的变量,如图片所示
然后通过mavlink generator生成新的库,方法如下:
运行该软件 指令是 python -m mavgenerate
填写xml路径与要生成库的路径,语言选C,然后生成就行了。成功后去库里找你要的头文件。
圈起来的文件就是自动生成的,把这个文件考到arducopter文件原库下,库的地址是
ardupilot/Build.ArduCopter/libraries/GCS_MAVLink/include/mavlink/v2.0/ardupilotmega/
之后就简单了,按原方式调用及可,这里给出个简单的方法。
在ardupilot/libraries/GCS_MAVLink/GCS.h中声明一个自定义函数如:void send_chengcong(void)
在GCS_Common.cpp中写函数的实体
void GCS_MAVLINK::send_chengcong(void)
{
mavlink_msg_cheng_cong_send(chan, 0x0b,0x0b,0x0b,0x0b);
}
0x0b,0x0b,0x0b,0x0b为测试数据,方便在消息中查找。
然后将send_chengcong(void) 函数在ardupilot/arducopter/GCS_Mavlink.cpp中的try_send_message函数的任一个case中调用即可:
至此代码完毕,接下来编译测试即可,测试及在输出的mavlink消息中寻找我们定义的0x0b,0x0b,0x0b,0x0b数据。
需要将飞控先与mission planner连接,否则一直发应答包,不会发数据包,检测不到。与地面站连接后,关闭地面站,打开串口调试助手获取16进制数据,保持成txt文件,在里面查找验证即可。下图是我验证的: