为了成功转发 MAVLink,需要做一些事情。我假设您需要与 GCS 的可用连接,例如 QGroundControl 或 MissionPlanner。我使用 QGC,我的设计对其进行了基本测试。
请注意,这是用 Python3 编写的。这个片段没有经过测试,但我有一个(更复杂的)版本经过测试和工作。
from pymavlink import mavutil
import time
# PyMAVLink has an issue that received messages which contain strings
# cannot be resent, because they become Python strings (not bytestrings)
# This converts those messages so your code doesn't crash when
# you try to send the message again.
def fixMAVLinkMessageForForward(msg):
msg_type = msg.get_type()
if msg_type in ('PARAM_VALUE', 'PARAM_REQUEST_READ', 'PARAM_SET'):
if type(msg.param_id) == str:
msg.param_id = msg.param_id.encode()
elif msg_type == 'STATUSTEXT':
if type(msg.text) == str:
msg.text = msg.text.encode()
return msg
# Modified from the snippet in your question
# UDP will work just as well or better
gcs_conn = mavutil.mavlink_connection('tcp:localhost:15795', input=False)
gcs_conn.wait_heartbeat()
print(f'Heartbeat from system (system {gcs_conn.target_system} component {gcs_conn.target_system})')
vehicle = mavutil.mavlink_connection('tcp:localhost:5760')
vehicle.wait_heartbeat()
print(f'Heartbeat from system (system {vehicle.target_system} component {vehicle.target_system})')
while True:
# Don't block for a GCS message - we have messages
# from the vehicle to get too
gcs_msg = gcs_conn.recv_match(blocking=False)
if gcs_msg is None:
pass
elif gcs_msg.get_type() != 'BAD_DATA':
# We now have a message we want to forward. Now we need to
# make it safe to send
gcs_msg = fixMAVLinkMessageForForward(gcs_msg)
# Finally, in order to forward this, we actually need to
# hack PyMAVLink so the message has the right source
# information attached.
vehicle.mav.srcSystem = gcs_msg.get_srcSystem()
vehicle.mav.srcComponent = gcs_msg.get_srcComponent()
# Only now is it safe to send the message
vehicle.mav.send(gcs_msg)
print(gcs_msg)
vcl_msg = vehicle.recv_match(blocking=False)
if vcl_msg is None:
pass
elif vcl_msg.get_type() != 'BAD_DATA':
# We now have a message we want to forward. Now we need to
# make it safe to send
vcl_msg = fixMAVLinkMessageForForward(vcl_msg)
# Finally, in order to forward this, we actually need to
# hack PyMAVLink so the message has the right source
# information attached.
gcs_conn.mav.srcSystem = vcl_msg.get_srcSystem()
gcs_conn.mav.srcComponent = vcl_msg.get_srcComponent()
gcs_conn.mav.send(vcl_msg)
print(vcl_msg)
# Don't abuse the CPU by running the loop at maximum speed
time.sleep(0.001)
笔记
确保您的循环没有被阻塞
循环必须快速检查消息是否可从一个连接或另一个连接获得,而不是等待消息可从单个连接获得。否则,在阻塞连接有消息之前,另一个连接上的消息将不会通过。
检查消息有效性
检查您是否确实收到了有效消息,而不是 BAD_DATA 消息。尝试发送 BAD_DATA 将崩溃
确保收件人获得有关发件人的正确信息
默认情况下,PyMAVLink 在发送消息时会编码您的系统和组件 ID(通常为零),而不是消息中的 ID。接收到此消息的 GCS 可能会混淆(即 QGC)并且无法正确连接到车辆(尽管在 MAVLink 检查器中显示消息)。
这可以通过破解 PyMAVLink 来解决,这样您的系统和组件 ID 就可以匹配转发的消息。如有必要,可以在发送消息后对其进行崇敬。请参阅示例以了解我是如何做到的。
循环更新率
更新速率足够快以处理高流量条件(尤其是下载参数)很重要,但它也不应该与 CPU 挂钩。我发现 1000hz 的更新率足够好。