基于元胞自动机NaSch模型的多车道手动-自动混合驾驶仿真模型的Matlab实现

模型的建立基本来自于:http://www.doc88.com/p-2078634086043.html

花了一天半的时间用新学会的matlab实现了一下。

NaSch模型主函数:

function [ret_Vave] = NaSch()
rng(‘shuffle‘);

global CellsNum; CellsNum = 200; %The number of cells in each lane
global LanesNum; LanesNum = 3; %The number of Lanes
global D; D = 0.02; %The cell occupancy rate
global L; L = 5; %The length of one cell
global CarsNum; CarsNum = round( LanesNum .* CellsNum .* D ); %The number of cars
global SelfRatio; SelfRatio = 0.5; %Self-driving vehicle rate
global Vmin; Vmin = 1; %Minimum speed limit
global Vmax; Vmax = 6; %Maximum speed limit

%Meet the lane changing conditions...
global ChangeRightP; ChangeRightP = 0.5; %The probability of changing into the right lane
global ChangeLeftP; ChangeLeftP = 0.8; %The probability of changing into the left lane

[z,cars] = RoadInit();
cells = z;
cars = CarInit(cars);

T = 1000; %The duration of simulation
Vave = zeros(1,T); %Average velocity per unit time

global loopCars; loopCars = [];
%Start the simulation
for t = 1:1:T

    [cells,cars] = EntryControl(cells,cars);

    %Calculate each distance
    for i = 1:1:CarsNum
        [d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac] = calcDist(cells,cars);
    end

    %Get the next state
    for i = 1:1:CarsNum
        if(cars(i).M==1) %Leftmost lane
            [cells,cars] = L_NextState(i,cells,cars,d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac);
        elseif(cars(i).M==LanesNum) %Rightmost lane
            [cells,cars] = R_NextState(i,cells,cars,d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac);
        else %Middle lane
            [cells,cars] = M_NextState(i,cells,cars,d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac);
        end
    end

    cars = RandSlow(cars);
    [cells,cars] = Update(cells,cars);
    cells = cells(1:LanesNum,1:CellsNum); %Control the size of Cells Matrix
    Vave(t) = calc_Vave(cars); %Calculate current average velocity
end

ret_Vave = mean(Vave); %Calculate average velocity
end

初始化函数:

function [cell_mat,car_mat] = RoadInit()
global LanesNum;
global CellsNum;
global CarsNum;

mat = zeros(LanesNum,CellsNum);

Car(1,CarsNum) = struct(‘ID‘,[],‘V‘,[],‘M‘,[],‘N‘,[],‘Self‘,[]);
%Vehicle Information: ID, Speed, Position, Whether self driving or not

for i = 1:1:CarsNum
    m=round( 1 + ( LanesNum - 1 ) * rand(1) );
    n=round( 1 + ( CellsNum - 1 ) * rand(1) );
    while( mat(m,n) ~= 0 )
        m = round( 1 + ( LanesNum - 1 ) * rand(1) );
        n = round( 1 + ( CellsNum - 1 ) * rand(1) );
    end
    mat(m,n) = i;

    Car(i).ID = i;
    Car(i).M = m;
    Car(i).N = n;
end

cell_mat = mat;
car_mat = Car;
end
function car_mat = CarInit(Car)
global CarsNum;
global Vmin;
global Vmax;
global SelfRatio;

for i = 1:1:CarsNum
    Car(i).V = round( Vmin + ( Vmax - Vmin ) * rand(1) );
    if(rand(1)<=SelfRatio) Car(i).Self = 1;
    else Car(i).Self = 0;
    end
end

car_mat = Car;
end

入口控制:

function [new_cells,new_cars] = EntryControl(cells,cars)
global loopCars;
global LanesNum;
global Vmin;

while(StackSize(loopCars) > 0)

    if( all( cells(:,1) ~= 0 ) == 1 )
        break
    end

    for i = 1:1:LanesNum
        if(cells(i,1) == 0)
            id = topStack(loopCars); popStack(loopCars);
            cells(i,1) = id;
            cars(id).V = Vmin;
            cars(id).M = i;
            cars(id).N = 1;
            break
        end
    end

end

new_cells = cells;
new_cars = cars;
end

计算各种车距:

function [Ret_d,Ret_d_safe,Ret_d_l_for,Ret_d_l_bac,Ret_d_r_for,Ret_d_r_bac] = calcDist(cells,cars)
global LanesNum;
global CellsNum;
global CarsNum;

d = linspace(-1,-1,CarsNum);
d_safe = linspace(-1,-1,CarsNum);
d_l_for = linspace(-1,-1,CarsNum);
d_l_bac = linspace(-1,-1,CarsNum);
d_r_for = linspace(-1,-1,CarsNum);
d_r_bac = linspace(-1,-1,CarsNum);

for i = 1:1:CarsNum

    m = cars(i).M; %The m_th lane
    n = cars(i).N; %The n_th cell

    %Calculate the distance to front car
    d(i) = inf;
    for f = n+1:1:CellsNum
        if(cells(m,f) ~= 0)
            d(i) = f - n;
            break
        end
    end

    %If the left lane exist
    if( m-1 >= 1 )
        %Forward
        d_l_for(i) = inf;
        for p = n:1:CellsNum
            if( cells( m-1 , p ) ~= 0 )
                d_l_for(i) = p - n;
                break
            end
        end
        %Backward
        for p = n:-1:1
            d_l_bac(i) = inf;
            if( cells( m-1 , p ) ~= 0 )
                d_l_bac(i) = n - p;
                break
            end
        end
    end

    %If the right lane exist
    if( m+1 <= LanesNum )
        %Forward
        d_r_for(i) = inf;
        for p = n:1:CellsNum
            if( cells( m+1 , p ) ~= 0 )
                d_r_for(i) = p - n;
                break
            end
        end
        %Backward
        d_r_bac(i) = inf;
        for p = n:-1:1
            if( cells( m+1 , p ) ~= 0 )
                d_r_bac(i) = n - p;
                break
            end
        end
    end

    %The d_safe of two kinds of cars is different
    if(cars(i).Self == 1)
        d_safe(i) = cars(i).V;
    else
        d_safe(i) = 2 .* cars(i).V;
    end

end

Ret_d = d;
Ret_d_safe = d_safe;
Ret_d_l_for = d_l_for;
Ret_d_l_bac = d_l_bac;
Ret_d_r_for = d_r_for;
Ret_d_r_bac = d_r_bac;
end

加减速规则实现:

function new_cars = Accelerate(id,cars,d,d_Safe)
global Vmax;
global Pa;
Pa = 0.8; %Acceleration probability

if( d(id) > d_Safe(id) && cars(id).V < Vmax )
    if(rand(1) <= Pa)
        cars(id).V = cars(id).V + 1;
    end
end

new_cars = cars;
end
function new_cars = Decelerate(id,cars,d,d_safe)
global Vmax;
global Vmin;

if( d(id) < d_safe(id) && d(id) >= Vmax - Vmin )
    cars(id).V = max( cars(id).V - 1 , Vmin );
elseif( d(id) < Vmax - Vmin )
    cars(id).V = Vmin;
end

new_cars = cars;
end

关于变道的状态更新:

function [new_cells,new_cars] = L_NextState(i,cells,cars,d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac)
global Vmax;
global LanesNum;
global loopCars;

if( d_r_for(i) > d_safe(i) ) %与右前方车辆距离大于安全距离
    ok1 = 1;
else
    ok1 = 0;
end

if( d_r_bac(i) > 1 + Vmax - min(cars(i).V+1,Vmax) ) %与右后方车辆安全
    ok2 = 1;
else
    ok2 = 0;
end

if( cars(i).M+2 <= LanesNum && cells(cars(i).M+2,cars(i).N) ~= 0 ) %右边相隔一个车道平行位置有车
    id = cells(cars(i).M+2,cars(i).N); %获取该车编号
    if( min( d_l_for(id) , d_l_bac(id) ) < d_safe(id) ) %判断该车不能向左变道
        ok3 = 1;
    else
        ok3 = 0;
    end
else
    ok3 = 1;
end

ChangeLaneOK = ok1 && ok2 && ok3; %得到是否有变道条件

if( d(i) < d_safe(i) ) %与前车距离小于安全距离,能变道则必须变道
    if(ChangeLaneOK)

        cells(cars(i).M,cars(i).N) = 0;
        cars(i).M = cars(i).M + 1;
        if( cells( cars(i).M , cars(i).N ) ~= 0 ) %撞车控制
            loopCars = pushStack(loopCars,cars(i).ID);
        else
            cells(cars(i).M,cars(i).N) = cars(i).ID; %变道
        end

        cars = Accelerate(i,cars,d,d_safe); %加速
    else
        cars = Decelerate(i,cars,d,d_safe); %减速
    end
else %与前车距离大于等于安全距离
    ChangeLaneDesire = getCLD(i,cars,‘R‘); %计算变道欲望
    if(ChangeLaneOK && ChangeLaneDesire)

        cells(cars(i).M,cars(i).N) = 0;
        cars(i).M = cars(i).M + 1;
        if( cells( cars(i).M , cars(i).N ) ~= 0 ) %撞车控制
            loopCars = pushStack(loopCars,cars(i).ID);
        else
            cells(cars(i).M,cars(i).N) = cars(i).ID; %变道
        end

        cars = Accelerate(i,cars,d,d_safe); %加速
    else
        cars = Accelerate(i,cars,d,d_safe); %加速
        cars = Decelerate(i,cars,d,d_safe); %减速
    end
end

new_cells = cells;
new_cars = cars;
end
function [new_cells,new_cars] = M_NextState(i,cells,cars,d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac)
global Vmax;
global LanesNum;
global loopCars;
%计算中间车道上车辆的下一时刻状态

if( d_l_for(i) > d_safe(i) ) %与左前方车辆距离大于安全距离
    ok1 = 1;
else
    ok1 = 0;
end

if( d_l_bac(i) > 1 + Vmax - min(cars(i).V+1,Vmax) ) %与左后方车辆安全
    ok2 = 1;
else
    ok2 = 0;
end

if( cars(i).M-2 >= 1 && cells(cars(i).M-2,cars(i).N) ~= 0 ) %左边相隔一个车道平行位置有车
    id = cells(cars(i).M-2,cars(i).N); %获取该车编号
    if( min( d_r_for(id) , d_r_bac(id) ) < d_safe(id) ) %判断该车不能向右变道
        ok3 = 1;
    else
        ok3 = 0;
    end
else
    ok3 = 1;
end

ChangeLeftLaneOK = ok1 && ok2 && ok3; %得到是否有向左变道条件

if( d_r_for(i) > d_safe(i) ) %与右前方车辆距离大于安全距离
    ok1 = 1;
else
    ok1 = 0;
end

if( d_r_bac(i) ~= inf && d_r_bac(i) ~= -1 && cells( cars(i).M + 1 , cars(i).N - d_r_bac(i) ) > 0 ) %右后方有车
    id = cells( cars(i).M + 1 , cars(i).N - d_r_bac(i) ); %得到该车的编号
    if( d_r_bac(i) > d_safe(id) ) %与右后方车辆安全
        ok2 = 1;
    else
        ok2 = 0;
    end
else
    ok2 = 1;
end

if( cars(i).M+2 <= LanesNum && cells(cars(i).M+2,cars(i).N) ~= 0 ) %右边相隔一个车道平行位置有车
    id = cells(cars(i).M+2,cars(i).N); %获取该车编号
    if( min( d_l_for(id) , d_l_bac(id) ) < d_safe(id) ) %判断该车不能向左变道
        ok3 = 1;
    else
        ok3 = 0;
    end
else
    ok3 = 1;
end

ChangeRightLaneOK = ok1 && ok2 && ok3; %得到是否有向右变道条件

if( d(i) < d_safe(i) ) %与前车距离小于安全距离

    if(ChangeRightLaneOK) %能够向右变道则向右变道

        cells(cars(i).M,cars(i).N) = 0;
        cars(i).M = cars(i).M + 1;
        if( cells( cars(i).M , cars(i).N ) ~= 0 ) %撞车控制
            loopCars = pushStack(loopCars,cars(i).ID);
        else
            cells(cars(i).M,cars(i).N) = cars(i).ID; %变道
        end

        cars = Accelerate(i,cars,d,d_safe); %加速

    else %不能向右变道则尝试向左变道

        if(ChangeLeftLaneOK == 1) %能向左变道则向左变道

            cells(cars(i).M,cars(i).N) = 0;
            cars(i).M = cars(i).M - 1;
            if( cells( cars(i).M , cars(i).N ) ~= 0 ) %撞车控制
                loopCars = pushStack(loopCars,cars(i).ID);
            else
                cells(cars(i).M,cars(i).N) = cars(i).ID; %变道
            end

        else %两边都不允许变道
            cars = Decelerate(i,cars,d,d_safe); %减速
        end

    end

else %与前车距离大于等于安全距离

    ChangeLaneDesire = getCLD(i,cars,‘R‘); %计算变道欲望

    if(ChangeRightLaneOK && ChangeLaneDesire) %能够向右变道,且有变道欲望

        cells(cars(i).M,cars(i).N) = 0;
        cars(i).M = cars(i).M + 1;
        if( cells( cars(i).M , cars(i).N ) ~= 0 ) %撞车控制
            loopCars = pushStack(loopCars,cars(i).ID);
        else
            cells(cars(i).M,cars(i).N) = cars(i).ID; %变道
        end

        cars = Accelerate(i,cars,d,d_safe); %加速
    else
        cars = Accelerate(i,cars,d,d_safe); %加速
        cars = Decelerate(i,cars,d,d_safe); %减速
    end

end

new_cells = cells;
new_cars = cars;
end
function [new_cells,new_cars] = R_NextState(i,cells,cars,d,d_safe,d_l_for,d_l_bac,d_r_for,d_r_bac)
global Vmax;
global loopCars;
%计算最右侧车道上车辆的下一时刻状态

if( d_l_for(i) > d_safe(i) ) %与左前方车辆距离大于安全距离
    ok1 = 1;
else
    ok1 = 0;
end

if( d_l_bac(i) > 1 + Vmax - min(cars(i).V+1,Vmax) ) %与左后方车辆安全
    ok2 = 1;
else
    ok2 = 0;
end

if( cars(i).M-2 >= 1 && cells(cars(i).M-2,cars(i).N) ~= 0 ) %左边相隔一个车道平行位置有车
    id = cells(cars(i).M-2,cars(i).N); %获取该车编号
    if( min( d_r_for(id) , d_r_bac(id) ) < d_safe(id) ) %判断该车不能向右变道
        ok3 = 1;
    else
        ok3 = 0;
    end
else
    ok3 = 1;
end

ChangeLaneOK = ok1 && ok2 && ok3; %得到是否有变道条件

if( d(i) < d_safe(i) ) %与前车距离小于安全距离
    ChangeLaneDesire = getCLD(i,cars,‘L‘); %计算变道欲望
    if(ChangeLaneOK && ChangeLaneDesire)
        cells(cars(i).M,cars(i).N) = 0;
        cars(i).M = cars(i).M - 1;
        if( cells( cars(i).M , cars(i).N ) ~= 0 ) %撞车控制
            loopCars = pushStack(loopCars,cars(i).ID);
        else
            cells(cars(i).M,cars(i).N) = cars(i).ID; %变道
        end
    else
        cars = Decelerate(i,cars,d,d_safe); %减速
    end
else %与前车距离大于等于安全距离
    cars = Accelerate(i,cars,d,d_safe); %加速
    cars = Decelerate(i,cars,d,d_safe); %减速
end

new_cells = cells;
new_cars = cars;
end

计算变道欲望:

function ret = getCLD(id,cars,Type)
%Calculate the desire to change the lane
global ChangeRightP;
global ChangeLeftP;

if(Type == ‘R‘) %To right
    if(cars(id).Self == 1) %Self driving
        ret = 1;
    else %Manual driving
        if(rand(1) <= ChangeRightP)
            ret = 1;
        else
            ret = 0;
        end
    end;
else %To left
    if(cars(id).Self == 1) %Self driving
        ret = 1;
    else %Manual driving
        if(rand(1) <= ChangeLeftP)
            ret = 1;
        else
            ret = 0;
        end
    end;
end

end

随机慢化:

function new_cars = RandSlow(cars)
global CarsNum;
global Vmin;

p=0.1; %手动车慢化概率
q=0.03; %自动驾驶车慢化概率

for i = 1:1:CarsNum
    if(cars(i).Self==1)
        if(rand(1) <= q)
            cars(i).V = max( cars(i).V - 1 , Vmin );
        end
    else
        if(rand(1) <= p)
            cars(i).V = max( cars(i).V - 1 , Vmin );
        end
    end
end

new_cars = cars;
end

状态更新:

function [new_cells,new_cars] = Update(cells,cars)
global CarsNum;
global CellsNum;
global loopCars;

for i = 1:1:CarsNum
    cells( cars(i).M , cars(i).N ) = 0;
    if( cars(i).N + cars(i).V > CellsNum ) %Drive out of the road
        loopCars = pushStack(loopCars,cars(i).ID);
    else
        cells( cars(i).M , cars(i).N ) = cars(i).ID;
    end;
end

new_cells = cells;
new_cars = cars;
end

栈模拟:

function newStack = pushStack(Stack,val)
newStack = [val,Stack];
end
function newStack = popStack(Stack)
newStack = Stack(2:end);
end
function ret = StackSize(Stack)
ret = size(Stack,2);
end
function Val = topStack(Stack)
Val = Stack(1);
end

源代码直接下载链接

原文地址:https://www.cnblogs.com/dilthey/p/8365141.html

时间: 2024-10-09 18:21:41

基于元胞自动机NaSch模型的多车道手动-自动混合驾驶仿真模型的Matlab实现的相关文章

元胞自动机+生命游戏

元胞自动机 元胞自动机(Cellular Automaton,复数为Cellular Automata,简称CA,也有人译为细胞自动机.点格自动机.分子自动机或单元自动机).是一时间和空间都离散的动力系统.散布在规则格网 (Lattice Grid)中的每一元胞(Cell)取有限的离散状态,遵循同样的作用规则,依据确定的局部规则作同步更新.大量元胞通过简单的相互作用而构成动态系统的演化. 不同于一般的动力学模型,元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的规则构成.凡是满

元胞自动机简介

摘要: 元胞自动机能利用简单的局部规则和离散方法描述复杂的全局的连续系统,已成为探索复杂系统的一种有效工具. 文章 阐述了元胞自动机的发展历程.结构.特征及基本理论与方珐: 介绍了元胞自动机在寡头垄断行为.交通管理及工程运输.城市发展.市场营销.股票投资.企业战略等管理领域中的应用: 指出元胞自动机理论的优势与不足, 并提出进一步的研究展望. 1引言 复杂科学 20世纪80年代,以美国圣塔菲(SantaFe)学派为首提出了复杂科学,一经提出,在世界范围内引起了广泛的关注.目前,关于复杂性和复杂系

编程模拟自然(九):元胞自动机

序 旧书有云:发鸠之山,其上多柘木.有鸟焉,其状如乌,文首.白喙.赤足,名曰精卫,其鸣自詨. 一日,精卫游于码海,溺而不返,后常衔西山之木石,以堙于海.有诗为证: 万事有不平,尔何空自苦: 长将一寸身,衔木到终古? 我愿平码海,身沉心不改: 码海无平期,我心无绝时. 呜呼!君不见,西山衔木众鸟多,鹊来燕去自成窠! (前情提要:主角元乘坐返回舱降落到了码海上,随后遇到了个鸟人...) “咳咳,远道的客人,我名精卫XIV,乃是先祖精卫鸟的第十四代后裔...”鸟人作自我介绍 “...你是谁,从哪里来又

简要概述元胞自动机及其应用

谈一些自己的所学,有错误请指正. 元胞自动机( Cellular Automata) 是 20 世纪 50 年代初由计算机之父冯·诺依曼( J. von Neumann) 为了模拟生命系统所具有的自复制功能而提出来的.此后,史蒂芬·沃尔夫勒姆( Stephen Wolfram) 对元胞自动机理论进行了深入的研究,例如,他对一维初等元胞机全部 256 种规则所产生的模型进行了深入研究,并将元胞自动机分为平稳型.周期型.混沌型和复杂型 4 种类型. 元胞自动机采用离散的空间布局和离散的时间间隔,将元

元胞自动机

元胞自动机(cellular automata,CA)  元胞自动机(cellular automata,CA) 是一种时间.空间.状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力. 元胞自动机是一类模型的总称,或者说是一个方法框架.其特点是时间.空间.状态都离散,每个变量只取有限多个状态,且其状态改变的规则在时间和空间上都是局部的. 有限自动机 有限自动机是一种控制状态有限.符号集有限的自动机,是一种离散输入输出系统的数学模型. 从数学上来定义,

【转载】【元胞自动机】生命游戏(时间简史)

原帖:http://www.cnblogs.com/lvpengms/archive/2010/02/08/1666095.html 晚上闲着没事干,鉴于前一段时间数学建模中看到了生命游戏 Game of Life,所以用C++实现一下,效果还不错. 本程序是用vs2005 C++编写,有意想要程序和源码的朋友可以给我发邮件. 更新:程序源码可以从这个地址下载:下载元胞自动机源码及程序 =======================================================

用元胞自动机实现多数分类算法

元胞自动机(Cellular automaton) 元胞自动机是由元胞组成的网格,每个元胞都根据邻域的状态来选择开或关.所有的元胞都遵循同样的规则,也称为元胞的更新规则,规则根据各元胞邻域的当前状态决定元胞的下一步状态.同自然界的复杂系统一样,元胞自动机也是由大量简单个体(元胞)组成,不存在中央控制,每个个体都只与少量其他个体交互.而且元胞自动机也能表现出非常复杂的行为,它们的行为很难甚至不可能通过其更新规则来预测.元胞自动机有很多种类型,著名的"生命游戏"也是元胞自动机的一种. 初等

几个设计元胞自动机式智能的挑战

知道我的理论的人不多,但是这个问题完全可以当成一个小游戏,规则如下: 有若干"神经元",每个处在激活态或未激活态(一共2个状态) 神经元有"能量"和"阈值",为方便理解,先假设每个神经元都一样 神经元间存在单向的联系,允许两个神经元间有多个联系(比如一正一反) 这若干个神经元可以进行"演化",每次演化,神经元同时行动,先把自己的能量平均分给联系到的神经元,然后如果接收到超过阈值的能量,就激活,否则不激活. 如果两个神经元同时激

Python案例(一):协程实现康威生命游戏,元胞自动机

from collections import namedtuple import os,time import random Query=namedtuple('Query',('y','x')) Transition=namedtuple('Transition',('y','x','state')) ALIVE="*" EMPTY="-" def count_neighbors(y,x): n_=yield Query(y+1,x+0) ne=yield Qu