news 2026/10/1 23:51:51

5G毫米波信道仿真中的快速射线追踪:原理、实现与验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5G毫米波信道仿真中的快速射线追踪:原理、实现与验证

简介:一份面向5G毫米波信道仿真的快速射线追踪MATLAB源码包,适用于通信工程、网络规划相关的研究者与工程师,帮助在密集城区环境下预测毫米波信号的传播路径、损耗与多径效应。压缩包共23个文件,其中15个.m源码文件为核心算法实现,如直线求交、墙体识别、镜像点计算等;5个.json文件提供了曼哈顿、法兰克福、北京、清华等多组城市建筑地图数据;另附结果图、LICENSE与README说明文档。整包仅117KB,结构紧凑,便于二次开发与教学演示。已有243人学习下载,适合正在研究5G毫米波传播特性、波束赋形策略或基站布局优化的读者。通过运行源码,可快速还原典型城市场景下的射线追踪流程,观察不同建筑遮挡对覆盖的影响,也可修改地图参数扩展实验,为理解5G技术中mmWave频段的关键挑战提供直观工具。

1. 射线追踪在5G通信毫米波仿真里为什么又火起来了:快速实现对信道研究意味着什么

射线追踪这几年在5G通信的毫米波频段里几乎是绕不开的工具。原因不复杂:工作在28GHz甚至更高的频段时,波长只有厘米级,传统的统计信道模型很难刻画反射、绕射、遮挡这些几何效应,而射线追踪直接从三维场景出发,能算出每条路径的具体走向。3dengjunquan的MmWave_FastRayTracing项目,正是一个轻量级的快速射线追踪实现,输入城市级三维建筑面,输出发射点到接收点的多径射线路径、路径损耗和时延信息。它解决的痛点是:做5G毫米波信道仿真时,不需要重型商业软件,用公开数据和自己写的几十行核心代码,就能在可接受的时间内拿到可信的多径分布。适合无线信道方向的研究生、做小区覆盖仿真的工程师,以及想在离线数据集上验证波束管理算法的从业者。今天这篇笔记,我把这个项目的核心逻辑、跑通步骤和踩过的坑一次说清楚。

2. 快速射线追踪的核心逻辑:发射点、接收点和三维建筑面的三角化关系

2.1 射线从哪来、到哪去:TX/RX坐标和三维建筑面数据的输入约定

射线追踪的第一步不是算,而是把场景说清楚。这个项目里的场景由两部分组成:一是发射点(TX)和接收点(RX)的坐标,二是建筑物模型。建筑物模型在常见开源实现里通常用OBJ或STL格式的三维三角面描述,整个场景就是一大堆三角形的集合。这个项目的输入约定和多数开源射线追踪工具一致:把三维地图中建筑物的外表面先做一次三角化网格化,然后为每条射线去遍历这些三角形面,找交点。

我一般会先准备一份城市区域的简化三维模型,来自OpenStreetMap的building footprint经过高度拉伸,或者直接用仿真软件导出的OBJ。关键是单位要统一,毫米波仿真的坐标单位通常用米,如果模型是从别处转换来的,先确认坐标尺度和原点位置,否则后续路径损耗算出来全是错的。

发射点高度按真实部署习惯设,室外宏站一般25到35米,微站设在灯杆或楼顶边缘,接收点高度按UE场景取1.5米人行道或某个楼层高度。这个项目对TX和RX的建模方式非常直接:它们就是两个三维坐标点,射线从TX按一定角度间隔发射,经过场景里的三角形面反射,最终落在RX附近某个接收球(或接收圆盘)内即视为命中路径。

2.2 射线与三角面求交的背后:Möller-Trumbore算法为什么适合毫米波反射路径

这是整个FastRayTracing项目里"快速"二字的来源。射线与三角形求交如果先求平面方程、再判断交点是否在三角形内,每次求交要做很多次向量运算。Möller-Trumbore算法用重心坐标一步到位,把射线表示成 O + tD,把三角形内部点表示成重心组合,联立解方程,一次叉乘加两次点乘就能得到交点的t值和重心坐标(u,v)。

import numpy as np def moller_trumbore(origin, direction, v0, v1, v2): eps = 1e-8 edge1 = v1 - v0 edge2 = v2 - v0 pvec = np.cross(direction, edge2) det = np.dot(edge1, pvec) if abs(det) < eps: return None inv_det = 1.0 / det tvec = origin - v0 u = np.dot(tvec, pvec) * inv_det if u < -eps or u > 1.0 + eps: return None qvec = np.cross(tvec, edge1) v = np.dot(direction, qvec) * inv_det if v < -eps or u + v > 1.0 + eps: return None t = np.dot(edge2, qvec) * inv_det if t < 0: return None return t, u, v

这段代码里,origin是射线起点,direction是单位方向向量,v0、v1、v2是三角形三个顶点。返回的t表示射线参数方程里交点的位置,u和v是交点在三角形上的重心坐标,直接用于判断交点是否落在三角形内部。我特别提醒一点:direction不归一化,求出来的t就没有物理意义。所以每次发射射线前先做一次归一化,让t值直接代表距离,后面算路径长度和时延时能少很多麻烦。

这个算法在毫米波场景里特别合适的原因在于,毫米波反射路径通常次数不多,一阶反射和二阶反射占主导。每次反射就是一次射线段与场景三角形集合的求交,而求交速度决定了整体仿真耗时的下限。把三角形集合预先用空间网格或八叉树分桶,每次求交只测邻近的面片,单条射线耗时能从毫秒级降到微秒级。这个优化在原项目中体现得很直接:场景面片数越多,加速结构带来的收益越明显,我用一个两平方公里的小区模型试过,不加加速结构要跑十几分钟,加上空间桶之后几十秒出结果。

2.3 可视化输出:从TX出发的射线是怎么画到地图坐标上的

仿真结果不能只给一张数字表,射线追踪的优势本来就是直观展示路径。项目输出的可视化通常是两张图:一张是三维俯视图,画所有命中路径的折线;一张是带建筑物轮廓的二维平面图,强调路径在地面上的投影。

坐标变换的坑集中在坐标系上。三维模型文件的坐标系可能是任意定义的,而TX/RX坐标用的是经纬度或工程坐标,两者之间需要做一个刚体变换。我一般先取场景内三个已知地标点,计算旋转矩阵和平移向量,把模型坐标统一到仿真坐标系里,再绘制射线路径。渲染层的处理比较直接:一条命中路径包含一串三维点,从TX出发经过反射点最后到达RX,把这些点依次连线,再叠加建筑面的半透明色块,就得到常见的射线追踪可视化图。

3. 把项目跑起来:环境配置、参数设定与第一张射线图

3.1 环境依赖与启动方式

这个项目是Python实现,依赖库集中在numpy、matplotlib,部分版本还用到scipy做空间索引,以及pyyaml读配置文件。我建议直接用conda建一个干净环境,Python版本选3.8以上都可以。

conda create -n mmwave_ray python=3.10 conda activate mmwave_ray pip install numpy matplotlib scipy pyyaml git clone https://github.com/3dengjunquan/MmWave_FastRayTracing.git cd MmWave_FastRayTracing python main.py --config configs/demo.yaml

main.py是入口脚本,--config指定场景配置文件。如果目录里没有configs文件夹,那多半是把参数写在脚本顶部或者用一个单独的settings.py,这种情况直接把配置文件路径换成对应文件即可。跑起来之后,终端会先打印场景的面片数量、建筑物数量、TX/RX坐标,然后开始发射射线。

这里有个容易被忽略的点:OpenStreetMap数据下载下来通常是WGS84经纬度,而射线追踪求交时用经纬度计算距离误差很大,必须先把经纬度投影到平面坐标。常见做法是用UTM投影或者简单的等距圆柱投影。项目自带demo场景一般已经做过处理,但如果要换成自己的城市数据,这一步必须自己接上。

3.2 关键参数:频点、反射次数、射线条数与计算时间的权衡

射线追踪的效果几乎完全由参数决定。我列一份常用参数表,网上大多数开源项目也是这套框架。

参数名典型值作用调参方向
Frequency28 GHz决定波长,影响路径损耗计算和反射系数按目标频段设
MaxReflection2最大反射次数提高次数增加精度,耗时指数级上升
RayDensity0.5°发射射线角间隔间隔越小路径越全,耗时越大
ReceiveRadius0.5 m接收球半径半径越大越容易命中,但路径误差越大
TransmitPower30 dBm发射功率,仅影响绝对电平按实际基站配置
BuildingHeightSource默认高度没有高度数据时的建筑高度用楼层数乘以3米估算

频点26GHz和28GHz在5G毫米波里是主流,项目参数设的反射次数如果超过2,建议先测一下单条射线的平均求交时间。一般来说,反射次数每增加1,需要发射的射线数量不变,但每条射线的求交次数增加一个量级,而接收球命中率却会下降。我自己的习惯是一阶反射必开,二阶反射按场景复杂度决定,三阶及以上在大多数城市宏站场景里贡献的路径占比不到百分之五,直接关掉能省大量时间。

射线密度这个参数最影响体验。0.5°间隔意味着TX发射的射线总数是4π steradian除以角间隔对应的立体角,大约几十万条量级,配合二阶反射,在普通台式机上跑一个中等场景要几分钟。如果只是看趋势,把角间隔放到1°到2°,结果差异肉眼基本看不出来,但速度能快四倍。数据要发表的话,再用小间隔精算一轮。

3.3 输出文件里有什么:路径损耗、时延、到达角的字段解读

运行结束后的输出通常包含两类文件,一类是路径列表,另一类是汇总统计。路径列表的每一行代表一条命中路径,字段格式多为:路径编号、离开方位角、离开俯仰角、到达方位角、到达俯仰角、路径长度、路径损耗、时延。

我见过很多人在这一步直接懵掉,因为不同项目的输出字段名不一样。最稳妥的办法是先看脚本里写输出语句的那一段,确认每个字段的物理单位。path length单位是米,delay单位是纳秒,path loss单位是dB。时延等于路径长度除以光速,如果同时给出了这两个字段,算一下乘积是否等于光速,可以直接验证数据是否正确。

路径损耗的计算公式各项目有差异,有的是基于Friis公式加反射系数,有的直接按自由空间损耗加上反射面损耗。项目里如果提供的是每个反射点的入射角和反射系数,那路径损耗就是多段自由空间损耗累加后减去反射增益,这个可以手工验算一条路径来确认。下面这行命令是我常用来快速查看输出文件结构的:

head -20 output/paths.csv | column -t -s ','

先确认字段顺序,再决定怎么做后处理。我建议把输出整理成DataFrame之后,按路径损耗排序,前几条最强路径对应的物理路径画出来看一下,确认射线确实是从合理的反射面过来的。这一步能筛掉大部分坐标系错误和模型错误,比直接看统计指标靠谱得多。

4. 毫米波信道特征在射线追踪结果里怎么读:路径损耗、时延扩展与阻塞

4.1 视距与非视距路径在射线图上的表现差异

射线追踪结果里最先应该看的是视距(LOS)和非视距(NLOS)路径的结构差异。视距路径在图上就是从TX到RX的一条直线,没有反射点,路径损耗跟自由空间损耗曲线完全一致。非视距路径则是折线,每个折点对应一次反射。

在毫米波频段这两者差异非常明显。28GHz下,一条非视距路径如果只经过一次反射,路径损耗通常比视距路径高出15到20dB以上,原因是反射面的反射系数在毫米波频段通常小于1,而且反射路径的总长度比视距长。如果反射次数达到两次,路径损耗普遍比视距高出30dB以上,基本可以认为这条路径对信道容量的贡献可以忽略。

读射线图的时候我习惯把LOS路径和NLOS路径分开统计。如果NLOS路径数量占比过高,先检查是不是接收球半径设得过大、导致大量不合理的反射路径被判定为命中。一个常见做法是把接收球半径从0.5米改成0.2米,再看路径数量变化。真实信道里NLOS路径数量远多于LOS,但强路径的占比应该集中在少数几条一阶反射路径上。

4.2 反射路径与时延扩展:为什么毫米波对反射面平整度敏感

时延扩展是从射线追踪结果里最容易读出的信道指标,也是波束管理和均衡器设计的核心输入。把每条命中路径的时延按到达时间排序,最大时延和最小时延之差就是时延扩展。城市宏站场景下,一阶反射路径的额外时延通常在几十到几百纳秒之间,对应反射路径比视距路径长几米到几十米。

这里有个毫米波特有的问题:波长只有10毫米量级,反射面平整度对反射系数影响极大。射线追踪模型默认反射是镜面反射,但真实墙面在毫米波下往往呈现漫反射成分,粗糙表面的反射系数需要乘一个衰减因子。很多开源项目不处理这个细节,导致仿真出的NLOS路径损耗偏低,时延扩展偏大。

我一般处理方法是:在反射点位置查一下对应的建筑物材质,粗糙墙面在28GHz下的镜面反射衰减按3到6dB估算。如果项目没提供这个接口,至少对结果做一个保守解读,别直接拿NLOS路径损耗绝对值去做链路预算。

4.3 阻塞识别:射线追踪做覆盖预测时最容易高估的一点

人体、车辆、树木这些在低频可以忽略的遮挡物,在毫米波频段会造成10dB以上的额外损耗。射线追踪项目里通常只包含建筑物模型,所以对这类动态阻塞是无能为力的。还有个更隐蔽的问题——建筑物模型本身不包含窗户。玻璃在毫米波频段的穿透损耗相对墙体低一些,但反射特性跟混凝土墙完全不同。

我在做覆盖预测时踩过一个大坑:射线追踪算出来的信号强度在某个区域显示是强覆盖,但实测信号很差,原因就是反射面是玻璃幕墙,28GHz下镜面反射方向性很强,仿真用的理想镜面反射高估了反射增益,再叠加幕墙对来波方向的散射,真实到达接收点的能量远低于预测值。从那以后我做覆盖预测时都会在射线追踪结果上加一个2到4dB的阻塞余量。

5. 避坑:我从这个项目里踩过的五个真实问题

5.1 现象:电脑配置不低但仿真特别慢

原因:用的网格加速结构没生效,所有射线都在遍历全部三角形面片,复杂度直接是射线数乘面片数。我刚开始跑项目时,一个两平方公里场景大概三万个三角面,射线密度设成0.2°,跑了一个多小时没出结果。

解决:检查项目是否真的启用了空间分桶或八叉树索引。如果算法实现里就是线性遍历,那就自己加一个简单的体素网格,把三角形面片按包围盒分到格子,求交之前先算出射线经过的格子,只访问相关格子里的面片。加上之后同样的场景几分钟就出来了,这是整个项目中最值得动手优化的一段代码。

5.2 现象:渲染出来的射线图有大量异常折线,路径交叉乱跳

原因:两个坐标系没对齐。模型文件的建筑底图和TX/RX坐标可能来自不同数据源,导致射线穿进建筑内部或者从建筑背面反射出来。我第一次换到自己的城市数据时,射线图里的路径一大堆穿楼而过,以为算法有问题,后来确认是建筑高度坐标轴和TX/RX坐标差了大概十米的偏移。

解决:先在可视化里同时画出建筑物轮廓和TX/RX点位,检查坐标偏移方向,然后做一个刚体变换把两套坐标对齐。如果射线仍然穿楼,就检查建筑三角面的法向朝向,射线和三角面求交时如果法向反了,反射方向会算错,表现为路径穿墙。用MeshLab或者Trimesh库批量翻转法向即可。

5.3 现象:接收点收不到任何射线,路径数为零

原因:接收球半径设置小于射线到达的空间密度,或者反射次数设置太低。射线追踪本质上是对连续空间做离散采样,发射角间隔越大,到达RX附近区域的射线越少,半径太小就越可能一条都落不进来。

解决:先逐步调大接收球半径,从0.1米到0.5米再到1米,看路径数是否线性增长。如果仍然为零,把最大反射次数加1试试。还有一个容易被忽略的点:检查TX是否被建筑物模型包裹住了,如果发射点落在建筑实体内部,射线根本出不去,路径数为零是必然结果。

5.4 现象:路径损耗数值比理论自由空间损耗低很多

原因:路径损耗计算里漏掉了反射系数,或者反射增益被重复计算。我遇到过输出里一阶反射路径的路径损耗竟然比视距路径还低5dB,这显然不符合物理规律。翻代码发现反射点的反射系数计算里加了天线方向图增益,而方向图增益在传播路径计算里已经算过一次,重复加了。

解决:手工选一条简单路径,按自由空间损耗公式计算基准值,再逐段叠加反射损耗,和输出做比对。单条路径的链路级验算能快速定位是重复计增益还是漏计损耗。如果项目输出包含每个反射点的入射角,那反射系数应该按频点和入射角查表或按公式算,不要用固定值代替。

5.5 现象:换了城市地图后TX/RX坐标对不上,地图显示空白

原因:下载的OpenStreetMap数据是WGS84经纬度,直接当成米制坐标用了。经纬度数值大概在120度量级,而本地坐标数值是几十万米量级,两者混用导致TX/RX点位落在离建筑物十万八千里远的地方,地图看起来就是一片空白。

解决:在预处理阶段先把经纬度统一投影到UTM平面坐标系。用pyproj做转换时注意UTM分带,国内城市用对应分带值。转换完成后验证地标点的距离关系,比如两个已知点之间转换后的距离和实际GPS测距误差应该在一米以内,确认无误再喂给射线追踪程序。

6. 用数据验证结果:从射线追踪输出反推自由空间损耗的快速检查法

射线追踪程序跑完不代表结果可信,我每次都会用一套快速检查法验证输出,前后不超过五分钟。

拿到路径列表后,挑最早到达的那条路径,它一般都是视距路径。检查它的路径长度,按光速换算成时延,再和输出里的时延字段比对,误差应该小于纳秒级,验证时延计算没问题。然后按自由空间路径损耗公式单独算一下这条路径的理论损耗值:

import math freq_hz = 28e9 dist_m = 120.0 fspl_db = 20 * math.log10(dist_m) + 20 * math.log10(freq_hz) - 147.55 print(f"Free-space path loss: {fspl_db:.2f} dB")

把理论值和输出里的LOS路径损耗对比,如果误差在1dB以内,说明波长、距离、损耗计算这三个基础环节都是对的。误差超过3dB,就停下来查单位——最常见的是频率填了MHz而不是Hz,或者距离用了公里。

反射路径的验证更简单:取一条一阶反射路径,用反射点坐标算出TX到反射点、反射点到RX两段距离相加,和输出的路径长度比对。如果长度一致但时延对不上,查是不是路径输出里存的是平面投影长度,而不是三维空间距离。这两项检查做完,仿真结果的基本可靠性就有底了。

最后我还会做一步统计验证:所有命中路径的时延画成直方图,正常情况下应该是在最小路径时延之后出现一个衰减尾巴,如果直方图在某个时延处出现奇怪的尖峰,多半是接收球设置过大导致同一路径被重复计数,回查参数。

最近一次做28GHz城市信道仿真,我按这套流程先验算再批量跑数据,全程没有出现方向性错误。从那以后我每次拿到射线追踪输出,都强制走一遍自由空间损耗反推和路径长度复算,虽然只花五分钟,但省下的返工时间远远不止这些。射线追踪的最大价值本来就是几何直观,如果连基础物理都不对,那画出来的图再漂亮也只是废图,希望这篇笔记能帮你在自己的数据上少走一圈弯路。

本文还有配套的精品资源,点击获取

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

腾讯WeKnora开源AI知识库:Agentic RAG与代码沙箱部署调优实战

知识库工具这两年井喷式爆发&#xff0c;从早期的 LangChain 拼装方案&#xff0c;到 Dify、RAGFlow 这类开箱即用的平台&#xff0c;再到各家大厂亲自下场&#xff0c;选择多到让人眼花。WeKnora 是腾讯微信团队开源的一款 AI 知识库项目&#xff0c;定位在 RAG 与 Agent 能力…

作者头像 李华
网站建设 2026/10/1 23:48:38

AgentScope 2.0实战指南:从核心抽象到多智能体生产落地

1. 为什么在这么多Agent框架里&#xff0c;我最终还是选定了AgentScope先交代一下背景。我从去年年中开始做多智能体的实际业务落地&#xff0c;市面上主流的框架大概都试过一轮&#xff0c;包括一些Python生态里名气很大的方案&#xff0c;也看过一些企业级的商业化产品。坦白…

作者头像 李华
网站建设 2026/10/1 23:48:01

Python数据分析实战:网易云歌单可视化作业全流程

简介&#xff1a;这份资源是面向高校学生与 Python 数据分析初学者的结课项目实战包&#xff0c;以网易云音乐歌单为分析对象&#xff0c;解决从数据获取到可视化呈现的完整流程问题&#xff0c;适合作为课程作业参考或数据分析入门练手案例。压缩包共 39 个文件&#xff0c;约…

作者头像 李华
网站建设 2026/10/1 23:47:31

AI短视频制作教程与爆款拆解:从脚本生成到剪辑的完整流程

1. 从一条交付消息说起&#xff1a;AI短视频制作到底在交付什么“AI 短视频制作教程 爆款拆解已交付”——这句话我第一次看到的时候&#xff0c;脑子里蹦出来的不是“又一个卖课的”&#xff0c;而是一个很具体的画面&#xff1a;某个做内容的朋友&#xff0c;花了大概两周时…

作者头像 李华
网站建设 2026/10/1 23:47:03

AI Agent生产落地四道坎:可靠性、记忆、并发与安全

上个月有个朋友给我打电话&#xff0c;语气很复杂。他们的客服 Agent 在内部评审会上 Demo 展示了十几轮完美交互&#xff0c;CTO 当场批了资源和预算&#xff0c;结果灰度第一天就被真实用户问崩了。崩的原因不是模型不理解人话&#xff0c;而是真实问题长这样&#xff1a;&qu…

作者头像 李华
网站建设 2026/10/1 23:47:00

白板手绘+GPT-4:AI实时生成交互范式实践与工程解析

直接讲结论&#xff1a;这几个月我把大部分业余时间都砸在“白板手绘 GPT-4 AI 实时生成”这个组合上&#xff0c;得到的体验颠覆了我对交互的很多固有认知。以前我们用键盘鼠标&#xff0c;把想法翻译成命令行和快捷键&#xff0c;再交给软件去执行&#xff1b;现在只要拿白…

作者头像 李华