✅作者简介热爱科研的Matlab仿真开发者擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 往期回顾关注个人主页Matlab科研工作室 关注我领取海量matlab电子书和数学建模资料个人信条格物致知,完整Matlab代码获取及仿真咨询内容私信。 内容介绍一、背景一四旋翼飞行器的特点与控制挑战四旋翼飞行器作为一种典型的欠驱动系统具有结构简单、机动性强、垂直起降等优点在航拍、物流配送、农业植保、搜索救援等领域得到了广泛应用。然而其动力学模型具有高度非线性、强耦合性以及易受外界干扰等特性这给精确控制带来了巨大挑战。例如在执行航拍任务时四旋翼飞行器需要在复杂多变的环境中保持稳定姿态以获取高质量的图像在物流配送中要准确地跟踪设定的飞行路径将货物安全送达目的地。因此设计一种高效的控制策略对于四旋翼飞行器的稳定运行和精确控制至关重要。二传统控制方法的局限性传统的单环控制方法如单纯的比例 - 积分 - 微分PID控制在处理四旋翼飞行器这种复杂系统时存在一定局限性。由于四旋翼飞行器的姿态和位置控制之间存在强耦合关系单环控制难以同时兼顾姿态调整和位置跟踪的性能尤其在面对快速变化的外界干扰时控制效果往往不尽如人意。例如当遇到突然的阵风干扰时单环控制可能无法迅速有效地调整飞行器的姿态导致飞行轨迹偏离设定路径。三双环纯 P 控制器级联的优势基于双环纯 P 控制器级联的控制策略通过外环调节姿态、内环控制电机推力的方式能够有效地解耦姿态和位置控制之间的复杂关系增强系统对干扰的抑制能力提高设定点跟踪的精度。这种控制策略结构相对简单易于实现且在实际应用中表现出良好的动态性能和鲁棒性。它能够快速响应外界干扰使四旋翼飞行器在各种复杂环境下都能稳定地跟踪设定点满足不同应用场景的需求。二、原理一四旋翼飞行器动力学模型基础三快速干扰抑制和精确设定点跟踪原理快速干扰抑制当四旋翼飞行器受到外界干扰如阵风、气流等时飞行器的姿态会发生变化导致实际姿态角与设定姿态角之间产生误差。外环姿态控制器检测到这个误差后迅速计算出期望的力矩变化通过内环电机推力控制器快速调整电机推力使飞行器产生相应的力矩来抵消干扰的影响恢复到设定的姿态。由于双环控制结构能够快速响应姿态误差并且内环直接作用于电机推力所以能够在短时间内抑制干扰保持飞行器的稳定姿态。例如当遇到阵风使飞行器产生滚转偏差时外环控制器立即计算出纠正滚转的期望力矩内环快速调整电机推力使飞行器恢复到正确的滚转姿态。精确设定点跟踪在跟踪设定点时外环姿态控制器根据设定的姿态值与实际姿态值的误差不断调整期望的力矩使飞行器的姿态逐渐向设定姿态靠近。内环电机推力控制器则根据外环的期望力矩精确地控制电机推力确保飞行器按照期望的姿态变化从而实现精确的位置跟踪。由于外环和内环的协同工作能够不断地修正姿态和位置误差使飞行器准确地跟踪设定点。例如在飞行器按照设定路径飞行时外环根据路径所需的姿态调整期望力矩内环通过精确控制电机推力使飞行器保持正确姿态从而精确地沿着设定路径飞行。基于双环纯 P 控制器级联的控制策略通过合理设计外环和内环的控制参数能够有效地实现四旋翼飞行器的快速干扰抑制和精确设定点跟踪为四旋翼飞行器在各种复杂环境下的稳定运行和精确控制提供了有力保障。⛳️ 运行结果 部分代码positionData out.position.Data;attitudeData -out.attitude.Data;x squeeze(positionData(1, 1, :));y squeeze(positionData(2, 1, :));h -squeeze(positionData(3, 1, :));% Set up the figurefig1 figure; hold on;view(3);grid on;set(fig1, Position, [100, 000, 1200, 700]); % Wider and taller window% Partition settings and UAV arm lengthpartition size(x, 1) / 3;lineLength l * 100 / 2;dataLength size(x, 1);bounds max([max(abs(x)), max(abs(y)), max(abs(h))]) 5;% Set axis limits explicitly so they remain constant throughoutxlim([-bounds, bounds]);ylim([-bounds, bounds]);zlim([-bounds, bounds]);xlabel(X-axis);ylabel(Y-axis);zlabel(H-axis);title(Flight Data of UAV);% Plot the entire flight trajectory in the backgroundplot3(x, y, h, b-, LineWidth, 2);% Plot the UAV in its initial position (one marker)uavHandle plot3(x(1), y(1), h(1), ko, MarkerFaceColor, k, MarkerSize, 3);% InitializesampleIndex round(0 * dataLength / partition);sampleIndex min(max(sampleIndex, 1), dataLength);roll squeeze(attitudeData(1, 1, sampleIndex));pitch squeeze(attitudeData(2, 1, sampleIndex));yaw squeeze(attitudeData(3, 1, sampleIndex));R eul2rotm([yaw, pitch, roll], ZYX);midpoint [x(sampleIndex); y(sampleIndex); h(sampleIndex)];% UAV arms (rotated according to its orientation)uavArm1 [[x(sampleIndex), x(sampleIndex) lineLength/2];[y(sampleIndex), y(sampleIndex)];[h(sampleIndex), h(sampleIndex)]];uavArm1 rotatePoints(uavArm1, R, midpoint);uavArm3 [[x(sampleIndex) - lineLength/2, x(sampleIndex)];[y(sampleIndex), y(sampleIndex)];[h(sampleIndex), h(sampleIndex)]];uavArm3 rotatePoints(uavArm3, R, midpoint);uavArm2 [[x(sampleIndex), x(sampleIndex)];[y(sampleIndex) - lineLength/2, y(sampleIndex) lineLength/2];[h(sampleIndex), h(sampleIndex)]];uavArm2 rotatePoints(uavArm2, R, midpoint);% Propellerscircle1 propellerPoints(midpoint, [lineLength / 2, 0], R);circle2 propellerPoints(midpoint, [-lineLength / 2, 0], R);circle3 propellerPoints(midpoint, [0, lineLength / 2], R);circle4 propellerPoints(midpoint, [0, -lineLength / 2], R);% Pre-allocate handles for arms and propellersarm1Handle plot3(uavArm1(1, :), uavArm1(2, :), uavArm1(3, :), black, LineWidth, 2); % Red line for arm1arm2Handle plot3(uavArm2(1, :), uavArm2(2, :), uavArm2(3, :), r-, LineWidth, 2); % Red line for arm2arm3Handle plot3(uavArm3(1, :), uavArm3(2, :), uavArm3(3, :), r-, LineWidth, 2); % Red line for arm2propHandle1 plot3(circle1(1, :), circle1(2, :), circle1(3, :), blue, MarkerSize, 5); % Green dot for propeller1propHandle2 plot3(circle2(1, :), circle2(2, :), circle2(3, :), blue, MarkerSize, 5); % Green dot for propeller2propHandle3 plot3(circle3(1, :), circle3(2, :), circle3(3, :), g., MarkerSize, 5); % Green dot for propeller3propHandle4 plot3(circle4(1, :), circle4(2, :), circle4(3, :), g., MarkerSize, 5); % Green dot for propeller4disp(true)% Loop to animate UAV movementwhile truefor part 1: partitionsampleIndex round(part * dataLength / partition);sampleIndex min(max(sampleIndex, 1), dataLength);roll squeeze(attitudeData(1, 1, sampleIndex));pitch squeeze(attitudeData(2, 1, sampleIndex));yaw squeeze(attitudeData(3, 1, sampleIndex));R [roll, pitch, yaw];midpoint [x(sampleIndex); y(sampleIndex); h(sampleIndex)];% UAV arms (rotated according to its orientation)uavArm1 [[x(sampleIndex), x(sampleIndex) lineLength/2];[y(sampleIndex), y(sampleIndex)];[h(sampleIndex), h(sampleIndex)]];uavArm1 rotatePoints(uavArm1, R, midpoint);uavArm3 [[x(sampleIndex) - lineLength/2, x(sampleIndex)];[y(sampleIndex), y(sampleIndex)];[h(sampleIndex), h(sampleIndex)]];uavArm3 rotatePoints(uavArm3, R, midpoint);uavArm2 [[x(sampleIndex), x(sampleIndex)];[y(sampleIndex) - lineLength/2, y(sampleIndex) lineLength/2];[h(sampleIndex), h(sampleIndex)]];uavArm2 rotatePoints(uavArm2, R, midpoint);% Propellerscircle1 propellerPoints(midpoint, [lineLength / 2, 0], R);circle2 propellerPoints(midpoint, [-lineLength / 2, 0], R);circle3 propellerPoints(midpoint, [0, lineLength / 2], R);circle4 propellerPoints(midpoint, [0, -lineLength / 2], R);% Update UAV position in the plotfigure(fig1);set(uavHandle, XData, x(sampleIndex), YData, y(sampleIndex), ZData, h(sampleIndex));% Update the arms (as lines)set(arm1Handle, XData, uavArm1(1, :), YData, uavArm1(2, :), ZData, uavArm1(3, :));set(arm2Handle, XData, uavArm2(1, :), YData, uavArm2(2, :), ZData, uavArm2(3, :));set(arm3Handle, XData, uavArm3(1, :), YData, uavArm3(2, :), ZData, uavArm3(3, :));% Update the propellers (as circles or points)set(propHandle1, XData, circle1(1, :), YData, circle1(2, :), ZData, circle1(3, :));set(propHandle2, XData, circle2(1, :), YData, circle2(2, :), ZData, circle2(3, :));set(propHandle3, XData, circle3(1, :), YData, circle3(2, :), ZData, circle3(3, :));set(propHandle4, XData, circle4(1, :), YData, circle4(2, :), ZData, circle4(3, :));% Pause for animation effectpause(0.009);endendhold off; 参考文献往期回顾扫扫下方二维码