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)" % (
master.target_system, 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)" % (
master.target_system, 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)" % (
master.target_system, 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進行開發, 但是官方給的文檔有些不完善, 內容有些老舊, 因此自己看源碼找了總結了一些實際的使用方法.