惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Google DeepMind News
Google DeepMind News
S
SegmentFault 最新的问题
Project Zero
Project Zero
D
DataBreaches.Net
I
InfoQ
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Vercel News
Vercel News
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
I
Intezer
The Hacker News
The Hacker News
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
Help Net Security
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Scott Helme
Scott Helme
T
Threatpost
爱范儿
爱范儿
N
Netflix TechBlog - Medium
D
Docker
云风的 BLOG
云风的 BLOG
C
Cisco Blogs
K
Kaspersky official blog
H
Help Net Security
S
Secure Thoughts
T
Threat Research - Cisco Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Security @ Cisco Blogs
Cyberwarzone
Cyberwarzone
N
News and Events Feed by Topic
G
Google Developers Blog
Forbes - Security
Forbes - Security
博客园 - 三生石上(FineUI控件)
博客园 - 叶小钗
B
Blog
Google DeepMind News
Google DeepMind News
Recent Announcements
Recent Announcements
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
P
Privacy International News Feed
Spread Privacy
Spread Privacy
The Last Watchdog
The Last Watchdog

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12) Snack JSONPath 项目架构分析 Claude Code Buddy 小析:一个非核心功能,如何体现产品的细节完成度 AI新时代下的图床管理方案-Cloudflare图床+MCP+Skills方案指南 化繁为简:顺丰速运App如何通过 HarmonyOS SDK实现专业级空间测量 从零实现富文本编辑器#13-React非编辑节点的内容渲染 AI开发-python-langchain框架(3-23-OpenAI Functions风格Tool Calling智能助手) .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut PbootCMS 网站内容数量多导致访问慢?这些实用优化方案帮你提速! - 家兴网络技术工作室 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 网站漏洞怎么发现并修复?一篇实用指南(附完整流程) - 家兴网络技术工作室 开了 TUN 模式还是直连?90% 的人都踩过这个坑 Github日报|2026年04月12日 - AI一族 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术 Etsy 把 1000 个 MySQL 分片迁进 Vitess:425TB 数据背后的真正问题不是性能,而是运维规模 MicroPython LVGL基础知识和概念:底层渲染与性能优化 - FreakStudio 数据库草图算法 Python 潮流周刊#146:CPython 引入 Rust 的进展 - 豌豆花下猫 最小生成树 - mofei1116 红日靶场七:从外网入口、容器逃逸到 AD 接管的完整利用链复盘 - YouDiscovered1t 分享四款开源且实用的 Kafka 管理工具 - 追逐时光者 vLLM 权重加载机制全解析:从挑战到理想架构 LCT 学习笔记 - ACehomoxue Avalonia UI 12.0.0 正式发布:架构演进和性能飞跃 - 张善友 当 AI Agent 把调用链拉长,延迟开始成为一门生意 conhost.exe 无法显示 U+2717 - 145a 太秀了,我把自己蒸馏成了 Skill!已开源 - 程序员鱼皮 ASP.NET Core 内存缓存实战:一篇搞懂该怎么配、怎么避坑 基于 Ghostty 带有分割标签页和为 Claude 编程设计的通知终端 - BugShare AI 焊死入口:教育的“操作系统级”重塑 - 郝hai 初级Java开发工程师使用sql脚本编写代码的过程是简单而且不糊涂 - CoderOilStation Claude Code通关手册(六):MCP协议完全指南 - 暮色之狐 边框灯光环绕动画特效实现指南 - Newbe36524 开源:子木蒸馏版的 SEO 审计工具 seo-audit-skill v1.0 我所理解的Python元模型 【从0到1构建一个ClaudeAgent】规划与协调-TodoWrite - 程序员Seven Claude 和 Codex 在审计 Skill 上性能差异探究 - ACai_sec AScript如何实现中文脚本引擎 - rockey627 【渗透测试】HTB Season10 Garfield 全过程wp - dynasty_chenzi Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革 树状数组正确性证明 - AC-wyr 你的 AI 焦虑,可能比 AI 本身更危险——ATM 机没有消灭银行柜员,但恐慌消灭了你的判断力 - 我没有三颗心脏 一个拉胯的分库分表方案有多绝望?整个部门都在救火! - 冰河团队 动态规划入门必学之走方格问题 - Ofnoname PostgREST 与 PostgreSQL 角色权限配置全解析(生产级实践) - SheepDog1998 使用 UEFI 图形输出协议 GOP 在屏幕上显示图像的方法 - 阿源- Claude Code通关手册(五):组建你的AI专家团队,子代理系统 - 暮色之狐 一个程序员到架构师的催婚路之感悟(整整10年后的催婚相亲感悟) - MisterLip 用 Agent Skill 自动生成工作周报 - 赵康
TIG*算法的基本原理和仿真
Ilorich · 2026-06-28 · via 博客园_首页

一.创作声明

创作核心引用论文:Cheriet et al., IEEE OJVT, 2026, DOI: 10.1109/OJVT.2026.3659786,原论文GitHub相关库:https://github.com/hichemcher/TIG--3D-UAV-Planning。相关核心算法最终解释权归属TIG*算法提出者,还请多多支持。本文为本人原创,数据皆来源于仿真实验。


二.引言

无人机在复杂城市环境中的自主导航,离不开高效、平滑的三维路径规划。传统的RRT算法虽然应用广泛,但依赖随机采样,导致路径结果不确定、平滑性差;A*算法虽能保证最优性,但计算量随环境分辨率快速增长。

2026年,Cheriet等人在《IEEE Open Journal of Vehicular Technology》上发表了TIG*算法(Tangent Intersection Guidance Star),提出了一种基于几何推理的路径规划新方法。该算法通过计算无人机与障碍物之间的切线交点直接生成航点,以几何计算替代随机采样,在路径平滑度和计算效率上都有显著提升。

本文复现该算法,在MATLAB R2022b环境下完成仿真实验,并分享完整的配置、运行和结果分析过程。


三.算法原理

3.1核心思想

TIG*算法的核心思想是:用几何计算替代随机采样。当无人机前方遇到障碍物时,算法不依赖随机试探,而是精确计算绕行所需的切点,将这些切点作为候选航点,再通过A式搜索选择最优路径。

TIG*分为两种规划模式:S-TIG*静态规划和O-TIG*在线规划

模式 全程 运用环境
S-TIG* 静态切线交点制导 环境完全已知的情况
O-TIG* 在线切线交点制导 环境并非完全已知,需要在线计算

S-TIG*利用全局地图信息,一次性规划出完整路径;O-TIG*依靠机载传感器局部感知,遇到未知障碍时动态重规划。

3.2障碍物建模

与原始TIG算法使用椭圆不同,TIG*采用凸多边形棱柱表示障碍物。算法首先对不规则障碍物应用凸包算法(Convex Hull),将其转换为凸多边形,再向上拉伸形成3D棱柱。每个障碍物定义为:

V_{_{k}}=\left { \left ( x_{k1},y_{k1}\right),...,\left ( x_{kn} ,y_{kn}\right ) \right}

z\epsilon \left [ z_{kmin},z_{kmax} \right ]

论文指出(Section IV):“Polygonal representations provide a more accurate and flexible way to capture the complex geometries of real-world obstacles.”说明多边形表示法能更准确、更灵活地描述真实世界障碍物的复杂几何形状。

3.3虚拟椭圆与安全距离

为了确保无人机飞行安全,TIG*算法在真实障碍物周围构建“虚拟椭圆”,引入安全距离余量:

\left{\begin{matrix} a_{vir} = a + d & \ b_{vir} = b + d& \end{matrix}\right.

其中,d表示安全距离,即UAV与障碍物之间保持的最小间距。

这种设计的核心思想是:让无人机沿着虚拟椭圆的边界飞行,而非真实的障碍物边界,从而保证足够的安全余量。

3.4航点生成策略

TIG*算法的核心在于航点的几何生成方法。当从当前节点N到目标点T的直线被障碍物阻挡时,算法会通过切线交点来生成绕行航点,其基本原理如下:

1.从当前节点N向首个碰撞的障碍物绘制两条切线;

2.从目标点T向同一障碍物绘制两条切线;

3.不同切线的交点构成候选航点。

针对可能出现的几种不可行情况,例如切线平行、无交点等,算法采用虚拟椭圆技术,即航点被定义为虚拟椭圆与切线的交点,并选择距离当前节点较远的交点作为实际航点。设从当前节点N出发的切线交虚线椭圆与两点P_{1}P_{2},其中P_{1}P_{2}更接近N,所以选择较远点P_{2}作为航点,即:

W=P_{2}

这种“故意绕远路”的策略可以避免无人机在飞行过程中出现急转弯,让飞行轨迹在绕过障碍物后更加平缓流畅,做到“平滑”。

3.5启发式函数

为了在多个候选航点中选择最优者,TIG*算法定义了如下启发式函数:

其中:

1.D(N,W):从当前节点N到候选航点W的路径长度;

2.P:从N到W的切线段上穿过的障碍物数量;

3.α:障碍物数量的权重系数,用于衡量路径长度与安全性;

4.D(W,T):从W到目标点T的欧式距离估计。

启发式函数H(W)的设计体现了三个优化目标:

1.最短路径:通过D(N,W)+D(W,T)实现;

2.最少障碍交互:通过\alpha\cdot P实现,减少绕行次数;

3.高计算效率:启发式引导搜索向目标方向迅速收敛。

3.6路径平滑处理

TIG*算法生成的原始路径由直线段连接各航点构成,在航点处存在转角。这些转角无法被无人机直接执行,因此需要平滑处理。

TIG*算法采用二次贝塞尔曲线对每三个连续节点进行平滑处理:

其中P_{1}P_{2}P_{3}为三个连续的控制点(航点)。

经过平滑处理后,还需验证一下性能指标:

路径长度目标函数:

转弯角度目标函数:

3.7算法流程


四.仿真实现

4.1开发环境与工具

本研究的仿真实验采用以下开发环境:

项目 配置
操作系统 Windows11
编程环境 MATLAB R2022b
核心依赖 TIG-3D-UAV-Planning开源框架
可视化工具 MATLAB plot3三位绘图

在MATLAB R2022b环境中,TIG-3D-UAV-Planning框架的代码结构如下:

- main/:主入口文件,run_static.m用于静态规划,run_unknown.m用于在线规划

- algorithms/:S-TIG*和O-TIG*核心算法

- geometry/:碰撞检测、切线生成等几何计算

- waypoint_generation/:虚拟椭圆与航点生成

- visualization/:3D可视化绘图

- evaluation/:性能指标计算

- maps/:预定义测试地图

本报告使用run_static.m和map_city.mat进行仿真实验。

4.2核心代码实现

4.2.1虚拟椭圆

计算虚拟椭圆与安全距离

function inflated_obstacles = inflate_obstacles(obstacles, safety_distance)
% ------------------------------------------------------------
% Inflates polygonal prism obstacles by safety_distance
% in XY plane and Z direction.
% ------------------------------------------------------------

inflated_obstacles = obstacles;

for i = 1:length(obstacles)

    prism = obstacles{i};
    vertices = prism.vertices;

    % --- Inflate polygon in XY ---
    inflated_vertices = inflate_polygon(vertices, safety_distance);

    % --- Inflate in Z ---
    z_min = prism.z_range(1) - safety_distance;
    z_max = prism.z_range(2) + safety_distance;

    prism.vertices = inflated_vertices;
    prism.z_range  = [z_min z_max];
    prism.height   = z_max;

    inflated_obstacles{i} = prism;
end
end

function inflated_vertices = inflate_polygon(vertices, d)
% ------------------------------------------------------------
% Inflates convex polygon outward by distance d
% ------------------------------------------------------------

centroid = mean(vertices,1);
inflated_vertices = zeros(size(vertices));

for i = 1:size(vertices,1)
    direction = vertices(i,:) - centroid;
    direction = direction / norm(direction + eps);
    inflated_vertices(i,:) = vertices(i,:) + d * direction;
end
end

4.2.2计算转弯角度

function angle = calculate_angle(A, B, C)
% Calculate vectors AB and BC in 3D
AB = A - B;
BC = C - B;

% Check if any two points are the same
if all(round(A,6) == round(B,6)) || all(round(B,6) == round(C,6))
    angle = 180;
else
    % Calculate dot product and magnitudes of the vectors
    dotProduct = dot(AB, BC);
    magAB = norm(AB);
    magBC = norm(BC);

    % Calculate the cosine of the angle between AB and BC
    cosTheta = dotProduct / (magAB * magBC);

    % Ensure the cosine value is within the valid range for acos
    cosTheta = max(min(cosTheta, 1), -1);

    % Calculate the angle in radians and convert to degrees
    angle = acosd(cosTheta);
end
end

4.2.3获取感知内障碍物

function in_range_indices = obstacles_in_range(uav_pos, polygons, r)
    % polygons: array of structs with fields 'vertices' (Nx2) and 'height'
    % uav_pos: 1x3 [x, y, z]
    % r: sensing radius (scalar)
    
    in_range_indices = {};
    
    for i = 1:length(polygons)
        if is_obstacle_in_range(polygons{i}, uav_pos, r)
           
            in_range_indices = [in_range_indices polygons{i}] ; %#ok<AGROW>
        end
    end
end

function in_range = is_obstacle_in_range(polygon, uav_pos, r)
    % UAV position and sensing radius
    x_uav = uav_pos(1);
    y_uav = uav_pos(2);
    z_uav = uav_pos(3);
    
    % Polygon base and height
    base_xy = polygon.vertices;  % Nx2
    z_min = 0;
    z_max = polygon.height;

    % 1. Project UAV to polygon base plane (2D)
    dist_xy = point2poly_distance([x_uav, y_uav], base_xy);

    % 2. Compute vertical (z) distance to polygon
    if z_uav < z_min
        dz = z_min - z_uav;
    elseif z_uav > z_max
        dz = z_uav - z_max;
    else
        dz = 0;
    end

    % 3. Euclidean distance to polygon prism
    d = sqrt(dist_xy^2 + dz^2);

    % 4. Check if within sensing range
    in_range = d <= r;
end

function d = point2poly_distance(p, poly)
    % Compute shortest distance from point to 2D polygon
    if inpolygon(p(1), p(2), poly(:,1), poly(:,2))
        d = 0;
    else
        % Distance to polygon edges
        d = inf;
        n = size(poly,1);
        for i = 1:n
            v1 = poly(i,:);
            v2 = poly(mod(i,n)+1,:);
            d = min(d, point2segment_dist(p, v1, v2));
        end
    end
end

function d = point2segment_dist(p, a, b)
    % Distance from point p to segment ab
    ap = p - a;
    ab = b - a;
    t = dot(ap, ab) / dot(ab, ab);
    t = max(0, min(1, t));
    proj = a + t * ab;
    d = norm(p - proj);
end

4.2.4计算感知内航点

function waypoint = calculate_inrange_waypoint(waypoint,current_point,range)


    [x,y,z] = lineCircleIntersection(current_point.coor, waypoint.coor,range);
    %disp(["x and y",num2str([x,y])])
    %disp([current_point.coor,waypoint.coor,[range.x range.y]])
    if(length(x)==2)
        d1 = norm([x(1) y(1) z(1)]-waypoint.coor);
        d2 = norm([x(2) y(2) z(2)]-waypoint.coor);
        if(d1<d2)
            waypoint.coor =[x(1),y(1),z(1)] ;
            
        else
            waypoint.coor =[x(2),y(2),z(2)] ;

        end
    else
        waypoint.coor =[x,y,z] ;
    end
    waypoint.tang = [-1 -1 -1];

    waypoint.istop = current_point.istop;
    waypoint.currobs = current_point.currobs;

end
function [x_intersect, y_intersect z_intersect] = lineCircleIntersection(A, B,range)
    % Calculate direction vector of the line segment
    h = range.x;
    k = range.y;
    v = range.z;
    r = range.radius;
    x1 = A(1);
    x2 = B(1);
    y1 = A(2);
    y2 = B(2);
    z1 = A(3);
    z2 = B(3);
     dx = x2 - x1;
    dy = y2 - y1;
    dz = z2 - z1;
    % Calculate parameters for quadratic equation
    A = dx^2 + dy^2 + dz^2;
    B = 2 * (dx * (x1 - h) + dy * (y1 - k) + + dz * (z1 - v));
    C = (x1 - h)^2 + (y1 - k)^2 + (z1 - v)^2 - r^2;

    % Calculate discriminant
    discriminant = B^2 - 4 * A * C;

    if discriminant < 0
        % No intersection
        x_intersect = [];
        y_intersect = [];
        z_intersect = [];
    elseif discriminant == 0
        % One intersection
        t = -B / (2 * A);
        x_intersect = x1 + t * dx;
        y_intersect = y1 + t * dy;
        z_intersect = z1 + t * dz;
        if ~isBetween(x_intersect, x1, x2) || ~isBetween(y_intersect, y1, y2) || ~isBetween(z_intersect, z1, z2)
            % Intersection point lies outside the line segment
            x_intersect = [];
            y_intersect = [];
             z_intersect = [];
        end
    else
        % Two intersections
        t1 = (-B + sqrt(discriminant)) / (2 * A);
        t2 = (-B - sqrt(discriminant)) / (2 * A);
        x_intersect = [x1 + t1 * dx, x1 + t2 * dx];
        y_intersect = [y1 + t1 * dy, y1 + t2 * dy];
        z_intersect = [z1 + t1 * dz, z1 + t2 * dz];
        % Filter out points outside the line segment
        outside_idx = ~isBetween(x_intersect, x1, x2) | ~isBetween(y_intersect, y1, y2)| ~isBetween(z_intersect, z1, z2);
        x_intersect(outside_idx) = [];
        y_intersect(outside_idx) = [];
         z_intersect(outside_idx) = [];
    end
end
function inside = isBetween(value, lowerBound, upperBound)
    inside = value >= min(lowerBound, upperBound) & value <= max(lowerBound, upperBound);
end

4.3多环境仿真

4.3.1S-TIG*静态规划仿真

TIG*算法作者在提供的资料中包含了一个完整S-TIG*静态规划仿真仿真代码。

% ------------------------------------------------------------
% TIG*3D Planner
%
% Author: H. Cheriet
% Affiliation: USTO-MB 
% Year: 2026
% ------------------------------------------------------------


clc; clear; close all;

% ------------------------------------------------------------
% Setup Paths
% ------------------------------------------------------------
currentFolder = fileparts(mfilename('fullpath'));
projectRoot   = fileparts(currentFolder);
addpath(genpath(projectRoot));

% ------------------------------------------------------------
% Load Environment
% ------------------------------------------------------------
load(fullfile(projectRoot, "maps", "short1.mat"));

safety_distance = 2;  % meters

% ------------------------------------------------------------
% Run Planner
% ------------------------------------------------------------
[path, elapsedTime] = stig3d_planner(start, goal, mapSize, polygons, safety_distance);
fprintf('Computation Time: %.4f s\n', elapsedTime);

% ------------------------------------------------------------
% Metrics
% ------------------------------------------------------------
ds = 1.0;
metrics = compute_path_metrics(path, ds);

disp('--- Static TIG* ---')
disp(metrics)

% ------------------------------------------------------------
% Visualization
% ------------------------------------------------------------
env.start     = start;
env.goal      = goal;
env.polygons  = polygons;
env.mapSize   = mapSize;

results.path           = path;
results.path_smoothed  = [];
results.algorithm_name = "S-TIG*";

options.show_index        = false;
options.highlight_obstacle = -1;

display_environment_3d(env, results, options);

% ------------------------------------------------------------
% Animate UAV Motion
% ------------------------------------------------------------
anim_options.speed = 1;   % smaller = faster
anim_options.trail = false;   % leave red trail

%animate_path(path, anim_options);

在MATLAB R2022b中的运行结果如下图,其路径呈现平滑、避障合理的特点

4.3.2O-TIG*静态规划仿真

TIG*算法作者在提供的资料中包含了一个完整O-TIG*在线规划仿真仿真代码。

% ------------------------------------------------------------
% TIG*3D Planner
%
% Author: H. Cheriet
% Affiliation: USTO-MB 
% Year: 2026
% ------------------------------------------------------------


clc; clear; close all;

% ------------------------------------------------------------
% Setup Paths
% ------------------------------------------------------------
currentFolder = fileparts(mfilename('fullpath'));
projectRoot   = fileparts(currentFolder);
addpath(genpath(projectRoot));

% ------------------------------------------------------------
% Load Environment
% ------------------------------------------------------------
load(fullfile(projectRoot, "maps", "short3.mat"));

safety_distance = 2;  % meters
UAV_range.x = start(1);
UAV_range.y = start(2);
UAV_range.z = start(3);
UAV_range.radius = 100;  % meters

% ------------------------------------------------------------
% Run Planner
% ------------------------------------------------------------
[path, elapsedTime] = otig3d_unknown_planner(start, goal, mapSize, polygons,safety_distance,  UAV_range);
fprintf('Computation Time: %.4f s\n', elapsedTime);

% ------------------------------------------------------------
% Metrics
% ------------------------------------------------------------
ds = 1.0;
metrics = compute_path_metrics(path, ds);

disp('--- Unknown D-TIG* ---')
disp(metrics)

% ------------------------------------------------------------
% Visualization
% ------------------------------------------------------------
env.start     = start;
env.goal      = goal;
env.polygons  = polygons;
env.mapSize   = mapSize;

results.path           = path;
results.path_smoothed  = [];
results.algorithm_name = "D-TIG*";

options.show_index        = false;
options.highlight_obstacle = -1;

display_environment_3d(env, results, options);

% ------------------------------------------------------------
% Animate UAV Motion
% ------------------------------------------------------------
anim_options.speed = 1;   % smaller = faster
anim_options.trail = false;   % leave red trail

%animate_path(path, anim_options);

在运行该代码的朋友一定要注意一下第三十三行代码中原作者有一个书写错误,想要运行成功需要将这一行的“dtig3d_unknown_planner”改为“otig3d_unknown_planner”,对应algorithms文件夹里的static文件夹的otig3d_unknown_planner.m文件。

在MATLAB R2022b中的运行结果如下图,彰显了其在在线规划路径方面的优秀能力。


五.仿真实验与总结

5.1S-TIG*静态规划仿真实验

使用stig3d_planner进行静态环境下的路径规划,在完全已知地图中运行S-TIG*算法,MATLAB命令行输出结果如下:

结果分析:

输出项 数值 含义
Computation Time 0.2460 s 算法总计算时间
length 520.8927 规划路径总长度
TotalTurningAngle 0.9001 rad 路径总转弯角度
sharpTurns 0 急转弯数量
maxHeadingChange 0.2391 rad 最大航向变化量

5.2O-TIG*在线规划仿真实验

使用otig3d_unknown_planner进行未知环境下的在线路径规划,模拟无人机依靠机载传感器实时感知环境、边飞边规划的场景。传感器探测半径设置为100米,MATLAB命令行输出结果如下:

结果分析:

输出项 数值 含义
Computation Time 0.1367 s 算法总计算时间
length 602.8357 规划路径总长度
TotalTurningAngle 4.7668 rad 路径总转弯角度
sharpTurns 0 急转弯数量
maxHeadingChange 0.7696 rad 最大航向变化量

5.3S-TIG*静态规划与O-TIG*在线规划的区别与选择

通过上面的仿真数据我们可以看出两者的sharpTurns都是为0的,说明二者在路径规划时都避免了急转弯的产生,符合动力学原理,达到了使飞行路径更平滑的优化目标。

但是S-TIG*静态规划是在地图已知的情况下进行的路径规划,适合室内机器人的路径规划;而O-TIG*在线规划是在地图未知的情况下进行的路径规划,适合室外侦察无人机的路径规划。二者的使用场景有所不同,使用者应在特定的环境下做出合适的规划选择。


六.算法对比分析

6.1静态环境对比分析

评估指标 S-TIG* 3D-STG PRM* RRT* Informed RRT*
路径长度 最短 较长(+18.7%) 平均长17% 平均长11% 平均长4.15%
计算时间
<0.2s(最快<0.01s)
0.01(易失败) 慢93%以上 慢78%以上 慢93%以上
平滑度(转弯角度) 最小 较大 转弯多84% 转弯多83% 转弯多86%
成功率(密集地图) 100% 失败 部分成功 部分成功 部分成功
算法确定性 确定性 确定性 随机性 随机性 随机性

论文原文结论(Section VI-A):

“S-TIG generates feasible paths in less than 0.2 sec across most map categories and maintains an average well below 0.4 sec. S-TIG* reduces path length by approximately 17% compared to PRM* and 11% compared to RRT.”用具体的数据,清晰地对比了S-TIG和PRM、RRT*的差距,其快速且精准的特点说明了它比传统静态规划更优秀。在S-TIG基础上发展的S-TIG*也有这个优势。

6.2未知/动态环境对比结果

评估指标 O-TIG* 3D-DTG APF RH-RRT*
路径长度 最短 略长 长9-38% 较长
计算时间
<0.08s
较慢 最快(易失败) 0.14s以上
平滑度(转弯角度) 最小 较大 大50-90% 较大
成功率(密集地图) 100% 25%(大/高海拔地图) 低(振荡) 100%(不稳定)
算法确定性 极稳定 较差 极不稳定 中等

论文原文结论(Section VI-A):

“O-TIG consistently handles newly introduced obstacles with limited performance degradation across all scenarios. O-TIG* outperforms 3D-DTG, RH-RRT, and APF in path length, smoothness, and execution time.”这句话说明了O-TIG在未知或动态环境中具备极强的鲁棒性、综合优越性和实用性。在O-TIG基础上发展的O-TIG*也有这个优势。

6.3核心优势对比

对比维度 TIG* 传统算法
路径长度 平均缩短11-17% 随机采样导致路径次优
计算效率 <0.2秒完成规划 PRM/RRT*需0.5-2秒
路径平滑度 转弯减少70-86% 折线路径需后处理
成功率 100%(含密集地图) 部分算法失败率高达75%
确定性 结果可重现 随机采样导致结果不稳定
环境适应性 支持静态+动态双模式 需切换算法

七.总结

本文复现了 TIG* 算法,在MATLAB R2022b环境下完成了 S-TIG* 和 O-TIG* 两种模式的仿真实验。TIG* 算法实在原始TIG算法的基础上得到的。上实验结果表明:S-TIG* 适用于已知环境,计算时间0.5132秒,路径平滑无急转弯;O-TIG* 适用于未知环境,计算时间0.3082秒,具备动态重规划能力。两种模式的 sharpTurns 均为0,均满足无人机动力学约束。TIG* 算法通过几何推理替代随机采样,具有确定性高、计算快、路径平滑的优点,为无人机三维路径规划提供了一种高效可靠的解决方案。

项目资源:论文DOI 10.1109/OJVT.2026.3659786,

GitHub仓库 https://github.com/hichemcher/TIG--3D-UAV-Planning