如何向APM四旋翼无人机发送样条航点?C# WinForms实现求助
看起来你已经搞定了解锁/上锁的核心功能,卡在样条航点发送上大概率是参数设置或者流程细节的小问题。我先帮你排查下现有代码的潜在问题,再给一个完整的WinForms按钮点击发送示例:
先说说你现有代码可能的坑点
- 遗漏关键参数:
MAV_CMD_NAV_SPLINE_WAYPOINT要求设置param2(速度比例,-1表示用飞控默认速度,0.0~1.0是相对最大速度的比例)和param3(过渡类型,0=常规过渡,1=平滑过渡),你的代码里没配置这两个参数,飞控可能直接忽略这条指令。 - 目标组件ID可能错误:多数飞控的组件ID(
target_component)是50(飞控专属组件),而不是1,你可以先确认无人机的系统ID和组件ID是否匹配。 - 未切换到任务模式:无人机需要处于AUTO模式才能执行航点任务,发送航点前最好先切换到AUTO模式确保指令能被执行。
完整的WinForms按钮点击示例代码
下面是一个可直接复用的按钮点击事件,包含模式切换、航点构建、数据包发送的完整流程:
using System; using System.Windows.Forms; using MAVLink; namespace MiniGCS { public partial class MainGCSForm : Form { // 假设你已经初始化了串口对象,根据实际配置调整端口、波特率 private SerialPort _droneSerialPort; public MainGCSForm() { InitializeComponent(); // 初始化串口(示例配置,替换成你的实际参数) _droneSerialPort = new SerialPort("COM3", 57600); _droneSerialPort.Open(); } private void btnSendSplineWaypoint_Click(object sender, EventArgs e) { try { // 第一步:先切换到AUTO模式(可选但强烈建议,确保飞控进入任务执行状态) SendModeSwitchCommand(1, 50, MAV_MODE.MAV_MODE_AUTO_ARMED); // 第二步:构建样条航点指令 mavlink_command_long_t splineWaypointCmd = new mavlink_command_long_t(); splineWaypointCmd.target_system = 1; // 无人机系统ID,根据实际调整 splineWaypointCmd.target_component = 50; // 飞控组件ID,通常为50 splineWaypointCmd.command = (ushort)MAV_CMD.MAV_CMD_NAV_SPLINE_WAYPOINT; splineWaypointCmd.confirmation = 0; // 0为首次发送,1为重复确认 // 参数详细说明 splineWaypointCmd.param1 = 0; // 航点停留时间(秒),0表示不停留 splineWaypointCmd.param2 = -1; // 速度比例:-1使用飞控默认速度,0.0~1.0为相对最大速度比例 splineWaypointCmd.param3 = 1; // 过渡类型:1=平滑过渡,0=常规硬过渡 splineWaypointCmd.param4 = 0; // 偏航角(度),0表示沿航线自动调整方向 splineWaypointCmd.param5 = 37.7749f; // 目标纬度(示例值,替换成你的实际坐标) splineWaypointCmd.param6 = -122.4194f; // 目标经度(示例值,替换成你的实际坐标) splineWaypointCmd.param7 = 10f; // 目标高度(米,注意是相对高度还是绝对MSL高度,和飞控设置一致) // 第三步:生成MAVLink v1.0数据包 MAVLink.MavlinkWrite mavWriter = new MAVLink.MavlinkWrite(); byte[] packet = mavWriter.GenerateMAVLinkPacket10(MAVLINK_MSG_ID.COMMAND_LONG, splineWaypointCmd); // 第四步:发送数据包到串口 _droneSerialPort.Write(packet, 0, packet.Length); MessageBox.Show("样条航点已成功发送!"); } catch (Exception ex) { MessageBox.Show($"发送失败:{ex.Message}"); } } // 辅助方法:发送模式切换指令 private void SendModeSwitchCommand(byte targetSysId, byte targetCompId, MAV_MODE targetMode) { mavlink_command_long_t modeCmd = new mavlink_command_long_t(); modeCmd.target_system = targetSysId; modeCmd.target_component = targetCompId; modeCmd.command = (ushort)MAV_CMD.MAV_CMD_DO_SET_MODE; modeCmd.param1 = (float)MAV_MODE_FLAG.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED; modeCmd.param2 = (float)targetMode; MAVLink.MavlinkWrite mavWriter = new MAVLink.MavlinkWrite(); byte[] packet = mavWriter.GenerateMAVLinkPacket10(MAVLINK_MSG_ID.COMMAND_LONG, modeCmd); _droneSerialPort.Write(packet, 0, packet.Length); } } }
额外注意事项
- 飞控兼容性:确保你的无人机飞控(比如Pixhawk系列)固件支持
MAV_CMD_NAV_SPLINE_WAYPOINT指令,部分旧版本固件可能不支持该功能。 - 参数单位:纬度/经度是度,高度是米,注意飞控设置的是相对起飞点高度还是绝对MSL高度。
- ACK确认:生产环境中建议监听飞控返回的
COMMAND_ACK消息,确认指令被成功接收并执行,避免重复发送。 - 串口配置:务必保证串口的波特率、数据位、停止位、奇偶校验和飞控完全匹配,否则数据包会丢失或乱码。
内容的提问来源于stack exchange,提问作者Ala'a Hassan
相关产品推荐
相关产品推荐

