matlab——双车道模型及出图模板

2020年6月8日更新双车道模型及流量密度图模板。

matlab——双车道模型及出图模板_第1张图片

 

 

之前的模板都是无实物操作,所以,这次贴完整代码,是在双车道模型基础上出流量密度图。

%%  单向 2 车道模型——先更新换道完的位置,换道阶段和跟驰阶段位置更新分两步
%%  跟驰位置随机顺序更新
%%  此模型车辆从左向右运动,左右车道是以车辆前进方向的左右
clc;
clear;
dbstop if error;
%%  参数设置
lane_length = 100; %车道长度
car_rate = 0.3;  %车辆占有率
v_max = 5; %最大车速
time_max = 1000; %仿真步长
time_span = 0.1; %仿真图片输出间隔
p_slowdown = 0.3; %随机慢化概率
empty_safe = 2; %安全车距

v_mid = zeros(1,time_max);
n_mid = 20;
v_mean = zeros(1,n_mid);
for rate = 1:n_mid
    car_rate = (rate-1)/(n_mid);
     car_number = fix(1+(2*lane_length-1)*car_rate); %按车辆占有率算出的车辆数
    %%  创建空间
    space = zeros(2,lane_length);%元胞空间
    car = struct('v',zeros(1,car_number),'m',zeros(1,car_number),'n',zeros(1,car_number));% 车辆信息结构体从左到右为速度,车道,列
    %%  随机生成初始车辆信息
    for time = 1:car_number
        %%  位置信息初始化
        if  time <= fix(car_number/2)
            %%  向 1 车道随机投放车辆
            car.m(time) = 1;
            car.n(time) = fix( 1+rand(1)*(lane_length-1) );
            while space(car.m(time),car.n(time))==1
                car.n(time) = fix( 1+rand(1)*(lane_length-1) );
            end
        else
            %%  向 2 车道随机投放车辆
            car.m(time) = 2;
            car.n(time) = fix( 1+rand(1)*(lane_length-1) );
            while space(car.m(time),car.n(time))==1
                car.n(time) = fix( 1+rand(1)*(lane_length-1) );
            end
        end
        car.v(time) = fix( 1+rand(1)*(v_max-1) );
        space(car.m(time) , car.n(time) ) = 1;
    end
    
%     %%  显示初始仿真图
%     space = -1*space;
%     H = imshow(space,[]);
%     title('虚拟车道','color','red');
%     space = -1*space;
    
    %%  开始仿真
    for time=1:time_max
        if length(find(space == 1)) ~= car_number
           keyboard; 
        end
        %%  换道阶段
        for  id = 1:car_number
            %% 车距获取
            [empty_front,~] = get_empty(car.m(id),car.n(id),space,lane_length,v_max); %当前车道前车距
            if car.m(id) == 1
                m = 2;
            else
                m = 1;
            end
            [empty_front_aims,empty_back_aims] = get_empty(m,car.n(id),space,lane_length,v_max); %目标车道前后车距
            if  empty_front < min(car.v(id)+1,v_max)
                %%  前车阻碍对速度的追求
                if  empty_front_aims >= empty_safe && empty_back_aims >= empty_safe && space(m,car.n(id) ) == 0 %目标车道前后及旁边均安全
                    %%  满足安全条件换道
                    space (car.m(id),car.n(id)) =0;
                    car.m(id) = m;
                    space (car.m(id),car.n(id)) =1;
                end
            end
        end
         %%  跟驰阶段
        for id = 1:car_number
            %%  加速
            car.v(id) = min(car.v(id)+1,v_max);
            %%  减速
            [empty_front,~] = get_empty(car.m(id),car.n(id),space,lane_length,v_max); %当前车道前车距
            car.v(id) = min( car.v(id) , empty_front );
            %%  概率慢化
            if  rand(1) <= p_slowdown
                car.v(id) = max( car.v(id)-1,0 );
            end
            %% 位置更新
            space(car.m(id) , car.n(id)) = 0;
            car.n(id) = car.n(id) + car.v(id);
            if car.n(id) > lane_length %执行周期边界条件
                car.n(id) = car.n(id) - lane_length;
            end
            space(car.m(id) , car.n(id)) = 1;
        end
        v_mid(time) = mean(car.v);
    %%  显示仿真图
%     space = -1*space;
%     set(H,'CData',space);
%     pause(time_span);
%     space = -1*space;
    end
v_mean(rate) = mean(v_mid);    
end
disp(v_mean);
plot(1/(n_mid)*[0:n_mid-1]/0.005 , 1/(n_mid)*[0:n_mid-1]/0.005 .* v_mean*12);
xlabel('密度');
ylabel('流量');

%%  求距离函数
function [empty_front,empty_back] = get_empty(m,n,space,lane_length,v_max)
%用于求m车道n列的前车距,周期边界条件:头车的前车是尾车,尾车的后车是前车

space_mid = [space,space];
for mid = [1 , -1]
    empty = 1;
    while space_mid(m , n+mid*empty) == 0
        empty = empty + 1;
        if empty > v_max
            break;  %减少运算次数
        end
    end
    if mid == 1
        empty_front = empty - 1;
        n = n + lane_length;
    else
        empty_back = empty - 1;
    end
end
end

学matlab之后一直写模型,而没有对所得数据进行处理,之后更多做数据处理,但受制于专业知识及matlab水平,尤其对matlab出图这块实在菜的扣脚,暂时只想到以下三个类型的图,会不定时更新,希望看到的小伙伴能批评指正,相互学习。

以下内容以MATLAB——考虑驾驶员特性及前车速度的快速路模型为基础,建议先看完MATLAB——考虑驾驶员特性及前车速度的快速路模型,再看本篇文章。

在周边边界条件下,车辆数目固定,车道总长度固定,即,平均密度固定,平均速度可以算出,用平均密度*平均速度 = 平均流量。

空间占有率和密度的换算取决于单个元胞对应的实际长度。

ρ = rate / len

其中ρ是平均密度,rate是空间占有率,len是单个元胞对应的实际长度,单位:km。

①空间占有率-平均速度图

%%  数据储存矩阵的初始化
v = zeros(1,time_max);
v_mean = zeros(1,9);
for rate = 1:9  %获取不同车道占有率下的平均速度
    car_rate = rate * 0.1;  %车辆占有率
    
    %%  随机生成初始车辆信息
    car_number = fix(1+(3*lane_length-1)*car_rate); %按车辆占有率算出的车辆数
    %  调用初始化函数
    for time = 1:time_max
        %% 仿真阶段
        v(time) = mean(car.v); %每个时间步的平均速度
    end
v_mean(rate) = mean(v); %总的平均速度
end
plot(0.1*[1:9] , v_mean);
xlabel('空间占有率');
ylabel('平均速度');

 

matlab——双车道模型及出图模板_第2张图片

②时空图

出图的基本思路是,在每个时间步结束处,将space的值赋值给中间变量mid,并将mid中的1全部替换为time,以1:lane_length为横轴,再利用hold on,使每个时间步的空间分布图(一个时间步的空间分布图就是y = time这条散点线)出现在同一个图形界面(figure)上。

for time = 1:time_max
%%
   %%仿真阶段
%%
  mid= space(1,:)
    mid(mid == 1) = time;
    scatter(1:lane_length , mid,1);  %第三个输入参数可以调节气泡大小
    hold on;
end
xlabel('空间');
ylabel('时间');

matlab——双车道模型及出图模板_第3张图片

③换道次数-空间占有率

利用containers.Map类型作为函数输入可以直接更改键对值的特点。containers.Map不了解可看这篇文章。

map1 = containers.Map;
for rate = 1:9
    car_rate = 0.1*rate;  %车辆占有率
    map1(num2str(car_rate)) = 0;
%%
    %%其他过程
%%
  if car.m(id) == 1
     [space,car] = change_lane(space,car,lane_length,id,empty_front,v_front,p_changelane,1,car_rate,map1);
  elseif car.m(id) == 2
     [space,car] = change_lane(space,car,lane_length,id,empty_front,v_front,p_changelane,2,car_rate,map1);
  elseif car.m(id) == 3
     [space,car] = change_lane(space,car,lane_length,id,empty_front,v_front,p_changelane,0,car_rate,map1);
  end
%%
    %%跟驰阶段
%%
end
plot(0.1*[1:9] , cell2mat(map1.values)); %注意,map.values返回类型为元胞
xlabel('空间占有率');
ylabel('换道次数');

%% 换道函数
%%
  %% 中间过程
%% 换道决策
if a && b && c
    if  rand(1)

matlab——双车道模型及出图模板_第4张图片

 

最后,不管是plot () 和scatter () 都有包括线性(scatter的气泡类型),颜色等属性设置,具体查看帮助文档。

你可能感兴趣的:(笔记,matlab)