Code covered by the BSD License  

Highlights from
CTMSIM - an interactive freeway traffic macrosimulator

image thumbnail
from CTMSIM - an interactive freeway traffic macrosimulator by Alex Kurzhanskiy
Freeway traffic simulation based on Asymmetric Cell Transmission Model

controller_swarm1(densities, flows, celldata, ts, idx)
function new_flows = controller_swarm1(densities, flows, celldata, ts, idx)
% CONTROLLER_SWARM1 - implementation of SWARM 1 ramp metering strategy.
%
% Call:   new_flows = controller_swarm1(densities, flows, celldata, ts, idx)
%
% Parameters:
%             densities - vector of densities;
%             flows     - vector of on-ramp flows, same size as 'densities';
%             celldata  - array of freeway cell structures, whose length
%                         must be the same as size of 'densities';
%             ts        - sampling period;
%             idx       - index of the cell with our on-ramp.
%
% Returns:   new_flows - updated vector of on-ramp flows.
%
% REMARK: currently, we only do 1 time step forecast.
%
% Last modified:   11/17/2006.

%
% Alex Kurzhanskiy   <akurzhan@eecs.berkeley.edu>
%

global CTMSIM_ORC;

L = size(densities, 1);
M = size(flows, 1);
N = size(celldata, 2);

if L ~= N
  error('CONTROLLER_SWARM1: number of densities does not match number of cells.');
end

if M ~= N
  error('CONTROLLER_SWARM1: number of flows does not match number of cells.');
end

if (idx < 1) | (idx > N)
  error('CONTROLLER_SWARM1: invalid cell index.');
end

new_flows = flows;  % initialize flow vector with current values

if ~isstruct(CTMSIM_ORC)  % SWARM1 invoked for the first time
  CTMSIM_ORC.nodelete          = 1;
  CTMSIM_ORC.swarm1_denhistory = densities;
  CTMSIM_ORC.swarm1_currcell   = idx;
  CTMSIM_ORC.swarm1_Tp         = round(celldata(idx).ORmlcontroller.Tp);
  if CTMSIM_ORC.swarm1_Tp < 2
    CTMSIM_ORC.swarm1_Tp = 2;
  end
  return;  % enough for the first time
end

if idx >= CTMSIM_ORC.swarm1_currcell  % we are at most downstream on-ramp
  CTMSIM_ORC.swarm1_denhistory = [CTMSIM_ORC.swarm1_denhistory densities];
  CTMSIM_ORC.swarm1_Tp         = round(celldata(idx).ORmlcontroller.Tp);
  if CTMSIM_ORC.swarm1_Tp < 2
    CTMSIM_ORC.swarm1_Tp = 2;
  end
end

K  = size(CTMSIM_ORC.swarm1_denhistory, 2);
Tp = CTMSIM_ORC.swarm1_Tp;

if K < Tp  % not enough historic density data
  CTMSIM_ORC.swarm1_currcell = idx;
  return;  % nothing else to do
end

if idx >= CTMSIM_ORC.swarm1_currcell  % we are at most downstream on-ramp
  if K > Tp  % more than enough historic density data
    CTMSIM_ORC.swarm1_denhistory = CTMSIM_ORC.swarm1_denhistory(:, (K-Tp+1):K);
  end

  % compute forecast
  rho  = CTMSIM_ORC.swarm1_denhistory;
  tt   = 1:Tp;
  S    = (sum(rho'))';
  SS   = S;
  for i = 2:Tp
    SS = SS  +  (i * S);
  end
  nom  = Tp * sum(diag(tt) * rho')' - SS;
  dnom = (Tp * sum(tt.^2))  -  ((sum(tt))^2);
  CTMSIM_ORC.swarm1_fdensities = densities + (nom / dnom);
  CTMSIM_ORC.swarm1_zone       = celldata(idx).ORmlcontroller.zone;
  CTMSIM_ORC.swarm1_zonelen    = 0;

  % reinitialize Rex
  Rex = 0;
else
  Rex = CTMSIM_ORC.swarm1_Rex;
  if CTMSIM_ORC.swarm1_zone ~= celldata(idx).ORmlcontroller.zone
    % we enter new zone
    Rex                       = max([CTMSIM_ORC.swarm1_psy (0/CTMSIM_ORC.swarm1_zonelen)]) * Rex;  % FIXME: what is 1/L??
    CTMSIM_ORC.swarm1_zonelen = 0;
    CTMSIM_ORC.swarm1_zone    = celldata(idx).ORmlcontroller.zone;
  end
end

i  = idx;
nv = 0;
L  = 0;
while (i > 0) & ((i == idx) | isempty(celldata(i).ORname))
  l  = abs(celldata(i).PMend - celldata(i).PMstart);  % length of i-th cell
  nc = celldata(i).FDrhocrit * l;  % critical number of vehicles in i-th cell
  n  = CTMSIM_ORC.swarm1_fdensities(i, 1) * l;  % forecasted number of vehicles in i-th cell
  nv = nv  +  (n - nc);
  L  = L + l;
  i  = i - 1;
end

fdes              = flows(idx, 1) - (nv/ts) - (Rex/ts);  % desired flow
f                 = max([0 fdes celldata(idx).ORmlcontroller.Cmin]);
f                 = min([f celldata(idx).ORmlcontroller.Cmax]);

new_flows(idx, 1) = f;  % update flow vector

CTMSIM_ORC.swarm1_Rex      = celldata(idx).ORmlcontroller.phi * f - fdes;
CTMSIM_ORC.swarm1_psy      = celldata(idx).ORmlcontroller.psy;
CTMSIM_ORC.swarm1_zonelen  = CTMSIM_ORC.swarm1_zonelen + L;
CTMSIM_ORC.swarm1_currcell = idx;


return;

Contact us at files@mathworks.com