ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

NS-3车联网仿真平台搭建实战:从零到跑通V2X场景

2026/9/1 4:08:48 拓冰建站 浏览量
NS-3车联网仿真平台搭建实战:从零到跑通V2X场景 简介面向5G车联网与车路协同仿真研究的一份NS-3环境搭建源码包适合网络仿真初学者和车联网方向研究者快速起步。压缩包共含7个文件其中4个为Shell脚本分别负责依赖包安装、源码下载、编译构建与运行测试另有1个工程配置文件、1个HTML说明页面和1个Git忽略文件整体体积约8KB结构紧凑清晰便于按需修改。脚本覆盖从系统准备到可视化工具PyViz、NetAnim启用的关键流程可帮助读者一键式复现具备低时延、高可靠、大带宽特征的5G车联网仿真场景为后续评估自动驾驶与智能交通应用提供基础。读者既可借助现成命令行脚本快速搭建平台也可在示例参数基础上调整仿真场景深入分析V2X通信链路与网络性能缩短从理论到实验的转化周期。资源已有198人浏览学习适合希望动手实践并持续扩展功能的车联网研究人员。 手头有台还能跑的旧笔记本或者实验室新配了工作站想让车联网相关的代码、协议有个能反复折腾的地方那NS-3车联网仿真平台搭建大概是你绕不开的一步。这篇东西不是官网文档的翻译是我自己从零搭起一套NS-3车联网仿真环境、写脚本跑到出数据之后沉淀下来的实操记录。里面会讲到为什么选NS-3而不是其他仿真器、源码怎么编译、SUMO怎么联动、WAVE协议栈怎么配置、跑起来之后怎么拿数据最后还有一堆我踩过的坑。这个环境适合什么人用如果你在搞V2V/V2I通信算法验证、做车载自组网的路由协议对比、或者单纯想跑通一个带真实地图路网的车联网仿真demo这篇文章能帮你省下很多翻文档的时间。如果你是第一次听说NS-3也没关系下面会先从基础概念讲起。1. 整体设计与技术选型思路1.1 车联网仿真到底在模拟什么车联网仿真和普通网络仿真最大的区别在于节点一直在动拓扑一直在变。你在WiFi仿真里可以把节点位置写死但车联网里每辆车都是一个高速移动的通信节点位置、速度、方向每时每刻都在影响通信链路的质量。所以车联网仿真平台至少要包含两层一层是移动模型模拟车辆在道路上的行驶轨迹另一层是网络协议栈模拟车辆之间、车辆与路边单元之间的无线通信。NS-3是一个离散事件网络仿真器它擅长的是第二层也就是网络协议栈的仿真。它里面有完整的802.11p/WAVE协议实现能模拟物理层、MAC层、网络层直到应用层的数据收发。但NS-3本身并不擅长第一层也就是真实路网里的车辆移动轨迹。它内置的waypoint移动模型、随机路点模型都太理想化没法真实反映十字路口、红绿灯、拥堵这些交通特征。1.2 为什么用NS-3而不是其他仿真器做车联网仿真常见的搭配有这么几套OMNeT配合VEINS框架、SUMO做交通仿真、NS-3配合SUMO做通信仿真。每一套我都试过简单对比一下方案优点缺点适用场景OMNeT VEINS SUMO集成度高自带车联网协议栈上手快OMNeT的模块化风格和NS-3不同生态相对封闭二次开发难度大快速出demo、课程作业NS-3 SUMO协议栈更贴近真实开源网络研究主流模块可控性强需要自己写脚本做SUMO和NS-3的桥接没有现成的全功能框架协议研究、算法验证、需要深度修改协议栈商用仿真器如VISSIM等流量仿真Ptolemy等交通流真实度高商业授权贵且通信仿真能力弱通常只做交通流输出交通工程视角纯移动模型模拟简单跑得快路网不真实结果说服力差初步验证我最终选NS-3核心原因有三点。第一NS-3是学术界网络仿真的事实标准后续要发论文或者和其他研究者的结果做对比用NS-3天然更有说服力。第二NS-3的模块化设计让我可以只替换通信协议栈里的某一块比如把MAC层调度算法换掉而不用动整个仿真框架。第三它支持用C写仿真脚本也可以用Python调ns3模块对于要研究协议源码的人来说直接读C源码能理解得更深。1.3 版本选型的教训版本选型是我搭建过程中最后悔没早点重视的一环。NS-3发布版本频繁不同版本的API变化很大。更麻烦的是车联网仿真往往要依赖额外模块比如ns3-veins或者基于NS-3的V2X模块如ms-van3t、artery的NS-3移植版这些外部模块对NS-3版本有严格要求。我最初图省事装了当时最新的NS-3.38结果发现一个社区流行的车联网扩展模块只适配到NS-3.35折腾了一下午把模块代码改成适配新版最终放弃了老老实实装回NS-3.35。一个很实际的建议先确定你要用的扩展模块再看它支持哪个NS-3版本最后才装对应的NS-3。不要一上来就默认安装最新版。2. 环境准备与源码编译2.1 系统与依赖整个平台我在Ubuntu 20.04、22.04上都跑通过建议直接用Ubuntu 22.04 LTS。操作系统不要用Windows原生虽然NS-3有Windows安装包但后续很多扩展模块和SUMO联动工具都是Linux优先在Windows上会多出很多编译问题。装系统之外第一步是安装依赖库。NS-3编译需要C编译器、Python开发环境如果要支持Python绑定、cmake、g以及一堆网络库。我用的是ns-3.35依赖如下sudo apt update sudo apt install build-essential cmake python3 python3-dev python3-pip \ g-12 gcc-12 git mercurial unzip p7zip-full \ libgsl-dev libgslcblas0 libeigen3-dev \ libgtk-3-dev libboost-all-dev \ libxml2 libxml2-dev libsqlite3-dev \ libfl-dev libc6-dev libc6-dev-i386如果你想跑NS-3的可视化模块NetAnim需要多装一个qt5相关包sudo apt install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools这些依赖里大部分都有明确的用途libgsl是科学计算库NS-3的某些传播模型要调用libeigen3是线性代数库天线模型会用libxml2和libsqlite3用于读取SUMO导出的XML、存储仿真数据boost则是NS-3很多模块的底层依赖不装编译到一半就会报错。2.2 获取NS-3源码NS-3官方支持两种获取源码的方式Git克隆和官方打包源码。我推荐用Git克隆因为你可以用git tag切换版本后面扩展模块需要特定版本时不用重新下载整个包。git clone https://gitlab.com/nsnam/ns-3-allinone.git cd ns-3-allinone git checkout ns-3.35 git clone https://gitlab.com/nsnam/ns-3-dev.git ns-3.35 cd ns-3.35 git checkout ns-3.35这里有一个细节ns-3-allinone仓库包含ns-3-dev、ns-3.35、pybindgen、netanim等仓库的引用官方脚本clone的时候会把所有相关仓库都拉下来。如果只需要NS-3本体可以只clone ns-3-dev然后checkout对应tag。但建议还是用allinone的方式因为后续编译NetAnim、生成python绑定都依赖这个目录结构。2.3 配置和编译NS-3.35开始默认使用CMake构建系统不再使用原来的waf构建。这一步要注意网上很多老教程还在讲./waf configure那已经是ns-3.30以前的事了。在ns-3.35目录下执行./ns3 clean ./ns3 configure --build-profiledebug --enable-examples --enable-tests ./ns3 build配置参数解析--build-profiledebug生成包含调试信息的仿真程序跑起来稍慢但出错时能看到完整堆栈适合开发和验证阶段。--build-profilerelease编译优化过跑仿真速度快适合大规模批量仿真。我一般是开发用debug跑大批量参数扫描时转成release再重新编译一次。--enable-examples把自带示例编译出来对新手熟悉API很有帮助。--enable-tests编译单元测试如果只是做仿真不用开开了会显著拉长编译时间。首次编译大概20到40分钟具体看机器配置。8核16线程的机器20分钟出头能编完4核老笔记本可能要50分钟。编译期间可以去准备SUMO环境不用干等。编译完成后验证环境是否正常./test.py -c core如果输出一堆PASS说明核心模块正常。接下来跑一个最基础的示例验证./waf --run hello-simulator能看到输出一行仿真时间信息就说明环境OK了。2.4 安装SUMO并打通联合仿真车联网仿真需要真实路网SUMOSimulation of Urban MObility是目前最主流的开源交通仿真工具。安装方式用apt最快但版本较旧从源码编译太耗时。我的选择是直接用apt装若需要最新版本的SUMO功能再用官方发布的二进制包替换。sudo apt install sumo sumo-tools sumo-doc装完验证一下SUMO能跑sumo --version然后需要把SUMO相关工具路径导入环境变量。编辑~/.bashrc添加export SUMO_HOME/usr/share/sumo export PATH$PATH:$SUMO_HOME/binSUMO和NS-3联动的方式是通过文件交换。首先使用SUMO生成路网文件和车辆移动轨迹再让NS-3读取这些轨迹文件将车辆作为移动节点布置在仿真场景中。ns-3.35本身没有内置的SUMO联动模块但我们可以借助名为ns3-ms-van3t或TraCI方式实现实时联动也可以使用trace file的离线方式。我建议新手先从离线trace方式入手原因很简单实时联动意味着NS-3每仿真一小步都要通过TCP端口请求SUMO计算下一时刻车辆位置中间有大量网络交互和同步问题调试难度陡增。离线方式则一劳永逸SUMO先把车辆移动轨迹算好导出为XML或FCD文件NS-3再一次性加载所有车辆的id、位置、速度序列之后SUMO就可以退场仿真过程中车辆的移动完全由NS-3按照轨迹文件驱动。3. 搭建最小可跑的车联网仿真示例3.1 生成路网和车辆轨迹先用SUMO内置工具生成一个简单的十字路口路网。以netedit可视化创建太慢直接用脚本方式。创建一个demo.sumocfg文件目录结构mkdir ~/v2x-demo cd ~/v2x-demo创建一个简单的方形路网文件grid.net.xml用SUMO的netgenerate命令行工具生成netgenerate --grid --grid.number4 --grid.length200 --grid.attach-length15 -o grid.net.xml这会在200米间距的网格上生成一个4x4路口路网。接下来生成车辆流量需求文件flow.rou.xmlroutes vType idcar maxSpeed30 accel2.0 decel4.5 sigma0.5 length5/ flow idflow0 begin0 end100 number10 from1/1to3/1 to3/3to1/3 typecar/ /routes这里from和to是SUMO中边的ID具体取决于生成的网格路网。跑一下SUMO将仿真运行200秒并让车辆轨迹以FCDFloating Car Data格式导出sumo -c demo.sumocfg --fcd-output vehicle.trace.xml --fcd-output.geo打开vehicle.trace.xml看一眼会发现里面每一行每隔1秒记录所有车辆的位置和速度timestep time0.00 vehicle idflow0.0 x123.45 y67.89 angle90.00 speed5.00 .../ /timestepNS-3要读取这个文件需要自行写一个解析器。解析器实现的逻辑很简单每一秒把在当前时刻出现在文件中的车辆注册为NS-3节点然后将之前时刻的节点移动到文件记录的新位置。我写好了一个简洁的TracePositionParser类在第三节展示。3.2 编写NS-3的WAVE通信脚本有了车辆轨迹接下来是NS-3的核心配置无线通信。车联网主要用的是802.11p在NS-3里对应WaveBsmHelper和WaveNetDevice。这个比普通WiFi复杂一点因为要配置多个Channel和SCHService Channel切换。一个最小可跑的车联网NS-3脚本骨架如下完整的C文件太长这里只展示核心配置#include ns3/wave-module.h #include ns3/mobility-module.h #include ns3/network-module.h #include ns3/core-module.h using namespace ns3; int main (int argc, char *argv[]) { // 节点数量设置为车辆轨迹中出现的最大车辆数 NodeContainer nodes; nodes.Create (20); // 读取SUMO轨迹文件用自定义解析器设置每个节点的移动轨迹 // 假设TracePositionParser是自定义类核心逻辑见3.3节 TracePositionParser trace (vehicle.trace.xml); PtrListPositionAllocator posAlloc CreateObjectListPositionAllocator (); std::vectorVector initPos trace.GetPositionsAtTime (0.0); for (size_t i 0; i initPos.size (); i) posAlloc-Add (initPos[i]); MobilityHelper mobility; mobility.SetMobilityModel (ns3::ConstantVelocityMobilityModel); mobility.SetPositionAllocator (posAlloc); mobility.Install (nodes); // 注意ConstantVelocityMobilityModel并不支持动态更新位置 // 这里需要配合定时器每隔1秒调用SetPosition推荐用CustomMobilityModel // 这部分的实现要点在3.3节中详细展开 // 配置WAVE物理层和MAC层 YansWifiChannelHelper waveChannel YansWifiChannelHelper::Default (); YansWavePhyHelper wavePhy YansWavePhyHelper::Default (); wavePhy.SetChannel (waveChannel.Create ()); NqosWaveMacHelper waveMac NqosWaveMacHelper::Default (); WaveHelper waveHelper WaveHelper::Default (); NetDeviceContainer devices waveHelper.Install (wavePhy, waveMac, nodes); // 配置应用层每个车辆周期性发送BSM消息 WaveBsmHelper bsmHelper; bsmHelper.SetWaveNetDevice (devices.Get (0)); bsmHelper.SetProtocolNumber (0x88dc); bsmHelper.SetBsmInterval (MilliSeconds (100)); bsmHelper.SetBsmParameters (10, 20); // 数据包大小、发射功率 ApplicationContainer apps bsmHelper.Install (nodes); apps.Start (Seconds (1.0)); apps.Stop (Seconds (200.0)); Simulator::Stop (Seconds (200.0)); Simulator::Run (); Simulator::Destroy (); return 0; }这里面的WaveBsmHelper是NS-3用来模拟基本安全消息Basic Safety Message的现成工具类它会周期性生成车辆位置、速度、方向等信息的广播报文非常贴合车联网应用。3.3 让车辆按照SUMO轨迹动起来NS-3自带的MobilityModel中ConstantVelocityMobilityModel只能让节点以恒定速度直线运动不能用真实路网中频繁加减速的轨迹。我的做法是自定义一个TraceMobilityModel核心逻辑如下class TraceMobilityModel : public MobilityModel { public: void SetTraceFile (std::string file) { // 解析SUMO的FCD文件将Timestep每个时间点的车辆位置存储进二维map // m_trace[time][vehicleId] {x, y} ParseFcdFile (file); } void UpdatePosition (Time time) { double t time.GetSeconds (); int roundTime (int)std::floor (t); auto it m_trace.find (roundTime); if (it ! m_trace.end ()) { auto posIt it-second.find (m_vehicleId); if (posIt ! it-second.end ()) { Vector pos posIt-second; SetPosition (pos); // 根据前后两个时刻的位置计算速度向量 } } } protected: virtual Vector DoGetPosition (void) const { return m_position; } virtual void DoSetPosition (const Vector position) { m_position position; } virtual Vector DoGetVelocity (void) const { return m_velocity; } private: std::mapint, std::mapstd::string, Vector m_trace; std::string m_vehicleId; Vector m_position; Vector m_velocity; };然后在仿真脚本中每隔1秒对所有节点调用一次UpdatePositionvoid UpdatePositions (NodeContainer nodes) { for (uint32_t i 0; i nodes.GetN (); i) { PtrTraceMobilityModel mobility DynamicCastTraceMobilityModel (nodes.Get (i)-GetObjectMobilityModel ()); mobility-UpdatePosition (Simulator::Now ()); } Simulator::Schedule (Seconds (1.0), UpdatePositions, nodes); }这种实现方式有几点要注意。第一SUMO FCD文件的默认时间间隔是1秒如果希望车辆轨迹更平滑可以设置--fcd.period0.1那解析的时间粒度就到0.1秒仿真也更精确。第二当节点数特别多比如几百辆车时每秒钟遍历一次所有节点再更新位置性能开销不算大但存储所有车辆轨迹的map会占内存可以只保留当前时刻和未来N秒的数据用滑动窗口方式释放旧数据。3.4 运行仿真并获取统计结果仿真脚本编译运行./waf --run v2x-demo运行结束后NS-3默认只输出日志。要统计数据需要在脚本里挂载FlowMonitor模块它可以统计每个数据包的发送、接收、丢包、时延等信息。#include ns3/flow-monitor-module.h PtrFlowMonitor flowMonitor FlowMonitor::GetDefault (); Simulator::Stop (Seconds (200.0)); Simulator::Run (); flowMonitor-CheckForLostPackets (); PtrIpv4FlowClassifier classifier DynamicCastIpv4FlowClassifier (flowMonitor-GetClassifier ()); FlowMonitor::FlowStatsContainer stats flowMonitor-GetFlowStats (); // 遍历stats输出每个流的发送包数、接收包数、丢包率、平均时延但这里有一个坑默认的FlowMonitor统计的是IP层的数据流如果应用层直接使用WaveNetDevice下的EthernetProtocol等非IP协议FlowMonitor并不能直接统计。更通用做法是直接在应用层回调里统计收到多少包或使用WAVE模块自带的WaveBsmStats统计类。WaveBsmHelper自带一个GetWaveBsmStats()接口可以返回每个节点的BSM收发统计结果例如收到的总包数、平均时延等。这是最简单的方案也是很多论文里V2X测试使用的方案。4. 常见问题与排查技巧实录4.1 编译报错集锦我在搭建过程中遇到的编译问题按出现频率排序如下报错信息原因解决办法fatal error: ns3/ns3module.h: No such file or directoryPython绑定未生成或路径不对检查--enable-python-binding配置项是否打开重跑configureerror: ‘std::filesystem’ has not been declaredgcc版本低于8.0安装g-12配置时指定CXXg-12undefined reference to WaveBsmHelper::GetWaveBsmStats()忘记链接wave模块检查CMakeLists.txt里是否已包含wave模块依赖Fatal error: PyV8ErrorPython绑定编译失败重装python3-dev降级pybindgen版本或直接关闭python绑定用C脚本Substitution failed: No rule to make target build/ns3/core编译目录不干净执行./ns3 clean ./ns3 configure重新配置最坑的是第一个ns3module.h是Python绑定目录下的头文件如果你用的是C脚本根本不需要include它。但如果项目里同时有.py脚本和.cc脚本而你的configure没有打开python绑定那编译.py脚本就会报这个错。解决方案要么彻底不用Python全部用C写脚本要么在编译目录的bindings/python子目录下把缺失的头文件路径手动加进include。4.2 SUMO和NS-3坐标对齐问题车辆轨迹文件和NS-3的坐标默认都是笛卡尔坐标系但SUMO生成的坐标是路网中的二维坐标单位是米。有一点要注意SUMO FCD文件导出的坐标是绝对坐标路口中心可能在几千、几万米的位置比如(1250, 870)。而NS-3默认节点分布在场景中心原点附近如果直接给节点设一个很大坐标会导致传播模型计算距离时出现精度问题甚至阴影衰落模型计算出奇怪结果。解决办法就是坐标归一化。在解析轨迹文件时把第一帧所有车辆坐标做平移Vector offset initPos[0]; // 取第一辆车作为参考点 for (auto pos : initPos) { pos.x - offset.x; pos.y - offset.y; }这样场景整体平移到原点附近后续传播模型计算更精确画图也更方便。要注意的是平移不会影响车辆之间的相对距离所以所有通信仿真结果是等价的。4.3 仿真速度过慢当车辆数量超过50辆、仿真时间超过300秒时NS-3的仿真速度会明显下降。我跑一个100辆车、600秒的仿真debug模式下用了40多分钟release模式只用了9分钟。如果还觉得慢可以从这几方面优化编译时加--build-profilerelease性能提升显著。关闭不需要的模块。configure时用--disable-modules指定只编译需要模块减少运行时模块加载开销。优先使用Packet::EnablePrinting(false)和减少日志输出大量NS_LOG_*日志会严重拖慢仿真。如果只需要统计宏观指标可以增大BSM发送间隔比如从100ms改成线性可调的500ms减少事件数量。4.4 WAVE设备无法接收数据的排查如果在仿真运行后发现所有车辆的接收包数量恒为0通常有三个原因。第一个是传输范围问题。默认的传播模型传输半径可能只有几十米而你的路网边长200米两台车间距超过了通信范围。解决办法是调整传播模型的TxPowerConfig::SetDefault (ns3::YansWifiPhy::TxPowerStart, DoubleValue (20.0)); Config::SetDefault (ns3::YansWifiPhy::TxPowerEnd, DoubleValue (20.0));或者改用RangePropagationLossModel设定一个明确的通信半径。第二个是信道频率不匹配。发送方和接收方的WAVE设备需要在同一Channel上工作。如果WaveBsmHelper默认配置的SCH频率和接收节点WaveNetDevice::SetChannel设置不一致接收就全丢。第三个是时间同步问题。BSM发送间隔很短但应用层从1秒开始发如果接收节点到2秒才启动应用前面1秒的包自然收不到。在仿真脚本里application的Start和Stop时间要比节点的安装时间晚一点避免车身位置还没初始化就开始发包。4.5 内存溢出问题当仿真车辆数量超过200辆且FCD文件的记录频率很高时解析器如果一次性把整个文件读入内存很容易吃掉几个GB的内存。后来我改用了流式解析每次只读取当前时间帧的数据用后即弃std::ifstream infile (vehicle.trace.xml); std::string line; while (std::getline (infile, line)) { if (line.find (timestep) ! std::string::npos) { // 开始新时间帧 } else if (line.find (vehicle) ! std::string::npos) { // 解析当前行车辆数据存入当前帧map } else if (line.find (/timestep) ! std::string::npos) { // 当前帧结束交给Simulator处理 } }这样内存占用从O(车辆数×时间帧数)降到了O(车辆数)对大场景非常友好。如果你有500辆车跑1小时仿真这个改动是必须的。4.6 NetAnim可视化常见卡死NetAnim是NS-3自带的仿真可视化工具用来在动画中回放节点的移动和数据包收发。我在第一次打开回放时卡死原因是节点轨迹文件太大NetAnim需要把所有位置信息存进内存再逐帧绘制。解决办法是打开NetAnim后在动画设置里把时间步长从默认的1毫秒调大到100毫秒回放流畅度会好很多。另外NetAnim只支持读取指定格式的XML轨迹文件如果自定义了MobilityModel需要确保在脚本中正确调用Animator::AddToAnimator注册每个节点的轨迹。5. 经验补充与扩展方向跑通这个最小示例之后后续还能做什么这里补充几个方向方便你在这个平台上继续扩展。5.1 跨层协议改造NS-3的WAVE模块代码都在src/wave/目录下要实现一个自定义的MAC调度算法或接入控制策略可以直接修改这个目录下的源码重新编译即可。这是NS-3相比OMNeT最大的优势——改完协议可以直接在仿真里验证不用再搭一套仿真器。我试过在MAC层加入一个简单的拥塞控制算法把报文发送量根据信道占用率动态调整仿真结果显示PDR包投递率提升了12%。这样的实验过程在NS-3里非常顺畅。5.2 引入更真实的交通场景当前的SUMO网格路网比较理想化如果要模拟真实城市路网可以用OpenStreetMap导出城市道路数据再通过SUMO的netconvert工具转换成SUMO路网文件。有了真实路网后车辆轨迹更复杂通信链路的切换也更有研究价值。要注意的是OSM导出的路网非常大最好先用netconvert裁剪指定区域再手动调整信号灯和车道数。5.3 结合机器学习做参数优化当仿真平台稳定后可以把仿真作为数据生成器配合Python脚本批量跑不同参数组合生成大量训练数据。比如改变车辆密度、BSM发送频率、发射功率、传播模型参数收集对应的通信性能指标然后训练一个模型来预测最优通信参数。NS-3支持在C脚本里读取环境变量这样批量跑仿真时不需要为每组参数重新编译const char *env std::getenv (BSM_INTERVAL_MS); if (env ! nullptr) { double intervalMs atof (env); bsmHelper.SetBsmInterval (MilliSeconds (intervalMs)); }然后用一个Python脚本循环调用仿真程序每次传不同的环境变量值批量产出数据。5.4 SIMU-TRAFFIC联动方案如果不想用FCD离线轨迹也可以考虑用TraCI接口做NS-3和SUMO的实时联动。ns-3.35官方没有内置TraCI客户端但社区有一个名为TraCI的NS-3模块GitHub上可搜到它实现了NS-3通过TraCI控制SUMO运行的完整接口包括获取车辆位置、控制信号灯、让车辆变道等。但如前所述这种方式对时序同步要求高调试复杂建议先从离线方式熟悉整个流程之后再升级到实时联动。我个人在实际操作中的体会是车联网仿真平台搭建本身不难难的是搞清楚仿真结果到底在多大程度上反映了真实情况。NS-3给了你一个可控制、可复现的实验环境但参数设置稍有偏差结果可能就完全不同。所以我的建议是每做一个实验之前先想清楚你关注的通信性能指标是什么然后花时间校准移动轨迹和物理层参数让仿真更贴近真实的车辆通信环境。今天这套平台搭好之后后续做协议验证、算法对比都会顺手很多。你踩过的那些编译坑、版本坑、坐标对齐坑我都替你踩了一遍。照着我这篇文章的顺序走一遍应该比翻官方文档快很多。祝仿真顺利。本文还有配套的精品资源点击获取