3、系统需求分析:飞控系统顶层需求分解、功能架构定义、接口信号定义

好,咱们进入第三讲。前面两讲我们聊了什么是基于模型的设计,以及它为什么能帮我们少走弯路。今天要聊的,是真正动手干活前的第一步——系统需求分析

说白了,就是搞清楚两件事:飞控到底要干什么? 以及 它跟外界怎么打交道?

我见过不少团队,上来就写代码、调参数,结果飞到一半发现需求没对齐,推倒重来。嗯,这种坑我踩过不止一次。所以今天这部分,我建议你认真看。

3.1 顶层需求分解:从“能飞”到“怎么飞”

顶层需求,通常来自客户或者产品定义。比如:“我们要做一款物流无人机,载重5公斤,续航30分钟,能在6级风下稳定飞行。”

这句话听起来很美好,但直接拿给飞控工程师,他没法干活。为什么?因为太模糊了。你得把它拆成飞控系统能理解的语言。

我个人习惯,把顶层需求拆成三个维度:

  • 性能需求:比如悬停精度、最大角速度、爬升率、抗风等级。
  • 功能需求:比如自主起降、航线飞行、返航、故障保护。
  • 接口需求:比如跟地面站怎么通信、跟舵机怎么连接、传感器数据怎么传。

举个例子,顶层需求里的“6级风下稳定飞行”,怎么拆?

性能需求分解示例:

  • 最大抗风风速:13.8 m/s(6级风上限)
  • 位置保持精度:水平 ±1.5m,垂直 ±0.8m(6级风条件下)
  • 姿态角波动范围:滚转/俯仰 ≤ ±5°
  • 控制带宽:至少 10 Hz(保证对风扰动的快速响应)

你看,这样一拆,飞控算法工程师就知道:哦,我需要设计一个鲁棒性够强的控制器,而且传感器更新率不能太低。

我的经验: 分解需求时,一定要跟测试团队对齐。我曾经遇到过,需求写的是“抗6级风”,但测试标准用的是瞬时风速,而实际飞行遇到的是阵风。结果就是,实验室过了,外场炸了。所以,需求分解要连带测试条件一起定义

3.2 功能架构定义:飞控系统的“骨架”

需求拆完了,接下来要画功能架构。说白了,就是飞控系统由哪些模块组成,每个模块干什么活。

我习惯用一张功能框图来搞定这件事。飞控系统通常包含以下几个核心功能模块:

功能模块 职责描述 输入 输出
传感器管理 采集IMU、GPS、气压计、磁力计等数据,进行时间戳对齐和预处理 原始传感器数据 校准后的传感器数据
状态估计 融合多传感器数据,估算姿态、位置、速度 传感器数据 姿态角、位置、速度
导航与制导 根据目标航点,生成期望轨迹和期望姿态 目标航点、当前位置 期望姿态、期望推力
飞行控制 根据期望姿态和实际姿态,计算舵面/电机控制量 期望姿态、实际姿态 PWM控制信号
任务管理 处理飞行模式切换、故障保护逻辑、指令解析 遥控器指令、地面站指令 模式切换信号、故障响应
通信管理 管理与地面站、遥控器、数传电台的数据收发 外部通信数据 遥测数据、状态信息

你想想看,这个架构图一旦画出来,整个团队的沟通成本就大大降低了。硬件工程师知道要给传感器留什么接口,算法工程师知道自己的模块输入输出是什么,测试工程师也知道该测哪些边界条件。

注意: 功能架构定义时,最容易犯的错误是模块耦合过紧。比如把状态估计和飞行控制写在一个函数里。当时觉得方便,后面想换一个估计算法,结果牵一发动全身。所以,模块间接口要清晰,耦合要松

3.3 接口信号定义:把“连线”画清楚

架构定好了,接下来就是定义每个模块之间的接口信号。这一步看似琐碎,但往往是项目后期最头疼的地方。

我举个例子。状态估计模块输出给飞行控制模块的信号,至少应该包含:

  • 姿态角:滚转、俯仰、偏航(单位:度或弧度)
  • 角速度:滚转、俯仰、偏航速率(单位:度/秒)
  • 位置:经纬度、高度(单位:度、米)
  • 速度:北向、东向、地向速度(单位:米/秒)
  • 时间戳:数据有效时间(单位:微秒)

这些信号,每个都要明确:

  • 数据类型:float32 还是 int16?
  • 取值范围:比如姿态角是 -180~180 还是 0~360?
  • 更新频率:100Hz 还是 200Hz?
  • 单位:统一用国际单位制,别混用。

我个人习惯,用一张接口定义表来管理所有信号。比如:

信号名称 源模块 目标模块 数据类型 范围 单位 频率
roll_angle 状态估计 飞行控制 float32 -180 ~ 180 deg 200 Hz
pitch_rate 状态估计 飞行控制 float32 -500 ~ 500 deg/s 200 Hz
gps_lat 传感器管理 状态估计 double -90 ~ 90 deg 10 Hz
pwm_output 飞行控制 舵机/电机 uint16 1000 ~ 2000 us 400 Hz

你看,这样定义完,每个工程师拿到手就知道自己该发什么、收什么。不会出现“我以为你传的是度,结果你传的是弧度”这种低级错误。

避坑指南: 我曾经在一个项目里,因为接口信号的时间戳没对齐,导致状态估计和飞行控制之间差了20毫秒的延迟。飞起来就是高频抖动,查了三天才找到原因。所以,时间戳一定要在接口定义里明确写出来,而且最好用统一的系统时钟。

3.4 从需求到模型的桥梁

好了,需求分解了,架构画了,接口定义了。接下来干什么?

在基于模型的设计流程里,这些文档化的东西,最终要变成可执行的模型。比如在 Simulink 里,你会把每个功能模块建一个子系统,接口信号用总线(Bus)来定义。

我建议你,在建模之前,先把接口定义表做成一个 .m 文件或者数据字典。这样模型可以直接读取,避免手敲出错。

% 接口定义示例(MATLAB 数据字典)
% 状态估计 -> 飞行控制
est_to_ctrl.roll_angle  = Simulink.BusElement;
est_to_ctrl.roll_angle.Name = 'roll_angle';
est_to_ctrl.roll_angle.DataType = 'single';
est_to_ctrl.roll_angle.Dimensions = 1;
est_to_ctrl.roll_angle.Unit = 'deg';
est_to_ctrl.roll_angle.Description = '滚转角';

est_to_ctrl.pitch_rate = Simulink.BusElement;
est_to_ctrl.pitch_rate.Name = 'pitch_rate';
est_to_ctrl.pitch_rate.DataType = 'single';
est_to_ctrl.pitch_rate.Dimensions = 1;
est_to_ctrl.pitch_rate.Unit = 'deg/s';
est_to_ctrl.pitch_rate.Description = '俯仰角速率';

% 创建总线对象
estToCtrlBus = Simulink.Bus;
estToCtrlBus.Elements = [est_to_ctrl.roll_angle, est_to_ctrl.pitch_rate];

嗯,这一步做好了,后面建模、仿真、代码生成都会顺畅很多。说白了,需求分析阶段多花点时间,后面调试阶段就能少熬几个夜

我的习惯: 每次开始一个新项目,我都会先花一周时间专门做需求分析和接口定义。团队里有人觉得慢,但项目后期他们就知道值了。尤其是做基于模型的设计,模型本身就是需求的可执行表达,前期定义越清楚,模型越不容易跑偏。

好,这一讲就到这里。下一讲,我们会聊怎么把这些需求变成可执行的规格模型——也就是真正开始建模了。到时候见。