pymavlink
Pymavlink是MAVLink協(xié)議的python實(shí)現(xiàn)。 自身包括一個(gè)源代碼生成器(generator / mavgen.py),用于為其他編程語言創(chuàng)建MAVLink協(xié)議實(shí)現(xiàn)。 還包含用于分析飛行日志的工具。
主要包含的模塊
- mavutil: 用于設(shè)置通信鏈接,接收和解碼消息,運(yùn)行定期任務(wù)等.
- mavwp: 用于加載/保存航點(diǎn),地理圍欄等.
- mavparm: 用于加載/保存MAVLink 的參數(shù).
- mavextra: 用于轉(zhuǎn)換單位和消息的工具。
- mavexpression (internal): MAVLink表達(dá)式評(píng)估的一些函數(shù).
連接
首先是進(jìn)行連接, 因?yàn)槲矣玫氖悄M器所以用udp進(jìn)行連接并獲取心跳包
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口號(hào)
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是你要獲取的消息的類型,可以是單個(gè)消息,也可以是一組消息,組消息用[]即可,blocking 是該消息是否阻塞,即在收到type類的消息前一直等待.msg可以使用to_dict()將其變成dict
樣例
不停接收UAV的ATTITUDE消息
from pymavlink import mavutil
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口號(hào)
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
設(shè)置任務(wù)
在使用自動(dòng)航點(diǎn)模式的時(shí)候,需要上傳自己的mission,mission的格式標(biāo)注可參考mavlink手冊(cè),這里簡(jiǎn)單舉例:
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
根據(jù)需要是否清空UAV自身的waypoint, master是上面提到的連接
master.waypoint_clear_all_send() # need connect the uav at first!
使用'master.mav.send'向UAV發(fā)送waypoint內(nèi)容
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 是端口號(hào)
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')
更改飛行參數(shù)param
飛控的全部飛行參數(shù)為Full Parameter List of Copter latest V4.0.4 dev
mavutil可以直接讀取UAV的參數(shù).
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提供了直接設(shè)置參數(shù)的函數(shù).
master.param_set_send(param, value) # need connect the uav at first!
param是參數(shù)的名稱, value是具體的值
樣例
讀取
from pymavlink import mavutil
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口號(hào)
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']))
設(shè)置
from pymavlink import mavutil
master = mavutil.mavlink_connection('udp:0.0.0.0:{}'.format(port))# port 是端口號(hào)
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的飛行模式
設(shè)置為loiter
master.set_mode_loiter()
解鎖 uav
master.arducopter_arm()
設(shè)置為auto模式
master.set_mode_auto()
這里舉幾個(gè)例子, 切換成其他模式就不一一展示了.
這里要注意的是在auto模式下是無法arm解鎖的, 需要切換成其他模式解鎖.
總結(jié)
最近正好使用pymavlink進(jìn)行開發(fā), 但是官方給的文檔有些不完善, 內(nèi)容有些老舊, 因此自己看源碼找了總結(jié)了一些實(shí)際的使用方法.