# GCS linkmavlink start -x -u $udp_gcs_port_local -r 4000000 -fmavlink stream -r 50 -s POSITION_TARGET_LOCAL_NED -u $udp_gcs_port_localmavlink stream -r 50 -s LOCAL_POSITION_NED -u $udp_gcs_port_localmavlink stream -r 50 -s GLOBAL_POSITION_INT -u $udp_gcs_port_localmavlink stream -r 50 -s ATTITUDE -u $udp_gcs_port_localmavlink stream -r 50 -s ATTITUDE_QUATERNION -u $udp_gcs_port_localmavlink stream -r 50 -s ATTITUDE_TARGET -u $udp_gcs_port_localmavlink stream -r 50 -s SERVO_OUTPUT_RAW_0 -u $udp_gcs_port_localmavlink stream -r 20 -s RC_CHANNELS -u $udp_gcs_port_localmavlink stream -r 10 -s OPTICAL_FLOW_RAD -u $udp_gcs_port_local# API/Offboard linkmavlink start -x -u $udp_offboard_port_local -r 4000000 -f -m onboard -o $udp_offboard_port_remote# Onboard link to cameramavlink start -x -u $udp_onboard_payload_port_local -r 4000 -f -m onboard -o $udp_onboard_payload_port_remote# Onboard link to gimbalmavlink start -x -u $udp_onboard_gimbal_port_local -r 400000 -m gimbal -o $udp_onboard_gimbal_port_remote
https://mavlink.io/zh/messages/common.html
可根据官网示例,生成mavlink依赖协议。如下

(2)开发外部程序插件
通过调用mavlink底层协议,开发控制函数,如下
staticvoidsend_mavlink_msg(constmavlink_message_t &msg){uint8_t buffer[MAVLINK_MAX_PACKET_LEN];uint16_t len = mavlink_msg_to_send_buffer(buffer, &msg);// udp_multicast::send_multicast(buffer, len);udp_unicast::send_unicast(buffer, len);}voidsend_heartbeat(){mavlink_message_t msg;mavlink_msg_heartbeat_pack_chan(GCS_SYS_ID, GCS_COMP_ID, MAVLINK_CHAN, &msg,MAV_TYPE_ONBOARD_CONTROLLER, MAV_AUTOPILOT_GENERIC,0, 0, MAV_STATE_ACTIVE);send_mavlink_msg(msg);}voidset_mode(uint32_t mode){mavlink_message_t msg;mavlink_msg_command_long_pack_chan(GCS_SYS_ID, GCS_COMP_ID, MAVLINK_CHAN, &msg,TARGET_SYS_ID, TARGET_COMP_ID,MAV_CMD_COMPONENT_ARM_DISARM, 0,1, 0, 0, 0, 0, 0, 0 // param1=1 解锁);send_mavlink_msg(msg);std::this_thread::sleep_for(500ms); // 等待解锁生效mavlink_msg_command_long_pack_chan(GCS_SYS_ID, GCS_COMP_ID, MAVLINK_CHAN, &msg,TARGET_SYS_ID, TARGET_COMP_ID,MAV_CMD_DO_SET_MODE, 0,MAV_MODE_FLAG_CUSTOM_MODE_ENABLED, // param1:启用自定义模式PX4_CUSTOM_MODE_GUIDED, // param2:PX4 GUIDED 模式0, 0, 0, 0, 0);send_mavlink_msg(msg);}voidtakeoff(float altitude){set_mode(0);std::this_thread::sleep_for(1s);mavlink_message_t msg;mavlink_msg_command_long_pack_chan(GCS_SYS_ID, GCS_COMP_ID, MAVLINK_CHAN, &msg,TARGET_SYS_ID, TARGET_COMP_ID,MAV_CMD_NAV_TAKEOFF, 0,0, 0, 0, 0, 0, 0, altitude);send_mavlink_msg(msg);}voidupload_mission(const Waypoint *waypoints, size_t count){// 1. 发送航点数量mavlink_message_t msg;mavlink_msg_mission_count_pack_chan(GCS_SYS_ID, GCS_COMP_ID, MAVLINK_CHAN, &msg,TARGET_SYS_ID, TARGET_COMP_ID,count, MAV_MISSION_TYPE_MISSION, 0);send_mavlink_msg(msg);// 2. 逐个发送航点for (size_t i = 0; i < count; ++i){const Waypoint &wp = waypoints[i];mavlink_msg_mission_item_int_pack_chan(GCS_SYS_ID, GCS_COMP_ID, MAVLINK_CHAN, &msg,TARGET_SYS_ID, TARGET_COMP_ID,wp.seq, wp.frame, wp.cmd, wp.current, wp.autocontinue,wp.param1, wp.param2, wp.param3, wp.param4,static_cast<int32_t>(wp.lat * 1e7), // 转换为INT32 1e7度static_cast<int32_t>(wp.lon * 1e7),wp.alt, MAV_MISSION_TYPE_MISSION);send_mavlink_msg(msg);}}
(3)在你的外部程序启动通讯,然后把你在外部程序部署的软件,比如集群管理、避障、导航等智能软件的控制输出通过你写的mavlink函数输出到飞控上。
三、实践效果


1.以PX4仿真为例,启动固定翼和复合翼模型,然后加载外部智能软件,通过网络通讯,把规划生成的控制指令通过此插件发送到px4飞控上。
2. 比如我们测试航线装订,通过mavlink的航线装订函数,我们把规划的航线进行装订,装订注意航点数量和属性和地面站装订形式保持一致。在你的开发的插件上也要装订如下航点。

3.你的智能软件航线规划好,实现航线装订和飞行



4.最后实现的效果是你可以通过外部智能软件对集群飞机进行航线控制,效果等同于你通过单机地面站对每架飞机进行航线装订

后续我们会继续分享 PX4 自定义模块开发、ROS2 与 PX4 通信、自主避障算法开发、多机集群控制等进阶内容,欢迎关注我的公众号,第一时间获取最新的无人机开发干货。
同时我们有无人机开发爱好者群聊,汇聚开发者们共同交流技术心得,欢迎加入~


夜雨聆风