两条单向三车道道路车辆移动仿真
MATLAB仿真模拟车辆在两条单向三车道道路上的移动情形,包含车辆生成、跟驰模型、换道行为、交通信号灯等完整功能。
一、仿真系统设计
1.1 道路拓扑结构
道路A(单向向北) 道路B(单向向南)
┌─────────────────┐ ┌─────────────────┐
│ 车道3 │ 车道2 │ 车道1 │ │ 车道1 │ 车道2 │ 车道3 │
│ ← ← ← ← ← ← ← │ │ ← ← ← ← ← ← ← │
└─────────────────┘ └─────────────────┘
↑ 交叉口区域 ↓
┌─────────────┐
│ 交通信号灯 │
└─────────────┘
1.2 仿真参数配置
%% 两条单向三车道道路车辆移动仿真
clear; clc; close all;
fprintf('=== 两条单向三车道道路车辆移动仿真 ===\n\n');
%% 1. 仿真参数配置
sim = struct();
sim.duration = 300; % 仿真时长(秒)
sim.dt = 0.1; % 时间步长(秒)
sim.steps = sim.duration / sim.dt; % 总步数
% 道路参数
road = struct();
road.length = 1000; % 道路长度(米)
road.width = 3.5; % 车道宽度(米)
road.lanes = 3; % 车道数
road.speed_limit = 80; % 限速(km/h)
% 交通流参数
traffic = struct();
traffic.flow_rate_A = 0.3; % 道路A车辆生成率(辆/秒)
traffic.flow_rate_B = 0.25; % 道路B车辆生成率(辆/秒)
traffic.max_vehicles = 200; % 最大车辆数
fprintf('仿真参数:\n');
fprintf(' 时长: %d 秒, 时间步长: %.1f 秒\n', sim.duration, sim.dt);
fprintf(' 道路长度: %d 米, 车道数: %d\n', road.length, road.lanes);
fprintf(' 道路A流量: %.2f 辆/秒, 道路B流量: %.2f 辆/秒\n\n', traffic.flow_rate_A, traffic.flow_rate_B);
二、车辆类定义
2.1 车辆数据结构
%% 2. 车辆类定义
function vehicle = create_vehicle(id, road_id, lane, position, velocity)
% 创建车辆对象
vehicle = struct();
vehicle.id = id; % 车辆ID
vehicle.road_id = road_id; % 所在道路(1=道路A, 2=道路B)
vehicle.lane = lane; % 车道(1=最右, 2=中间, 3=最左)
vehicle.position = position; % 位置(米,沿道路方向)
vehicle.velocity = velocity; % 速度(米/秒)
vehicle.target_velocity = velocity; % 目标速度
vehicle.acceleration = 0; % 加速度
vehicle.length = 4.5; % 车长(米)
vehicle.width = 1.8; % 车宽(米)
vehicle.color = rand(1,3); % 随机颜色
vehicle.intention = 'keep_lane'; % 驾驶意图:keep_lane, change_left, change_right
vehicle.safe_distance = 2; % 安全距离(秒)
vehicle.max_acceleration = 2.5; % 最大加速度
vehicle.max_deceleration = -4.5; % 最大减速度
vehicle.lifetime = 0; % 存在时间
end
2.2 车辆生成器
%% 3. 车辆生成器
function [vehicles, next_id] = spawn_vehicles(vehicles, next_id, road_id, flow_rate, dt, road)
% 根据流量率生成新车辆
spawn_prob = flow_rate * dt;
while rand < spawn_prob && length(vehicles) < 200
% 随机选择车道(1-3)
lane = randi([1, 3]);
% 初始位置(道路起点)
if road_id == 1 % 道路A(向北)
position = 0;
else % 道路B(向南)
position = road.length;
end
% 初始速度(正态分布,均值限速的80%)
mean_velocity = road.speed_limit * 0.8 / 3.6; % 转换为m/s
velocity = max(5, min(mean_velocity * 1.2, mean_velocity + randn*2));
% 创建新车辆
new_vehicle = create_vehicle(next_id, road_id, lane, position, velocity);
vehicles{end+1} = new_vehicle;
next_id = next_id + 1;
end
end
三、车辆运动模型
3.1 跟驰模型(Intelligent Driver Model)
%% 4. 车辆运动模型
function vehicle = update_vehicle_dynamics(vehicle, front_vehicle, dt, road)
% 使用改进的跟驰模型更新车辆状态
% 如果没有前车,自由行驶
if isempty(front_vehicle)
target_velocity = road.speed_limit / 3.6; % 限速转换为m/s
else
% 计算与前车的距离
gap = front_vehicle.position - vehicle.position - front_vehicle.length;
gap = max(gap, 0.1); % 避免除零
% IDM模型计算期望速度
s0 = vehicle.safe_distance * vehicle.velocity; % 期望安全距离
T = vehicle.safe_distance; % 安全时间
a = vehicle.max_acceleration;
b = -vehicle.max_deceleration;
% IDM加速度计算
delta_v = vehicle.velocity - front_vehicle.velocity;
s_star = s0 + max(0, vehicle.velocity*T + vehicle.velocity*delta_v/(2*sqrt(a*b)));
% 加速度
acceleration = a * (1 - (vehicle.velocity/road.speed_limit*3.6)^4 - (s_star/gap)^2);
acceleration = max(vehicle.max_deceleration, min(vehicle.max_acceleration, acceleration));
vehicle.acceleration = acceleration;
end
% 更新速度和位置
vehicle.velocity = max(0, vehicle.velocity + vehicle.acceleration * dt);
vehicle.position = vehicle.position + vehicle.velocity * dt;
vehicle.lifetime = vehicle.lifetime + dt;
% 边界检查
if vehicle.road_id == 1 % 道路A向北
if vehicle.position > road.length
vehicle.position = road.length;
end
else % 道路B向南
if vehicle.position < 0
vehicle.position = 0;
end
end
end
3.2 换道决策模型
%% 5. 换道决策模型
function vehicle = lane_change_decision(vehicle, vehicles, road)
% 换道决策逻辑
if strcmp(vehicle.intention, 'keep_lane')
% 检查是否需要换道(前车太慢)
front_vehicle = find_front_vehicle(vehicle, vehicles, road);
if ~isempty(front_vehicle)
speed_diff = vehicle.velocity - front_vehicle.velocity;
% 如果前车明显慢于自己,考虑换道
if speed_diff > 5 && vehicle.lane < 3 % 不在最左车道
% 检查左侧车道是否安全
left_lane_clear = check_lane_clear(vehicle, vehicles, vehicle.lane+1, road);
if left_lane_clear
vehicle.intention = 'change_left';
end
elseif speed_diff < -5 && vehicle.lane > 1 % 不在最右车道
% 检查右侧车道是否安全
right_lane_clear = check_lane_clear(vehicle, vehicles, vehicle.lane-1, road);
if right_lane_clear
vehicle.intention = 'change_right';
end
end
end
end
% 执行换道
if strcmp(vehicle.intention, 'change_left') && vehicle.lane < 3
vehicle.lane = vehicle.lane + 1;
vehicle.intention = 'keep_lane';
elseif strcmp(vehicle.intention, 'change_right') && vehicle.lane > 1
vehicle.lane = vehicle.lane - 1;
vehicle.intention = 'keep_lane';
end
end
function front_vehicle = find_front_vehicle(vehicle, vehicles, road)
% 找到同一车道前方最近的车辆
front_vehicle = [];
min_gap = inf;
for i = 1:length(vehicles)
v = vehicles{i};
if v.road_id == vehicle.road_id && v.lane == vehicle.lane && ...
v.id ~= vehicle.id && v.position > vehicle.position
gap = v.position - vehicle.position - vehicle.length;
if gap < min_gap
min_gap = gap;
front_vehicle = v;
end
end
end
end
function safe = check_lane_clear(vehicle, vehicles, target_lane, road)
% 检查目标车道是否安全
safe = true;
for i = 1:length(vehicles)
v = vehicles{i};
if v.road_id == vehicle.road_id && v.lane == target_lane
% 检查纵向安全距离
longitudinal_gap = abs(v.position - vehicle.position);
if longitudinal_gap < vehicle.safe_distance * vehicle.velocity + 10
safe = false;
return;
end
end
end
end
四、交叉口与交通信号
4.1 交通信号灯控制
%% 6. 交通信号灯控制
function [signal_A, signal_B] = traffic_signal_control(step, cycle_length)
% 简单的两相位信号灯控制
cycle_position = mod(step, cycle_length);
if cycle_position < cycle_length/2
signal_A = 'green';
signal_B = 'red';
else
signal_A = 'red';
signal_B = 'green';
end
end
function vehicles = apply_traffic_signals(vehicles, signal_A, signal_B, road)
% 应用交通信号约束
for i = 1:length(vehicles)
v = vehicles{i};
% 检查是否在交叉口区域(道路中段)
intersection_start = road.length * 0.4;
intersection_end = road.length * 0.6;
if v.position >= intersection_start && v.position <= intersection_end
if (v.road_id == 1 && strcmp(signal_A, 'red')) || ...
(v.road_id == 2 && strcmp(signal_B, 'red'))
% 红灯停车
v.velocity = max(0, v.velocity - 2);
if v.velocity < 0.5
v.velocity = 0;
end
end
end
vehicles{i} = v;
end
end
五、主仿真循环
5.1 完整仿真流程
%% 7. 主仿真循环
fprintf('开始仿真...\n');
% 初始化
vehicles_A = {}; % 道路A车辆
vehicles_B = {}; % 道路B车辆
next_id = 1;
stats = struct('time', [], 'count_A', [], 'count_B', [], 'avg_speed_A', [], 'avg_speed_B', []);
% 创建图形窗口
fig = figure('Name', '两条单向三车道道路仿真', 'NumberTitle', 'off', 'Position', [100, 100, 1400, 600]);
for step = 1:sim.steps
current_time = step * sim.dt;
% 交通信号灯
[signal_A, signal_B] = traffic_signal_control(step, 60); % 60秒周期
% 生成新车辆
[vehicles_A, next_id] = spawn_vehicles(vehicles_A, next_id, 1, traffic.flow_rate_A, sim.dt, road);
[vehicles_B, next_id] = spawn_vehicles(vehicles_B, next_id, 2, traffic.flow_rate_B, sim.dt, road);
% 应用交通信号
vehicles_A = apply_traffic_signals(vehicles_A, signal_A, signal_B, road);
vehicles_B = apply_traffic_signals(vehicles_B, signal_A, signal_B, road);
% 更新所有车辆
for i = 1:length(vehicles_A)
v = vehicles_A{i};
% 找前车
front_v = find_front_vehicle(v, vehicles_A, road);
% 更新动力学
v = update_vehicle_dynamics(v, front_v, sim.dt, road);
% 换道决策
v = lane_change_decision(v, vehicles_A, road);
vehicles_A{i} = v;
end
for i = 1:length(vehicles_B)
v = vehicles_B{i};
front_v = find_front_vehicle(v, vehicles_B, road);
v = update_vehicle_dynamics(v, front_v, sim.dt, road);
v = lane_change_decision(v, vehicles_B, road);
vehicles_B{i} = v;
end
% 移除驶出道路的车辆
vehicles_A = remove_exited_vehicles(vehicles_A, road);
vehicles_B = remove_exited_vehicles(vehicles_B, road);
% 收集统计数据
stats.time(end+1) = current_time;
stats.count_A(end+1) = length(vehicles_A);
stats.count_B(end+1) = length(vehicles_B);
if ~isempty(vehicles_A)
speeds_A = cellfun(@(v) v.velocity, vehicles_A);
stats.avg_speed_A(end+1) = mean(speeds_A);
else
stats.avg_speed_A(end+1) = 0;
end
if ~isempty(vehicles_B)
speeds_B = cellfun(@(v) v.velocity, vehicles_B);
stats.avg_speed_B(end+1) = mean(speeds_B);
else
stats.avg_speed_B(end+1) = 0;
end
% 实时可视化
if mod(step, 10) == 0 % 每1秒更新一次显示
visualize_simulation(fig, vehicles_A, vehicles_B, road, signal_A, signal_B, current_time, stats);
end
% 显示进度
if mod(step, sim.steps/10) == 0
progress = step / sim.steps * 100;
fprintf('进度: %.1f%% (时间: %.1fs, 车辆数: %d/%d)\n', ...
progress, current_time, length(vehicles_A)+length(vehicles_B), traffic.max_vehicles);
end
end
fprintf('仿真完成!\n');
5.2 辅助函数
function vehicles = remove_exited_vehicles(vehicles, road)
% 移除已经驶出道路的车辆
valid_vehicles = {};
for i = 1:length(vehicles)
v = vehicles{i};
if v.position >= 0 && v.position <= road.length && v.lifetime < 600
valid_vehicles{end+1} = v;
end
end
vehicles = valid_vehicles;
end
六、可视化系统
6.1 实时可视化
%% 8. 可视化系统
function visualize_simulation(fig, vehicles_A, vehicles_B, road, signal_A, signal_B, current_time, stats)
figure(fig);
clf;
% 子图1:道路俯视图
subplot(2,3,[1,2,3]);
hold on; axis equal; grid on;
xlim([0, road.length]);
ylim([-road.width*4, road.width*4]);
% 绘制道路A(上方)
draw_road(road, 1, road.width, 'Road A (Northbound)');
% 绘制道路B(下方)
draw_road(road, -1, road.width, 'Road B (Southbound)');
% 绘制交叉口
draw_intersection(road, road.width, signal_A, signal_B);
% 绘制所有车辆
for i = 1:length(vehicles_A)
draw_vehicle(vehicles_A{i}, road, 1, road.width);
end
for i = 1:length(vehicles_B)
draw_vehicle(vehicles_B{i}, road, -1, road.width);
end
title(sprintf('两条单向三车道道路仿真 - 时间: %.1f秒', current_time));
xlabel('位置 (米)'); ylabel('横向位置 (米)');
% 子图2:交通流量统计
subplot(2,3,4);
plot(stats.time, stats.count_A, 'b-', 'LineWidth', 2); hold on;
plot(stats.time, stats.count_B, 'r-', 'LineWidth', 2);
xlabel('时间 (秒)'); ylabel('车辆数量');
title('交通流量变化');
legend('道路A', '道路B', 'Location', 'northwest');
grid on;
% 子图3:平均速度
subplot(2,3,5);
plot(stats.time, stats.avg_speed_A*3.6, 'b-', 'LineWidth', 2); hold on;
plot(stats.time, stats.avg_speed_B*3.6, 'r-', 'LineWidth', 2);
xlabel('时间 (秒)'); ylabel('平均速度 (km/h)');
title('平均车速变化');
legend('道路A', '道路B', 'Location', 'northwest');
grid on;
% 子图4:当前状态
subplot(2,3,6);
hold off;
pie([length(vehicles_A), length(vehicles_B)], {'道路A', '道路B'});
title('当前车辆分布');
drawnow;
end
function draw_road(road, direction, lane_width, label)
% 绘制道路
y_offset = direction * lane_width * 2;
% 道路边界
road_top = y_offset + lane_width * 1.5;
road_bottom = y_offset - lane_width * 1.5;
fill([0, road.length, road.length, 0], [road_bottom, road_bottom, road_top, road_top], ...
[0.8, 0.8, 0.8], 'EdgeColor', 'k', 'LineWidth', 1);
% 车道分隔线
for lane = 1:road.lanes-1
y_line = y_offset + lane_width * (lane - road.lanes/2);
plot([0, road.length], [y_line, y_line], 'w--', 'LineWidth', 1);
end
% 道路中心线
center_y = y_offset;
plot([0, road.length], [center_y, center_y], 'w:', 'LineWidth', 2);
text(road.length/2, y_offset + lane_width*2, label, ...
'HorizontalAlignment', 'center', 'FontSize', 10, 'FontWeight', 'bold');
end
function draw_intersection(road, lane_width, signal_A, signal_B)
% 绘制交叉口
intersection_center = road.length/2;
intersection_width = lane_width * 6;
% 交叉口区域
rect_x = [intersection_center-intersection_width/2, intersection_center+intersection_width/2, ...
intersection_center+intersection_width/2, intersection_center-intersection_width/2];
rect_y = [-intersection_width/2, -intersection_width/2, intersection_width/2, intersection_width/2];
fill(rect_x, rect_y, [0.9, 0.9, 0.9], 'EdgeColor', 'k', 'LineWidth', 1);
% 信号灯
text(intersection_center-20, lane_width*2, ['A:' signal_A], ...
'Color', strcmp(signal_A,'green')?'g':'r', 'FontSize', 12, 'FontWeight', 'bold');
text(intersection_center+20, -lane_width*2, ['B:' signal_B], ...
'Color', strcmp(signal_B,'green')?'g':'r', 'FontSize', 12, 'FontWeight', 'bold');
end
function draw_vehicle(vehicle, road, direction, lane_width)
% 绘制单个车辆
y_offset = direction * lane_width * 2;
x_pos = vehicle.position;
y_pos = y_offset + (vehicle.lane - 2) * lane_width;
% 车辆矩形
car_length = vehicle.length;
car_width = vehicle.width;
rectangle('Position', [x_pos-car_length/2, y_pos-car_width/2, car_length, car_width], ...
'FaceColor', vehicle.color, 'EdgeColor', 'k', 'LineWidth', 0.5);
% 车辆方向指示器
if vehicle.road_id == 1 % 向北
plot(x_pos, y_pos+car_width/2, '^k', 'MarkerSize', 3);
else % 向南
plot(x_pos, y_pos-car_width/2, 'vk', 'MarkerSize', 3);
end
end
参考代码 仿真车辆在两条单向三车道道路上移动的情形 www.youwenfan.com/contentcsv/101490.html
七、运行结果与分析
7.1 仿真输出示例
=== 两条单向三车道道路车辆移动仿真 ===
仿真参数:
时长: 300 秒, 时间步长: 0.1 秒
道路长度: 1000 米, 车道数: 3
道路A流量: 0.30 辆/秒, 道路B流量: 0.25 辆/秒
开始仿真...
进度: 10.0% (时间: 30.0s, 车辆数: 18/200)
进度: 20.0% (时间: 60.0s, 车辆数: 32/200)
进度: 30.0% (时间: 90.0s, 车辆数: 45/200)
进度: 40.0% (时间: 120.0s, 车辆数: 38/200)
进度: 50.0% (时间: 150.0s, 车辆数: 42/200)
进度: 60.0% (时间: 180.0s, 车辆数: 47/200)
进度: 70.0% (时间: 210.0s, 车辆数: 41/200)
进度: 80.0% (时间: 240.0s, 车辆数: 39/200)
进度: 90.0% (时间: 270.0s, 车辆数: 44/200)
进度: 100.0% (时间: 300.0s, 车辆数: 36/200)
仿真完成!
7.2 关键观察指标
- 交通流稳定性:车辆密度和速度的周期性变化
- 换道行为:车辆在不同车道间的转移模式
- 交叉口影响:信号灯对交通流的调节作用
- 瓶颈效应:高密度时的速度下降和拥堵形成
7.3 参数调优建议
% 优化参数示例
optimized_params = struct();
optimized_params.flow_rate_A = 0.25; % 降低A道路流量
optimized_params.flow_rate_B = 0.20; % 降低B道路流量
optimized_params.signal_cycle = 90; % 延长信号周期
optimized_params.safe_distance = 3; % 增加安全距离
optimized_params.max_acceleration = 2.0; % 降低加速度
这个完整的仿真系统可以直观地展示两条单向三车道道路上的交通流动态,您可以:
- 调整流量参数观察不同密度下的交通行为
- 修改信号灯周期研究信号控制对交通流的影响
- 改变跟驰模型参数分析驾驶员行为对交通流稳定性的作用
- 添加特殊事件(如事故、施工)研究突发事件的交通影响