ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Matlab的绿波带建模、仿真与优化方法

基于Matlab的绿波带建模、仿真与优化方法 简介Matlab模拟交通领域绿波带是一份面向高校本科、硕士阶段教研学习的Matlab仿真基础教程聚焦于城市交通信号协调控制中的绿波带模拟。基于Matlab 2019a环境运行通过编写仿真代码直观呈现车辆连续通过多个信号交叉口的动态过程帮助读者理解相位差、周期时长、行驶车速与绿波带宽度的内在关系适合交通工程相关课程设计、毕业设计或教师课堂演示使用。资源以zip压缩包形式提供整体大小约1.35MB目前已有311人学习。内容围绕基础仿真案例展开作者也提供“不会运行可私信”的辅助承诺对于初次接触交通仿真或Matlab编程的读者尤为友好可直接借鉴仿真思路并扩展为更复杂的路网场景也可在此基础上加入车辆排队、随机扰动等要素加深对干线协调控制的理解。1. 用Matlab模拟交通领域绿波带先把“一路绿灯”变成可计算的问题当你在城市主干道上连续通过几个路口都是绿灯通常会觉得自己运气不错。交通工程里这种人为设计的现象叫绿波带上游放行的车队到达下游路口时信号灯正好转为绿灯。用Matlab模拟交通领域绿波带实际上是在计算机里搭一条虚拟干线把信号周期、相位差、车速、排队长度这些参数放进去看车辆跑一遍会出现什么结果。对做信号配时的工程师、研究车路协同算法的人以及交通专业的在校学生来说这套模拟能直接回答“相位差设多少合适”“为什么双向绿波很难实现”“某个路口加一个公交站会不会打断绿波”。下面会从时距图原理开始依次给出最小可用建模代码、参数优化方法和验证技巧让你把绿波带从肉眼观察变成可以量化计算的工程对象。2. 交通领域绿波带的理论模型周期、相位差与绿时距图模拟绿波带不能只看视频里的“绿灯依次亮起”必须先建立控制变量。信号协调控制中真正被优化的是周期、绿信比和相位差三者共同决定一个方向的车队能否连续通过多个交叉口。在Matlab里建模第一步就是把这几个参数数字化。2.1 干线协调控制的基本参数一条做绿波控制的干线所有交叉口的信号周期 C 通常取相同值。相位差 offset_i 指第 i 个路口的协调相位一般是直行方向相对于基准路口绿灯起点的时差单位秒。绿信比 λ_i 决定一个周期内绿灯时长 G_i λ_i × C。这三个参数之间必须满足以下关系车辆从路口 i 行驶到路口 i1 的理论时间为 T L / vL 是路口间距v 是设计车速。若车辆在时刻 t 通过路口 i到达路口 i1 的时刻为 t T那么理想情况下路口 i1 的绿灯起点应出现在 t T 附近。严格说到达时刻要落在绿灯区间内即 t T ∈ [start_{i1}, start_{i1} G_{i1}]。因此最简单的相位差计算公式是offset_{i1} (offset_i L_i / v) mod C这里 mod C 是因为信号以周期循环超过一个周期后相位状态重复。这个公式只能保证单向协调反向车辆到达时不一定是绿灯这是双向绿波问题的根源。实际工程中还要区分单向绿波、双向绿波和“红波带”。单向绿波只需要沿主方向逐路口平移绿灯起点双向绿波要求两个方向的行驶时间之和接近周期的整数倍通常带宽会明显变窄。红波带则相反特意让车辆到达时遇到红灯常用于控制进城流量或限流。用Matlab模拟时这些场景只是目标函数和相位差计算方式不同底层状态机完全一样。2.2 时距图怎么画把信号条和车辆轨迹放在同一张图上时距图Time-Space Diagram是绿波带仿真最常见的输出。横轴是时间纵轴是距离或路口位置绿色条带表示该路口协调方向放行车辆轨迹是斜线斜率等于车速。从图上能直接看出车队是否落在绿色区域内。在Matlab里用 rectangle 函数画信号条用 plot 画轨迹最小代码如下% 基础参数 C 60; % 信号周期(秒) G 30; % 协调方向绿灯时长(秒) nIntersections 5; % 路口数量 spacing 300; % 路口间距(米) v 40; % 设计车速(km/h) v v / 3.6; % 换算成m/s % 相位差序列按行驶时间逐步累加 offset(1) 0; for i 2:nIntersections offset(i) mod(offset(i-1) spacing / v, C); end % 画两个周期的信号时距图 figure(Color, w); hold on; for i 1:nIntersections yBase (i-1) * spacing; % 路口的纵坐标 for k 0:1 tStart k * C offset(i); % 绿灯区间 rectangle(Position, [tStart, yBase, G, 25], ... FaceColor, [0.47, 0.67, 0.19], EdgeColor, none); % 红灯区间此处用简单二分未含黄灯 rectangle(Position, [tStart G, yBase, C - G, 25], ... FaceColor, [0.65, 0.65, 0.65], EdgeColor, none); end end xlim([0, 2*C]); ylim([0, (nIntersections-1)*spacing 40]); xlabel(时间 (s)); ylabel(距离 (m)); title(绿波带时距图绿色为绿灯区间);这段代码的关键在于每个路口都按自己的 offset 平移信号条。rectangle 的 Position 参数分别是 [x起点时间, y距离, 宽度时长, 高度厚度]。y 坐标用路口绝对距离后面画车辆轨迹时可以直接叠加上去。绿波带是否成立的直接判据就是一条从第一个路口出发、按设计车速画的斜线能不能一路穿过绿色矩形。如果斜线和绿色矩形的交叠覆盖所有路口说明基础配时满足绿波如果中间碰到灰色矩形说明该路口相位差需要调整。模拟中先忽略黄灯和全红能让你快速验证核心数学关系等基本逻辑跑通再把黄灯加回来。2.3 绿灯时间不是越长越好绿波带存在的前提是“车辆带宽度”足够。一个绿灯周期内能连续通过的车队宽度由绿灯时长决定但绿灯过长会把另一个方向的排队延误推高。用Matlab模拟时最简单的做法是固定周期扫描绿信比观察干线停车次数和支路最大排队长度的变化。你会发现当主路绿信比从0.5加到0.7时干线延误下降的幅度越来越小而支路排队溢出风险明显增加。另一个容易忽略的是排队消散时间。绿灯亮起时上一轮红灯积压的车辆需要逐个启动启动波向后传播的速度约为每秒3到5米。模拟中如果车辆从停止线瞬间启动会高估绿波带宽。实际仿真里至少要在绿灯开始后加1至2秒的启动损失时间或者用简单的跟驰模型让排队车辆逐步加速。这一细节对短周期的绿波带影响尤其明显。3. 用Matlab搭建最小可运行的绿波带车辆模拟上一章把信号配时的数学关系讲清了现在开始车辆级仿真。车辆模型可以先从匀速运动开始再逐步加入停车、排队和启动过程。用时间步进法可以比较直观地看到绿波带的动态效果。3.1 状态机设计行驶、到达停车线、排队等待、启动通过仿真中每辆车只有两个状态行驶和等待。行驶时车辆按巡航速度前进接近路口时如果信号灯不是绿灯车辆停在停车线前进入等待状态。等待状态下车辆位置固定在停车线处直到下一时刻信号变为绿灯才恢复行驶。最小实现不处理车辆之间的跟驰关系因此可能出现多辆车停在同一个位置的重叠现象。为了解决这个问题可以把停车线位置向前移动一个车辆长度加安全间距或者用排队索引让第二辆车停在第一辆车后方。下面给一个可运行的脚本框架控制单一方向车队。% 绿波带车辆模拟最小版本 clear; clc; % --- 路网参数 --- C 60; % 信号周期(s) G 30; % 协调方向绿灯时长(s) n 6; % 路口数量 dist 350 * ones(1, n-1); % 相邻路口间距(m) v 45 / 3.6; % 车辆巡航速度(m/s) offset zeros(1, n); % 各路口相位差 for i 2:n offset(i) mod(offset(i-1) dist(i-1)/v, C); end % --- 信号状态函数t时刻第i个路口是否绿灯 --- isGreen (t, i) mod(t - offset(i), C) G; % --- 车辆列表 --- nVehicles 10; headway 3; % 发车间隔(s) vehPos zeros(nVehicles, 1); % 车辆位置 vehState zeros(nVehicles, 1); % 0行驶, 1排队 hasStopped zeros(nVehicles, 1); waitTime zeros(nVehicles, 1); stopCount zeros(nVehicles, 1); % --- 仿真时间推进 --- Tsim 3 * C; dt 0.1; t 0; currentVehicle 1; traj cell(nVehicles, 1); stopLineDist cumsum([0, dist]); % 每个路口的绝对距离 while t Tsim % 按发车间隔释放车辆 if currentVehicle nVehicles t (currentVehicle - 1) * headway vehPos(currentVehicle) 0; currentVehicle currentVehicle 1; end for iv 1:nVehicles if vehPos(iv) stopLineDist(end) 20 continue; % 已驶离区域 end % 找到车辆前方最近的路口编号 nextInter find(vehPos(iv) stopLineDist, 1, last); if isempty(nextInter) vehPos(iv) vehPos(iv) v * dt; else stopLine stopLineDist(nextInter); if vehPos(iv) stopLine - 0.05 ~isGreen(t, nextInter) % 到达停车线且红灯停在停车线 vehPos(iv) stopLine; if vehState(iv) 0 vehState(iv) 1; stopCount(iv) stopCount(iv) 1; hasStopped(iv) 1; end waitTime(iv) waitTime(iv) dt; else vehPos(iv) vehPos(iv) v * dt; vehState(iv) 0; end end traj{iv}(end1, :) [t, vehPos(iv)]; end t t dt; end代码中的stopLineDist是每个路口距离起点的绝对位置find(..., last)找出车辆还没到达的下一个路口。isGreen匿名函数是仿真的核心把绝对时间减去该路口的相位差再对周期取余得到当前周期内的相位秒数小于绿灯时长就是绿灯。这样写避免了在每个时间步维护数千个信号状态数组。运行这段代码后traj 元胞数组里保存了每辆车在每一个dt时刻的位置。你可能会发现有些车在第一、第二路口都是绿灯但在第三个路口被截停这就是因为相位差计算时用的车速与实际车速不完全匹配或者发车间隔导致车辆到达时间偏移。这正是模拟要暴露的问题。3.2 绘制车辆轨迹并叠加到信号时距图仿真结束后把车辆轨迹与信号条画在同一张图上的代码如下hold on; colors lines(nVehicles); for iv 1:nVehicles if isempty(traj{iv}), continue; end plot(traj{iv}(:,1), traj{iv}(:,2), Color, colors(iv,:), ... LineWidth, 1.2); end绘制时需要注意顺序信号条先画轨迹后画这样车辆轨迹不会被矩形盖住。如果车辆数量较多轨迹颜色不要用循环色阶里的相近颜色最好按发车时间从深到浅渐变便于观察车队形态。3.3 从模拟结果提取绿波性能指标绿波带方案好不好要看三个指标停车次数、停车延误、行程速度。停车次数已经在仿真的stopCount中累计停车延误用waitTime表示平均行程速度则是总行驶距离除以首车到末车的总耗时。下面这段统计代码可以放在仿真循环之后% 统计每辆车的总行驶时间和平均速度 for iv 1:nVehicles if isempty(traj{iv}), continue; end timeVec traj{iv}(:,1); posVec traj{iv}(:,2); travelTime timeVec(end) - timeVec(1); travelDist posVec(end) - posVec(1); avgSpeed travelDist / travelTime; % m/s fprintf(车辆%d: 停车%d次, 延误%.1fs, 平均速度%.2fm/s\n, ... iv, stopCount(iv), waitTime(iv), avgSpeed); end这段统计代码逻辑简单但要注意最后一辆车如果仿真结束时还在路网内timeVec(end)与发车时间的差不能代表完整行程。需要把最后一个路口的通过时间也记录下来或者在仿真循环结束后强制让所有车辆继续行驶到终点。更稳妥的方法是设置条件循环当所有车辆都已驶离最后停止线且再没有新的发车需求时才结束仿真。3.4 发车模式均匀发车与随机到达上面代码用的是等间隔发车适合观察车队在绿波带中的离散过程。但真实交通到达是随机的如果把发车间隔从固定值变成泊松分布模拟结果会明显不同。最简单的方法是生成一组指数分布的间隔nVehicles 15; lambda 0.3; % 平均每秒到达车辆数 interArrival exprnd(1/lambda, nVehicles, 1); arrivalTime cumsum(interArrival);然后把章节3.1里的发车判断条件改成用arrivalTime(iv)来控制发车时刻。随机到达会降低绿波带的表现因为晚到或早到的车辆更容易被红灯截住。通过对比均匀发车和随机发车的延误你可以估算绿波方案的鲁棒性这部分数据在方案汇报中很有说服力。4. 用Matlab优化绿波带参数相位差与绿信比的联合调整手工试参数只能得到一个“视觉上绿波”的方案但要找到最优解还是要把优化问题数字化。绿波带优化的决策变量通常是各路口相位差有时也把周期和绿信比纳入但那样会变成混合整数非线性问题。工程上更常见的做法是分两步走先根据流量粗略定周期与绿信比再固定这两个值只优化相位差。4.1 网格扫描相位差先看全局趋势因为相位差取值范围是 [0, C)路口数量少时可以直接用网格扫描。5个路口、固定第一个路口为基准需要优化4个相位差。如果每个相位差以2秒为步长60秒周期有30个候选值组合数是 30^4 810000跑一次完整仿真如果耗时0.01秒大约需要2小时可以接受。实际做方案时我习惯先用10秒粗步长扫一遍找出低谷区再在低谷附近加密。网格扫描的代码结构如下C 60; bestDelay inf; bestOffset zeros(1, n); % 粗扫描步长5秒 for o2 0:5:C-1 for o3 0:5:C-1 for o4 0:5:C-1 offset [0, o2, o3, o4, 0, 0]; % 示例只有前4个路口 % 调用仿真函数返回总延误 delay simulateGreenWave(C, G, offset, dist, v); if delay bestDelay bestDelay delay; bestOffset offset; end end end end嵌套循环虽然笨但结果稳定不依赖初始值。这里simulateGreenWave是单独封装的函数内部实现前面章节里的时间步进逻辑。网格扫描的步长选择很重要步长太粗可能漏掉最优解所在的窄谷太细则计算量指数上升。一种变通办法是先粗扫再用 fminsearch 在最优附近做局部搜索。4.2 用 fmincon 优化连续相位差网格扫描只适合路口数少的情况。当路口数达到8个以上组合数爆炸就需要用优化工具箱。下面是一个 fmincon 的典型调用方式% 目标函数输入相位差向量返回干线总延误 function cost greenWaveCost(x) C 60; G 30; n 5; dist 300 * ones(1, n-1); v 40 / 3.6; offset [0, x]; result simulateGreenWave(C, G, offset, dist, v); cost result.totalDelay; end % 主程序 x0 cumsum(dist) / v; % 初始解按理想行驶时间 lb zeros(1, n-1); ub C * ones(1, n-1); options optimoptions(fmincon, Display, iter, ... Algorithm, sqp, MaxFunctionEvaluations, 300); xopt fmincon(greenWaveCost, x0, [], [], [], [], lb, ub, [], options);这里把第一个路口的相位差固定为0优化剩余路口的相位差。lb和ub把搜索空间限制在一个周期内因为相位差超过一个周期没有物理意义。使用sqp算法是因为它处理边界约束稳定而且不依赖目标函数二阶导。需要提醒的是fmincon 是为连续可微优化设计的而放行-停车仿真会产生不连续的延误函数。用 fmincon 求得的“最优”很可能只是局部最优而且迭代过程会很慢。更稳妥的办法是将排队延误近似成车流到达曲线与绿灯窗口的交叠面积得到一个连续可微的模型再交给 fmincon。如果你的团队以快速验证为主网格扫描加局部寻优是更好的组合。4.3 用粒子群或遗传算法做全局搜索如果不想写连续近似模型可以直接用全局优化算法。Matlab全局优化工具箱里的particleswarm和ga对离散噪声有更好的容忍度。调用方式如下options optimoptions(particleswarm, SwarmSize, 30, ... MaxIterations, 50, Display, final); [xopt, fval] particleswarm(greenWaveCost, n-1, lb, ub, options);粒子群不保证找到全局最优但它不要求目标函数光滑或可微适合直接嵌入原始仿真器。每次迭代会起风50次仿真50轮迭代就是2500次几分钟内能跑完一个中等规模算例。如果你的Matlab版本没有全局优化工具箱可以用自带的fminsearch搭配随机多起点效果类似只是收敛速度慢一些。优化完成之后一定要把优化结果重新放入含随机到达的仿真里验证。目标函数用的是均匀发车数据真实交通流在优化解附近的表现会略有退化。如果退化超过10%说明优化解过度拟合了确定性的发车时刻需要把仿真目标函数改成多组随机到达的期望值。4.4 绿信比和周期的联合调整两步走策略相位差优化解决的是“绿灯什么时候亮”的问题但绿信比解决的是“绿灯亮多久”的问题。绿信比大小直接影响排队消散所需时间如果绿灯太短即使相位差算得再精确车队也会被堵在路口。常见的调整流程是根据各进口道长时期流量用韦伯斯特公式估算一个合适周期 C。根据关键交叉口流量比确定各相位绿信比。固定 C 和绿信比只优化相位差。用模拟结果诊断哪个路口延误突出适当增加或减少该路口协调相位绿信比再回到第3步重新优化相位差。在Matlab里做第4步时可以把绿信比也放入优化变量但要注意约束条件所有相位绿信比加总等于1减去黄灯和全红比例。此时用 fmincon 带线性约束比较方便% 变量为 [offset2, offset3, ..., lambda1, lambda2, ...] % 线性约束 A*x b 确保 lambda 总和不超过上限这样的模型更接近真实信号配时但仿真运行时间也随之增加。我个人的建议是先做相位差优化因为绿信比的影响直观且容易通过关键路口单独调整把绿信比纳入自动优化放到第二步避免一开始就在多个耦合参数里失去物理直觉。5. 绿波带模拟结果怎么验证与调优带宽检测和几个必踩的坑跑完仿真、拿到优化参数后最后一步是验证绿波带是否真的“带”起来了。单纯看总停车次数下降还不够你要量化绿波带宽并且检查在非理想条件下方案是否还能成立。绿波带宽的工程定义是在一个信号周期内车队从第一个路口出发能够连续不停车通过后续所有路口的最大时间窗口。用Matlab检测带宽最直接的方法是遍历发车时刻对每个时刻测试一辆车能否一路绿灯scanStep 0.5; % 分辨率 C 60; okMask zeros(1, round(C / scanStep) 1); idx 0; for t0 0:scanStep:C idx idx 1; if isZeroStopRelease(t0) okMask(idx) 1; end end % 计算连续为1的最长序列长度 maxBand 0; count 0; for k 1:length(okMask) if okMask(k) count count 1; maxBand max(maxBand, count); else count 0; end end bandwidthSeconds maxBand * scanStep;isZeroStopRelease(t0)是一个测试函数在 t0 时刻让一辆车从第一个路口出发沿着干线跑完整段路返回这辆车是否从未停车。逐点测试虽然计算量大但结果完全由仿真器决定完全不依赖理论近似。带宽的单位是秒数值越大说明绿波能容纳的交通流量越大。验证过程中有几个坑每个都会让模拟出来的绿波在现实中失效第一是排队消散时间。绿灯亮起车道上的排队车辆逐台启动启动波从队头向后传播。模拟里如果车辆瞬间从0加速到设计车速带宽会被显著高估。建议每辆排队车加1秒启动损失或者在绿灯开始后的前2秒不释放排队车辆。第二是相位差基准不一致。计算行驶时间时用的是路口中心间距还是停止线间距这两者相差一个路口宽度车速60km/h时一个路口宽度约30米相当于0.5秒到1秒的相位差错。整条干线累计下来可能让最下游的路口完全错过绿波。写代码时最好把stopLine和offset统一为同一距离基准。第三是速度假设过于单一。绿波按设计车速计算相位差但实际道路上的车速分布是连续谱。模拟时可以把每辆车速度设为v randn * 2看看带宽覆盖范围是否缩小。如果缩小的比例超过一半这个绿波方案应对混行车流的能力不足要么调整周期让绿波对速度不敏感要么在路段上增加绿波车速提示标志。第四是双向绿波的不可能三角。两个方向的行驶时间之和如果等于周期整数倍理论上双向都能获得绿波但带宽会被压缩到很窄。在Matlab里优化双向绿波时目标函数要写成两个方向延误的加权和并且权重根据早晚高峰期流量设定。不要试图在一个模型里同时让两个方向都达到最大带宽现实中通常优先保障流量大的方向。验证完带宽后再把优化后的配时放回包含随机到达的仿真中运行多次统计平均延误和最大排队长度。如果最大排队长度溢出到上游交叉口即使平均延误好看方案也不能落地。绿波带模拟的交付物不只是几张时距图而是一组对速度变化、流量波动、排队长度都给出量化响应的信号配时方案。把isZeroStopRelease和bandwidthSeconds封装成独立函数以后每次调整配时都能立刻得到带宽反馈这一步能为后续的干线协调优化省下大量时间。本文还有配套的精品资源点击获取
返回列表