天天看點

matlab length_matlab——雙車道模型及出圖模闆

matlab length_matlab——雙車道模型及出圖模闆

2020年6月8日更新雙車道模型及流量密度圖模闆。

matlab length_matlab——雙車道模型及出圖模闆

之前的模闆都是無實物操作,是以,這次貼完整代碼,是在雙車道模型基礎上出流量密度圖。

%%  單向 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 length_matlab——雙車道模型及出圖模闆

②時空圖

出圖的基本思路是,在每個時間步結束處,将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 length_matlab——雙車道模型及出圖模闆

③換道次數-空間占有率

利用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)<p_changelane %滿足換道條件時車輛以機率換道
        map1(num2str(car_rate)) =  map1(num2str(car_rate))+1;  %計數器
        space(car.m(id),car.n(id)) =0; 
        car.m(id) = car.m(id)+2*direction-1;
        space(car.m(id),car.n(id)) =1;
    end
end
           
matlab length_matlab——雙車道模型及出圖模闆

最後,不管是plot () 和scatter () 都有包括線性(scatter的氣泡類型),顔色等屬性設定,具體檢視幫助文檔。

繼續閱讀