python实现自定义MavlinK协议消息发送

一心想要写个python的发送mavlink协议的自定义消息的程序,网上资源太少微乎其微。于是去mavlink的官方仔细研读终于实现了。

先挂一个mavlink官方网址https://mavlink.io/

1.先通过pip安装pymavlink的官方库:pip install pymavlink

其他还需安装的依赖库有pyserial(串口连接依赖库),安装future库(异步执行操作库)

 

2.生成自定义mavlink消息依赖库这个网上有教程贴个图,是这个:

 

 

3.生成自定义后的python依赖文件后将文件放入到安装的pymavlink的路径下的dialects文件夹下

pymavlink的路径如图

dialects文件结构如图,放v10或者v20文件夹下都可以,一般1.0的mavlink放v10,2.0的mavlink放v20

 

 

4.在pymavlink的文件路径中找到工具类mavutil

在mavutil类的最前面加上:

os.environ['MAVLINK_DIALECT'] = "自定义生成,刚才拷贝进pymavlink路径的python依赖文件"
os.environ["MAVLINK20"] = "2.0"

#示例:
#os.environ['MAVLINK_DIALECT'] = "mavlink"
#os.environ["MAVLINK20"] = "2.0"
#比如使用mavlink的生成工具生成的库名字为mavlink.py,此处添加只能用mavlink,不然出现以下报错
ModuleNotFoundError: No module named 'pymavlink.dialects.v20.mavlink.py'; 'pymavlink.dialects.v20.mavlink' is not a package也就是评论1的报错

 

在mavutil类中以下两个代码片段实现将默认的v1.0中的ardupilotmega  mavlink协议引入工具类mavutil,调用mavutil类时默认的收发解析时调用的即为v1.0中ardupilotmega

在加入以上代码片段后在工具类mavutil中即引入的为v2.0中拷贝的自定义生成的自定义mavlink消息协议。

if not 'MAVLINK_DIALECT' in os.environ:
    os.environ['MAVLINK_DIALECT'] = 'ardupilotmega'
def set_dialect(dialect):
    '''set the MAVLink dialect to work with.
    For example, set_dialect("ardupilotmega")
    '''
    global mavlink, current_dialect
    from .generator import mavparse
    if 'MAVLINK20' in os.environ:
        wire_protocol = mavparse.PROTOCOL_2_0
        modname = "pymavlink.dialects.v20." + dialect
    elif mavlink is None or mavlink.WIRE_PROTOCOL_VERSION == "1.0" or not 'MAVLINK09' in os.environ:
        wire_protocol = mavparse.PROTOCOL_1_0
        modname = "pymavlink.dialects.v10." + dialect
    else:
        wire_protocol = mavparse.PROTOCOL_0_9
        modname = "pymavlink.dialects.v09." + dialect

    try:
        mod = __import__(modname)
    except Exception:
        # auto-generate the dialect module
        from .generator.mavgen import mavgen_python_dialect
        mavgen_python_dialect(dialect, wire_protocol)
        mod = __import__(modname)
    components = modname.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    current_dialect = dialect
    mavlink = mod

# Set the default dialect. This is done here as it needs to be after the function declaration
set_dialect(os.environ['MAVLINK_DIALECT'])

 

5,在需要调用mavlink的类中引入mavlink的工具类mavutil,该工具类实现了很多mavlink的通用方法,如各种串口,udp,tcp的连接方法,即可调用类mavutil进行连接,消息收发解析等

from pymavlink import mavutil


//建立mavlink协议连接
the_connection2 = mavutil.mavlink_connection(('udp:127.0.0.1:20'))
一些连接的字符串示例
连接类型连接字符串
通过USB连接到车辆的Linux计算机/ dev / ttyUSB0
通过串行端口连接到车辆的Linux计算机(以RaspberryPi为例)/ dev / ttyAMA0(还设置了baud = 57600)
MAVLink API通过UDP监听SITL连接udpin:localhost:14540(或udp:localhost:14540、127.0.0.1:14540等)
MAVLink API通过UDP启动到SITL的连接udpout:localhost:14540(或udpout:127.0.0.1:14540)
GCS通过UDP连接到车辆127.0.0.1:14550或udp:localhost:14550
通过TCP连接到车辆的SITLtcp:127.0.0.1:5760(仅ArduPilot,PX4不支持TCP)
通过USB连接到车辆的OSX计算机dev / cu.usbmodem1
Windows计算机通过USB连接到车辆(在本例中为COM14)com14
Windows计算机使用COM14上的3DR遥测无线电连接到车辆com14(还设置了baud = 57600)

两台电脑之间连接示例:

python端:

远程端:

 

6.调用发送mavutil发送消息,以下代码段中如果没有进行第4步操作则the_connection2中的mav实列为默认的ardupilotmega协议类,若进行修改则为自定义生成的mavlink协议类

//发送心跳包
the_connection2.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_ONBOARD_CONTROLLER,
                                   mavutil.mavlink.MAV_AUTOPILOT_INVALID, 1, 0, 0)

 

7.在the_connection2中的mav实列即自定义生成的mavlink协议类中包含所有xml中定义的消息收发接收解析方法,直接调用即可

部分接收消息函数截图:

 

8.消息接收

例如,使用the_connection的设置,可以等待任何消息,如下所示:

msg = the_connection.recv_match(blocking=True) #blocking参数为是否阻塞

并且在尝试解析该消息之前检查该消息是否有效:

msg = m.recv_match(type='SYS_STATUS',blocking=True)
if not msg:
    return
if msg.get_type() == "BAD_DATA":
    if mavutil.all_printable(msg.data):
        sys.stdout.write(msg.data)
        sys.stdout.flush()
else:
    #Message is valid
    # Use the attribute
    print('Mode: %s' % msg.mode)

 

请求多条指定消息

msg = the_connection2.recv_match(type=['HEARTBEAT','OPTITRACK_POSITION','TARGET_INFORMATION'], blocking=True) 

请求一条指定消息

msg = the_connection2.recv_match(type='HEARTBEAT', blocking=True) 

 

### 如何在PX4中自定义MAVLink消息协议 #### 背景介绍 PX4 是一种开源的飞行控制系统框架,广泛应用于无人机开发领域。它对 MAVLink 协议的支持非常全面,允许开发者通过 GCS 控制无人机并接收来自无人机的数据[^2]。然而,在某些特殊应用场景下,可能需要扩展或修改现有的 MAVLink 消息集以满足特定需求。 以下是关于如何在 PX4 中实现自定义 MAVLink 消息协议的具体方法: --- #### 1. 修改 MAVLink XML 文件 MAVLink 使用基于 XML 的文件来描述消息结构。这些文件通常位于 `mavlink/message_definitions/v1.0` 目录下。要创建新的自定义消息,需按照以下步骤操作: - **新增 XML 条目** 在对应的 XML 文件中添加一个新的 `<message>` 元素。例如: ```xml <message id="200" name="CUSTOM_MESSAGE"> <field type="uint8_t" name="custom_param">Custom parameter</field> <field type="float" name="value">Value to be sent</field> </message> ``` 此处的消息 ID (`id`) 需要在现有范围之外分配,以免冲突。 - **重新生成头文件** 添加新消息后,运行以下命令以更新 MAVLink 头文件: ```bash cd Tools/mavlink_gens/ ./regenerate_uorb.sh ``` 这一步会自动解析 XML 并生成 C/C++ 和 Python 接口所需的代码[^3]。 --- #### 2. 实现发送与接收逻辑 完成上述配置后,可以在 PX4 固件中集成自定义消息的处理逻辑。 - **发送端** 如果希望从地面站向无人机发送自定义消息,则可以通过 MAVLink 库调用相应函数。例如: ```c++ mavlink_message_t msg; uint8_t system_id = 1, component_id = 1; mavlink_msg_custom_message_pack(system_id, component_id, &msg, custom_param_value, float_value); mavlink_send_uart(MAVLINK_COMM_0, &msg); ``` - **接收端** 对于接收到的自定义消息,可在 PX4 的 UORB 主题订阅器中注册回调函数进行处理。例如: ```cpp void handle_custom_message(const mavlink_message_t* msg) { if (msg->msgid == MAVLINK_MSG_ID_CUSTOM_MESSAGE) { mavlink_custom_message_t parsed_msg; mavlink_msg_custom_message_decode(msg, &parsed_msg); // Process the message fields here printf("Received Custom Param: %d\n", parsed_msg.custom_param); } } register_mavlink_handler(handle_custom_message); ``` --- #### 3. 测试与验证 为了确保自定义消息能够正常工作,建议执行以下测试流程: - **静态分析** 确认生成的头文件是否包含预期字段,并检查编译过程中是否存在错误或警告。 - **动态调试** 利用 QGroundControl 或其他支持 MAVLink 的地面站软件模拟通信过程,观察自定义消息的实际传输效果。 --- #### 注意事项 - 自定义消息可能会增加系统的复杂度,因此应谨慎评估其必要性和潜在影响。 - 若计划与其他团队共享固件版本,请提前协商一致的消息命名空间和编号方案,防止重复定义引发冲突[^1]。 --- ```python def generate_mavlink_message(custom_param, value): """ 构造一个简单的 MAVLink 自定义消息实例。 :param custom_param: int 类型参数 :param value: float 类型数值 :return: 字典形式表示的消息体 """ return {"custom_param": custom_param, "value": value} ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值