做车联网通信仿真的朋友应该都有这种体验:链路层仿真跑起来容易,跑得像回事难。我去年做一个V2I(车对基础设施)项目,要验证毫米波链路在真实城市道路环境下的吞吐量表现,一开始沿用4G时代那套“路径损耗加慢衰落加随机误码”的链路层建模思路,结果仿真结论跟实测数据差了很远。后来老老实实把毫米波信道的阻塞特性、波束对准开销和HARQ反馈延迟一起塞进链路层模型,曲线才对得上。这篇文章把毫米波V2I网络链路层仿真的完整思路、Matlab代码实现框架和踩坑记录整理出来,给正在做类似方向的同学一点参考。
文章内容是围绕我自己在实际项目中搭建的仿真环境展开的,侧重点不是OFDM符号级的物理层精确建模,而是站在链路层的视角,把影响调度、重传、时延的关键因素建模到位。全程使用Matlab实现,跑通了信道状态更新、MAC调度器、HARQ反馈环和结果统计这一条最小闭环。
1. 毫米波V2I链路层仿真绕不开的“三个物理债”
链路层协议设计者是站在物理层肩膀上干活的,尤其是毫米波频段,物理层欠下的“债”会直接决定链路层算法怎么设计。我把它总结成三笔账:高频段路径损耗、严重的阻塞效应、窄波束对准开销。
1.1 频段本身带来的链路预算压力
毫米波V2I场景最常讨论的频段是28GHz和39GHz。这个频段跟Sub-6GHz最大的区别是波长短,天线阵元可以做得很小,能在车端和路侧单元(RSU)上布置大规模天线阵列,但代价是自由空间路径损耗随频率升高而变大。
链路预算的计算值得掰开揉碎讲清楚。以28GHz为例,波长大约0.0107m,假设车辆距离RSU 150m,自由空间路径损耗按Friis公式:
PL = 20log10(4πd/λ)
代入d=150m,λ=0.0107m,4πd/λ大约是176000,取对数乘20后约为105dB。这还只是自由空间损耗,实际城市环境还要叠加阴影衰落、雨衰、植被衰减。而4G LTE在1.8GHz频段同样150m距离的自由空间路径损耗只有80dB左右,差了二十多个dB,得靠波束赋形增益补回来。
天线阵列增益不是白拿的。64阵元的均匀矩形阵列,最大方向性增益近似为10log10(64),约18dB,加上收发两端,能补回来30多dB。这就解释了为什么毫米波通信几乎必须走波束赋形——没有阵增益,链路预算根本转不动。在链路层仿真里,这个特性表现为SINR不再是慢变随机过程,而是高度依赖波束是否对准、阵列增益是否充分发挥作用。
1.2 阻塞效应:毫米波最大的链路层威胁
比路径损耗更麻烦的是阻塞。毫米波绕射能力很弱,一个路牌、一棵树、一辆公交车横在传播路径上,链路直接从中断掉或者跌到NLOS状态。V2I场景的阻塞源比固定通信多得多,车辆本身就是移动的障碍物,行人、建筑转角、绿化带都会造成时变阻塞。
阻塞在链路层的影响极大。一次大型车辆遮挡可能持续1到2秒,在1ms时隙粒度的仿真里就是上千个连续时隙的链路劣化。这直接导致重传堆积、HARQ缓冲区被占满、调度器必须做出激进的MCS回退。这些行为用传统随机误码模型是模拟不出来的,因为阻塞造成的错误是长相关、突发性的,信道编码的纠错能力在这个尺度上完全失效。
所以链路层仿真里的信道状态必须包含LOS与NLOS的判别逻辑。我在Matlab里用一个简化的几何遮挡判定:把发射点T、接收点R连成一条线段,把障碍物建模成矩形区域,判断线段是否与矩形相交。相交就是阻塞状态,不相交且没有其他散射路径劣化就视为LOS。这个判定虽然不精细,但能抓住阻塞事件的时间相关性和空间分布特性,对链路层指标推导已经够用了。
1.3 窄波束下的对准与切换开销
毫米波低SNR环境下需要窄波束提供足够增益,但窄波束也带来了波束管理问题。车辆是高速移动的,V2I场景里车辆相对RSU的角度变化很快,波束每隔一段时间就得重新扫描、对准。这个扫描过程用掉的时间资源,链路层得买单。
拿一个典型配置举例:假设RSU使用32个候选发送波束,进行一次粗扫描需要32个时隙,每100个时隙触发一次全向扫描校准,这意味着10%的资源直接被波束管理吃掉了。波束切换期间链路还会中断,反馈回来的NACK可能并不是数据真的丢了,而是波束还没对准。
链路层仿真如果不把这个开销算进可用时隙里去,得到的吞吐量就会偏高,我自己早期版本就犯过这个错误。具体的建模方式在第四章算例里会给出详细配置。
2. 链路层仿真与PHY层的边界:接口抽象与映射关系
链路层仿真不是越精细越好。很多人上手就把OFDM调制、低密度奇偶校验编码、速率匹配全部做进去,结果一个场景跑几个小时,调度器逻辑反而没精力细抠。我倾向于在仿真里做一个“PHY抽象层”,把物理层对链路层真正重要的几个接口提炼出来。
2.1 链路级仿真的职责边界
首先得搞清楚自己做的链路层仿真要回答什么问题。如果关心的是某种调度算法在盲区路段的吞吐量表现,链路层只需要知道一个传输块发出去有多大概率失败,失败之后重传能带来多少增益。如果关心的是重传时延分布和服务质量保障,就需要精确模拟HARQ的RTT、最大重传次数、软合并增益。
毫米波V2I链路层研究通常是后者。所以我把信源编码、星座映射、快速傅里叶变换这些物理层细节完全剥离,只保留一个从当前SINR到传输块错误概率的映射函数,以及HARQ重传时的等效合并增益。这是链路级仿真和系统级仿真最大的区别:系统级关心用户间干扰和小区吞吐量,链路级关心单条链路上的可靠性和时延。
2.2 链路层需要的PHY抽象接口
我把PHY抽象接口设计成三块。
第一块是SINR到BLER映射。给定当前时隙的有效SINR、调制编码方案(MCS)和传输块大小,接口返回该传输块的成功概率。实际工程里这个映射可以从链路级仿真曲线里查表得到,简化版本直接用高斯近似:当有效SINR低于某个MCS的工作点门限时,BLER指数上升;高于门限时趋近于零。
第二块是HARQ合并增益。每次重传采用Chase合并,Matlab里等效为把重传数次数的功率叠加,近似看作SINR每次重传提升约3dB,这是通用做法。虽说真实信道下的合并增益没那么理想,但链路层研究的粒度下够用了。
第三块是MCS自适应规则。调度器根据当前SINR选择一个编码调制方式,要求误块率预期在某个门限以下。比如SINR在16到18dB之间,就选16QAM加3/4编码;超过22dB再上64QAM。这样调度器能即时调整传输速率以适配信道状态变化。
2.3 时间粒度的选择:时隙级而不是符号级
时间粒度的取舍决定了仿真速度和结论有效性。我在仿真里以1ms为一个时隙,一个时隙内假设信道状态不变,发送一个传输块,等待一个RTT周期的HARQ反馈。
OFDM符号级仿真的时间粒度是几十微秒级别的,在这个尺度上可以精确模拟信道快衰落和子载波级干扰。但V2I的场景目标是以数百毫秒为单位的时延统计和吞吐量分布,链路层指标对信道快速变化的细节并不敏感,重要的是信道状态在数个时隙内是持续劣化还是持续良好。时隙级抽象能在一个小时内跑完数千个时隙的蒙特卡洛仿真,这是符号级仿真做不到的。
事件驱动可以进一步加速。比如车辆行驶过程中,阻塞状态不会每个时隙都变化,我实际实现时先判断每个时隙的LOS状态,如果与前一个时隙相同,就直接复用上一时隙的SINR,只有状态切换时才重新计算路径损耗和干扰功率。这一步能砍掉大量冗余计算。
3. Matlab代码架构:信道模块、调度器与HARQ反馈环
搭建仿真环境时,我按照模块化思路拆成四块:参数配置、信道状态更新、MAC调度器、HARQ反馈和统计。每一块都是独立函数,主循环负责按时间推进把它们串起来。
3.1 信道状态更新:几何遮挡判断与SINR计算
信道状态模块的核心任务是回答一个问题:这一时隙,车和RSU之间的链路是什么状态?我把需要的输入参数定为RSU坐标、车辆坐标、障碍物列表和随机数发生器状态。输出是LOS标志和SINR。
车辆坐标是由速度和轨迹决定的,假设车辆沿直线道路匀速行驶,位置在每个时隙线性更新:
vehicleX = startX + speed * slotIdx * slotDuration; vehiclePos = [vehicleX, roadCenterY]; % 车辆坐标障碍物遮挡判断是整个几何逻辑里最容易出错的地方。我写了这样一个辅助函数,基于线段与轴对齐矩形的相交检测:
function isBlocked = lineRectIntersect(p1, p2, rectCenter, rectHalfSize) % p1: 发射点坐标; p2: 接收点坐标 % rectCenter: 障碍物中心; rectHalfSize: 半宽半高 d = p2 - p1; tMin = 0; tMax = 1; for dim = 1:2 if abs(d(dim)) < 1e-12 % 线段平行于该轴,检查是否落在矩形范围内 if p1(dim) < rectCenter(dim) - rectHalfSize(dim) || ... p1(dim) > rectCenter(dim) + rectHalfSize(dim) isBlocked = false; return; end else t1 = (rectCenter(dim) - rectHalfSize(dim) - p1(dim)) / d(dim); t2 = (rectCenter(dim) + rectHalfSize(dim) - p1(dim)) / d(dim); tMin = max(tMin, min(t1, t2)); tMax = min(tMax, max(t1, t2)); if tMin > tMax isBlocked = false; return; end end end isBlocked = true; end这个函数返回的是两个点之间的线段是否穿过矩形障碍物。判断出阻塞状态后,LOS路径用自由空间加阴影衰落计算接收功率,NLOS路径在LOS基础上再扣一个穿透损耗,数值可以取20到30dB左右。接收功率算出来之后,SINR就是接收功率除以热噪声和干扰功率之和。
需要提醒的是,因为毫米波波束很窄,阴影衰落的标准差通常比Sub-6GHz要小,我实际工程中取2到3dB。这也是毫米波信道建模里一个容易被忽略的细节。
3.2 MAC调度器与HARQ反馈环的实现
调度器的职责是决定每个时隙把传输资源分给哪个车辆,以及用什么MCS发送。单用户场景比较简单,轮询调度即可。多用户调度我实现了比例公平算法,调度度量是当前可达速率除以历史平均吞吐量的比值:
metric = instantaneousRate / (0.8 * avgThroughput + 0.2 * historicalRate);这个度量方式画成表达式就是比例公平的标准形式,兼顾了瞬时信道条件和长期公平性。具体实现时,每个用户维护一个历史平均吞吐量,每个时隙结束后按一阶低通滤波方式更新。
HARQ反馈环是我最重视的部分。发送端维护一个待确认传输块的记录表,记录每个传输块的发送序号、MCS、重传次数和状态。发送后进入等待周期,RTT设为1ms。接收端根据SINR和BLER映射生成随机数决定是否成功接收,反馈ACK或NACK。发送端收到NACK后将该传输块放入重传队列,重传次数达到上限后丢弃本次传输块,统计为一次丢包。
% HARQ状态机简化示例 for txIdx = 1:length(txBuffer) switch txBuffer(txIdx).state case 'waitingAck' txBuffer(txIdx).age = txBuffer(txIdx).age + 1; if txBuffer(txIdx).age >= rttSlots % 判定ACK/NACK sinrEff = txBuffer(txIdx).sinr + 3 * txBuffer(txIdx).retxCount; % Chase合并近似 bler = sinrToBler(sinrEff, txBuffer(txIdx).mcs); if rand() > bler txBuffer(txIdx).state = 'acked'; else txBuffer(txIdx).retxCount = txBuffer(txIdx).retxCount + 1; if txBuffer(txIdx).retxCount <= maxRetx txBuffer(txIdx).state = 'pendingRetx'; else txBuffer(txIdx).state = 'dropped'; end end end case 'pendingRetx' % 下一时隙重传 txBuffer(txIdx).state = 'sent'; end end这段代码描述的HARQ逻辑虽然简化,但保留了同步反馈、重传次数限制和Chase合并增益三个关键环节,足够支撑链路层时延和可靠性分析。
3.3 主循环组织:代码骨架串起整个仿真流程
仿真主循环以时隙为单位推进,每一轮依次更新车辆位置、更新信道状态、执行调度、处理HARQ反馈,最后更新统计量。
for slot = 1:nSlots % 1. 更新车辆位置和信道状态 posV = computeVehiclePosition(vehId, slot); [losFlag, sinrDb] = updateChannel(posRsu, posV, obstacles, rngStream); % 2. 调度器决策 [vehScheduled, mcsSelected] = scheduler(sinrDb, vehId, slot); % 3. 生成新传输块并进入HARQ流程 if ~isempty(vehScheduled) tx = createTxBlock(vehScheduled, mcsSelected, sinrDb); txBuffer(end+1) = tx; end % 4. 更新所有传输块的反馈状态 updateHarq(txBuffer); % 5. 统计吞吐量、重传次数、时延 collectStats(txBuffer, slot); end主循环结构保持清晰,各模块之间的关系一目了然。实际运行中我发现,如果一开始就把波束扫描、频域调度、多用户配对全部塞进主循环,代码复杂度会爆炸式增长,调试的时候根本分不清是调度逻辑错了还是信道建模错了。先跑通这个最小闭环,再逐步加复杂度,是最稳妥的做法。
4. 一个能跑通的算例:28GHz V2I下行链路仿真配置
有了代码架构,接下来要给出一套能直接复现的仿真配置。这套配置我跑了很多轮,参数都经过了检查,可以作为后续扩展的基线版本。
4.1 仿真参数配置表
参数的选取尽量贴近实际V2I部署场景。载波频率28GHz,带宽100MHz,子载波间隔30kHz,时隙长度1ms,这些都是通信系统设计中比较主流的配置。完整参数下表所示:
| 参数项 | 配置值 | 说明 |
|---|---|---|
| 载波频率 | 28 GHz | 毫米波典型频段 |
| 系统带宽 | 100 MHz | 子载波间隔30kHz,可用RB数约273个 |
| 时隙长度 | 1 ms | 一个时隙发送一个传输块 |
| RTT反馈延迟 | 2 ms | 发送至收到ACK/NACK的往返时延 |
| 最大重传次数 | 3 | 超过则丢弃并计丢包 |
| RSU天线阵 | 8x8均匀矩形阵列 | 最大增益约18dB |
| 车辆天线阵 | 4x4均匀矩形阵列 | 最大增益约12dB |
| RSU高度 | 5 m | 路边杆站 |
| 车辆高度 | 1.5 m | 车顶天线 |
| 车辆速度 | 20 m/s | 约72km/h城区车速 |
| 道路长度 | 300 m | 单方向直线道路 |
| 阴影衰落标准差 | 2.5 dB | 毫米波窄波束下典型值 |
| 阻塞穿透损耗 | 25 dB | LOS转NLOS的附加损耗 |
| 噪声系数 | 5 dB | 接收机前端 |
| 热噪声功率谱密度 | -174 dBm/Hz | 常温下基底噪声 |
| 每100时隙波束扫描开销 | 10个时隙 | 波束管理资源占用 |
表中的波束扫描开销值得展开说。仿真里我给每100个时隙安排了10个时隙的静默期,模拟波束扫描和重新对准的过程。这个静默期里调度器不发送数据,所有传输块保持在等待状态。实际通信系统里这个开销跟波束数量强相关,波束越多扫描越频繁,开销越大。链路层仿真如果不显式建这个开销,吞吐量虚高百分之十是很正常的。
4.2 三种阻塞场景的设计
为了让仿真结果能说明问题,我设计了三种场景。
场景A是全LOS链路,道路上没有障碍物,车辆从距离RSU 50m处驶向250m处,全程可以直射。这个场景的仿真结果代表系统性能上限。
场景B是行人随机阻塞。在道路的人行横道区域,每隔一段时间就会有一个行人障碍物出现在车辆和RSU之间。我把它建模成一个持续时间服从均匀分布0.5到1.5秒的阻塞事件,事件之间间隔服从指数分布。这个场景对应城区十字路口附近的行车状态。
场景C是大型车辆遮挡。RSU附近的车道上会停着一辆高度足够的卡车,当目标车辆经过卡车后侧时,链路进入NLOS状态。卡车这个障碍物的几何尺寸是长10m、宽2.5m、高3m,持续阻塞时间可以持续2到3秒。这个场景模拟最恶劣的V2I链路中断情形。
三种场景使用相同的MCS集合和HARQ参数,区别只在信道状态的时间演化过程。这样对比出来的差异完全由阻塞模式驱动,结论干净。
4.3 运行方式与输出指标
每一轮仿真跑5000个时隙,相当于5秒的车辆行驶过程。为了降低随机性影响,每个场景跑20轮,取平均值。输出的核心指标包括平均吞吐量、平均时延、重传率、丢包率和MCS使用分布。
Matlab主脚本里只需调用三个函数就能启动仿真:
cfg = configureSimulation('scenarioA'); statsA = runSimulation(cfg); reportStats(statsA);configureSimulation函数里根据场景参数填入表1的配置,runSimulation函数内跑主循环,reportStats负责汇总指标。整个代码量控制在几百行以内,代码可实现性和可读性都比较好。
5. 三种阻塞类型下的仿真结果对比:多轮运行后的统计规律
我跑完三种场景,得到了几组有说服力的数据。把这些数据放在一起对比,毫米波车联网链路层的核心矛盾看得特别清楚。
5.1 LOS全程通畅:性能上限参考
场景A的仿真结果是平均吞吐量约460Mbps,平均时延2.8ms,重传率约3%,丢包率接近于零。重传主要出现在车辆驶向250m边缘地带时,信噪比下降导致高MCS的BLER升高。
这个结果的解释很直观:LOS条件下,28GHz链路的容量主要受限于覆盖边缘的路径损耗。越靠近RSU,64QAM和256QAM可以稳定运作,接近500Mbps的吞吐量;越远离RSU,可用MCS掉到16QAM,吞吐量随之下降。车辆完整穿越300m道路的吞吐量曲线是波浪形的,而不是一条平坦直线。
5.2 行人随机阻塞:重传率与时延的拉扯
场景B的平均吞吐量降到190Mbps,重传率抬升到21%,平均时延5.5ms,最差情况出现了一次持续12ms的排队时延。
行人阻塞事件持续时间在0.5到1.5秒,对应500到1500个时隙。阻塞期间SINR从大约20dB跌到负数,调度器检测到BLER升高后把MCS从256QAM一路降到QPSK,MCS掉档过程至少要经历几次反馈往返。重传次数多了之后,新的传输块排队等待,时延自然上升。这个场景里链路层的核心矛盾是吞吐量和时延的此消彼长:如果激进保留高MCS,重传率飙升,资源浪费严重;如果保守压低MCS,虽然重传少,但有效速率也掉下来了。
5.3 大型车辆遮挡:长中断下的链路失稳
场景C的结果最扎眼,平均吞吐量只有85Mbps,平均时延12.3ms,丢包率接近4%,重传率58%。卡车造成的连续阻塞超过3秒时,HARQ重传次数达到上限,部分传输块直接被丢弃。
这个场景暴露出的问题可以说是链路层调度策略的阿克琉斯之踵。长中断期间调度器反复用高MCS发送,连续NACK既浪费资源又填满HARQ缓冲区。等到阻塞结束,缓冲区里的积压传输块需要大量时隙清理,清理过程中新数据又在排队,形成了恶性循环。我验证了一个改进思路:调度器在连续收到几个NACK后,主动进入低MCS探测模式,发送一个探测包恢复信道状态估计,再决定是否跳回高MCS,这样确实减少了无效重传,丢包率从4%降到1.8%左右,但这个机制在协议标准里属于可选项,部署不部署由具体实现决定。
这三个场景的数据说明了一个事实:V2I链路层的瓶颈不在平均信道条件,而在阻塞事件的持续时间和恢复速度。链路层仿真只有把阻塞的时间相关结构建模出来,才能复现出这些真实的性能劣化现象。
6. 实际调试中踩过的坑与调优经验
这一部分是我个人在仿真实现过程中花费最多时间的环节。有些问题看代码觉得完全正确,跑出来的数却明显不合理,排查过程很考验耐心。
6.1 SINR在时隙内的聚合方式:均值还是低分位值
早期版本的仿真把每个时隙内SINR变化的平均值作为反馈依据,结果发现突发阻塞场景的时延被严重低估。原因在于阻塞事件在时隙内是突变的,如果阻塞发生在时隙后半段,平均SINR可能仍然高于正常工作门限,BLER判定结果就会偏乐观。
后来我把时隙内的SINR采样分布改为取5%分位值来判定BLER。这样处理的物理含义是:只要传输块在某个瞬间经历了深度衰落,就倾向于判定为失败。实际网络里的解码性能也确实由最差的那段子帧决定,因为信道编码的纠错能力有限,瞬时恶化会直接破坏整块数据。这个改动让仿真结果跟实测数据更接近。如果你在复现时发现仿真吞吐量普遍偏高,先检查是不是用了SINR均值。
6.2 随机种子与多实验平均
链路层仿真里有大量随机数生成,从信道快衰到BLER判定到阻塞事件发生时刻,全部依赖随机数。我刚开始只跑一轮就下结论,结果加一个随机数种子进去结果能差30%。这是蒙特卡洛仿真的经典陷阱,需要在每个场景下用多个种子重复实验并统计置信区间。
我实际的做法是给每个场景分配一组种子,例如seed 1到20,然后把吞吐量和时延的均值、标准差都汇报出来。这样得到的结果才能支撑结论。写代码时注意Matlab的随机数流控制:
rngStream = RandStream('mt19937ar', 'Seed', seedIdx); rand(rngStream);信道模块的每个随机采样都从同一个流里取数,保证可复现性。这个习惯一开始就要养成,不然后期改参数重新跑一轮就发现之前的结果对不上,痛苦万分。
6.3 向量化计算与执行效率
Matlab写成循环加判断的代码容易跑得慢。尤其是阻塞检测里的矩形相交判断,如果对每个时隙每个障碍物都调用函数,5000个时隙下来光是函数调用开销就很显著。我把这部分向量化:先把所有时隙的车辆位置一次性算出来,然后对所有障碍物做矩阵化的线段相交检测。向量化之后整个仿真从几分钟缩到几十秒。
一个实用的调优经验是先跑一小段剖析:
profile on runSimulation(cfg); profile viewer找到耗时占比最高的函数,再针对性地向量化。不要一开始就把所有代码向量化,那样可读性太差,出了问题反而不好查。
6.4 BLER映射关系的校准问题
SINR转BLER的映射表如果不校准,仿真结果会出现系统性偏差。我早期用的是某种通用MCS工作点表格,用来算24GHz和28GHz的混合场景,结果发现高MCS的BLER被高估了,导致自适应调度算法过于保守,吞吐量被压低。
后来我把BLER曲线替换成基于一定假设的近似模型:对每个MCS,先根据香农容量公式计算其谱效率对应的等效SINR门限,再把门限附近区域做指数过渡。这个近似比纯查表更平滑,也更好调参。需要注意的是,BLER曲线的形状直接影响重传率和MCS分布,最终又影响时延统计,所以这块参数值得专门花时间校准。
6.5 波束管理开销的建模细节
最后提一个最容易被人忽略的细节:波束管理开销如果只做资源扣除,不考虑波束切换时链路中断造成的NACK,结果也会偏差。我在仿真里把波束扫描周期的前两个时隙设定为不可用,这两个时隙内的传输块直接收到NACK,反馈后进入重传。这样处理带来的额外重传压力,反而更接近真实系统的表现。
波束切换造成的那点重传虽然不致命,但会推高重传率指标。如果你看到重传率里有一小部分高得异常,先排查是不是波束切换期间发送了数据导致的。
最后谈一点个人体会
链路层仿真不是越复杂越好。我最早的一版把OFDM符号级生成、低密度奇偶校验编解码、循环冗余校验全部搬进仿真,结果算力消耗巨大,结论还没有简化模型清晰。后来削减到只保留SINR到BLER映射和HARQ反馈环,三千个时隙几秒钟就能跑完,抓主要矛盾的能力反而更强了。
做V2I链路层研究,核心是要搞明白哪一种物理层细节对链路层指标影响最大。毫米波场景里,我认为最重要的是阻塞事件的时间相关结构、波束对准开销和HARQ反馈环这三件事。把它们建模到位,链路层调度、重传、时延的优化就有据可依。现在回看这个工程,最值得的投资就是把前面说的六步闭环跑通:信道状态更新、PHY抽象、调度器、HARQ反馈、统计指标、多场景对比。从这个闭环出发,后续扩展多用户调度、移动性管理、波束跟踪策略都有了稳定的地基。