模型辨识篇

  在实际的无人机系统中,控制器的设计至关重要,它直接影响无人机的稳定性和响应能力。然而,要设计出高效、可靠的控制器,首先必须准确理解无人机的动态行为,这就需要通过收集输入输出数据来辨识其运动学模型。运动学模型是描述无人机在空间中运动规律的数学模型,它通常包含了无人机的位置、速度、加速度以及与之相关的控制输入等参数。通过辨识运动学模型,能够理解无人机在受到不同控制输入时的响应方式,这对于控制器设计极为重要。具体来说,这个过程包括以下几个步骤:

  1. 数据采集:在实际飞行测试中,通过无人机上的传感器收集关于其位置、速度、姿态等的数据,同时记录下相应的控制输入信息,如推力、方向控制等。

  2. 模型假设:在数据分析之前,需要先建立运动学模型的基本形式。这通常涉及到选择合适的数学结构来描述无人机的运动,如线性模型、非线性模型或是混合模型等。

  3. 参数辨识:使用统计或机器学习方法,如最小二乘法、神经网络等,根据收集到的数据来估计模型的参数。这一步的目标是找到一组参数,使得模型能够尽可能准确地预测无人机的实际行为。

  4. 模型验证:通过将模型预测的结果与实际飞行数据进行对比,评估模型的准确性和可靠性。如果模型表现不佳,可能需要返回上一步调整模型结构或参数,或者收集更多数据进行分析。

完成运动学模型的辨识后就可以基于该模型设计控制器。

1.数据采集

期望速度输入:


desv_x = 0.3 \cdot \cos(\theta)


desv_y = 0.2 \cdot \sin(\theta)

input_data = [desv_x, desv_y]

位置差分得到速度输出:


output_{data} =[\frac{{{real_x}} - {{lastreal_x}}}{\Delta t},
\frac{{{real_y}} - {{lastreal_y}}}{\Delta t} ]

output_data = np.array([real_x - last_real_x, real_y - last_real_y]) / 0.001

其中0.001为采样时间

仿真环境中运动轨迹:


这样得到了无人机的输入输出速度,可进行下一步的模型辨识。

2.模型辨识

2.1数据查看

将保存的数据导入Matlab,x,y方向的输入输出速度关系如下:


2.2辨识工具箱

打开系统辨识工具箱:【System ldentification】


导入数据:选择时域


选择要导入的数据名称


成功导入:


点击Time plot查看导入的数据是否正确:


数据预处理:Matlab系统辨识工具箱提供了一系列数据预处理功能,我们这里选择去均值


  1. Select channels…:选择数据通道功能允许用户从多通道数据中选择特定的通道进行分析。适用于处理多变量系统时,当用户仅对系统中的部分变量感兴趣或需要排除某些变量的干扰时使用。
  2. Select experiments…:选择实验功能用于从数据集中选择特定的实验或数据批次进行分析。这在处理包含多个实验条件或批次的数据集时特别有用,允许用户专注于特定条件下的系统行为。
  3. Merge experiments…:合并实验功能允许用户将来自不同实验或数据批次的数据合并为一个单一数据集。这对于增加数据量以提高系统模型的鲁棒性和泛化能力特别有用。
  4. Select range…:选择范围功能使用户能够指定数据集中的特定时间范围或数据点范围进行分析。这适用于专注于特定事件或系统响应阶段的分析。
  5. Remove means:去除均值功能用于从数据中去除平均值,通常用于消除静态偏置或将数据中心化,有助于突出数据的动态变化。
  6. Remove trends:去除趋势功能用于消除数据中的线性或非线性趋势。这对于处理具有时间相关趋势的数据非常有用,可以帮助揭示系统的内在动态行为。
  7. Filter…:滤波功能允许用户应用各种滤波器来处理数据,以去除噪声或提取感兴趣的信号频段。这在数据含有高频噪声或需要分析特定频率内容时非常有用。
  8. Resample…:重采样功能用于改变数据的采样率,通过插值或降采样来适应不同的分析需求。适用于处理采样率不一致的数据或优化处理速度。
  9. Transform data…:数据转换功能提供了多种数据转换方法,如对数变换、幂律变换等,用于改善数据的统计特性或适应特定的分析方法。
  10. Quick start:快速开始指南为用户提供了一个简易的操作流程,帮助用户快速开始数据预处理,尤其适用于初学者或需要快速处理数据的场景。

将预处理完成后,需要进行辨识的数据拖入working区域:



选择要拟合的模型形式:Matlab系统辨识工具箱中的一系列模型估计功能。覆盖了从线性到非线性模型的广泛范围,适用于各种系统和信号处理场景


  1. Transfer Function Models…:传递函数模型用于描述输入信号和输出信号之间的线性关系,适用于线性时不变(LTI)系统。这类模型在控制系统和信号处理中非常常见。
  2. State Space Models…:状态空间模型提供了一种更为通用的方式来表示线性系统,允许包含内部状态变量。这使得状态空间模型特别适用于复杂的动态系统分析和多变量系统控制设计。
  3. Process Models…:过程模型是简化的传递函数模型,通常用于描述具有少量可调参数的过程控制系统。它们适用于快速建模和初步控制系统设计。
  4. Polynomial Models…:多项式模型通过使用多项式来描述输入和输出之间的关系,适用于可以用多项式近似的非线性系统。
  5. Nonlinear ARX Models…:非线性自回归滑动平均模型(Nonlinear ARX)是一种非线性模型,能够捕捉输入输出数据之间的非线性关系。适用于那些线性模型无法有效描述的系统。
  6. Hammerstein-Wiener Models…:Hammerstein-Wiener模型是一种特殊的非线性模型,它在输入端和输出端分别加入非线性环节,用于描述输入和输出之间存在非线性静态关系的系统。
  7. Spectral Models…:频谱模型通过分析信号的频谱特性来建模,适用于需要在频域内分析和设计的系统。
  8. Correlation Models…:相关模型基于输入和输出数据之间的相关性来建立模型,适用于分析和预测时间序列数据。
  9. Refine Existing Models…:优化现有模型功能允许用户调整和改进已经建立的模型,以提高模型的精度和适用性。
  10. Quick Start:快速开始指南为用户提供了一个简易的操作流程,帮助用户快速开始模型估计工作,特别适合初学者或需要快速建模的场景。

模型形式调整:用于配置和估计过程模型,”Process Models“这类模型通常用于描述动态系统的输入输出行为


  • K:增益参数,代表系统增益的大小。
  • Tp1, Tp2, Tp3:时间常数,用于描述系统动态行为的速率。在这个界面中,Tp1和Tp2对应一阶和二阶时间常数,而Tp3是可选的额外时间常数,用于描述更复杂的系统动态。
  • Tz:零点时间常数,用于添加系统动态中的零点。
  • Td:纯延迟时间,表示系统响应与输入信号之间存在的时间延迟。
  • Poles:设置系统极点的数量和类型(例如,所有实数极点)。
  • Zero:是否包含零点。
  • Delay:是否包含延迟。
  • Integrator:是否包含积分器,用于描述系统积分特性。
  • Disturbance Model:选择是否考虑系统中的干扰模型,以及干扰模型的类型。

得到辨识的模型:


辨识的模型输出与实际模型输出对比:


模型导入到工作区:


得到模型:

tf(P2)

为了简便,忽略模型x、y轴的耦合,只考虑u1对y1及u2对y2的影响。得到辨识模型

从输入u1到输出y1:传递函数为:


\frac{ 3.384}{0.004499s^2 + 0.1367s + 1}

从输入u2到输出y2:传递函数为:


\frac{3.825}{ 2.335e-06s^2 + 0.1551s + 1}

下一篇将利用此模型使用matlab控制系统工具箱进行控制器的设计。

代码

采集数据

# 设置目标循环时间
target_loop_time = 0.0015
trajectory_input = []
trajectory_output = []
last_real_x = obs[0]
last_real_y = obs[1]

while True:
    start_time = time.time()
    if terminated:
        env.reset()
    angle = current_count * angular_velocity
    desv_x = 0.3 * math.cos(math.radians(angle))
    desv_y = 0.2 * math.sin(math.radians(angle))

    # 控制器部分
    random_action[0][0] = desv_x
    random_action[0][1] = desv_y
    random_action[0][2] = 0
    random_action[0][3] = 1
    random_action = np.clip(random_action, -1, 1)

    obs, reward, terminated, info = env.step(random_action)
    real_x = obs[0]
    real_y = obs[1]

    current_count += 1
    if angle > 360:
        current_count = 0
        count_turns += 1
        # 计算实际循环时间
    input_data = [desv_x, desv_y]
    output_data = np.array([real_x - last_real_x, real_y - last_real_y]) / 0.001
    trajectory_input.append(input_data)
    trajectory_output.append(output_data)
    last_real_x = real_x
    last_real_y = real_y

    if count_turns > 5:
        break

data_dict = {
    'input': trajectory_input,
    'output': trajectory_output
}
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
mat_filename = f"data_{timestamp}.mat"
scipy.io.savemat(mat_filename, data_dict)