news 2026/7/5 1:35:57

【无人机】基于Matlab模拟一个无人机包裹递送拟,城市场景设置、递送任务规划、飞行模拟

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【无人机】基于Matlab模拟一个无人机包裹递送拟,城市场景设置、递送任务规划、飞行模拟

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、算法改进、程序设计科研仿真。

🍎完整代码获取 定制创新 论文复现私信

🍊个人信条:做科研,博学之、审问之、慎思之、明辨之、笃行之,是为:博学慎思,明辨笃行。

🔥 内容介绍

1. 整体框架与功能概述

  • 脚本目的:执行无人机包裹递送的完整任务模拟,包括场景搭建、任务规划、飞行模拟及结果展示。

  • 所需工具箱:UAV ToolboxNavigation ToolboxAerospace Toolbox

2. 参数定义 (params)

  • dt:仿真时间步长,设置为0.05秒,用于离散化时间推进模拟。

  • mass:无人机质量,1.5千克。

  • g:重力加速度,9.81m/s²。

  • IxxIyyIzz:分别为无人机绕 x、y、z 轴的转动惯量。

  • tau:速度响应时间常数,0.3秒,用于描述无人机速度对控制输入的响应快慢。

  • cruiseAlt:巡航高度,25米,即无人机在飞行过程中保持的稳定高度。

  • cruiseSpeed:巡航速度,6m/s,是无人机飞行的目标速度。

  • lidarRange:激光雷达最大探测距离,50米。

  • lidarRays:激光雷达发射光线数量,72条,对应5度的分辨率。

  • safeRadius:避障激活半径,18米,当无人机距离障碍物小于此半径时启动避障机制。

  • repGain:斥力势场增益,25,用于调整避障时的斥力大小。

3. 步骤 1:设置城市场景 (setup_scenario)

  • 功能:创建一个包含建筑物的城市场景,用于无人机递送模拟。

  • 返回值:

    • sceneuavScenario对象,用于 3D 可视化和激光雷达模拟。

    • buildings:一个Nx5的矩阵,每一行代表一个建筑物,包含建筑物的中心坐标 (cx,cy)、半宽 (half_w)、半深 (half_d) 和高度 (height)。

  • 场景构建细节:

    • 使用uavScenario创建场景,并设置更新速率、参考位置和停止时间。

    • 添加地面平面、道路网格以及各个建筑物的模型,同时为建筑物分配不同的颜色。

    • 在原点和递送地点分别添加绿色和红色的平台。

4. 步骤 2:规划递送任务 (plan_mission)

  • 功能:生成无人机包裹递送任务的航路点。

  • 返回值:一个结构体wpts,包含以下字段:

    • positionsNx3的矩阵,存储航路点的三维坐标[x y z]

    • toaNx1的向量,记录每个航路点的到达时间(秒)。

    • totalTime:任务总时长(秒)。

    • labels:单元格数组,包含每个航路点的名称。

  • 任务规划细节:

    • 定义了从仓库出发、起飞、前往取货点、悬停取货、前往送货点、悬停送货、返回仓库并降落的一系列航路点。

    • 根据相邻航路点的距离和巡航速度计算每个航路点的到达时间,并考虑在取货和送货点的悬停时间。

5. 步骤 3:运行飞行模拟 (simulate_flight)

  • 功能:使用导航工具箱的航路点轨迹、一阶速度模型和势场避障方法,运行无人机飞行模拟,并通过 2D 光线投射模拟激光雷达。

  • 返回值:一个结构体logs,记录了模拟过程中的各种数据,包括时间、位置、速度、参考位置、姿态、激光雷达扫描数据以及避障是否激活等信息。

  • 模拟过程细节:

    • 从航路点轨迹获取参考位置和速度。

    • 通过比例 - 前馈控制计算期望速度,并将其限制在巡航速度内。

    • 使用势场避障方法调整期望速度,考虑与建筑物的距离并计算斥力。

    • 根据一阶速度响应模型更新无人机的速度和位置,并确保高度不低于地面。

    • 根据加速度计算无人机的近似姿态。

    • 0.5秒进行一次激光雷达扫描模拟,并记录相关数据。

    • 记录当前时间步的各项数据,并通过进度指示符显示模拟进度。

    • 根据给定的时间步长和任务总时长确定模拟的步数,并创建航路点轨迹对象。

    • 初始化无人机的位置、速度和姿态。

    • 在每个时间步中:

6. 步骤 4:可视化结果 (plot_results)

  • 功能:代码中未给出plot_results函数的具体实现,但从整体逻辑来看,它应该用于根据模拟记录的数据生成可视化结果,可能包括无人机的飞行轨迹、与建筑物的相对位置、激光雷达扫描结果等。

7. 其他函数

  • potential_field_avoidance:实现了基于斥力势场的避障算法。根据无人机当前位置和建筑物信息,计算斥力并调整期望速度,以避免与建筑物碰撞。如果无人机处于避障激活半径内,则标记为正在避障,并限制输出速度在1.5倍巡航速度内。

  • simulate_lidar:通过光线与轴对齐包围盒(AABB)的相交检测,模拟 2D 水平激光雷达扫描。在水平平面上均匀发射nRays条光线,找到每条光线与最近建筑物墙壁的交点,记录距离和角度信息,并以结构体形式返回扫描结果。

⛳️ 运行结果

📣 部分代码

function plot_results(scene, logs, wpts, buildings, params)%PLOT_RESULTS Generate all mission visualisation figures.%% Figure 1: 3D mission view (scenario + flight path)% Figure 2: Position tracking (X, Y, Z vs time)% Figure 3: Speed profile + obstacle avoidance activity% Figure 4: Lidar obstacle map (last scan)% Figure 5: UAV attitude (roll, pitch, yaw vs time)speed = vecnorm(logs.vel, 2, 2);%% Figure 1: 3D Mission Viewfig1 = figure('Name','UAV Package Delivery - 3D Mission', ...'Position',[50 50 1100 750]);ax1 = axes(fig1);show3D(scene, 'Parent', ax1);hold(ax1, 'on');plot3(ax1, logs.pos(:,1), logs.pos(:,2), logs.pos(:,3), ...'r-', 'LineWidth', 2.5, 'DisplayName', 'Actual path');plot3(ax1, logs.ref(:,1), logs.ref(:,2), logs.ref(:,3), ...'b--', 'LineWidth', 1.5, 'DisplayName', 'Reference path');% Mark waypointsfor i = 1:size(wpts.positions,1)p = wpts.positions(i,:);if i == 1 || i == size(wpts.positions,1)plot3(ax1, p(1), p(2), p(3), 'k^', 'MarkerSize',14, ...'MarkerFaceColor','k', 'HandleVisibility','off');elseplot3(ax1, p(1), p(2), p(3), 'go', 'MarkerSize',10, ...'MarkerFaceColor','g', 'HandleVisibility','off');endtext(ax1, p(1)+3, p(2)+3, p(3)+3, wpts.labels{i}, ...'FontSize', 8, 'Color', 'w');end% Avoidance segmentsavoidIdx = find(logs.avoidActive);if ~isempty(avoidIdx)plot3(ax1, logs.pos(avoidIdx,1), logs.pos(avoidIdx,2), logs.pos(avoidIdx,3), ...'y.', 'MarkerSize', 6, 'DisplayName', 'Avoidance active');endxlabel(ax1,'X (m)'); ylabel(ax1,'Y (m)'); zlabel(ax1,'Z (m)');title(ax1,'UAV Package Delivery — 3D Mission View');legend(ax1, 'Location','northwest');grid(ax1,'on');view(ax1, 45, 30);axis(ax1, 'tight');%% Figure 2: Position Trackingfigure('Name','Position Tracking', 'Position',[100 100 950 650]);lbls = {'X (m)','Y (m)','Z (m)'};for k = 1:3subplot(3,1,k);plot(logs.t, logs.pos(:,k), 'r', 'LineWidth',1.5, 'DisplayName','Actual');hold on;plot(logs.t, logs.ref(:,k), 'b--','LineWidth',1.2, 'DisplayName','Reference');% Mark waypoint arrivalsfor w = 1:length(wpts.toa)xline(wpts.toa(w), 'k:', 'HandleVisibility','off');endylabel(lbls{k}); grid on;if k == 1legend('Location','northeast');title('Position Tracking — Actual vs Reference');endif k == 3, xlabel('Time (s)'); endend%% Figure 3: Speed & Avoidance Activityfigure('Name','Speed Profile', 'Position',[150 150 950 500]);yyaxis left;plot(logs.t, speed, 'b', 'LineWidth', 1.5);yline(params.cruiseSpeed, 'b--', 'Cruise speed', 'LabelVerticalAlignment','bottom');ylabel('Speed (m/s)');yyaxis right;area(logs.t, double(logs.avoidActive), ...'FaceColor',[1 0.5 0], 'FaceAlpha', 0.3, 'EdgeColor','none');ylabel('Avoidance active');yticks([0 1]); yticklabels({'No','Yes'});xlabel('Time (s)');title('UAV Speed Profile and Obstacle Avoidance Activity');grid on; legend('Speed','Cruise speed','Avoidance');%% Figure 4: Lidar Obstacle MaplastIdx = find(~cellfun(@isempty, logs.lidar), 1, 'last');if ~isempty(lastIdx)scan = logs.lidar{lastIdx};figure('Name','Lidar Obstacle Map', 'Position',[200 200 650 650]);theta = scan.angles;r = scan.ranges;[px, py] = pol2cart(theta, r);% Colour by rangescatter(px, py, 10, r, 'filled');colormap('jet'); cb = colorbar;cb.Label.String = 'Range (m)';hold on;plot(0, 0, 'rv', 'MarkerSize',14, 'MarkerFaceColor','r', ...'DisplayName', sprintf('UAV pos (%.0f, %.0f, %.0f m)', ...logs.pos(lastIdx,1), logs.pos(lastIdx,2), logs.pos(lastIdx,3)));% Show max-range arctArc = linspace(0, 2*pi, 200);plot(params.lidarRange*cos(tArc), params.lidarRange*sin(tArc), ...'k:', 'LineWidth',0.8, 'DisplayName','Max range');xlabel('X — UAV frame (m)'); ylabel('Y — UAV frame (m)');title(sprintf('Lidar Obstacle Map (t = %.1f s)', logs.t(lastIdx)));legend('Location','northwest'); axis equal; grid on;clim([0 params.lidarRange]);end%% Figure 5: Attitudefigure('Name','UAV Attitude', 'Position',[250 250 950 600]);attLabels = {'Roll (deg)','Pitch (deg)','Yaw (deg)'};for k = 1:3subplot(3,1,k);plot(logs.t, logs.attitude(:,k), 'LineWidth',1.5);yline(0,'k--','HandleVisibility','off');ylabel(attLabels{k}); grid on;if k == 1, title('Estimated UAV Attitude'); endif k == 3, xlabel('Time (s)'); endendend

🔗 参考文献

🍅更多免费数学建模和仿真教程关注领取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 1:23:29

2026年联发科嵌入式岗位高频面试题带参考答案

大厂面试做到心里有数 本套题针对联发科嵌入式开发岗(覆盖芯片适配、驱动开发、系统移植、外设控制、物联网终端等方向)整理,遵循硬件模块前置、核心能力优先的考察逻辑,兼顾基础理论与项目实战,适配校招与社招面试备考。 总计:**46道** 分模块数量明细: 一、核心项目…

作者头像 李华
网站建设 2026/7/5 1:23:07

一条信息在 PowerMem 中的完整旅程,从写入到淘汰的工程拆解

存储和检索,随着数据量增长,系统会面临两个问题:检索信噪比持续下降,存储成本不可控。 香农信息论也解释了这件事:高概率事件的信息量趋近于零,不值得长期存储;低概率但关键事件的信息量极大&a…

作者头像 李华
网站建设 2026/7/5 1:22:42

提示词,上下文,RAG对llm来说都是一样的

首先我们得明确一个点,llm的本质根据前面每一个字预测下一个字,也就是自回归模型。举个例子,把“我爱”发给llm,llm会根据前前两个字预测第三个字可能是“你”,“吃”,“玩”,然后拼接成“我爱你…

作者头像 李华
网站建设 2026/7/5 1:21:37

系统调用错误处理:errno机制的线程安全与工程实践深度解析

系统调用错误处理:errno机制的线程安全与工程实践深度解析 一、errno的设计演进与线程安全革命 POSIX标准的errno看似简单却承载着核心职责。它是用户空间与内核空间错误传递的唯一桥梁。传统的全局变量实现在多线程环境下彻底失效。 flowchart TDA["用户进程调…

作者头像 李华
网站建设 2026/7/5 1:20:28

为什么说一面健康墙,七分在腻子?

装修这事儿,说起来门道一大堆。有人盯着地板砖的花纹挑了三个月,有人为了一款沙发跑遍全城家具城。可你要问他腻子选的啥牌子?十有八九一脸懵——"腻子?那不是随便买点就行吗?"还真不是。墙面这东西&#xf…

作者头像 李华