pymavlink
Pymavlink是MAVLink协议的python实现。 自身包括一个源代码生成器(generator / mavgen.py),用于为其他编程语言创建MAVLink协议实现。 还包含用于分析飞行日志的工具。
主要包含的模块
- mavutil: 用于设置通信链接,接收和解码消息,运行定期任务等.
- mavwp: 用于加载/保存航点,地理围栏等.
- mavparm: 用于加载/保存MAVLink 的参数.
- mavextra: 用于转换单位和消息的工具。
- mavexpression (internal): MAVLink表达式评估的一些函数.
连接
首先是进行连接, 因为我用的是模拟器所以用udp进行连接并获取心跳包
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口号
master.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (
self._master.target_system, self._master.target_system))
连接上了以后可以通过recv_match
获取消息
msg = master.recv_match(type='ATTITUDE', blocking=True)
其中type
是你要获取的消息的类型,可以是单个消息,也可以是一组消息,组消息用[]
即可,blocking
是该消息是否阻塞,即在收到type
类的消息前一直等待.msg
可以使用to_dict()
将其变成dict
样例
不停接收UAV的ATTITUDE
消息
from pymavlink import mavutil
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口号
master.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (
self._master.target_system, self._master.target_system))
while True:
try:
msg = master.recv_match(type='ATTITUDE', blocking=True)
if not msg:
raise ValueError()
print(msg.to_dict())
except KeyboardInterrupt:
print('Key bordInterrupt! exit')
break
设置任务
在使用自动航点模式的时候,需要上传自己的mission,mission的格式标注可参考mavlink手册,这里简单举例:
QGC WPL 110
0 1 0 16 0 0 0 0 40.072842 -105.230575 0.000000 1
1 0 3 22 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 10.000000 1
2 0 3 16 5.00000000 0.00000000 0.00000000 0.00000000 40.07351510 -105.23148180 20.000000 1
3 0 3 203 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.000000 1
4 0 3 16 1.00000000 0.00000000 0.00000000 0.00000000 40.07251400 -105.23154400 20.000000 1
5 0 3 16 0.00000000 0.00000000 0.00000000 0.00000000 40.07251400 -105.23154400 3.000000 1
6 0 3 178 1.00000000 5.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.000000 1
7 0 3 16 0.00000000 0.00000000 0.00000000 0.00000000 40.07254400 -105.23135400 3.000000 1
8 0 3 16 0.00000000 0.00000000 0.00000000 0.00000000 40.07260900 -105.23128500 5.000000 1
9 0 3 16 0.00000000 0.00000000 0.00000000 0.00000000 40.07284500 -105.23057600 5.000000 1
上传waypoint主要是用mavwp
首先加载mossion的waypoint
loader = mavwp.MAVWPLoader()
loader.load('mission.txt') # load mission
根据需要是否清空UAV自身的waypoint
, master
是上面提到的连接
master.waypoint_clear_all_send() # need connect the uav at first!
使用'master.mav.send'向UAV发送waypoint
内容
master.waypoint_count_send(loader.count())
try:
# looping to send each waypoint information
for i in range(loader.count()):
msg = self._master.recv_match(type=['MISSION_REQUEST'], blocking=True, timeout=timeout)
master.mav.send(loader.wp(msg.seq))
print('Sending waypoint {0}'.format(msg.seq))
mission_ack_msg = self._master.recv_match(type=['MISSION_ACK'], blocking=True, timeout=timeout)
except TimeoutError:
print('upload mission timeout')
样例
from pymavlink import mavutil, mavwp
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口号
master.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (
self._master.target_system, self._master.target_system))
loader = mavwp.MAVWPLoader()
loader.load('mission.txt') # load mission
master.waypoint_count_send(loader.count())
try:
# looping to send each waypoint information
for i in range(loader.count()):
msg = self._master.recv_match(type=['MISSION_REQUEST'], blocking=True, timeout=timeout)
master.mav.send(loader.wp(msg.seq))
print('Sending waypoint {0}'.format(msg.seq))
mission_ack_msg = self._master.recv_match(type=['MISSION_ACK'], blocking=True, timeout=timeout)
except TimeoutError:
print('upload mission timeout')
更改飞行参数param
飞控的全部飞行参数为Full Parameter List of Copter latest V4.0.4 dev
mavutil
可以直接读取UAV的参数.
master.param_fetch_all() # read all param| need connect the uav at first!
master.param_fetch_one(name) # read one param | need connect the uav at first!
mavutil
提供了直接设置参数的函数.
master.param_set_send(param, value) # need connect the uav at first!
param是参数的名称, value是具体的值
样例
读取
from pymavlink import mavutil
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口号
master.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (
self._master.target_system, self._master.target_system))
param = 'PSC_POSXY_P'
master.param_fetch_one(param) # need connect the uav at first!
message = self._master.recv_match(type='PARAM_VALUE', blocking=True).to_dict()
print('name: %s\t value: %f' % (message['param_id'], message['param_value']))
设置
from pymavlink import mavutil
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口号
master.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (
self._master.target_system, self._master.target_system))
param = 'PSC_POSXY_P'
value = 1
master.param_set_send(param, value)
message = self._master.recv_match(type='PARAM_VALUE', blocking=True).to_dict()
print('name: %s\t value: %f' % (message['param_id'], message['param_value']))
飞行模式
mavutil
同样可以直接改变UAV的飞行模式
设置为loiter
master.set_mode_loiter()
解锁 uav
master.arducopter_arm()
设置为auto模式
master.set_mode_auto()
这里举几个例子, 切换成其他模式就不一一展示了.
这里要注意的是在auto模式下是无法arm解锁的, 需要切换成其他模式解锁.
总结
最近正好使用pymavlink进行开发, 但是官方给的文档有些不完善, 内容有些老旧, 因此自己看源码找了总结了一些实际的使用方法.