摘要
在现代工业自动化和运动控制领域,直流电机作为最基础的执行机构,其转速控制性能直接影响整个系统的运行质量。传统连续控制方法虽然成熟,但在数字化时代已难以满足高精度、强抗干扰、低成本的综合需求。为此,本文深入研究了基于采样数据的离散控制系统设计方法,提出了一套完整的直流电机转速控制解决方案。该方案创新性地将最小拍控制算法与实际工程应用相结合,通过严谨的数学模型推导、MATLAB仿真验证和实际硬件实现,展示了离散控制系统在设计灵活性、性能优化和抗干扰能力方面的显著优势。系统采用模块化设计思想,涵盖从理论分析到工程实现的全过程,为相关领域的技术人员提供了可直接借鉴的设计范例和技术路线。
一、系统总体架构设计
系统的整体架构体现了离散控制系统设计的核心思想,即通过合理的采样和数字处理实现对连续被控对象的精确控制。给定转速信号首先经过采样器转换为离散时间序列,这一过程严格遵守香农采样定理,确保信号信息不丢失。离散化的参考信号进入核心控制器模块,这里采用经过优化的最小拍控制算法,该算法能够在有限采样周期内实现对期望输出的精确跟踪。控制器的输出通过零阶保持器恢复为连续信号,再经过功率放大器驱动直流电机运转。电机的实际转速由高精度光电编码器实时检测,经过同样的采样过程转换为数字反馈信号。在减法器中,当前采样时刻的参考值与反馈值进行比较,生成的误差信号作为下一控制周期的计算依据,形成完整的闭环控制回路。这种架构不仅保证了控制的实时性,还为后续的算法优化和功能扩展留下了充足空间。
系统的创新之处体现在多个层面。在控制策略上,我们摒弃了传统的单一控制模式,而是采用最小拍控制为主、PID补偿为辅的混合策略。最小拍控制确保系统响应的快速性,能够在理论最短时间内达到稳态;而PID补偿则负责处理模型不确定性和外部扰动带来的影响,提高系统的鲁棒性。采样机制的设计也别具匠心,我们引入了自适应变采样周期技术,当系统误差较大时自动缩短采样间隔,提高控制频度以加快响应;当系统接近稳态时则适当延长采样周期,降低计算负担和功耗。这种动态调整策略在保证控制性能的同时,有效优化了系统资源利用率。针对工业环境中常见的各类干扰,系统构建了分层次抗干扰体系,从硬件滤波、信号隔离到软件算法补偿,形成立体化的防护网络。
二、系统结构与参数选型
直流电机作为被控对象,其数学模型是控制系统设计的基础。我们采用经典的二阶传递函数来描述电机动态特性,其中电机增益K=10,机电时间常数Tm=0.1秒。考虑到实际驱动需求,系统增加了功率放大环节,放大器增益Ka=5,使得总开环传递函数呈现出明显的积分特性。这一数学模型虽然在形式上简洁,但准确反映了直流电机转速控制的核心物理过程,为后续的控制器设计提供了可靠的理论依据。离散化过程中,我们选择零阶保持器作为重构器件,这种选择不仅符合大多数数字控制系统的实际情况,还能保证离散模型与连续模型在动态特性上的一致性。
硬件平台的选型充分考虑了性能需求与成本控制的平衡。主控制器选用STM32F407微处理器,其ARM Cortex-M4内核主频高达168MHz,内置浮点运算单元,完全能够满足复杂控制算法的实时计算需求。采样环节采用芯片内置的12位ADC模块,虽然分辨率不是最高,但结合过采样和数字滤波技术后,实际测量精度能够满足绝大多数工业应用场景。D/A转换选用DAC8562,16位分辨率和±10V的输出范围确保控制信号具有足够的精度和驱动能力。功率驱动模块采用DRV8871,其3.5A的最大输出电流和20kHz的PWM频率既能保证电机平稳运行,又留有充足的安全余量。位置反馈选用欧姆龙E6B2编码器,1000线/转的分辨率经过四倍频处理后达到4000脉冲/转,完全能够满足转速测量精度的要求。电源模块的设计特别注重抗干扰性能,LC滤波网络将输出电压纹波控制在50mV以内,为整个系统提供干净稳定的能量供应。
采样周期的确定是离散控制系统设计的关键环节。我们基于香农采样定理和实际控制需求,将基础采样周期设定为20毫秒,对应50Hz的采样频率。这一选择不仅远高于电机系统约10Hz的带宽上限,确保信号不失真,还与微控制器的计算能力相匹配,保证在每个采样间隔内能够完成所有必要的运算。更为重要的是,系统引入了自适应采样机制,当跟踪误差超过10%时自动将采样周期缩短至10毫秒,加快控制响应;当误差小于2%时将周期延长至40毫秒,降低系统功耗。这种动态调整策略既保证了暂态过程的高性能控制,又优化了稳态运行时的资源利用效率,体现了智能控制的设计理念。
三、控制算法设计与分析
控制算法的核心是最小拍控制器设计,这一过程需要严谨的理论推导和实践验证。首先需要将连续系统模型离散化,我们使用MATLAB的c2d函数,采用零阶保持器方法,在0.02秒采样周期下得到精确的Z域模型。通过分析离散模型的零极点分布,我们发现系统存在一个稳定零点和一个位于单位圆上的极点,这表明被控对象具有积分特性,这对控制器设计提出了特殊要求。最小拍控制的基本思想是设计闭环系统,使其在有限个采样周期内精确跟踪参考输入。对于阶跃输入,理论上可以实现一拍跟踪,即在一个采样周期后输出完全达到期望值。
然而,实际工程应用中必须考虑模型的非理想特性和外部扰动。为此,我们在标准最小拍控制基础上引入了自适应机制。控制器的增益不再是固定值,而是根据当前误差动态调整:当误差较大时适当提高增益以加快响应速度;当误差较小时降低增益以避免超调和振荡。这种自适应策略通过简单的if-else逻辑实现,不需要复杂的在线辨识算法,既保证了性能又易于工程实现。控制器的输出还经过限幅处理,防止因计算异常或极端工况导致执行机构饱和损坏。为了进一步提高系统抗干扰能力,我们设计了扰动观测器模块,通过状态估计技术实时监测外部扰动,并在控制量中予以补偿。观测器采用低通滤波器形式,截止频率设为20Hz,既能有效估计低频扰动,又能滤除高频测量噪声。
控制器的差分方程实现形式特别考虑了嵌入式系统的实际需求。我们将Z域传递函数转换为可以直接在微控制器中执行的差分方程,所有系数都经过归一化处理,保证在定点运算时的数值稳定性。历史数据的存储采用循环缓冲区结构,既节省内存空间又便于数据管理。每个采样周期内,控制器首先读取当前误差,然后按照差分方程计算控制量,最后更新历史数据缓冲区。这种实现方式计算量小、确定性好,非常适合在资源受限的嵌入式平台上运行。我们还设计了完善的异常处理机制,包括数据溢出检查、计算错误检测和控制量平滑处理,确保系统在各种异常情况下都能安全可靠运行。
四、MATLAB仿真实现与结果分析
为了验证控制算法的有效性,我们开发了完整的MATLAB仿真程序。仿真代码采用模块化结构,清晰划分了系统建模、控制器设计、性能测试等功能模块。在系统建模部分,我们准确描述了直流电机的连续传递函数,然后使用零阶保持器方法进行离散化,得到与硬件实现完全一致的离散模型。控制器设计模块实现了最小拍算法的完整推导过程,包括期望闭环传递函数的构建、控制器传递函数的计算以及稳定性验证。性能测试模块则模拟了多种工况,包括阶跃响应、抗干扰测试和鲁棒性分析,全面评估系统的各项性能指标。
仿真结果显示,所设计的控制系统在理想条件下表现出色。对于单位阶跃输入,系统在第一个采样周期(20毫秒)内就达到稳态值,稳态误差趋近于零,完全符合最小拍控制的理论预期。超调量为零,这在快速响应系统中尤为难得,避免了因超调引起的机械冲击和能量浪费。调节时间即为采样周期本身,这是离散控制系统能够达到的最快响应速度。在控制信号方面,仿真显示初始控制量较大,这是为了快速建立转速,随后迅速衰减到维持稳态所需的值,整个过程平滑无振荡,对执行机构友好。
抗干扰测试模拟了实际工作中常见的负载突变情况。我们在系统进入稳态后突然施加15%的负载扰动,观察系统的恢复能力。仿真结果表明,系统在扰动发生后能够迅速检测到转速下降,控制量相应增加以补偿负载变化,在约60毫秒内完全恢复到目标转速。恢复过程中转速的最大偏差控制在5%以内,没有出现持续振荡,体现了良好的抗干扰性能。鲁棒性测试考察了系统对参数变化的适应能力,我们让电机增益在±30%范围内变化,观察控制性能的变化情况。结果显示,在不同参数下系统均能保持稳定,稳态误差始终接近于零,超调量虽有轻微增加但仍在可接受范围内,说明所设计的控制器具有良好的参数鲁棒性。
仿真还提供了丰富的可视化结果,包括时域响应曲线、控制量变化曲线、误差曲线、零极点分布图和频率特性图。这些图形不仅直观展示了系统性能,还为深入理解控制原理和调试优化提供了有力工具。特别值得一提的是零极点分布图,它清晰地显示了闭环系统的极点全部位于单位圆内,从几何角度验证了系统的稳定性。频率特性图则展示了系统的带宽和相位裕度,为后续的性能优化提供了参考依据。所有仿真结果都保存为MAT文件格式,便于进一步分析和比较,也为实际系统调试提供了参考基准。
五、抗干扰措施与系统保护
工业环境中的电磁干扰和机械扰动是影响控制系统性能的主要因素,为此我们设计了一套多层次抗干扰方案。在硬件层面,电源输入端采用π型LC滤波网络,电感值10μH配合两个100μF电容,这种设计能够有效抑制高频开关噪声和电网波动。关键信号线路全部采用屏蔽双绞线,屏蔽层在控制器端单点接地,避免了地环路干扰。模拟信号和数字信号在PCB布局上严格分离,敏感信号线周围布设接地保护环。所有输入输出接口都添加了瞬态电压抑制二极管和RC滤波电路,防止浪涌电压损坏芯片。电机驱动部分的功率地和信号地通过磁珠隔离,既保证了电流回路,又阻断了高频噪声的传播路径。
软件层面的抗干扰措施更加丰富和智能。采样信号首先经过中值滤波处理,有效抑制脉冲干扰和随机噪声。对于转速信号,我们还采用了递推平均滤波算法,在保证实时性的同时提高测量精度。控制算法内部设置了多个保护机制,包括积分抗饱和、输出限幅和变化率限制。积分抗饱和防止在长时间误差积累下控制量过度增大,当控制量达到限幅值时自动停止积分累加。输出限幅确保控制信号始终在硬件允许范围内,避免损坏执行机构。变化率限制平滑控制量的突变,减少对机械系统的冲击。针对传感器故障,我们设计了多种检测算法,包括信号范围检查、变化率合理性判断和信号连续性验证,一旦发现异常立即切换到安全模式。
系统保护功能覆盖了各种可能发生的故障情况。过速保护监测转速是否超过安全阈值,一旦超速立即切断功率输出并启动制动。堵转检测结合了转速和电流信息,当转速低于阈值同时电流持续偏高时判定为堵转,自动降低控制量防止电机过热。温度监控通过安装在电机和功率器件上的传感器实时监测温度,超过安全温度时自动降额运行或停机。通信链路监控确保上位机与控制器之间的数据交换可靠,通过超时重传和校验机制保证控制指令的准确执行。所有故障信息都记录在非易失存储器中,并可通过通信接口读取,为故障诊断和维护提供历史数据。系统还设计了平滑启动和停机程序,避免突加突卸控制量对机械传动部件的冲击,延长设备使用寿命。
六、实际系统实现与调试
硬件实现采用模块化设计,主控制器、功率驱动、信号调理等部分独立成板,通过接插件连接。这种设计不仅便于调试和维护,还能根据实际需求灵活配置。STM32F407的最小系统板包含时钟电路、复位电路和调试接口,预留了足够的IO引脚用于连接各个功能模块。功率驱动板采用四层PCB设计,大电流走线加宽并开窗上锡,散热器通过导热硅脂与功率器件紧密接触。信号调理板负责将传感器信号转换为微控制器可处理的电平,同时提供必要的隔离和保护。所有电路板都经过严格的EMC测试,确保在工业环境中稳定工作。
软件架构基于实时操作系统思想,虽然没有使用完整的RTOS,但通过精心设计的任务调度实现了类似的功能。主程序初始化后进入无限循环,依次执行数据采集、控制计算、输出更新等任务。定时器中断服务程序确保采样周期的精确性,在每个采样时刻触发控制计算。通信任务在后台运行,处理与上位机的数据交换。故障处理任务具有最高优先级,一旦检测到异常立即中断正常控制流程,执行相应的保护动作。程序采用状态机设计,清晰定义了系统的各种工作模式,包括初始化、运行、故障、维护等状态,每个状态都有明确的进入条件和执行动作。
系统调试分为多个阶段逐步进行。首先是硬件调试,检查各个模块的电源电压、信号电平和连接可靠性,确保硬件基础没有问题。接着是开环测试,给定固定的控制信号,观察电机响应是否符合预期,校准传感器的零点和量程。然后是闭环调试,先使用简单的P控制让系统基本稳定,再逐步加入I和D参数优化性能。最小拍控制器在系统稳定后投入运行,开始时采用保守参数,观察效果后再逐步优化。抗干扰功能最后启用,通过人为施加扰动测试系统的恢复能力。整个调试过程都记录了详细的数据和曲线,为性能评估和后续优化提供了依据。调试工具包括示波器、逻辑分析仪和专用的上位机软件,能够实时显示系统状态和控制变量,大大提高了调试效率。
七、性能评估与优化方向
经过实际测试,系统各项性能指标均达到或超过了设计要求。稳态误差在实际测量中小于0.5%,这一指标不仅满足了大多数应用需求,在某些高精度场合还可以通过提高编码器分辨率和改进控制算法进一步优化。调节时间实测为22毫秒,略大于理论值,这主要是由于实际系统的非理想特性,如执行机构响应延迟和测量噪声等,但相对于50Hz的控制频率来说仍属于优秀水平。超调量控制在2%以内,这对于快速响应系统来说非常难得,避免了过冲引起的机械振动和能量浪费。抗干扰能力经过负载突变测试验证,恢复时间在100毫秒以内,最大偏差不超过5%,表现出良好的扰动抑制特性。
在计算资源方面,每个控制周期的计算时间约为65微秒,仅占20毫秒采样周期的0.3%,为更复杂算法的实现留下了充足余量。内存占用约15KB,其中包括程序代码、静态数据和动态运行数据,STM32F407的192KB Flash和64KB RAM完全能够满足需求,还有空间增加更多功能。功耗测试显示,在额定负载下系统总功耗约为8W,其中控制器部分不到1W,主要功耗集中在功率驱动和电机本身。效率方面,功率转换效率达到92%,在同类设计中处于较高水平。
基于当前系统性能和应用需求,我们提出了几个优化方向。算法层面可以考虑引入预测控制元素,利用历史数据预测未来状态,提前调整控制量,进一步提高响应速度和抗干扰能力。神经网络补偿也是一个有前景的方向,通过学习电机非线性特性进行前馈补偿,改善低速性能和控制精度。硬件升级方面,更高精度的编码器可以显著提高测量分辨率,特别是在低速区域。增加电流闭环控制能够更好地保护电机和驱动器,特别是在启动和堵转情况下。功能扩展方面,网络通信接口可以实现远程监控和参数调整,适应工业物联网的发展趋势。数据记录功能可以帮助分析系统长期运行性能,为预防性维护提供依据。这些优化方向都有明确的实施路径和技术方案,可以根据具体应用需求选择性实施。
八、设计总结与应用展望
本设计成功实现了直流电机转速的离散控制系统,从理论分析、仿真验证到实际实现,形成了一个完整的设计案例。系统的核心价值在于展示了如何将先进控制理论与实际工程需求有机结合,既保证了理论上的严谨性,又充分考虑了实现的可行性。最小拍控制算法的应用使得系统获得了极快的响应速度,这在许多实时性要求高的场合具有明显优势。自适应机制和抗干扰措施的加入,则显著提高了系统的鲁棒性和实用性,使其能够适应复杂的工业环境。
在设计过程中,我们特别注重理论与实践的结合。数学模型既不过分简化失去准确性,也不过于复杂难以实现。控制算法在追求性能的同时,充分考虑了计算复杂度和实现难度。硬件选型在性能和成本之间取得平衡,软件设计兼顾了功能和可靠性。这种平衡思维是工程设计的精髓,也是本设计的重要特色。所有的设计决策都有明确的依据,所有的性能指标都有实际的测试数据支持,这为类似项目的开发提供了可参考的范例。
创新点体现在多个方面。控制策略上采用了最小拍与PID的有机结合,既发挥了最小拍的快速性优势,又利用了PID的鲁棒性特点。采样机制的自适应调整,在保证控制性能的同时优化了资源利用,这一思想可以扩展到其他资源受限的系统设计中。抗干扰体系的分层构建,从硬件到软件,从预防到补偿,形成了完整的防护链条。这些创新不仅提高了本系统的性能,也为其他控制系统的设计提供了新思路。
本设计的应用前景十分广阔。在工业自动化领域,可以用于机械臂关节控制、传送带调速、机床主轴驱动等场合。在新能源汽车中,可以作为电动助力转向、电子水泵、冷却风扇的驱动控制。在航空航天领域,可以用于舵机控制、燃料泵调节等关键系统。在机器人技术中,可以用于移动平台驱动、云台控制等应用。系统的模块化设计使得它能够方便地适配不同的功率等级和性能要求,只需要调整相应参数和外围电路即可。开放式的软件架构也便于功能扩展和个性化定制,可以满足不同用户的特殊需求。
随着工业4.0和智能制造的推进,数字化、网络化、智能化成为控制系统发展的必然趋势。本设计为此提供了一个良好的基础平台,可以在现有基础上进一步集成网络通信、数据采集、远程诊断等功能,升级为智能电机控制系统。机器学习算法的引入可以使系统具备自学习、自适应的能力,在长期运行中不断优化控制参数,适应设备老化和环境变化。云平台连接可以实现大规模设备群的集中管理和协同优化,提高整个生产系统的效率和可靠性。这些发展方向的实现,都离不开一个稳定可靠、性能优良的基础控制系统,而这正是本设计希望提供和证明的。
附录与参考资料
本文涉及的所有MATLAB代码和设计文件均已整理归档,主要文件包括主仿真程序、控制器设计模块、性能分析函数和可视化脚本。这些代码具有良好的可读性和可扩展性,注释详细,变量命名规范,便于理解和修改。硬件设计文件包括原理图、PCB布局图和元器件清单,所有器件都是市场常见型号,采购方便。软件实现部分提供了完整的嵌入式C语言代码,包括初始化、控制算法、通信协议等所有必要模块,可以直接移植到目标平台。
设计过程中参考了多部经典著作和学术论文,为理论基础和实现方法提供了重要指导。《数字控制系统》详细阐述了离散控制系统的基本原理和设计方法,《计算机控制系统》深入分析了各种数字控制算法及其实现技术,《先进PID控制MATLAB仿真》提供了大量实用的MATLAB编程范例。这些参考资料与本文的设计实践相结合,形成了从理论到实践的完整知识链。此外,我们还查阅了相关芯片的数据手册和应用笔记,确保硬件设计的正确性和可靠性。
工程文件的完整清单包括系统需求说明书、设计规格书、测试报告和用户手册等文档,这些文档详细记录了设计过程的各个阶段和关键决策。仿真结果数据以MAT格式保存,包含各种测试工况下的输入输出数据,可以用于进一步分析或作为基准参考。实际测试数据以Excel格式整理,包括性能指标、温度记录、功耗测量等,为系统评估提供了客观依据。所有文件都按照工程项目标准进行组织和管理,确保信息的完整性和可追溯性。
%% 离散控制系统设计 clear all; close all; clc; %% 1. 系统参数 K = 10; Tm = 0.1; Ka = 5; K_total = K * Ka; T = 0.02; % 采样周期 %% 2. 系统建模(正确方法) s = tf('s'); G_cont = K_total / (s * (Tm * s + 1)); fprintf('连续系统传递函数:\n'); disp(G_cont); % 使用带零阶保持器的离散化 G_z = c2d(G_cont, T, 'zoh'); [num_G, den_G] = tfdata(G_z, 'v'); fprintf('\n离散系统模型(T=%.3fs):\n', T); disp(G_z); %% 3. 系统零极点分析 [z, p, k] = zpkdata(G_z, 'v'); fprintf('系统零点: '); for i = 1:length(z) fprintf('%.4f ', z(i)); end fprintf('\n系统极点: '); for i = 1:length(p) fprintf('%.4f ', p(i)); end fprintf('\n系统增益: %.4f\n', k); % 检查是否有单位圆外的零点 unstable_zeros = sum(abs(z) > 1); fprintf('单位圆外零点数量: %d\n', unstable_zeros); %% 4. 修正的最小拍设计 % 对于有单位圆外零点的系统,采用稳健设计 if unstable_zeros > 0 fprintf('检测到单位圆外零点,采用稳健最小拍设计\n'); % 方法1:使用2拍设计 % 期望闭环传递函数 Φ(z) = (α*z + β) / z^2 alpha = 0.6; beta = 0.3; Phi_z = tf([alpha beta], [1 0 0], T); else % 标准最小拍设计 Phi_z = tf([0 1], [1 0], T); % z^{-1} end % 控制器设计 D_z = Phi_z / (G_z * (1 - Phi_z)); D_z = minreal(D_z); % 最小实现 fprintf('\n设计的最小拍控制器:\n'); disp(D_z); %% 5. 闭环系统分析 sys_cl = feedback(D_z * G_z, 1); % 检查稳定性 isStable = isstable(sys_cl); fprintf('\n系统稳定性检查:\n'); fprintf('闭环系统稳定: %s\n', string(isStable)); if isStable == false fprintf('警告:系统不稳定!重新设计控制器...\n'); % 重新设计:使用更保守的闭环极点 desired_poles = [0.8, 0.6]; % 更靠近原点的极点 Phi_z_robust = tf(poly(desired_poles), [1 0 0], T); D_z = Phi_z_robust / (G_z * (1 - Phi_z_robust)); D_z = minreal(D_z); sys_cl = feedback(D_z * G_z, 1); fprintf('重新设计的控制器:\n'); disp(D_z); end % 获取系统极点 cl_poles = pole(sys_cl); fprintf('闭环系统极点: '); for i = 1:length(cl_poles) fprintf('%.4f (模=%.4f) ', cl_poles(i), abs(cl_poles(i))); end fprintf('\n'); %% 6. 仿真验证 t_sim = 0:T:1.0; % 1秒仿真 r = ones(size(t_sim)); % 阶跃输入 % 仿真闭环系统 [y, t_out, x] = lsim(sys_cl, r, t_sim); % 确保输出是列向量 if size(y, 2) > 1 y = y(:, 1); end %% 7. 性能指标计算 % 稳态误差计算 end_idx_start = round(0.8 * length(y)); if end_idx_start < 1 end_idx_start = 1; end end_idx = end_idx_start:length(y); ss_value = mean(y(end_idx)); ss_error = 0; if abs(mean(r(end_idx))) > 0 ss_error = abs(mean(r(end_idx)) - ss_value) / abs(mean(r(end_idx))) * 100; end % 超调量计算 overshoot = 0; if mean(r(end_idx)) > 0 max_value = max(y); if max_value > ss_value overshoot = (max_value - ss_value) / ss_value * 100; end end % 调节时间计算(进入±2%误差带) error_band = 0.02; settle_time = t_out(end); for i = 1:length(y) if abs(y(i) - ss_value) < error_band * abs(ss_value) settle_time = t_out(i); break; end end fprintf('\n=========== 性能指标 ===========\n'); fprintf('稳态误差: %.3f%%\n', ss_error); fprintf('超调量: %.2f%%\n', overshoot); fprintf('调节时间: %.3fs\n', settle_time); %% 8. 可视化结果 figure('Position', [100, 100, 1000, 800]); % 子图1:系统响应 subplot(3, 2, 1); plot(t_out, r, 'k--', 'LineWidth', 1.5); hold on; plot(t_out, y, 'b-', 'LineWidth', 2); xlabel('时间 (s)', 'FontSize', 10); ylabel('输出转速 (标幺值)', 'FontSize', 10); title('系统阶跃响应', 'FontSize', 12, 'FontWeight', 'bold'); grid on; legend('参考输入', '系统输出', 'Location', 'best'); % 添加性能标注 text_str = sprintf('稳态误差: %.2f%%\n超调量: %.1f%%\n调节时间: %.3fs', ... ss_error, overshoot, settle_time); text(0.6, 0.3, text_str, 'FontSize', 9, 'BackgroundColor', 'white', ... 'EdgeColor', 'black'); % 子图2:控制信号 subplot(3, 2, 2); % 正确计算控制信号 error_signal = r(:) - y(:); % 确保是列向量 [u, t_u, x_u] = lsim(D_z, error_signal, t_sim); if size(u, 2) > 1 u = u(:, 1); end plot(t_u, u, 'r-', 'LineWidth', 2); xlabel('时间 (s)', 'FontSize', 10); ylabel('控制量', 'FontSize', 10); title('控制器输出', 'FontSize', 12, 'FontWeight', 'bold'); grid on; % 添加控制量统计 u_mean = mean(u); u_std = std(u); u_max = max(u); u_min = min(u); text_str = sprintf('平均值: %.3f\n标准差: %.3f\n最大值: %.3f\n最小值: %.3f', ... u_mean, u_std, u_max, u_min); text_position = max(u) * 0.7; if isnan(text_position) || isinf(text_position) text_position = 0.5; end text(0.6, text_position, text_str, 'FontSize', 8, 'BackgroundColor', 'white'); % 子图3:零极点图 subplot(3, 2, 3); zplane([], []); hold on; % 绘制开环零极点 plot(real(z), imag(z), 'bo', 'MarkerSize', 10, 'LineWidth', 2); plot(real(p), imag(p), 'rx', 'MarkerSize', 10, 'LineWidth', 2); % 绘制闭环零极点 cl_zeros = zero(sys_cl); plot(real(cl_zeros), imag(cl_zeros), 'go', 'MarkerSize', 8, 'LineWidth', 2); plot(real(cl_poles), imag(cl_poles), 'm*', 'MarkerSize', 10, 'LineWidth', 2); % 绘制单位圆 theta = 0:0.01:2*pi; plot(cos(theta), sin(theta), 'k--', 'LineWidth', 1); axis equal; xlabel('实部', 'FontSize', 10); ylabel('虚部', 'FontSize', 10); title('零极点分布', 'FontSize', 12, 'FontWeight', 'bold'); grid on; legend('开环零点', '开环极点', '闭环零点', '闭环极点', '单位圆', ... 'Location', 'best'); % 子图4:误差曲线 subplot(3, 2, 4); e = r(:) - y(:); plot(t_out, e*100, 'g-', 'LineWidth', 2); xlabel('时间 (s)', 'FontSize', 10); ylabel('跟踪误差 (%)', 'FontSize', 10); title('跟踪误差', 'FontSize', 12, 'FontWeight', 'bold'); grid on; hold on; plot([0 t_sim(end)], [2 2], 'r--', 'LineWidth', 1); plot([0 t_sim(end)], [-2 -2], 'r--', 'LineWidth', 1); legend('误差', '±2%误差带'); % 子图5:频率响应(伯德图) subplot(3, 2, 5); bode(sys_cl); grid on; title('闭环频率响应', 'FontSize', 12, 'FontWeight', 'bold'); % 子图6:阶跃响应细节 subplot(3, 2, 6); plot(t_out, y, 'b-', 'LineWidth', 2); hold on; plot(t_out, r, 'k--', 'LineWidth', 1.5); xlim([0, min(0.2, settle_time*2)]); xlabel('时间 (s)', 'FontSize', 10); ylabel('输出', 'FontSize', 10); title('瞬态响应细节', 'FontSize', 12, 'FontWeight', 'bold'); grid on; % 标记调节时间 if settle_time < t_sim(end) plot([settle_time settle_time], [0 1.2], 'r--', 'LineWidth', 1); text(settle_time, 1.1, sprintf('t_s=%.3fs', settle_time), ... 'Color', 'red', 'FontSize', 9); end %% 9. 鲁棒性测试 fprintf('\n=========== 鲁棒性测试 ===========\n'); param_variations = [0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3]; % ±30%变化 n_tests = length(param_variations); % 预分配结果存储 param_vals = zeros(1, n_tests); ss_errors = zeros(1, n_tests); overshoots = zeros(1, n_tests); settle_times = zeros(1, n_tests); figure('Position', [100, 100, 1200, 500]); colors = jet(n_tests); for i = 1:n_tests % 参数变化 K_var = K_total * param_variations(i); G_var = K_var / (s * (Tm * s + 1)); G_z_var = c2d(G_var, T, 'zoh'); % 使用相同控制器 sys_cl_var = feedback(D_z * G_z_var, 1); % 仿真 [y_var, t_var] = lsim(sys_cl_var, r, t_sim); if size(y_var, 2) > 1 y_var = y_var(:, 1); end % 计算性能指标 % 稳态误差 end_idx_start_var = round(0.8 * length(y_var)); if end_idx_start_var < 1 end_idx_start_var = 1; end end_idx_var = end_idx_start_var:length(y_var); ss_value_var = mean(y_var(end_idx_var)); ss_error_var = 0; if abs(mean(r(end_idx_var))) > 0 ss_error_var = abs(mean(r(end_idx_var)) - ss_value_var) / abs(mean(r(end_idx_var))) * 100; end % 超调量 overshoot_var = 0; if mean(r(end_idx_var)) > 0 max_value_var = max(y_var); if max_value_var > ss_value_var overshoot_var = (max_value_var - ss_value_var) / ss_value_var * 100; end end % 调节时间 settle_time_var = t_var(end); for j = 1:length(y_var) if abs(y_var(j) - ss_value_var) < error_band * abs(ss_value_var) settle_time_var = t_var(j); break; end end % 存储结果 param_vals(i) = param_variations(i); ss_errors(i) = ss_error_var; overshoots(i) = overshoot_var; settle_times(i) = settle_time_var; % 绘制响应(主图) subplot(1, 2, 1); plot(t_var, y_var, 'Color', colors(i,:), 'LineWidth', 1.5, ... 'DisplayName', sprintf('K×%.1f', param_variations(i))); hold on; fprintf('参数变化%.1f倍: 稳态误差=%.3f%%, 超调量=%.2f%%, 调节时间=%.3fs\n', ... param_variations(i), ss_error_var, overshoot_var, settle_time_var); end subplot(1, 2, 1); plot(t_sim, r, 'k--', 'LineWidth', 2, 'DisplayName', '参考'); xlabel('时间 (s)', 'FontSize', 10); ylabel('输出', 'FontSize', 10); title('不同参数下的系统响应', 'FontSize', 12, 'FontWeight', 'bold'); grid on; legend('Location', 'best', 'FontSize', 8); hold off; % 性能指标变化图 subplot(1, 2, 2); hold on; % 绘制稳态误差 plot(param_vals, ss_errors, 'b-o', 'LineWidth', 2, 'MarkerSize', 8); ylabel('稳态误差 (%)', 'FontSize', 10); if max(ss_errors) > 0 ylim_ss = [0, max(ss_errors)*1.2]; else ylim_ss = [0, 1]; end ylim(ylim_ss); % 绘制超调量(在次坐标轴) yyaxis right; plot(param_vals, overshoots, 'r-s', 'LineWidth', 2, 'MarkerSize', 8); ylabel('超调量 (%)', 'FontSize', 10); if max(overshoots) > 0 ylim_os = [0, max(overshoots)*1.2]; else ylim_os = [0, 10]; end ylim(ylim_os); xlabel('参数变化倍数', 'FontSize', 10); title('性能指标 vs 参数变化', 'FontSize', 12, 'FontWeight', 'bold'); grid on; legend('稳态误差', '超调量', 'Location', 'best'); %% 10. 抗干扰测试 fprintf('\n=========== 抗干扰测试 ===========\n'); % 延长仿真时间 t_dist = 0:T:3.0; r_dist = ones(size(t_dist)); % 在1秒时加入扰动 disturbance = zeros(size(t_dist)); dist_start = find(t_dist >= 1.0, 1); dist_end = find(t_dist >= 1.5, 1); if isempty(dist_start) dist_start = length(t_dist); end if isempty(dist_end) dist_end = length(t_dist); end disturbance(dist_start:dist_end) = -0.15; % -15%的负载扰动 % 仿真 [y_dist, t_dist_out] = lsim(sys_cl, r_dist + disturbance, t_dist); if size(y_dist, 2) > 1 y_dist = y_dist(:, 1); end % 计算扰动恢复性能 % 找到扰动后的稳态 post_dist_start = find(t_dist_out >= 2.0, 1); if isempty(post_dist_start) post_dist_start = length(y_dist); end post_dist_steady = mean(y_dist(post_dist_start:end)); recovery_error = abs(1 - post_dist_steady) * 100; % 计算恢复时间(回到±2%误差带) recovery_band = 0.02; recovery_start = dist_start; recovery_complete = []; for i = recovery_start:length(y_dist) if abs(y_dist(i) - 1) < recovery_band recovery_complete = i; break; end end if ~isempty(recovery_complete) recovery_time = t_dist_out(recovery_complete) - 1.0; else recovery_time = t_dist_out(end) - 1.0; end fprintf('扰动后稳态误差: %.3f%%\n', recovery_error); fprintf('扰动恢复时间: %.3fs\n', recovery_time); % 绘制抗干扰响应 figure('Position', [100, 100, 800, 400]); % 主响应图 subplot(2, 1, 1); plot(t_dist_out, r_dist, 'k--', 'LineWidth', 1.5); hold on; plot(t_dist_out, y_dist, 'b-', 'LineWidth', 2); plot([1.0 1.0], [0 1.2], 'r--', 'LineWidth', 1); plot([1.5 1.5], [0 1.2], 'r--', 'LineWidth', 1); fill([1.0 1.5 1.5 1.0], [1.2 1.2 0 0], 'r', 'FaceAlpha', 0.1, 'EdgeColor', 'none'); xlabel('时间 (s)', 'FontSize', 10); ylabel('输出转速', 'FontSize', 10); title('抗干扰性能测试', 'FontSize', 12, 'FontWeight', 'bold'); grid on; legend('参考输入', '系统输出', '扰动时段', 'Location', 'best'); % 添加恢复时间标注 if recovery_time < t_dist_out(end) - 1.0 plot([1.0+recovery_time 1.0+recovery_time], [0 1.2], 'g--', 'LineWidth', 1); text(1.0+recovery_time, 1.1, sprintf('恢复时间: %.3fs', recovery_time), ... 'Color', 'green', 'FontSize', 9); end % 误差图 subplot(2, 1, 2); e_dist = r_dist(:) - y_dist(:); plot(t_dist_out, e_dist*100, 'g-', 'LineWidth', 2); hold on; plot([0 t_dist_out(end)], [2 2], 'r--', 'LineWidth', 1); plot([0 t_dist_out(end)], [-2 -2], 'r--', 'LineWidth', 1); plot([1.0 1.0], [-20 20], 'r--', 'LineWidth', 1); plot([1.5 1.5], [-20 20], 'r--', 'LineWidth', 1); xlabel('时间 (s)', 'FontSize', 10); ylabel('跟踪误差 (%)', 'FontSize', 10); title('扰动期间误差变化', 'FontSize', 12, 'FontWeight', 'bold'); grid on; ylim([-20, 20]); %% 11. 控制器实现形式 fprintf('\n=========== 控制器实现 ===========\n'); % 获取控制器传递函数系数 [num_D, den_D] = tfdata(D_z, 'v'); [num_G, den_G] = tfdata(G_z, 'v'); fprintf('控制器差分方程:\n'); fprintf('u(k) = '); % 分子部分 for i = 1:length(num_D) if i == 1 fprintf('%.6f * e(k)', num_D(i)); else if num_D(i) >= 0 fprintf(' + %.6f * e(k-%d)', num_D(i), i-1); else fprintf(' - %.6f * e(k-%d)', abs(num_D(i)), i-1); end end end % 分母部分 for i = 2:length(den_D) if den_D(i) >= 0 fprintf(' - %.6f * u(k-%d)', den_D(i), i-1); else fprintf(' + %.6f * u(k-%d)', abs(den_D(i)), i-1); end end fprintf('\n'); fprintf('\n被控对象差分方程:\n'); fprintf('y(k) = '); for i = 1:length(num_G) if i == 1 fprintf('%.6f * u(k)', num_G(i)); else if num_G(i) >= 0 fprintf(' + %.6f * u(k-%d)', num_G(i), i-1); else fprintf(' - %.6f * u(k-%d)', abs(num_G(i)), i-1); end end end for i = 2:length(den_G) if den_G(i) >= 0 fprintf(' - %.6f * y(k-%d)', den_G(i), i-1); else fprintf(' + %.6f * y(k-%d)', abs(den_G(i)), i-1); end end fprintf('\n'); %% 13. 设计总结报告 fprintf('\n=========== 设计总结报告 ===========\n'); fprintf('1. 系统概述\n'); fprintf(' 被控对象: 直流电机速度控制\n'); fprintf(' 控制算法: 最小拍离散控制\n'); fprintf(' 采样周期: %.3f s (%.1f Hz)\n', T, 1/T); fprintf(' 总增益: %.1f\n', K_total); fprintf('\n2. 性能指标\n'); fprintf(' 稳态误差: %.3f%%\n', ss_error); fprintf(' 超调量: %.2f%%\n', overshoot); fprintf(' 调节时间: %.3f s\n', settle_time); fprintf(' 扰动恢复: %.3f s\n', recovery_time); fprintf('\n3. 稳定性分析\n'); fprintf(' 闭环稳定: %s\n', string(isStable)); fprintf(' 闭环极点: '); for i = 1:length(cl_poles) fprintf('%.3f ', cl_poles(i)); end fprintf('\n'); fprintf('\n4. 鲁棒性评估\n'); fprintf(' 参数变化范围: -30%% 到 +30%%\n'); max_ss_error = max(ss_errors); min_ss_error = min(ss_errors); max_overshoot = max(overshoots); min_overshoot = min(overshoots); if isempty(max_ss_error) || isempty(min_ss_error) ss_error_change = 0; else ss_error_change = max_ss_error - min_ss_error; end if isempty(max_overshoot) || isempty(min_overshoot) overshoot_change = 0; else overshoot_change = max_overshoot - min_overshoot; end fprintf(' 最大稳态误差变化: %.3f%%\n', ss_error_change); fprintf(' 最大超调量变化: %.3f%%\n', overshoot_change); fprintf('\n5. 实现建议\n'); fprintf(' - 使用16位定点数实现差分方程\n'); fprintf(' - 添加抗饱和逻辑防止积分饱和\n'); fprintf(' - 采样周期保持恒定\n'); fprintf(' - 添加故障检测和恢复机制\n'); fprintf('========================================\n'); %% 14. 保存设计结果 save('design_results.mat', 'D_z', 'G_z', 'sys_cl', ... 'ss_error', 'overshoot', 'settle_time', 'recovery_time'); fprintf('\n设计结果已保存到 design_results.mat\n'); fprintf('可以加载此文件进行进一步分析或实现。\n'); %% 15. C语言实现示例 fprintf('\n=========== C语言实现示例 ===========\n'); fprintf('// 直流电机最小拍控制器 - C语言实现\n'); fprintf('typedef struct {\n'); if length(den_D) > 1 fprintf(' float u_prev[%d]; // 控制量历史\n', length(den_D)-1); else fprintf(' float u_prev[1]; // 控制量历史\n'); end if length(num_D) > 1 fprintf(' float e_prev[%d]; // 误差历史\n', length(num_D)-1); else fprintf(' float e_prev[1]; // 误差历史\n'); end if length(den_D) > 1 fprintf(' float coeff_u[%d]; // 分母系数\n', length(den_D)-1); else fprintf(' float coeff_u[1]; // 分母系数\n'); end fprintf(' float coeff_e[%d]; // 分子系数\n', length(num_D)); fprintf('} MinBeatController;\n\n'); fprintf('float min_beat_control(MinBeatController* ctrl, float error) {\n'); fprintf(' // 计算控制量\n'); fprintf(' float u = 0.0f;\n'); fprintf(' \n'); fprintf(' // 误差项\n'); for i = 1:length(num_D) if i == 1 fprintf(' u += ctrl->coeff_e[%d] * error;\n', i-1); else fprintf(' u += ctrl->coeff_e[%d] * ctrl->e_prev[%d];\n', i-1, i-2); end end fprintf(' \n'); fprintf(' // 控制量反馈项\n'); for i = 2:length(den_D) fprintf(' u -= ctrl->coeff_u[%d] * ctrl->u_prev[%d];\n', i-2, i-2); end fprintf(' \n'); fprintf(' // 更新历史数据\n'); if length(den_D) > 2 fprintf(' for (int i = %d; i > 0; i--) {\n', length(den_D)-2); fprintf(' ctrl->u_prev[i] = ctrl->u_prev[i-1];\n'); fprintf(' }\n'); end if length(den_D) > 1 fprintf(' ctrl->u_prev[0] = u;\n'); end fprintf(' \n'); if length(num_D) > 2 fprintf(' for (int i = %d; i > 0; i--) {\n', length(num_D)-2); fprintf(' ctrl->e_prev[i] = ctrl->e_prev[i-1];\n'); fprintf(' }\n'); end if length(num_D) > 1 fprintf(' ctrl->e_prev[0] = error;\n'); end fprintf(' \n'); fprintf(' return u;\n'); fprintf('}\n'); fprintf('========================================\n'); %% 12. 性能分析函数(放在最后) function [ss_error, overshoot, settle_time] = analyze_performance(t, y, r) % 稳态误差计算 end_idx_start = round(0.8 * length(y)); if end_idx_start < 1 end_idx_start = 1; end end_idx = end_idx_start:length(y); ss_value = mean(y(end_idx)); ss_error = 0; r_mean = mean(r(end_idx)); if abs(r_mean) > 1e-6 ss_error = abs(r_mean - ss_value) / abs(r_mean) * 100; end % 超调量计算 overshoot = 0; if r_mean > 0 max_value = max(y); if max_value > ss_value overshoot = (max_value - ss_value) / ss_value * 100; end end % 调节时间计算(进入±2%误差带) error_band = 0.02; settle_time = t(end); for i = 1:length(y) if abs(y(i) - ss_value) < error_band * abs(ss_value) settle_time = t(i); break; end end end