跳到主要内容

swarm_api API 接口说明

快速查阅手册。理解设计原理与教学请读 SwarmCore 集群控制框架(swarm_api)使用说明与教程。 对应版本:swarm_api 0.1.0(2026-07-27)


目录


全局约定

from swarm_api import (
Swarm, SwarmError, # 集群控制(推荐入口)
Drone, DroneError, # 单机控制
Strategy, # 策略插件基类
discover_namespaces, # 发现在线飞机
enu_to_ned, yaw_enu_to_ned, # 坐标转换工具
)
约定
坐标系ENU:x=东,y=北,z=上(框架不接受 NED)
位置单位米(m)
航向 yaw弧度,0=东,逆时针为正
速度单位m/s;航向角速度 rad/s,逆时针为正
默认到达容差 tol0.3 m(水平与垂直分别判定,同时满足)
默认超时 timeout60 s
设定点流后台线程 20Hz 自动维持(takeoff 后启动,land 后停止)
状态轮询周期0.1 s
线程安全动作函数可从算法线程直接调用;不要多线程并发调用同一飞机的 goto

Drone 类

单机控制句柄。构造时启动订阅线程与设定点流线程;所有动作阻塞式(除注明外),失败抛 DroneError

构造

Drone(namespace, sys_id=None)
参数类型说明
namespacestr飞机命名空间,如 "uav_1"
sys_idint, 可选MAV_SYS_ID,缺省从命名空间尾部数字推断(uav_2→2,推不出→1)

状态属性(只读,实时更新)

属性类型说明
postuple(float,3) 或 NoneENU 位置 (x, y, z);无数据时为 None
yawfloatENU 航向(rad)
armedbool是否已解锁
offboardbool是否处于 Offboard 模式
nsstr命名空间
sys_idintMAV_SYS_ID

takeoff

takeoff(alt=1.5, tol=0.3, timeout=60.0)

起飞到相对高度并悬停。目标高度 = 起飞前实测高度 + alt(自动规避 EKF 高度原点偏差)。内部流程:等待飞控数据(≤10s)→ 预发设定点流 1s → 循环重发"切 Offboard + 解锁"命令直到生效 → 爬升到目标高度。

参数默认说明
alt1.5相对爬升高度(m)
tol0.3到达容差(m)
timeout60.0覆盖"切模式+解锁+爬升"全过程(s)

返回:无(到位后返回)。抛出:DroneError(无飞控数据 / 解锁超时 / 爬升超时)。

goto

goto(x, y, z, yaw=None, tol=0.3, timeout=60.0)

飞到 ENU 点 (x, y, z),到达(水平与垂直误差均 < tol)后返回。飞行中飞控 failsafe 接管(Offboard 丢失 >2s)会立即抛错而非等待超时。

参数默认说明
x, y, zENU 目标点(m)
yawNoneENU 航向(rad);None = 保持当前航向
tol0.3到达容差(m)
timeout60.0超时抛 DroneError,飞机仍在目标点悬停

前置:必须先 takeoff()(否则立即抛 DroneError)。

set_velocity

set_velocity(vx, vy, vz, yaw_rate=0.0) # 非阻塞

以 ENU 速度飞行,持续到下一个指令(hover/goto/land 或新的 set_velocity)。框架不做位置保护,位置监控由调用方或 PX4 围栏负责。

hover

hover() # 非阻塞

原地悬停(目标点设为当前位置与航向,速度模式切回位置模式)。

land

land(timeout=60.0)

原地降落,触地自动上锁后返回。内部先停止设定点流(不停流 PX4 会拒绝降落命令),再每 0.5s 重发 NAV_LAND 直到上锁。

shutdown

shutdown()

停止后台线程、销毁 ROS 节点。程序退出前必须调用(使用 Swarm 时由 Swarm.shutdown() 统一处理)。


Swarm 类

集群控制。多机动作 = 每机一个任务线程并行执行 + 屏障返回 + 异常隔离。

构造

Swarm(num_drones=None, namespaces=None, discovery_timeout=10.0)
参数说明
num_drones需要的机数。自动发现不足时抛 SwarmError;为 None 则接管发现的全部飞机
namespaces显式指定命名空间列表(跳过自动发现),如 ["uav_1", "uav_3"]
discovery_timeout自动发现的等待时限(s),默认 10

发现规则:扫描发布 /<ns>/fmu/out/vehicle_local_position 的命名空间,按自然序排列(uav_9 在 uav_10 前)。

容器接口

用法说明
len(swarm)机数
swarm[i]按下标取 Drone
swarm["uav_1"]按命名空间取 Drone,不存在抛 KeyError
swarm.dronesDrone 列表
swarm.namespaces命名空间列表(属性)

takeoff

takeoff(alt=1.5, tol=0.3, timeout=60.0)

全群同时起飞,各自以本机当前高度为基准。全部到位返回;部分失败抛 SwarmError(失败机已自动悬停)。

goto_all

goto_all(points, tol=0.3, timeout=60.0)

各机同时飞向各自目标。points 两种传法:

  • [(x,y,z), ...] 与机数等长 → 一一对应(推荐,真机防碰撞);
  • 单个 (x,y,z) → 全群飞同一相对点(仿真中各机在各自本地系,安全;真机 UWB 全局系下会撞机)。

数量不匹配抛 ValueError

set_velocity_all

set_velocity_all(velocities) # 非阻塞

单个 (vx,vy,vz) 全群共用,或与机数等长的列表每机一个。立即返回。

hover / emergency_stop

hover() # 非阻塞
emergency_stop() # 非阻塞,当前等价于 hover()

全群原地悬停(急停)。PX4 失联保护仍是最后防线。

land

land(timeout=60.0)

全群同时降落,全部上锁后返回。

formation_points(静态方法)

Swarm.formation_points(shape, n, spacing=2.0) -> list[tuple(float, float)]

生成 n 机编队 XY 偏移(以编队中心为原点,ENU),不含高度。shape 取值:

shape形状排列
"line"横排沿 x 轴等距
"column"纵队沿 y 轴等距
"triangle"三角逐行 1,2,3,... 架,行距 = spacing×√3/2
"grid"方阵⌈√n⌉ 列

未知 shape 抛 ValueError

goto_formation

goto_formation(shape, spacing=2.0, z=1.5, center=(0.0, 0.0), tol=0.3, timeout=60.0)

全群组成编队(每机在自己的本地坐标系内),等价于 goto_all(formation_points + center, z)

shutdown

shutdown()

对每架 Drone 调 shutdown()。在 land() 之后调用。


Strategy 类

策略插件基类(抽象类),用于编写可复用、可对比的集群算法。main() 托管完整生命周期:发现飞机 → setuprun →(异常则全群悬停)→ 自动降落 → teardown → 释放资源;Ctrl+C 安全触发降落。

类属性

属性默认说明
name"unnamed"策略名,用于日志输出

方法

方法必须实现说明
setup(swarm)run 前的准备(订阅传感器、加载参数)
run(swarm)算法主体(抽象方法)
teardown(swarm)降落后的清理(保存数据、生成报告)
main(num_drones=None, namespaces=None)托管执行入口,python3 my_strategy.py 直接运行

最小示例:

from swarm_api import Strategy

class MyStrategy(Strategy):
name = "my_strategy"
def run(self, swarm):
swarm.takeoff(1.5)
swarm.goto_formation("line", spacing=2.0, z=1.5)

if __name__ == "__main__":
MyStrategy().main(num_drones=3)

异常

DroneError

class DroneError(Exception)

单机操作失败(超时、无定位、解锁被拒、Offboard 丢失等)。消息格式 "uav_1: 具体原因"

SwarmError

class SwarmError(Exception)
errors: dict[str, Exception] # {命名空间: 单机异常}

多机并行执行的汇总错误。遍历 e.errors 逐机处理。


模块级函数

discover_namespaces

discover_namespaces(timeout=10.0) -> list[str]

扫描 ROS 话题发现在线飞机命名空间,自然序排列。Swarm 构造时内部调用,一般无需直接使用。

enu_to_ned

enu_to_ned(x, y, z) -> tuple(float, float, float)

位置 ENU→NED(换轴:(y, x, -z))。框架内部使用,绕过框架直接读 PX4 话题时需要。

yaw_enu_to_ned

yaw_enu_to_ned(yaw) -> float

航向 ENU(0=东, 逆时针正) → NED(0=北, 顺时针正),即 π/2 - yaw


ROS 接口清单

框架每架 Drone 占用以下话题(<ns> 为命名空间):

话题消息类型方向QoS频率
/<ns>/fmu/in/offboard_control_modepx4_msgs/OffboardControlMode发布reliable, depth 1020Hz(流线程)
/<ns>/fmu/in/trajectory_setpointpx4_msgs/TrajectorySetpoint发布reliable, depth 1020Hz(流线程)
/<ns>/fmu/in/vehicle_commandpx4_msgs/VehicleCommand发布reliable, depth 10按需(0.5s 重发直至生效)
/<ns>/fmu/out/vehicle_local_positionpx4_msgs/VehicleLocalPosition订阅best_effort, depth 5飞控决定(~50Hz)
/<ns>/fmu/out/vehicle_statuspx4_msgs/VehicleStatus订阅best_effort, depth 5飞控决定(~1Hz+事件)

设定点消息细节:

  • 位置模式:position=[n,e,d](NED 转换后),velocity=[NaN,NaN,NaN]yaw 已转换;
  • 速度模式:position=[NaN,NaN,NaN]velocity=[vn,ve,vd]yawspeed = -yaw_rate
  • 未用字段必须 NaN——PX4 对非 NaN 字段会尝试跟踪,混填行为未定义。

PX4 命令使用表

框架内部使用的 VehicleCommandtarget_system = sys_id):

命令param1param2用途使用位置
VEHICLE_CMD_DO_SET_MODE (176)1.06.0切 Offboard 主模式takeoff
VEHICLE_CMD_COMPONENT_ARM_DISARM (400)1.0解锁takeoff
VEHICLE_CMD_NAV_LAND (21)自动降落land

判定依据(VehicleStatus 字段):

判定条件
已解锁arming_state == ARMING_STATE_ARMED (2)
Offboard 中nav_state == NAVIGATION_STATE_OFFBOARD (14)

文档版本:v1.0(2026-07-27),对应 swarm_api 0.1.0。API 变更时本文档同步更新并递增版本。