├── cLTL+_continuous ├── lib │ ├── Polytope.m │ ├── getInit.m │ ├── TCP.m │ ├── getTCP.m │ ├── getNegInner.m │ ├── Neg.m │ ├── getZ.m │ ├── F.m │ ├── G.m │ ├── GG.m │ ├── GF.m │ ├── getNegOuter.m │ ├── getGGOuter.m │ ├── getAnd.m │ ├── getDyn.m │ ├── getLoop.m │ ├── getAP.m │ ├── getOrOuter.m │ ├── getAndOuter.m │ ├── getObs.m │ ├── AP.m │ ├── getOrInner.m │ ├── getAndInner.m │ ├── getGFInner.m │ ├── U.m │ ├── getFGInner.m │ ├── getFGOuter.m │ ├── getGFOuter.m │ ├── Or.m │ ├── getCol.m │ ├── And.m │ ├── getCol2.m │ ├── plot_continuous.m │ ├── getLTL.m │ ├── FG.m │ ├── getTCPTau.m │ ├── main_template.m │ └── plot_continuous_3D.m ├── README.md └── examples │ ├── example_3D.m │ ├── example_3D_double_integrator.m │ └── emergency_example.m ├── cLTL+ ├── lib │ ├── GOBLUE_40horizon_0tau_2017_5_18_4h32m.mat │ ├── getObs.m │ ├── getInit.m │ ├── getTP.m │ ├── getCol.m │ ├── getFF.m │ ├── getZ.m │ ├── getNeg.m │ ├── getGG.m │ ├── getGGI.m │ ├── getFFI.m │ ├── getLoop.m │ ├── getAnd.m │ ├── getFG.m │ ├── getGF.m │ ├── getFGI.m │ ├── getGFI.m │ ├── getNegI.m │ ├── getGF2.m │ ├── getDyn.m │ ├── getX.m │ ├── getOr.m │ ├── getAndI.m │ ├── getOrI.m │ ├── getZold.m │ ├── getLTL.m │ ├── getOrITau.m │ ├── getAndITau.m │ ├── getG.m │ ├── getF.m │ ├── tight_subplot.m │ ├── parseLTL.m │ ├── getTPTau.m │ ├── getU.m │ ├── main_template.m │ ├── generate_async_traces.m │ ├── install_mpt3.m │ ├── plot_trace.m │ ├── grid_plot.m │ ├── plot_robotarium.m │ └── plot_trace_grid.m ├── README.md └── examples │ ├── robotarium_example.m │ └── emergency_example.m ├── cLTL ├── lib │ ├── getInt.m │ ├── getCol.m │ ├── getObs.m │ ├── getDyn.m │ ├── getFF.m │ ├── getGG.m │ ├── getLoop.m │ ├── getZ.m │ ├── getFG.m │ ├── getGF.m │ ├── getLTL.m │ ├── getNeg.m │ ├── getGF2.m │ ├── getX.m │ ├── getOr.m │ ├── getAnd.m │ ├── getG.m │ ├── getF.m │ ├── parseLTL.m │ ├── getU.m │ └── cLTL_synth.m ├── examples │ ├── example_goblue.m │ ├── um_goblue.m │ ├── um_goblue2.m │ ├── earthquake.m │ ├── simulations.m │ └── simulationsTemplates.m └── README.md ├── README.md └── LICENSE /cLTL+_continuous/lib/Polytope.m: -------------------------------------------------------------------------------- 1 | function P = Polytope(A, b) 2 | P = struct('A', A, 'b', b); -------------------------------------------------------------------------------- /cLTL+/lib/GOBLUE_40horizon_0tau_2017_5_18_4h32m.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahiny/cLTL-synth/HEAD/cLTL+/lib/GOBLUE_40horizon_0tau_2017_5_18_4h32m.mat -------------------------------------------------------------------------------- /cLTL/lib/getInt.m: -------------------------------------------------------------------------------- 1 | function fInt = getInt(Mw,k,bigM,A) 2 | % Returns integer constraints 3 | 4 | % number of states 5 | n = length(A); 6 | 7 | % time horizon 8 | k = length(Mw); 9 | 10 | % vectorize Mw 11 | MW = reshape([Mw{:}],n*n*k,1); 12 | 13 | % Integer constraint 14 | fInt = [integer(MW(:))]; -------------------------------------------------------------------------------- /cLTL/lib/getCol.m: -------------------------------------------------------------------------------- 1 | function fCol = getCol() 2 | % Returns collision avoidence constraints 3 | global Mw; 4 | % number of states 5 | n = length(Mw{1}); 6 | 7 | % time horizon 8 | k = length(Mw); 9 | 10 | 11 | fCol = []; 12 | for i = 1:k 13 | Wi = Mw{i}*ones(n,1); 14 | fCol = [fCol, Wi<=ones(n,1)]; 15 | end 16 | 17 | -------------------------------------------------------------------------------- /cLTL+/lib/getObs.m: -------------------------------------------------------------------------------- 1 | function fObs = getObs(Obs,k) 2 | % returns collision avoidance constraints 3 | global W Wtotal; 4 | 5 | % fObs = Wtotal(Obs,:) == 0; 6 | 7 | % number of agents 8 | N = length(W); 9 | 10 | % Obstacle avoidance constraints 11 | fObs= []; 12 | for n = 1:N 13 | W{n}(Obs,:) = 0; 14 | %fObs = [fObs, W{n}(Obs,:) == 0]; 15 | end 16 | -------------------------------------------------------------------------------- /cLTL/lib/getObs.m: -------------------------------------------------------------------------------- 1 | function fObs = getObs(Obs,k) 2 | 3 | % Returns obstacle avoidance constraints 4 | global Mw Z zLoop ZLoop bigM epsilon; 5 | 6 | % number of states 7 | n = length(Obs); 8 | 9 | % time horizon 10 | k = length(Mw); 11 | 12 | % Obstacle avoidance constraints 13 | fObs=[]; 14 | for i = 1:k 15 | Wi = Mw{i}*ones(n,1); 16 | fObs = [fObs, Wi(Obs)<=0]; 17 | end 18 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getInit.m: -------------------------------------------------------------------------------- 1 | function fInit = getInit(X0) 2 | % returns initial state 3 | global X; 4 | 5 | % number of agents 6 | N = size(X0,2); 7 | % number of states 8 | dx = size(X0,1); 9 | % time horizon 10 | h = size(W{1},2)-1; 11 | 12 | % States u^i(t) = U{i}{t} - dx*du matrix 13 | X = cell(N,1); 14 | for n = 1:N 15 | X{n} = sdpvar(h,dx,'full'); 16 | end 17 | 18 | fInit = []; -------------------------------------------------------------------------------- /cLTL+_continuous/lib/TCP.m: -------------------------------------------------------------------------------- 1 | function tcp = TCP(phi,m) 2 | assert(strcmp(phi.type, 'inner') || strcmp(phi.type, 'ap'), ... 3 | 'first argument must be written according to inner syntax'); 4 | assert(isnumeric(m), 'second argument must be numeric'); 5 | tcp = struct('type', 'outer', 'phi', phi, 'm', m, 'Op', 'TCP', ... 6 | 'formula', strcat('TCP(', phi.formula, ', ', num2str(m), ')')); 7 | tcp.args = {tcp}; -------------------------------------------------------------------------------- /cLTL+/lib/getInit.m: -------------------------------------------------------------------------------- 1 | function fInit = getInit(W0) 2 | % returns initial state 3 | global W; 4 | % number of agents 5 | N = length(W); 6 | % number of states 7 | I = size(W{1},1); 8 | % time horizon 9 | h = size(W{1},2)-1; 10 | 11 | for n = 1:N 12 | current_state = find(W0>0,1); 13 | W{n}(:,1) = zeros(I,1); 14 | W{n}(current_state,1) = 1; 15 | W0(current_state) = W0(current_state) - 1; 16 | end 17 | 18 | fInit = []; -------------------------------------------------------------------------------- /cLTL/lib/getDyn.m: -------------------------------------------------------------------------------- 1 | function fDyn = getDyn(A,k) 2 | 3 | % Returns system dynamic constraints 4 | global Mw Z zLoop ZLoop bigM epsilon; 5 | 6 | % number of states 7 | n = length(A); 8 | % Indices of 0's of adjacency matrix 9 | %A0 = A(:)==0; 10 | A1 = A(:)==1; 11 | % Flow constraints 12 | fDyn=[]; 13 | for i = 2:k 14 | fDyn = [fDyn, Mw{i}*ones(n,1)==transpose(ones(1,n)*Mw{i-1})]; 15 | fDyn = [fDyn, Mw{i}(A1)>=0]; 16 | end 17 | 18 | 19 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getTCP.m: -------------------------------------------------------------------------------- 1 | function [fTP,phi] = getTCP(formula, k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | 5 | assert(strcmp(formula.Op, 'TCP'), 'tcp required'); 6 | 7 | % number of agents 8 | N = length(x); 9 | % time horizon 10 | h = size(x{1},2)-1; 11 | 12 | [fTP, z] = getLTL(formula.phi,k); 13 | phi = getZ(formula.formula,k,1); 14 | 15 | fTP = [fTP, sum(z) >= formula.m - (N+1)*(1-phi)]; 16 | fTP = [fTP, sum(z) <= formula.m + (N+1)*phi - 1]; 17 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getNegInner.m: -------------------------------------------------------------------------------- 1 | function [fNeg,phi] = getNegInner(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | 5 | % number of agents 6 | N = length(x); 7 | % time horizon 8 | h = size(x{1},2)-1; 9 | 10 | % number of arguments 11 | assert(length(formula.args)==1, 'Neg takes 1 argument'); 12 | 13 | % Get its constraints 14 | [fNeg,zNeg] = getLTL(formula.args{1},k); 15 | phi = ones(1,N) - zNeg; 16 | Z{length(Z)+1} = {phi,strcat(formula.formula,'[',num2str(k),']')}; -------------------------------------------------------------------------------- /cLTL+_continuous/lib/Neg.m: -------------------------------------------------------------------------------- 1 | function phi = Neg(varargin) 2 | assert(nargin == 1, 'Neg takes one variable'); 3 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 4 | phi = struct('type', 'inner', 'Op', 'Neg', 'args', {varargin}, ... 5 | 'formula', strcat('Neg(', varargin{1}.formula, ')')); 6 | else 7 | phi = struct('type', 'outer', 'Op', 'Neg', 'args', {varargin}, ... 8 | 'formula', strcat('Neg(', varargin{1}.formula, ')')); 9 | end 10 | -------------------------------------------------------------------------------- /cLTL+/lib/getTP.m: -------------------------------------------------------------------------------- 1 | function [fTP,phi] = getTP(formula, args, k) 2 | 3 | global W Wtotal Z bigM; 4 | 5 | if length(args) ~= 2 6 | disp('Missing argument'); 7 | asset(length(args)==2); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % time horizon 13 | h = size(W{1},2)-1; 14 | 15 | [fTP, z] = getLTL(args{1},k); 16 | phi = getZ(formula,h,1); 17 | phi = phi(k); 18 | 19 | fTP = [fTP, sum(z) >= args{2} - bigM*(1-phi)]; 20 | fTP = [fTP, sum(z) <= args{2} + bigM*phi-1]; 21 | -------------------------------------------------------------------------------- /cLTL+/lib/getCol.m: -------------------------------------------------------------------------------- 1 | function fCol = getCol() 2 | % returns collision avoidance constraints 3 | global W Wtotal; 4 | % number of agents 5 | N = length(W); 6 | % number of states 7 | I = size(W{1},1); 8 | % time horizon 9 | h = size(W{1},2)-1; 10 | 11 | Wtotal = W{1}; 12 | 13 | %fCol = []; 14 | for i = 1:h+1 15 | for n = 2:N 16 | Wtotal(:,i) = Wtotal(:,i) + W{n}(:,i); 17 | end 18 | %fCol = [fCol, Wtotal(:,i) <= ones(I,1)]; 19 | end 20 | 21 | fCol = Wtotal(:) <= ones(I*(h+1),1); 22 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getZ.m: -------------------------------------------------------------------------------- 1 | function z = getZ(formula,k,n) 2 | 3 | if strcmp(formula,'True') || strcmp(formula,' True') 4 | z = 1; 5 | return 6 | end 7 | 8 | global Z; 9 | formula = strcat(num2str(formula),... 10 | '[',num2str(k),']'); 11 | i = find(strcmp([Z{:}],formula)); 12 | 13 | if isempty(i) 14 | %create new sdpvar if not created before 15 | z = binvar(1,n,'full'); 16 | Z{length(Z)+1} = {z,formula}; 17 | else 18 | % else return the existing one 19 | z = Z{i/2}{1}; 20 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/F.m: -------------------------------------------------------------------------------- 1 | function phi = F(varargin) 2 | % Returns a polytope 3 | assert(nargin == 1, 'F takes one variable'); 4 | % Returns a polytope 5 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 6 | phi = struct('type', 'inner', 'Op', 'F', 'args', {varargin}, ... 7 | 'formula', strcat('F(', varargin{1}.formula, ')')); 8 | else 9 | phi = struct('type', 'outer', 'Op', 'F', 'args', {varargin}, ... 10 | 'formula', strcat('F(', varargin{1}.formula, ')')); 11 | end 12 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/G.m: -------------------------------------------------------------------------------- 1 | function phi = G(varargin) 2 | % Returns a polytope 3 | assert(nargin == 1, 'G takes one variable'); 4 | % Returns a polytope 5 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 6 | phi = struct('type', 'inner', 'Op', 'G', 'args', {varargin}, ... 7 | 'formula', strcat('G(', varargin{1}.formula, ')')); 8 | else 9 | phi = struct('type', 'outer', 'Op', 'G', 'args', {varargin}, ... 10 | 'formula', strcat('G(', varargin{1}.formula, ')')); 11 | end 12 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/GG.m: -------------------------------------------------------------------------------- 1 | function phi = GG(varargin) 2 | % Returns a polytope 3 | assert(nargin == 1, 'GG takes one variable'); 4 | % Returns a polytope 5 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 6 | phi = struct('type', 'inner', 'Op', 'GG', 'args', {varargin}, ... 7 | 'formula', strcat('GG(', varargin{1}.formula, ')')); 8 | else 9 | phi = struct('type', 'outer', 'Op', 'GG', 'args', {varargin}, ... 10 | 'formula', strcat('GG(', varargin{1}.formula, ')')); 11 | end -------------------------------------------------------------------------------- /cLTL+/lib/getFF.m: -------------------------------------------------------------------------------- 1 | function [fFF,phi] = getFF(formula, args, k) 2 | 3 | global Mw Z; 4 | 5 | if length(args)>1 6 | disp('FF takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of states 11 | n = length(Mw{1}); 12 | 13 | % time horizon 14 | h = length(Mw); 15 | 16 | z = []; 17 | fFF = []; 18 | for i = 1:h 19 | [fLTL,zi] = getLTL(args{1}, i); 20 | z = [z;zi]; 21 | fFF = [fFF, fLTL]; 22 | end 23 | 24 | phi = getZ(formula, 1); 25 | 26 | fFF = [fFF, repmat(phi,h,1)>=ZOr, phi<=sum(ZOr)]; 27 | 28 | -------------------------------------------------------------------------------- /cLTL/lib/getFF.m: -------------------------------------------------------------------------------- 1 | function [fFF,phi] = getFF(formula, args, k) 2 | 3 | global Mw Z; 4 | 5 | if length(args)>1 6 | disp('FF takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of states 11 | n = length(Mw{1}); 12 | 13 | % time horizon 14 | h = length(Mw); 15 | 16 | z = []; 17 | fFF = []; 18 | for i = 1:h 19 | [fLTL,zi] = getLTL(args{1}, i); 20 | z = [z;zi]; 21 | fFF = [fFF, fLTL]; 22 | end 23 | 24 | phi = getZ(formula, 1); 25 | 26 | fFF = [fFF, repmat(phi,h,1)>=ZOr, phi<=sum(ZOr)]; 27 | 28 | -------------------------------------------------------------------------------- /cLTL/lib/getGG.m: -------------------------------------------------------------------------------- 1 | function [fGG,phi] = getGG(formula, args, k) 2 | 3 | global Mw Z; 4 | 5 | if length(args)>1 6 | disp('GG takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of states 11 | n = length(Mw{1}); 12 | 13 | % time horizon 14 | h = length(Mw); 15 | 16 | z = []; 17 | fGG = []; 18 | for i = 1:h 19 | [fLTL,zi] = getLTL(args{1}, i); 20 | z = [z;zi]; 21 | fGG = [fGG, fLTL]; 22 | end 23 | 24 | phi = getZ(formula, 1); 25 | 26 | fGG = [fGG, repmat(phi,h,1)<=ZOr, phi>=1-h+sum(ZOr)]; 27 | 28 | -------------------------------------------------------------------------------- /cLTL+/lib/getZ.m: -------------------------------------------------------------------------------- 1 | function z = getZ(formula,k,n) 2 | 3 | if strcmp(formula,'True') || strcmp(formula,' True') 4 | z = 1; 5 | return 6 | end 7 | 8 | global Z; 9 | 10 | if isnumeric(formula) 11 | formula = strcat('[ ', num2str(formula), ']'); 12 | end 13 | 14 | formula = num2str(formula); 15 | 16 | 17 | i = find(strcmp([Z{:}],formula)); 18 | 19 | if isempty(i) 20 | %create new sdpvar if not created before 21 | z = binvar(k,n,'full'); 22 | Z{length(Z)+1} = {z,formula}; 23 | else 24 | % else return the existing one 25 | z = Z{i/2}{1}; 26 | end -------------------------------------------------------------------------------- /cLTL+/lib/getNeg.m: -------------------------------------------------------------------------------- 1 | function [fNeg,phi] = getNeg(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('Negation takes a single argument'); 7 | assert(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | % Get its constraints 18 | [fNeg,z] = getLTL(args{1},k); 19 | 20 | % a binary variable for formula 21 | phi = getZ(formula,h,1); 22 | phi = phi(k); 23 | 24 | % Negation constaint 25 | fNeg = [fNeg, phi == 1-z]; -------------------------------------------------------------------------------- /cLTL+_continuous/lib/GF.m: -------------------------------------------------------------------------------- 1 | function phi = GF(varargin) 2 | % Returns a polytope 3 | assert(nargin == 1, 'GF takes one variable'); 4 | % Returns a polytope 5 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 6 | phi = struct('type', 'inner', 'Op', 'GF', 'args', {varargin}, ... 7 | 'formula', strcat('GF(', varargin{1}.formula, ')')); 8 | else 9 | assert(strcmp(varargin{1}.type, 'outer') || strcmp(varargin{1}.type, 'tp')) 10 | phi = struct('type', 'outer', 'Op', 'GF', 'args', {varargin}, ... 11 | 'formula', strcat('GF(', varargin{1}.formula, ')')); 12 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getNegOuter.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getNegOuter(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | % number of agents 5 | N = length(x); 6 | % number of states 7 | I = size(x{1},1); 8 | % time horizon 9 | h = size(x{1},2)-1; 10 | 11 | % m*N binvar: a binary variable for each argument and agent 12 | z = []; 13 | 14 | % Constraints 15 | fAnd = []; 16 | 17 | % number of arguments 18 | assert(length(formula.args)==1, 'Neg takes 1 arguments'); 19 | 20 | [fAP,phiAP] = getLTL(formula.args{1},k); 21 | fAnd = [fAnd, fAP]; 22 | z = [z; phiAP]; 23 | 24 | phi = 1-z; 25 | Z{length(Z)+1} = {phi,strcat(formula.formula,'[',num2str(k),']')}; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cLTL-synth 2 | Generates provably correct trajectories from cLTL/cLTL+ specifications for large collection of agents 3 | 4 | Please refer to 5 | 6 | ```Sahin, Yunus Emre, Petter Nilsson, and Necmiye Ozay. Provably-correct coordination of large collections of agents with counting temporal logic constraints. Proceedings of the 8th International Conference on Cyber-Physical Systems. ACM, 2017.``` and ```Sahin, Yunus Emre, Petter Nilsson, and Necmiye Ozay. Synchronous and Asynchronous Multi-agent Coordination with cLTL+ 7 | Constraints. CDC, 2017.``` 8 | 9 | Additional README files on how to use tools can be found in respective folders. 10 | 11 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getGGOuter.m: -------------------------------------------------------------------------------- 1 | function [fGG,phi] = getGGOuter(formula, k) 2 | 3 | global x Z; 4 | 5 | % number of agents 6 | N = length(x); 7 | % number of states 8 | dx = size(x{1},1); 9 | % time horizon 10 | h = size(x{1},2)-1; 11 | 12 | if strcmp(formula.type, 'tp') 13 | formula.args = {formula}; 14 | end 15 | assert(length(formula.args)==1, 'GG takes a single argument'); 16 | 17 | z = []; 18 | fGG = []; 19 | 20 | 21 | for k = 1:h 22 | [fLTL,zLTL] = getLTL(formula.args{1}, k); 23 | z = [z;zLTL]; 24 | fGG = [fGG, fLTL]; 25 | end 26 | 27 | phi = getZ(formula.formula, k, 1); 28 | fGG = [fGG, repmat(phi,h,1)<=z, phi>=1-h+sum(z)]; 29 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getAnd.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAnd(formula, k) 2 | 3 | global x Z; 4 | 5 | % time horizon 6 | h = size(x{1},2)-1; 7 | 8 | if strcmp(formula.type, 'tp') 9 | formula.args = {formula}; 10 | end 11 | 12 | m = length(formula.args); 13 | 14 | z = []; 15 | fAnd = []; 16 | for k = 1:h 17 | [fLTL,zLTL] = getLTL(formula.args{1}, k); 18 | z = [z;zLTL]; 19 | fAnd = [fAnd, fLTL]; 20 | end 21 | 22 | if m > 1 23 | % a binary variable 24 | phi = getZ(formula.formula,h,1); 25 | phi = phi(k); 26 | % conjunction constraint 27 | fAnd = [fAnd, repmat(phi,m,1)<=z, phi>=1-m+sum(z)]; 28 | else 29 | phi = z; 30 | end 31 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getDyn.m: -------------------------------------------------------------------------------- 1 | function fDyn = getDyn(A, B, X0, Px, Pu) 2 | % returns dynamical constraints 3 | global u x; 4 | 5 | % number of agents 6 | N = length(u); 7 | 8 | % time horizon 9 | h = size(u{1},2); 10 | 11 | fDyn = []; 12 | for n = 1:N 13 | x{n} = X0(:,n); 14 | for t = 1:h 15 | 16 | % System dynamics 17 | xt = x{n}(:,t); 18 | ut = u{n}(:,t); 19 | x{n} = [x{n}, A*xt + B*ut]; 20 | 21 | % State constraints 22 | fDyn = [fDyn, Px.A*xt <= Px.b]; 23 | 24 | % Input constraints 25 | fDyn = [fDyn, Pu.A*ut <= Pu.b]; 26 | 27 | end 28 | end 29 | 30 | 31 | -------------------------------------------------------------------------------- /cLTL/lib/getLoop.m: -------------------------------------------------------------------------------- 1 | function fLoop= getLoop(h) 2 | % Returns loop constraints 3 | global Mw zLoop ZLoop bigM ; 4 | 5 | % number of states 6 | n = length(Mw{1}); 7 | 8 | % Loop variables 9 | % zLoop(i)=1 where loop starts 10 | zLoop = binvar(h,1); 11 | % ZLoop(i)=1 for all i in loop 12 | ZLoop = []; 13 | % Loop constraints 14 | fLoop = sum(zLoop)==1; 15 | 16 | for i=1:h 17 | fLoop = [fLoop, ones(1,n)*Mw{h}<=transpose(Mw{i}*ones(n,1)) + bigM*(1-zLoop(i))]; 18 | fLoop = [fLoop, ones(1,n)*Mw{h}>=transpose(Mw{i}*ones(n,1)) - bigM*(1-zLoop(i))]; 19 | ZLoop = [ZLoop; sum(zLoop(1:i))]; 20 | end 21 | 22 | % Check if loop started, i.e., ZLoopi = Or(zLoopi, Neg(sum(zLoop(i:end)))) 23 | 24 | -------------------------------------------------------------------------------- /cLTL+/lib/getGG.m: -------------------------------------------------------------------------------- 1 | function [fGG,phi] = getGG(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('GG takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | fGG = []; 18 | z = []; 19 | for k = 1:h 20 | % Get its constraints 21 | [fAP,phiAP] = getLTL(args{1},k); 22 | fGG = [fGG, fAP]; 23 | z = [z; phiAP]; 24 | end 25 | 26 | phi = binvar(1); 27 | Z{length(Z)+1} = {phi,formula}; 28 | % conjunction constraint 29 | fGG = [fGG, repmat(phi,h,1)<=z, phi>=1-h+sum(z)]; 30 | -------------------------------------------------------------------------------- /cLTL+/lib/getGGI.m: -------------------------------------------------------------------------------- 1 | function [fGGI,phi] = getGGI(formula, args, k) 2 | 3 | global W Wtotal Z zLoop ZLoop; 4 | 5 | if length(args)>1 6 | disp('GG takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | z = []; 18 | fGGI = []; 19 | for k = 1:h 20 | [fLTL,zLTL] = getLTL(args{1}, k); 21 | z = [z;zLTL]; 22 | fGGI = [fGGI, fLTL]; 23 | end 24 | 25 | phi = binvar(1,N); 26 | Z{length(Z)+1} = {phi,formula}; 27 | 28 | for n = 1:N 29 | fGGI = [fGGI, repmat(phi(n),h,1)<=z(:,n), phi(n)>=1-h+sum(z(:,n))]; 30 | end 31 | 32 | -------------------------------------------------------------------------------- /cLTL+/lib/getFFI.m: -------------------------------------------------------------------------------- 1 | function [fFF,phi] = getFFI(formula, args, k) 2 | 3 | global W Wtotal Z; 4 | 5 | if length(args)>1 6 | disp('GG takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | z = []; 18 | fFF = []; 19 | for k = 1:h 20 | for n = 1:N 21 | [fLTL,zLTL] = getLTL(args{1}, k); 22 | z = [z;zLTL]; 23 | fFF = [fFF, fLTL]; 24 | end 25 | end 26 | 27 | phi = binvar(1,N); 28 | Z{length(Z)+1} = {phi,formula}; 29 | 30 | for n = 1:N 31 | fFF = [fFF, repmat(phi(n),m,1)>=z(:,n), phi<=sum(z(:,n))]; 32 | end 33 | 34 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getLoop.m: -------------------------------------------------------------------------------- 1 | function fLoop= getLoop() 2 | % returns loop constraints 3 | global x bigM zLoop ZLoop; 4 | 5 | % number of agents 6 | N = length(x); 7 | % number of states 8 | dx = size(x{1},1); 9 | % time horizon 10 | h = size(x{1},2)-1; 11 | 12 | % Loop variables 13 | % zLoop(i)=1 where loop starts 14 | zLoop = binvar(h,1); 15 | % ZLoop(i)=1 for all i in loop 16 | ZLoop = cumsum(zLoop); 17 | % Loop constraints 18 | fLoop = sum(zLoop)==1; 19 | 20 | for t = 1:h 21 | for n = 1:N 22 | fLoop = [fLoop, x{n}(:,h+1) <= x{n}(:,t) + bigM*(1-zLoop(t))*ones(dx,1)]; 23 | fLoop = [fLoop, x{n}(:,h+1) >= x{n}(:,t) - bigM*(1-zLoop(t))*ones(dx,1)]; 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /cLTL+/lib/getLoop.m: -------------------------------------------------------------------------------- 1 | function fLoop= getLoop() 2 | % returns loop constraints 3 | global W bigM zLoop ZLoop; 4 | % number of agents 5 | N = length(W); 6 | % number of states 7 | I = size(W{1},1); 8 | % time horizon 9 | h = size(W{1},2)-1; 10 | 11 | % Loop variables 12 | % zLoop(i)=1 where loop starts 13 | zLoop = binvar(h,1); 14 | % ZLoop(i)=1 for all i in loop 15 | ZLoop = zLoop; 16 | % Loop constraints 17 | fLoop = sum(zLoop)==1; 18 | 19 | for i = 1:h 20 | for n = 1:N 21 | fLoop = [fLoop, W{n}(:,h+1) <= W{n}(:,i) + bigM*(1-zLoop(i))*ones(I,1)]; 22 | fLoop = [fLoop, W{n}(:,h+1) >= W{n}(:,i) - bigM*(1-zLoop(i))*ones(I,1)]; 23 | end 24 | ZLoop(i) = sum(zLoop(1:i)); 25 | end 26 | 27 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getAP.m: -------------------------------------------------------------------------------- 1 | function [fAP,phi] = getAP(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | 5 | assert(strcmp(formula.args{1}.Op, 'AP')) 6 | 7 | % number of agents 8 | N = length(x); 9 | % Polytope properties for ap 10 | A = formula.A; 11 | b = formula.b; 12 | m = size(A,1); 13 | 14 | phi = getZ(formula.formula,k,N); 15 | zAP = []; 16 | fAP = []; 17 | for n = 1:N 18 | xk = x{n}(:,k); 19 | ztemp = getZ(strcat('~',formula.formula,'[',num2str(n),']'),k,m); 20 | zAP = [zAP;ztemp]; 21 | 22 | for r = 1:m 23 | fAP = [fAP, A(r,:)*xk <= b(r) + bigM*(1-ztemp(r)),... 24 | A(r,:)*xk >= b(r) + 0.01 - bigM*ztemp(r)]; 25 | 26 | end 27 | 28 | fAP = [fAP, repmat(phi(n),1,m)<= ztemp, phi(n)>= sum(ztemp)+1-m]; 29 | end 30 | -------------------------------------------------------------------------------- /cLTL/lib/getZ.m: -------------------------------------------------------------------------------- 1 | function z = getZ(name,k) 2 | % 3 | % if an sdpvar with given name already exists returns it, 4 | % else, creates an sdpvar with given name and returns it 5 | % 6 | % INPUTS 7 | % name = string 8 | % 9 | % OUTPUTS 10 | % z = sdpvariable with given name 11 | 12 | if strcmp(name,'True') || strcmp(name,' True') 13 | z = 1; 14 | return 15 | end 16 | 17 | if isnumeric(name) 18 | name = strcat('[ ', num2str(name), ']'); 19 | end 20 | 21 | 22 | name = strcat(num2str(name),'[',num2str(k),']'); 23 | 24 | global Z; 25 | i = find(strcmp([Z{:}],name)); 26 | 27 | if isempty(i) 28 | %create new sdpvar if not created before 29 | z = binvar(1); 30 | Z{length(Z)+1} = {z,name}; 31 | else 32 | % else return the existing one 33 | z = Z{i/2}{1}; 34 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getOrOuter.m: -------------------------------------------------------------------------------- 1 | function [fOr,phi] = getOrOuter(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | % number of agents 5 | N = length(W); 6 | % number of states 7 | I = size(W{1},1); 8 | % time horizon 9 | h = size(W{1},2)-1; 10 | 11 | % m*N binvar: a binary variable for each argument and agent 12 | z = []; 13 | 14 | % Constraints 15 | fOr = []; 16 | 17 | % number of arguments 18 | m = length(formula.args); 19 | 20 | for i=1:m 21 | % Get its constraints 22 | [fAP,phiAP] = getLTL(formula.args{i},k); 23 | fOr = [fOr, fAP]; 24 | z = [z; phiAP]; 25 | end 26 | 27 | if m > 1 28 | % a binary variable 29 | phi = getZ(formula,k,1); 30 | % conjunction constraint 31 | fOr = [fOr, repmat(phi,m,1)>=z, phi<=sum(z)]; 32 | else 33 | phi = z; 34 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getAndOuter.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAndOuter(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | % number of agents 5 | N = length(x); 6 | % number of states 7 | I = size(x{1},1); 8 | % time horizon 9 | h = size(x{1},2)-1; 10 | 11 | % m*N binvar: a binary variable for each argument and agent 12 | z = []; 13 | 14 | % Constraints 15 | fAnd = []; 16 | 17 | % number of arguments 18 | m = length(formula.args); 19 | 20 | for i=1:m 21 | % Get its constraints 22 | [fAP,phiAP] = getLTL(formula.args{i},k); 23 | fAnd = [fAnd, fAP]; 24 | z = [z; phiAP]; 25 | end 26 | 27 | if m > 1 28 | % a binary variable 29 | phi = getZ(formula.formula,k,1); 30 | % conjunction constraint 31 | fAnd = [fAnd, repmat(phi,m,1)<=z, phi>=1-m+sum(z)]; 32 | else 33 | phi = z; 34 | end -------------------------------------------------------------------------------- /cLTL+/lib/getAnd.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAnd(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | % number of agents 6 | N = length(W); 7 | % number of states 8 | I = size(W{1},1); 9 | % time horizon 10 | h = size(W{1},2)-1; 11 | 12 | % m*N binvar: a binary variable for each argument and agent 13 | z = []; 14 | 15 | % Constraints 16 | fAnd = []; 17 | 18 | % number of arguments 19 | m = length(args); 20 | 21 | for i=1:m 22 | % Get its constraints 23 | [fAP,phiAP] = getLTL(args{i},k); 24 | fAnd = [fAnd, fAP]; 25 | z = [z; phiAP]; 26 | end 27 | 28 | if m > 1 29 | % a binary variable 30 | phi = getZ(formula,h,1); 31 | phi = phi(k); 32 | % conjunction constraint 33 | fAnd = [fAnd, repmat(phi,m,1)<=z, phi>=1-m+sum(z)]; 34 | else 35 | phi = z; 36 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getObs.m: -------------------------------------------------------------------------------- 1 | function [fObs,zObs] = getObs(Obs, epsilon) 2 | % returns collision avoidance constraints 3 | global x bigM; 4 | 5 | % number of agents 6 | N = length(x); 7 | % time horizon 8 | h = size(x{1},2); 9 | 10 | % Obstacle avoidance constraints 11 | fObs= []; 12 | zObs = []; 13 | % for each robot 14 | for n = 1:N 15 | % at each time instance 16 | for t = 1:h 17 | xt = x{n}(:,t); 18 | % for all obstacles 19 | for p = 1:length(Obs) 20 | P = Obs(p); 21 | ZP = binvar(length(P.b),1); 22 | zObs = [zObs; ZP]; 23 | for r = 1:length(P.b) 24 | fObs = [fObs, P.A(r,:)*xt >= P.b(r) + epsilon - bigM*(1-ZP(r))]; 25 | end 26 | fObs = [fObs, sum(ZP)>=1]; 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/AP.m: -------------------------------------------------------------------------------- 1 | function [ap, ap_cell] = AP(A, b, ap_cell) 2 | % 3 | % Returns a struct representing an atomic proposition 4 | % type: 'ap' 5 | % Op: 'AP' 6 | % formula: formula in string form 7 | % args: arguments are also inner formulas or ap 8 | % 9 | % A,b: Polytope given by Ax<=b 10 | % Op: AP 11 | % formula: apX where X is an integer which is assigned automatically 12 | % 13 | 14 | % Create ap 15 | assert(isnumeric(A), isnumeric(b), 'A and b must be numeric'); 16 | assert(size(A,1) == size(b,1), 'A and b must have same number of rows') 17 | ap = struct('type', 'inner', 'A', A, 'b', b, 'Op', 'AP', ... 18 | 'formula', strcat('ap', num2str(length(ap_cell)+1))); 19 | ap.args = {ap}; 20 | 21 | % add it to ap_list to keep track 22 | ap_cell{length(ap_cell)+1} = ap; 23 | 24 | 25 | -------------------------------------------------------------------------------- /cLTL+/lib/getFG.m: -------------------------------------------------------------------------------- 1 | function [fFG,phi] = getFG(formula, args, k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('GF takes a single argument') 7 | return 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | z = []; 18 | fFG = []; 19 | 20 | formulaOr = strcat('Or(', ... 21 | num2str(args{1}),', (1-ZLoop))'); 22 | zOr = getZ(formulaOr,h,1); 23 | 24 | for k = 1:h 25 | [fLTL,zk] = getLTL(args{1}, k); 26 | z = [z;zk]; 27 | fFG = [fFG, fLTL]; 28 | % Zi = And(zi,ZLoop) 29 | fFG = [fFG, zOr(k)>=z(k), zOr(k)>=1-ZLoop(k), zOr(k)<=1-ZLoop(k)+z(k)]; 30 | end 31 | 32 | phi = getZ(formula,1,1); 33 | 34 | fFG = [fFG, repmat(phi,h,1)<=zOr, phi>=1-h+sum(zOr)]; 35 | 36 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getOrInner.m: -------------------------------------------------------------------------------- 1 | function [fOr,phi] = getOrInner(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | 5 | % number of agents 6 | N = length(x); 7 | % time horizon 8 | h = size(x{1},2)-1; 9 | 10 | % m*N binvar: a binary variable for each argument and agent 11 | z = []; 12 | 13 | % Constraints 14 | fOr = []; 15 | 16 | % number of arguments 17 | m = length(formula.args); 18 | z =[]; 19 | fOr = []; 20 | 21 | for i=1:m 22 | % Get its constraints 23 | [fLTL,phiLTL] = getLTL(formula.args{i},k); 24 | fOr = [fOr, fLTL]; 25 | z = [z; phiLTL]; 26 | end 27 | 28 | if m > 1 29 | % a binary variable for each agent 30 | phi = getZ(formula.formula,k,N); 31 | % conjunction constraint 32 | for n = 1:N 33 | fOr = [fOr, repmat(phi,m,1)>=z(:,n), phi(n)<=sum(z(:,n))]; 34 | end 35 | else 36 | phi = z; 37 | end -------------------------------------------------------------------------------- /cLTL/lib/getFG.m: -------------------------------------------------------------------------------- 1 | function [fFG,phi] = getFG(formula, args, k) 2 | 3 | global Mw ZLoop; 4 | 5 | if length(args)>1 6 | disp('GF takes a single argument') 7 | return 8 | end 9 | 10 | % number of states 11 | n = length(Mw{1}); 12 | 13 | % time horizon 14 | h = length(Mw); 15 | 16 | phi = getZ(formula, 1); 17 | 18 | ZOr = []; 19 | z = []; 20 | fFG = []; 21 | for i = 1:h 22 | [fLTL,zi] = getLTL(args{1}, i); 23 | z = [z;zi]; 24 | fFG = [fFG, fLTL]; 25 | % Zi = Or(zi,1-ZLoop) 26 | formula = strcat('Or(', ... 27 | num2str(args{1}), '[', num2str(i), '],',... 28 | '(1-ZLoop)[', num2str(i), '])'); 29 | zOr = getZ(formula, -1); 30 | ZOr = [ZOr; zOr]; 31 | fFG = [fFG, zOr>=z(i), zOr>=1-ZLoop(i), zOr<=1-ZLoop(i)+z(i)]; 32 | 33 | end 34 | 35 | fFG = [fFG, repmat(phi,h,1)<=ZOr, phi>=1-h+sum(ZOr)]; 36 | 37 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getAndInner.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAndInner(formula,k) 2 | 3 | global x Z zLoop ZLoop bigM; 4 | 5 | % number of agents 6 | N = length(x); 7 | % time horizon 8 | h = size(x{1},2)-1; 9 | 10 | % m*N binvar: a binary variable for each argument and agent 11 | z = []; 12 | 13 | % Constraints 14 | fAnd = []; 15 | 16 | % number of arguments 17 | m = length(formula.args); 18 | z =[]; 19 | fAnd = []; 20 | 21 | for i=1:m 22 | % Get its constraints 23 | [fLTL,phiLTL] = getLTL(formula.args{i},k); 24 | fAnd = [fAnd, fLTL]; 25 | z = [z; phiLTL]; 26 | end 27 | 28 | if m > 1 29 | % a binary variable for each agent 30 | phi = getZ(formula.formula,k,N); 31 | % conjunction constraint 32 | for n = 1:N 33 | fAnd = [fAnd, repmat(phi,m,1)<=z(:,n), phi(n)>=1-m+sum(z(:,n))]; 34 | end 35 | else 36 | phi = z; 37 | end -------------------------------------------------------------------------------- /cLTL/lib/getGF.m: -------------------------------------------------------------------------------- 1 | function [fGF,phi] = getGF(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('GF takes a single argument') 7 | return 8 | end 9 | 10 | % number of states 11 | n = length(Mw{1}); 12 | 13 | % time horizon 14 | h = length(Mw); 15 | 16 | ZAnd = []; 17 | z = []; 18 | fGF = []; 19 | for i = 1:h 20 | [fLTL,zi] = getLTL(args{1}, i); 21 | z = [z;zi]; 22 | fGF = [fGF, fLTL]; 23 | % Zi = And(zi,ZLoop) 24 | formula = strcat('And(', ... 25 | num2str(args{1}), '[', num2str(i), '],',... 26 | 'ZLoop[', num2str(i), '])'); 27 | zAnd = getZ(formula, -1); 28 | ZAnd = [ZAnd; zAnd]; 29 | fGF = [fGF, zAnd<=zi, zAnd<=ZLoop(i), zAnd>=ZLoop(i)+zi-1]; 30 | 31 | end 32 | 33 | phi = getZ(formula, 1); 34 | 35 | fGF = [fGF, repmat(phi,h,1)>=ZAnd, phi<=sum(ZAnd)]; 36 | 37 | -------------------------------------------------------------------------------- /cLTL/lib/getLTL.m: -------------------------------------------------------------------------------- 1 | function [fLTL,phi] = getLTL(formula,k) 2 | 3 | [Op,args] = parseLTL(formula); 4 | 5 | switch Op 6 | case 'And' 7 | [fLTL,phi] = getAnd(formula,args,k); 8 | case 'Or' 9 | [fLTL,phi] = getOr(formula,args,k); 10 | case 'Neg' 11 | [fLTL,phi] = getNeg(formula,args,k); 12 | case 'G' 13 | [fLTL,phi] = getG(formula,args,k); 14 | case 'F' 15 | [fLTL,phi] = getF(formula,args,k); 16 | case 'X' 17 | [fLTL,phi] = getX(formula,args,k); 18 | case 'U' 19 | [fLTL,phi] = getU(formula,args,k); 20 | case 'GG' 21 | [fLTL,phi] = getGG(formula,args,k); 22 | case 'FF' 23 | [fLTL,phi] = getFF(formula,args,k); 24 | case 'FG' 25 | [fLTL,phi] = getFG(formula,args,k); 26 | case 'GF' 27 | [fLTL,phi] = getGF(formula,args,k); 28 | otherwise 29 | disp('wrong formula'); 30 | end 31 | -------------------------------------------------------------------------------- /cLTL+/lib/getGF.m: -------------------------------------------------------------------------------- 1 | function [fGF,phi] = getGF(formula, args, k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('GF takes a single argument') 7 | return 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | z = []; 18 | fGF = []; 19 | 20 | formulaAnd = strcat('And(', ... 21 | num2str(args{1}),', ZLoop)'); 22 | zAnd = getZ(formulaAnd, h, 1); 23 | % zAnd = binvar(h,1); 24 | % Z{length(Z)+1} = {zAnd,formulaAnd}; 25 | 26 | for k = 1:h 27 | [fLTL,zk] = getLTL(args{1}, k); 28 | z = [z;zk]; 29 | fGF = [fGF, fLTL]; 30 | % zAnd_k = And(z_k,ZLoop_k) 31 | fGF = [fGF, zAnd(k)<=z(k), zAnd(k)<=ZLoop(k), zAnd(k)>=ZLoop(k)+z(k)-1]; 32 | end 33 | 34 | phi = getZ(formula,1,1); 35 | 36 | fGF = [fGF, repmat(phi,h,1)>=zAnd, phi<=sum(zAnd)]; 37 | 38 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getGFInner.m: -------------------------------------------------------------------------------- 1 | function [fGFI,phi] = getGFInner(formula, k) 2 | 3 | assert(length(formula.args)==1, 'GF takes a single argument'); 4 | 5 | global x Z ZLoop; 6 | 7 | % number of agents 8 | N = length(x); 9 | % number of states 10 | dx = size(x{1},1); 11 | % time horizon 12 | h = size(x{1},2)-1; 13 | 14 | z = []; 15 | fGFI = []; 16 | 17 | formulaAnd = strcat('And(', formula.formula, ', ZLoop)'); 18 | ZAnd = []; 19 | for k = 1:h 20 | [fLTL,zLTL] = getLTL(formula.args{1}, k); 21 | z = [z;zLTL]; 22 | fGFI = [fGFI, fLTL]; 23 | zAnd = getZ(formulaAnd,k,N); 24 | ZAnd = [ZAnd;zAnd]; 25 | for n = 1:N 26 | fGFI = [fGFI, ZAnd(k,n)<=z(k,n), ZAnd(k,n)<=ZLoop(k), ZAnd(k,n)>=ZLoop(k)+z(k,n)-1]; 27 | end 28 | end 29 | 30 | phi = getZ(formula.formula, 1, N); 31 | 32 | for n = 1:N 33 | fGFI = [fGFI, repmat(phi(n),h,1)>=ZAnd(:,n), phi(n)<=sum(ZAnd(:,n))]; 34 | end 35 | 36 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/U.m: -------------------------------------------------------------------------------- 1 | function phi = U(varargin) 2 | assert(nargin == 2, 'U takes tow variables'); 3 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 4 | assert(strcmp(varargin{1}.type, 'inner') ||... 5 | strcmp(varargin{2}.type, 'ap'), ... 6 | 'Inner and outer logic formulas cannot be mixed'); 7 | 8 | phi = struct('type', 'inner', 'Op', 'U', 'args', {varargin}, ... 9 | 'formula', strcat('U(', varargin{1}.formula, ', ', ... 10 | varargin{2}.formula, ')')); 11 | else 12 | assert(strcmp(varargin{2}.type, 'outer')||... 13 | strcmp(varargin{2}.type, 'tp'), ... 14 | 'Inner and outer logic formulas cannot be mixed'); 15 | 16 | 17 | phi = struct('type', 'outer', 'Op', 'U', 'args', {varargin}, ... 18 | 'formula', strcat('U(', varargin{1}.formula, ', ', ... 19 | varargin{2}.formula, ')')); 20 | 21 | end 22 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getFGInner.m: -------------------------------------------------------------------------------- 1 | function [fFGI,phi] = getFGInner(formula, k) 2 | 3 | 4 | global x Z ZLoop; 5 | 6 | % number of agents 7 | N = length(x); 8 | % number of states 9 | dx = size(x{1},1); 10 | % time horizon 11 | h = size(x{1},2)-1; 12 | 13 | if strcmp(formula.type, 'ap') 14 | formula.args = {formula}; 15 | end 16 | assert(length(formula.args)==1, 'GF takes a single argument'); 17 | 18 | z = []; 19 | fFGI = []; 20 | 21 | formulaOr = strcat('And(', formula.formula, ', (1-ZLoop))'); 22 | ZOr = getZ(formulaOr,h,N); 23 | for k = 1:h 24 | [fLTL,zLTL] = getLTL(formula.args{1}, k); 25 | z = [z;zLTL]; 26 | fFGI = [fFGI, fLTL]; 27 | for n = 1:N 28 | fFGI = [fFGI, ZOr(k,n)>=z(k,n), ZOr(k,n)>=1-ZLoop(k), ZOr(k,n)<=1-ZLoop(k)+z(k,n)]; 29 | end 30 | end 31 | 32 | phi = getZ(formula.formula, 1, N); 33 | 34 | for n = 1:N 35 | fFGI = [fFGI, repmat(phi(n),h,1)<=ZOr(:,n), phi(n)>=1-h+sum(ZOr(:,n))]; 36 | end -------------------------------------------------------------------------------- /cLTL/lib/getNeg.m: -------------------------------------------------------------------------------- 1 | function [fNeg,phi] = getNeg(formula,args,k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('Negation takes a single argument'); 7 | assert(length(args)==1); 8 | end 9 | 10 | fNeg = []; 11 | 12 | if ischar(args{1}) % If argument is a formula 13 | % Get its constraints 14 | [fAP,z] = getLTL(args{1},k); 15 | fNeg = [fNeg, fAP]; 16 | 17 | else % if argument is counting proposition 18 | % sdpvar 19 | z = getZ(args{1},k); 20 | % state 21 | wi = args{1}(1:end-1); 22 | % threshold 23 | mi = args{1}(end); 24 | % number of states 25 | n = length(Mw{k}); 26 | % constraint 27 | W = Mw{k}*ones(n,1); 28 | fNeg = [fNeg, sum(W(wi))>=mi+epsilon-bigM*(1-z)]; 29 | fNeg = [fNeg, sum(W(wi))<=mi-epsilon+bigM*z-1]; 30 | end 31 | 32 | % a binary variable for formula 33 | phi = getZ(formula,k); 34 | 35 | % Negation constaint 36 | fNeg = [fNeg, phi == 1-z]; -------------------------------------------------------------------------------- /cLTL+/lib/getFGI.m: -------------------------------------------------------------------------------- 1 | function [fFGI,phi] = getFGI(formula, args, k) 2 | 3 | global W Wtotal Z ZLoop; 4 | 5 | if length(args)>1 6 | disp('GG takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | ZOr = []; 18 | z = []; 19 | fFGI = []; 20 | for k = 1:h 21 | formulaOr = strcat('Or(', num2str(args{1}), ', (1-ZLoop))'); 22 | zOr = getZ(formulaOr,k,0); 23 | ZOr = [ZOr; zOr]; 24 | [fLTL,zLTL] = getLTL(args{1}, k); 25 | z = [z;zLTL]; 26 | fFGI = [fFGI, fLTL]; 27 | for n = 1:N 28 | fFGI = [fFGI, ZOr(k,n)>=z(k,n), ZOr(k,n)>=1-ZLoop(k), ZOr(k,n)<=1-ZLoop(k)+z(k,n)]; 29 | end 30 | end 31 | 32 | phi = binvar(1,N); 33 | Z{length(Z)+1} = {phi,formula}; 34 | 35 | for n = 1:N 36 | fFGI = [fFGI, repmat(phi(n),h,1)<=ZOr(:,n), phi(n)>=1-h+sum(ZOr(:,n))]; 37 | end 38 | 39 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getFGOuter.m: -------------------------------------------------------------------------------- 1 | function [fFG,phi] = getFGOuter(formula, args, k) 2 | 3 | global x u Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('GF takes a single argument') 7 | return 8 | end 9 | 10 | % number of agents 11 | N = length(x); 12 | % number of states 13 | I = size(x{1},1); 14 | % time horizon 15 | h = size(x{1},2)-1; 16 | 17 | z = []; 18 | fFG = []; 19 | 20 | formulaOr = strcat('Or(', ... 21 | num2str(formula.args{1}.formula),', (1-ZLoop))'); 22 | zOr = getZ(formulaOr, 1, h); 23 | % zAnd = binvar(h,1); 24 | % Z{length(Z)+1} = {zAnd,formulaAnd}; 25 | 26 | for k = 1:h 27 | [fLTL,zk] = getLTL(formula.args{1}, k); 28 | z = [z;zk]; 29 | fFG = [fFG, fLTL]; 30 | % zAnd_k = And(z_k,ZLoop_k) 31 | fFG = [fFG, zOr(k)>=z(k), zOr(k)>=1-ZLoop(k), zOr(k)<=1-ZLoop(k)+z(k)]; 32 | end 33 | 34 | phi = getZ(formula.formula,1,1); 35 | 36 | fFG = [fFG, repmat(phi,1,h)<=zOr, phi>=sum(zOr)-h+1]; 37 | 38 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getGFOuter.m: -------------------------------------------------------------------------------- 1 | function [fGF,phi] = getGFOuter(formula, args, k) 2 | 3 | global x u Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('GF takes a single argument') 7 | return 8 | end 9 | 10 | % number of agents 11 | N = length(x); 12 | % number of states 13 | I = size(x{1},1); 14 | % time horizon 15 | h = size(x{1},2)-1; 16 | 17 | z = []; 18 | fGF = []; 19 | 20 | formulaAnd = strcat('And(', ... 21 | num2str(formula.args{1}.formula),', ZLoop)'); 22 | zAnd = getZ(formulaAnd, 1, h); 23 | % zAnd = binvar(h,1); 24 | % Z{length(Z)+1} = {zAnd,formulaAnd}; 25 | 26 | for k = 1:h 27 | [fLTL,zk] = getLTL(formula.args{1}, k); 28 | z = [z;zk]; 29 | fGF = [fGF, fLTL]; 30 | % zAnd_k = And(z_k,ZLoop_k) 31 | fGF = [fGF, zAnd(k)<=z(k), zAnd(k)<=ZLoop(k), zAnd(k)>=ZLoop(k)+z(k)-1]; 32 | end 33 | 34 | phi = getZ(formula.formula,1,1); 35 | 36 | fGF = [fGF, repmat(phi,1,h)>=zAnd, phi<=sum(zAnd)]; 37 | 38 | -------------------------------------------------------------------------------- /cLTL+/lib/getGFI.m: -------------------------------------------------------------------------------- 1 | function [fGFI,phi] = getGFI(formula, args, k) 2 | 3 | global W Wtotal Z ZLoop; 4 | 5 | if length(args)>1 6 | disp('GG takes a single argument'); 7 | asset(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % number of states 13 | I = size(W{1},1); 14 | % time horizon 15 | h = size(W{1},2)-1; 16 | 17 | ZAnd = []; 18 | z = []; 19 | fGFI = []; 20 | 21 | formulaAnd = strcat('And(', num2str(args{1}), ', ZLoop)'); 22 | ZAnd = getZ(formulaAnd,h,N); 23 | for k = 1:h 24 | [fLTL,zLTL] = getLTL(args{1}, k); 25 | z = [z;zLTL]; 26 | fGFI = [fGFI, fLTL]; 27 | for n = 1:N 28 | fGFI = [fGFI, ZAnd(k,n)<=z(k,n), ZAnd(k,n)<=ZLoop(k), ZAnd(k,n)>=ZLoop(k)+z(k,n)-1]; 29 | end 30 | end 31 | 32 | phi = getZ(formula, 1, N); 33 | %phi = binvar(1,N); 34 | %Z{length(Z)+1} = {phi,formula}; 35 | 36 | for n = 1:N 37 | fGFI = [fGFI, repmat(phi(n),h,1)>=ZAnd(:,n), phi(n)<=sum(ZAnd(:,n))]; 38 | end 39 | 40 | -------------------------------------------------------------------------------- /cLTL+/lib/getNegI.m: -------------------------------------------------------------------------------- 1 | function [fNeg,phi] = getNegI(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | if length(args)>1 6 | disp('Negation takes a single argument'); 7 | assert(length(args)==1); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % time horizon 13 | h = size(W{1},2)-1; 14 | 15 | % Constraints 16 | fNeg = []; 17 | 18 | if ischar(args{1}) % If argument is a formula 19 | % Get its constraints 20 | [fAP,z] = getLTL(args{1},k); 21 | fNeg = [fNeg, fAP]; 22 | else % if argument is atomic proposition 23 | % states 24 | wi = args{1}; 25 | z = getZ(args{1},h,N); 26 | z = z(k,:); 27 | for n = 1:N 28 | fNeg = [fNeg, sum(W{n}(wi,k))>=1+epsilon-bigM*(1-z(end,n))]; 29 | fNeg = [fNeg, sum(W{n}(wi,k))<=1-epsilon+bigM*z(end,n)-1]; 30 | end 31 | end 32 | 33 | 34 | % a binary variable for each agent 35 | phi = getZ(formula,h,N); 36 | phi = phi(k,:); 37 | % negation constraint 38 | fNeg = [fNeg, phi==ones(1,N)-z]; -------------------------------------------------------------------------------- /cLTL+/lib/getGF2.m: -------------------------------------------------------------------------------- 1 | function [fGF,phiGF] = getGF2(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | h = length(Mw); 6 | 7 | if length(args)~=1 8 | disp('GF(eventually) takes a single argument') 9 | assert(length(args)==1) 10 | end 11 | 12 | fGF = []; 13 | ZAnd = []; 14 | z = []; 15 | for i=1:h 16 | % za_i = << phi1 U phi2 >>_i 17 | [fLTL,zi] = getLTL(args{1},k); 18 | fGF = [fGF, fLTL]; 19 | z = [z;zi]; 20 | 21 | % zb_i = And(zLoop_i,za_i) 22 | formulaAnd = strcat('And(', ... 23 | 'ZLoop', '[',num2str(i),'],', ... 24 | num2str(args{1}), '[',num2str(i),'])'); 25 | zAnd = getZ(formulaAnd,-1); 26 | ZAnd = [ZAnd;zAnd]; 27 | fGF = [fGF, ZAnd(i)<=z(i), ZAnd(i)<=ZLoop(i), ZAnd(i)>=z(i)+ZLoop(i)-1]; 28 | 29 | end 30 | 31 | % finally (15) 32 | phiGF = getZ(formula,1); 33 | fGF = [fGF, phiGF<=sum(ZAnd), repmat(phiGF,h,1)>=ZAnd]; 34 | 35 | 36 | -------------------------------------------------------------------------------- /cLTL/lib/getGF2.m: -------------------------------------------------------------------------------- 1 | function [fGF,phiGF] = getGF2(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | h = length(Mw); 6 | 7 | if length(args)~=1 8 | disp('GF(eventually) takes a single argument') 9 | assert(length(args)==1) 10 | end 11 | 12 | fGF = []; 13 | ZAnd = []; 14 | z = []; 15 | for i=1:h 16 | % za_i = << phi1 U phi2 >>_i 17 | [fLTL,zi] = getLTL(args{1},k); 18 | fGF = [fGF, fLTL]; 19 | z = [z;zi]; 20 | 21 | % zb_i = And(zLoop_i,za_i) 22 | formulaAnd = strcat('And(', ... 23 | 'ZLoop', '[',num2str(i),'],', ... 24 | num2str(args{1}), '[',num2str(i),'])'); 25 | zAnd = getZ(formulaAnd,-1); 26 | ZAnd = [ZAnd;zAnd]; 27 | fGF = [fGF, ZAnd(i)<=z(i), ZAnd(i)<=ZLoop(i), ZAnd(i)>=z(i)+ZLoop(i)-1]; 28 | 29 | end 30 | 31 | % finally (15) 32 | phiGF = getZ(formula,1); 33 | fGF = [fGF, phiGF<=sum(ZAnd), repmat(phiGF,h,1)>=ZAnd]; 34 | 35 | 36 | -------------------------------------------------------------------------------- /cLTL+/lib/getDyn.m: -------------------------------------------------------------------------------- 1 | function fDyn = getDyn(A,CA_flag) 2 | % returns dynamical constraints 3 | global W; 4 | % number of agents 5 | N = length(W); 6 | % number of states 7 | I = size(W{1},1); 8 | % time horizon 9 | h = size(W{1},2)-1; 10 | 11 | fDyn = []; 12 | for n = 1:N 13 | fDyn = [fDyn, sum(W{n}) == ones(1,h+1)]; 14 | others = find([1:N]~=n); 15 | for i = 2:h+1 16 | wnext = W{n}(:,i); 17 | wcurrent = W{n}(:,i-1); 18 | %fDyn = [fDyn, sos1(wnext,ones(I,1))]; 19 | % move according to adj matrix 20 | fDyn = [fDyn, wnext <= A*wcurrent]; 21 | if CA_flag 22 | for other = 1:N-1 23 | wother_current = W{others(other)}(:,i-1); 24 | fDyn = [fDyn, wnext <= ones(size(I))-wother_current]; 25 | end 26 | end 27 | % conservation of mass 28 | %fDyn = [fDyn, sum(W{n}(:,i-1))==1]; 29 | % non-negative number of agents 30 | %fDyn = [fDyn, wnext >= zeros(I,1)]; 31 | end 32 | end 33 | 34 | 35 | -------------------------------------------------------------------------------- /cLTL+/lib/getX.m: -------------------------------------------------------------------------------- 1 | function [fX,phiX] = getX(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=1 7 | disp('X(next) takes a single argument'); 8 | assert(length(args)==1); 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi2 15 | [fX,phiX] = getLTL(args{1},k+1); 16 | 17 | else 18 | 19 | %constraints 20 | fX = []; 21 | 22 | % And(zLoop_i, args{1}_i) 23 | zAnd = []; 24 | 25 | for i=1:k 26 | 27 | phi_i = getZ(args{1},i); 28 | 29 | formulaAnd = strcat('And(', ... 30 | 'zLoop', '[',num2str(i),'],', ... 31 | num2str(args{1}), '[',num2str(i),'])'); 32 | zAnd_i = getZ(formulaAnd,-1); 33 | zAnd = [zAnd;zAnd_i]; 34 | 35 | fX = [fX, zAnd(i)<=phi_i, zAnd(i)<=zLoop(i), zAnd(i)>=phi_i+zLoop(i)-1]; 36 | 37 | end 38 | 39 | % finally (13) 40 | phiX = getZ(formula,k); 41 | fX = [fX, repmat(phiX,k,1)>=zAnd, phiX<=sum(zAnd)]; 42 | 43 | end 44 | -------------------------------------------------------------------------------- /cLTL/lib/getX.m: -------------------------------------------------------------------------------- 1 | function [fX,phiX] = getX(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=1 7 | disp('X(next) takes a single argument'); 8 | assert(length(args)==1); 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi2 15 | [fX,phiX] = getLTL(args{1},k+1); 16 | 17 | else 18 | 19 | %constraints 20 | fX = []; 21 | 22 | % And(zLoop_i, args{1}_i) 23 | zAnd = []; 24 | 25 | for i=1:k 26 | 27 | phi_i = getZ(args{1},i); 28 | 29 | formulaAnd = strcat('And(', ... 30 | 'zLoop', '[',num2str(i),'],', ... 31 | num2str(args{1}), '[',num2str(i),'])'); 32 | zAnd_i = getZ(formulaAnd,-1); 33 | zAnd = [zAnd;zAnd_i]; 34 | 35 | fX = [fX, zAnd(i)<=phi_i, zAnd(i)<=zLoop(i), zAnd(i)>=phi_i+zLoop(i)-1]; 36 | 37 | end 38 | 39 | % finally (13) 40 | phiX = getZ(formula,k); 41 | fX = [fX, repmat(phiX,k,1)>=zAnd, phiX<=sum(zAnd)]; 42 | 43 | end 44 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/Or.m: -------------------------------------------------------------------------------- 1 | function phi = Or(varargin) 2 | formula = strcat('Or(', varargin{1}.formula); 3 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 4 | for i = 2:nargin 5 | assert(strcmp(varargin{i}.type, 'inner') || ... 6 | strcmp(varargin{1}.type, 'ap'), ... 7 | 'Inner and outer logic formulas cannot be mixed'); 8 | formula = strcat(formula, ', ', varargin{i}.formula); 9 | end 10 | 11 | formula = strcat(formula, ')'); 12 | phi = struct('type', 'inner', 'Op', 'Or', ... 13 | 'formula', formula, 'args', {varargin}); 14 | else 15 | for i = 2:nargin 16 | assert(strcmp(varargin{i}.type, 'outer') || ... 17 | strcmp(varargin{1}.type, 'tcp'), ... 18 | 'Inner and outer logic formulas cannot be mixed'); 19 | formula = strcat(formula, ', ', varargin{i}.formula); 20 | end 21 | 22 | formula = strcat(formula, ')'); 23 | phi = struct('type', 'outer', 'Op', 'Or', ... 24 | 'formula', formula, 'args', {varargin}); 25 | end 26 | -------------------------------------------------------------------------------- /cLTL/examples/example_goblue.m: -------------------------------------------------------------------------------- 1 | % Trivially feasible, Yalmip claims otherwise 2 | close all;clear;clc; 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | % creates grid space and specifications 6 | um_goblue 7 | 8 | A = adj+eye(size(adj)); 9 | n = length(A); 10 | %A = ones(13*21)-eye(13*21); 11 | h = 50; 12 | N = 76; 13 | f = strcat('And(',f_um,',',f_go,')'); 14 | fps = 1; 15 | 16 | % m=1:N; 17 | % W0= m(sort(randperm(N,n))); 18 | % W0=diff(W0)'; 19 | % W0(end+1)=N-sum(W0); 20 | W0 = zeros(length(A),1); 21 | W0(1)=N; 22 | 23 | epsilon=0; 24 | CA_flag=0; 25 | 26 | tic 27 | [Mw,WT,Z,~] = cLTL_synth(f,A,h,W0,Obs,CA_flag); 28 | toc 29 | 30 | time = clock; 31 | 32 | filename = ['GOBLUE_' ... 33 | num2str(time(1)) '_'... % Returns year as character 34 | num2str(time(2)) '_'... % Returns month as character 35 | num2str(time(3)) '_'... % Returns day as char 36 | num2str(time(4)) 'h'... % returns hour as char.. 37 | num2str(time(5)) 'm'... %returns minute as char 38 | ]; 39 | 40 | 41 | save(filename,'WT','WT','Mw','Mw','ZLoop','ZLoop','A','A','mygrid','mygrid','Z','Z'); 42 | 43 | plot_trace(filename,fps); 44 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getCol.m: -------------------------------------------------------------------------------- 1 | function [fCol,zCol] = getCol(col_radius) 2 | % returns collision avoidance constraints 3 | global u x bigM; 4 | 5 | % number of agents 6 | N = length(u); 7 | 8 | % time horizon 9 | h = size(u{1},2); 10 | 11 | % dimension of x 12 | dx = size(x{1},1); 13 | 14 | % Ax <= b defines a box around x 15 | A = [eye(dx);-eye(dx)]; 16 | 17 | fCol = []; 18 | zCol = []; 19 | for t = 1:h 20 | for n1 = 1:N-1 21 | % position of agent n at time t 22 | xn1 = x{n1}(:,t); 23 | % epsilon ball around xn 24 | b = [2*col_radius + xn1; 2*col_radius - xn1]; 25 | 26 | %for all agents whose id's less than n1 27 | for n2 = n1+1:N 28 | % position of agent n2 at time t 29 | xn2 = x{n2}(:,t); 30 | 31 | ztemp = binvar(length(b),1); 32 | zCol = [zCol; ztemp]; 33 | for r = 1:length(b) 34 | fCol = [fCol, A(r,:)*xn2 >= b(r) + 0.01 - bigM*(1-ztemp(r))]; 35 | end 36 | 37 | fCol = [fCol, sum(ztemp)>=1]; 38 | 39 | end 40 | 41 | end 42 | end 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /cLTL+/lib/getOr.m: -------------------------------------------------------------------------------- 1 | function [fOr,phi] = getOr(formula,args,k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | % a binary variable for each argument 6 | z = []; 7 | 8 | % Constraints 9 | fOr = []; 10 | 11 | % number of arguments 12 | m = length(args); 13 | 14 | for i=1:m 15 | if ischar(args{i}) % If argument is a formula 16 | % Get its constraints 17 | [fAP,phiAP] = getLTL(args{i},k); 18 | fOr = [fOr, fAP]; 19 | z = [z;phiAP]; 20 | else % if argument is counting proposition 21 | % sdpvar 22 | ztemp = [getZ(args{i},k)]; 23 | z = [z;ztemp]; 24 | % state 25 | wi = args{i}(1:end-1); 26 | % threshold 27 | mi = args{i}(end); 28 | % number of states 29 | n = length(Mw{k}); 30 | % constraint 31 | W = Mw{k}*ones(n,1); 32 | fOr = [fOr, sum(W(wi))>=mi+epsilon-bigM*(1-z(i))]; 33 | fOr = [fOr, sum(W(wi))<=mi-epsilon+bigM*z(i)-1]; 34 | end 35 | end 36 | 37 | if m > 1 38 | % a binary variable for formula 39 | phi = getZ(formula,k); 40 | % conjunction constraint 41 | fOr = [fOr, repmat(phi,m,1)>=z, phi<=sum(z)]; 42 | else 43 | phi = z; 44 | end -------------------------------------------------------------------------------- /cLTL/lib/getOr.m: -------------------------------------------------------------------------------- 1 | function [fOr,phi] = getOr(formula,args,k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | % a binary variable for each argument 6 | z = []; 7 | 8 | % Constraints 9 | fOr = []; 10 | 11 | % number of arguments 12 | m = length(args); 13 | 14 | for i=1:m 15 | if ischar(args{i}) % If argument is a formula 16 | % Get its constraints 17 | [fAP,phiAP] = getLTL(args{i},k); 18 | fOr = [fOr, fAP]; 19 | z = [z;phiAP]; 20 | else % if argument is counting proposition 21 | % sdpvar 22 | ztemp = [getZ(args{i},k)]; 23 | z = [z;ztemp]; 24 | % state 25 | wi = args{i}(1:end-1); 26 | % threshold 27 | mi = args{i}(end); 28 | % number of states 29 | n = length(Mw{k}); 30 | % constraint 31 | W = Mw{k}*ones(n,1); 32 | fOr = [fOr, sum(W(wi))>=mi+epsilon-bigM*(1-z(i))]; 33 | fOr = [fOr, sum(W(wi))<=mi-epsilon+bigM*z(i)-1]; 34 | end 35 | end 36 | 37 | if m > 1 38 | % a binary variable for formula 39 | phi = getZ(formula,k); 40 | % conjunction constraint 41 | fOr = [fOr, repmat(phi,m,1)>=z, phi<=sum(z)]; 42 | else 43 | phi = z; 44 | end -------------------------------------------------------------------------------- /cLTL/lib/getAnd.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAnd(formula,args,k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | % a binary variable for each argument 6 | z = []; 7 | 8 | % Constraints 9 | fAnd = []; 10 | 11 | % number of arguments 12 | m = length(args); 13 | 14 | for i=1:m 15 | if ischar(args{i}) % If argument is a formula 16 | % Get its constraints 17 | [fAP,phiAP] = getLTL(args{i},k); 18 | fAnd = [fAnd, fAP]; 19 | z = [z;phiAP]; 20 | else % if argument is counting proposition 21 | % sdpvar 22 | ztemp = [getZ(args{i},k)]; 23 | z = [z;ztemp]; 24 | % state 25 | wi = args{i}(1:end-1); 26 | % threshold 27 | mi = args{i}(end); 28 | % number of states 29 | n = length(Mw{k}); 30 | % constraint 31 | W = Mw{k}*ones(n,1); 32 | fAnd = [fAnd, sum(W(wi))>=mi+epsilon-bigM*(1-z(i))]; 33 | fAnd = [fAnd, sum(W(wi))<=mi-epsilon+bigM*z(i)-1]; 34 | end 35 | end 36 | 37 | if m > 1 38 | % a binary variable for formula 39 | phi = getZ(formula,k); 40 | % conjunction constraint 41 | fAnd = [fAnd, repmat(phi,m,1)<=z, phi>=1-m+sum(z)]; 42 | else 43 | phi = z; 44 | end -------------------------------------------------------------------------------- /cLTL+/README.md: -------------------------------------------------------------------------------- 1 | # cLTL+ 2 | 3 | This Matlab implementation takes cLTL+ specifications, agent dynamics, environment as input and synthesizes individual trajectories for agents such that specifications are met. 4 | For more information on cLTL+ please refer to 5 | ```Yunus Emre Sahin, Petter Nilsson, Necmiye Ozay, Synchronous and Asynchronous Multi-agent Coordination with cLTL+ Constraints, CDC17 ``` 6 | 7 | ### Dependencies 8 | 9 | * [YALMIP](https://yalmip.github.io/) 10 | * YALMIP compatible MILP solver 11 | * [Gurobi](http://www.gurobi.com/) 12 | * [CPLEX](https://www-01.ibm.com/software/commerce/optimization/cplex-optimizer/) 13 | 14 | ### Installing 15 | 16 | * Easiest way to install YALMIP is to download [MPT3](http://control.ee.ethz.ch/~mpt/3/Main/Installation?action=download&upname=install_mpt3.m) tool by [Herceg et.al.](http://control.ee.ethz.ch/~mpt) 17 | 18 | * Download Gurobi optimizer and acquire a license file 19 | 20 | * Go to Gurobi installation path (e.g. ```/Library/gurobi702/mac64/matlab```) and run ```gurobi_setup.m``` 21 | 22 | 23 | ## Running the tests 24 | 25 | Run ```yalmiptest``` on Matlab to see if YALMIP is installed correctly and if Gurobi is added. 26 | 27 | ## Examples 28 | 29 | * ```emergency_example.m``` (Example in CDC17 paper) 30 | -------------------------------------------------------------------------------- /cLTL+/lib/getAndI.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAndI(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | % number of agents 6 | N = length(W); 7 | % time horizon 8 | h = size(W{1},2)-1; 9 | 10 | % m*N binvar: a binary variable for each argument and agent 11 | z = []; 12 | 13 | % Constraints 14 | fAnd = []; 15 | 16 | % number of arguments 17 | m = length(args); 18 | 19 | for i=1:m 20 | if ischar(args{i}) % If argument is a formula 21 | % Get its constraints 22 | [fAP,phiAP] = getLTL(args{i},k); 23 | fAnd = [fAnd, fAP]; 24 | z = [z; phiAP]; 25 | else % if argument is atomic proposition 26 | % states 27 | wi = args{i}; 28 | ztemp = getZ(args{i},h,N); 29 | z = [z; ztemp(k,:)]; 30 | for n = 1:N 31 | fAnd = [fAnd, sum(W{n}(wi,k))>=1+epsilon-bigM*(1-z(end,n))]; 32 | fAnd = [fAnd, sum(W{n}(wi,k))<=1-epsilon+bigM*z(end,n)-1]; 33 | end 34 | end 35 | end 36 | 37 | if m > 1 38 | % a binary variable for each agent 39 | phi = getZ(formula,h,N); 40 | phi = phi(k,:); 41 | % conjunction constraint 42 | for n = 1:N 43 | fAnd = [fAnd, repmat(phi(n),m,1)<=z(:,n), phi(n)>=1-m+sum(z(:,n))]; 44 | end 45 | else 46 | phi = z; 47 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/And.m: -------------------------------------------------------------------------------- 1 | function phi = And(varargin) 2 | % 3 | % Returns a struct representing the formula 4 | % type: Inner,Outer 5 | % Op: 'And' 6 | % formula: formula in string form 7 | % args: arguments are also inner formulas or ap 8 | % 9 | 10 | formula = strcat('And(', varargin{1}.formula); 11 | if strcmp(varargin{1}.type, 'inner')|| strcmp(varargin{1}.type, 'ap') 12 | for i = 2:nargin 13 | assert(strcmp(varargin{i}.type, 'inner') || ... 14 | strcmp(varargin{i}.type, 'ap'), ... 15 | 'Inner and outer logic formulas cannot be mixed'); 16 | formula = strcat(formula, ', ', varargin{i}.formula); 17 | end 18 | 19 | formula = strcat(formula, ')'); 20 | phi = struct('type', 'inner', 'Op', 'And', ... 21 | 'formula', formula, 'args', {varargin}); 22 | else 23 | for i = 2:nargin 24 | assert(strcmp(varargin{i}.type, 'outer') || ... 25 | strcmp(varargin{i}.type, 'tcp'), ... 26 | 'Inner and outer logic formulas cannot be mixed'); 27 | formula = strcat(formula, ', ', varargin{i}.formula); 28 | end 29 | 30 | formula = strcat(formula, ')'); 31 | phi = struct('type', 'outer', 'Op', 'And', ... 32 | 'formula', formula, 'args', {varargin}); 33 | end 34 | -------------------------------------------------------------------------------- /cLTL+/lib/getOrI.m: -------------------------------------------------------------------------------- 1 | function [fOr,phi] = getOrI(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | % number of agents 6 | N = length(W); 7 | % time horizon 8 | h = size(W{1},2)-1; 9 | 10 | % m*N binvar: a binary variable for each argument and agent 11 | z = []; 12 | 13 | % Constraints 14 | fOr = []; 15 | 16 | % number of arguments 17 | m = length(args); 18 | 19 | for i=1:m 20 | if ischar(args{i}) % If argument is a formula 21 | % Get its constraints 22 | [fAP,phiAP] = getLTL(args{i},k); 23 | fOr = [fOr, fAP]; 24 | z = [z; phiAP]; 25 | else % if argument is atomic proposition 26 | % states 27 | wi = args{i}; 28 | ztemp = getZ(args{i},h,N); 29 | z = [z; ztemp(k,:)]; 30 | for n = 1:N 31 | fOr = [fOr, sum(W{n}(wi,k))>=1+epsilon-bigM*(1-z(end,n))]; 32 | fOr = [fOr, sum(W{n}(wi,k))<=1-epsilon+bigM*z(end,n)-1]; 33 | end 34 | end 35 | end 36 | 37 | if m > 1 38 | % a binary variable for each agent 39 | phi2 = getZ(formula,h,N); 40 | % Robust version 41 | phi = getZ(strcat('Robust(', formula, ')'),h,N); % disjunction constraint 42 | for n = 1:N 43 | fOr = [fOr, repmat(phi(k,n),m,1)>=z(:,n), phi(k,n)<=+sum(z(:,n))]; 44 | end 45 | else 46 | phi = z; 47 | end -------------------------------------------------------------------------------- /cLTL+_continuous/README.md: -------------------------------------------------------------------------------- 1 | # cLTL+_continuous 2 | 3 | This Matlab implementation takes cLTL+ specifications, continuous agent dynamics, environment as input and synthesizes individual trajectories for agents such that specifications are met. 4 | For more information on cLTL+ please refer to 5 | ```Yunus Emre Sahin, Petter Nilsson, Necmiye Ozay, Synchronous and Asynchronous Multi-agent Coordination with cLTL+ Constraints, CDC17 ``` 6 | 7 | ### Dependencies 8 | 9 | * [YALMIP](https://yalmip.github.io/) 10 | * YALMIP compatible MILP solver 11 | * [Gurobi](http://www.gurobi.com/) 12 | * [CPLEX](https://www-01.ibm.com/software/commerce/optimization/cplex-optimizer/) 13 | 14 | ### Installing 15 | 16 | * Easiest way to install YALMIP is to download [MPT3](http://control.ee.ethz.ch/~mpt/3/Main/Installation?action=download&upname=install_mpt3.m) tool by [Herceg et.al.](http://control.ee.ethz.ch/~mpt) 17 | 18 | * Download Gurobi optimizer and acquire a license file 19 | 20 | * Go to Gurobi installation path (e.g. ```/Library/gurobi702/mac64/matlab```) and run ```gurobi_setup.m``` 21 | 22 | 23 | ## Running the tests 24 | 25 | Run ```yalmiptest``` on Matlab to see if YALMIP is installed correctly and if Gurobi is added. 26 | 27 | ## Examples 28 | 29 | * ```emergency_example.m``` (Example in CDC17 paper with continuous dynamics) 30 | -------------------------------------------------------------------------------- /cLTL/README.md: -------------------------------------------------------------------------------- 1 | # cLTL 2 | 3 | This Matlab implementation takes cLTL specifications, transition matrix, environment as input and synthesizes individual trajectories for agents such that specifications are met. 4 | For more information on cLTL+ please refer to 5 | ```Sahin, Yunus Emre, Petter Nilsson, and Necmiye Ozay. "Provably-correct coordination of large collections of agents with counting temporal logic constraints." Proceedings of the 8th International Conference on Cyber-Physical Systems. ACM, 2017. ``` 6 | 7 | ### Dependencies 8 | 9 | * [YALMIP](https://yalmip.github.io/) 10 | * YALMIP compatible MILP solver 11 | * [Gurobi](http://www.gurobi.com/) 12 | * [CPLEX](https://www-01.ibm.com/software/commerce/optimization/cplex-optimizer/) 13 | 14 | ### Installing 15 | 16 | * Easiest way to install YALMIP is to download [MPT3](http://control.ee.ethz.ch/~mpt/3/Main/Installation?action=download&upname=install_mpt3.m) tool by [Herceg et.al.](http://control.ee.ethz.ch/~mpt) 17 | 18 | * Download Gurobi optimizer and acquire a license file 19 | 20 | * Go to Gurobi installation path (e.g. ```/Library/gurobi702/mac64/matlab```) and run ```gurobi_setup.m``` 21 | 22 | 23 | ## Running the tests 24 | 25 | Run ```yalmiptest``` on Matlab to see if YALMIP is installed correctly and if Gurobi is added. 26 | 27 | ## Examples 28 | 29 | * ```earthquake.m``` (Example in ICCPS17 paper with continuous dynamics) 30 | -------------------------------------------------------------------------------- /cLTL+/lib/getZold.m: -------------------------------------------------------------------------------- 1 | function z = getZold(formula,k,n) 2 | 3 | if strcmp(formula,'True') || strcmp(formula,' True') 4 | z = 1; 5 | return 6 | end 7 | 8 | global W Z; 9 | % number of agents 10 | N = length(W); 11 | % number of states 12 | I = size(W{1},1); 13 | % time horizon 14 | h = size(W{1},2)-1; 15 | 16 | if isnumeric(formula) 17 | formula = strcat('[ ', num2str(formula), ']'); 18 | end 19 | 20 | formula = num2str(formula); 21 | 22 | 23 | i = find(strcmp([Z{:}],formula)); 24 | 25 | if isempty(i) 26 | %create new sdpvar if not created before 27 | if n >= 0 % for inner formulas 28 | z = binvar(h,N,'full'); 29 | Z{length(Z)+1} = {z,formula}; 30 | z = z(k,:); 31 | if n>0 32 | z = z(n); 33 | end 34 | else 35 | if k >= 0 % for outer formulas 36 | z = binvar(h,1); 37 | Z{length(Z)+1} = {z,formula}; 38 | if k>0 39 | z = z(k); 40 | end 41 | else 42 | z = binvar(1); 43 | Z{length(Z)+1} = {z,formula}; 44 | end 45 | end 46 | 47 | else 48 | % else return the existing one 49 | if n > 0 50 | z = Z{i/2}{1}(k,n); 51 | elseif n == 0 52 | z = Z{i/2}{1}(k,:); 53 | else 54 | if k > 0 55 | z = Z{i/2}{1}(k); 56 | else 57 | z = Z{i/2}{1}; 58 | end 59 | end 60 | end -------------------------------------------------------------------------------- /cLTL+/lib/getLTL.m: -------------------------------------------------------------------------------- 1 | function [fLTL,phi] = getLTL(formula,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon tau; 4 | 5 | [Op,args] = parseLTL(formula); 6 | 7 | switch Op 8 | case 'And' 9 | [fLTL,phi] = getAnd(formula,args,k); 10 | case 'Or' 11 | [fLTL,phi] = getOr(formula,args,k); 12 | case 'Neg' 13 | [fLTL,phi] = getNeg(formula,args,k); 14 | case 'AndI' 15 | [fLTL,phi] = getAndI(formula,args,k); 16 | case 'OrI' 17 | [fLTL,phi] = getOrI(formula,args,k); 18 | case 'NegI' 19 | [fLTL,phi] = getNegI(formula,args,k); 20 | case 'G' 21 | [fLTL,phi] = getG(formula,args,k); 22 | case 'F' 23 | [fLTL,phi] = getF(formula,args,k); 24 | case 'X' 25 | [fLTL,phi] = getX(formula,args,k); 26 | case 'U' 27 | [fLTL,phi] = getU(formula,args,k); 28 | case 'GG' 29 | [fLTL,phi] = getGG(formula,args,k); 30 | case 'FF' 31 | [fLTL,phi] = getFF(formula,args,k); 32 | case 'FG' 33 | [fLTL,phi] = getFG(formula,args,k); 34 | case 'GF' 35 | [fLTL,phi] = getGF(formula,args,k); 36 | case 'GGI' 37 | [fLTL,phi] = getGGI(formula,args,k); 38 | case 'FFI' 39 | [fLTL,phi] = getFFI(formula,args,k); 40 | case 'FGI' 41 | [fLTL,phi] = getFGI(formula,args,k); 42 | case 'GFI' 43 | [fLTL,phi] = getGFI(formula,args,k); 44 | case 'TP' 45 | [fLTL,phi] = getTPTau(formula,args,k); 46 | otherwise 47 | disp('wrong formula'); 48 | end 49 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getCol2.m: -------------------------------------------------------------------------------- 1 | function [fCol, zCol] = getCol2(col_radius) 2 | % returns collision avoidance constraints 3 | global u x; 4 | 5 | % number of agents 6 | N = length(u); 7 | 8 | % time horizon 9 | h = size(u{1},2); 10 | 11 | % dimension of x 12 | dx = size(x{1}(:,1)); 13 | 14 | % Ax <= b defines a box around x 15 | A = [eye(dx);eye(dx);-eye(dx);-eye(dx)]; 16 | 17 | fCol = []; 18 | zCol = []; 19 | for t = 1:h 20 | for n1 = 1:N-1 21 | % position of agent n at time t 22 | xn1 = x{n1}(:,t); 23 | xn1t = x{n1}(:,t+1); 24 | 25 | % % decide min and max rows 26 | % ztemp = binvar(dx,1); 27 | % zCol = [zCol; ztemp]; 28 | % for r = 1:dx 29 | % fCol 30 | % 31 | % 32 | % epsilon ball around xn 33 | b = [col_radius + xn1; col_radius - xn1;... 34 | col_radius + xn1; col_radius - xn1;]; 35 | 36 | %for all agents whose id's greater than n1 37 | for n2 = n1+1:N 38 | % position of agent n2 at time t 39 | xn2 = x{n2}(:,t); 40 | 41 | % avoid collision on discrete time instances 42 | fCol = [fCol, A*xn2 <= b]; 43 | 44 | % paths should not cross (there doesn't a alpha*xn1 =/= beta*xn2) 45 | alpha = sdpvar(1,dx); 46 | beta = sdpvar(1,dx); 47 | 48 | fCol = [fCol, alpha*ones(dx,1) == 1, alpha >= zeros(1,dx)]; 49 | fCol = [fCol, beta*ones(dx,1) == 1, beta >= zeros(1,dx)]; 50 | 51 | end 52 | 53 | end 54 | end 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, The Regents of the University of Michigan 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /cLTL+/lib/getOrITau.m: -------------------------------------------------------------------------------- 1 | function [fOr,phi] = getOrITau(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon; 4 | 5 | % number of agents 6 | N = length(W); 7 | % time horizon 8 | h = size(W{1},2)-1; 9 | 10 | % m*N binvar: a binary variable for each argument and agent 11 | z = []; 12 | 13 | % Constraints 14 | fOr = []; 15 | 16 | % number of arguments 17 | m = length(args); 18 | 19 | for i=1:m 20 | if ischar(args{i}) % If argument is a formula 21 | % Get its constraints 22 | [fAP,phiAP] = getLTL(args{i},k); 23 | fOr = [fOr, fAP]; 24 | z = [z; phiAP]; 25 | else % if argument is atomic proposition 26 | % states 27 | wi = args{i}; 28 | ztemp = getZ(args{i},h,N); 29 | z = [z; ztemp(k,:)]; 30 | for n = 1:N 31 | fOr = [fOr, sum(W{n}(wi,k))>=1+epsilon-bigM*(1-z(end,n))]; 32 | fOr = [fOr, sum(W{n}(wi,k))<=1-epsilon+bigM*z(end,n)-1]; 33 | end 34 | end 35 | end 36 | 37 | 38 | if tau>0 39 | % a binary variable for each agent 40 | phi2 = getZ(formula,h,N); 41 | phi = getZ(strcat('Robust(', formula, ')'),h,N); 42 | % disjunction constraint 43 | for n = 1:N 44 | fOr = [fOr, repmat(phi2(k,n),m,1)>=z(:,n), phi2(k,n)<=+sum(z(:,n))]; 45 | fOr = [fOr, repmat(phi(k,n),tau,1)<= phi2(k:k+tau,n),... 46 | phi(k,n)>= sum(phi2(k:k+tau,n))-tau]; 47 | end 48 | 49 | phi = phi(k,:); 50 | 51 | else 52 | if m > 1 53 | % a binary variable for each agent 54 | phi = getZ(formula,h,N); 55 | phi = phi(k,:); 56 | % disjunction constraint 57 | for n = 1:N 58 | fOr = [fOr, repmat(phi(n),m,1)>=z(:,n), phi(n)<=+sum(z(:,n))]; 59 | end 60 | else 61 | phi = z; 62 | end 63 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/plot_continuous.m: -------------------------------------------------------------------------------- 1 | function plot_continuous(x,Z) 2 | h = size(x{1},2)-1; 3 | N = length(x); 4 | cmap = jet(N); 5 | fps = 5; 6 | 7 | % state constraints 8 | Px = Polytope([eye(2); -eye(2)], [10; 10; 0; 0]); 9 | 10 | % input constraints 11 | Pu = Polyhedron([eye(2); -eye(2)], [1; 1; 1; 1]); 12 | 13 | % atomic propositions 14 | ap_cell = {}; 15 | 16 | % narrow passage 17 | [ap_narrow, ap_cell] = AP([eye(2); -eye(2)],[7; 8; -3; -7], ap_cell); 18 | 19 | % Region A 20 | [ap_A, ap_cell] = AP([eye(2); -eye(2)],[3; 10; 0; -5], ap_cell); 21 | 22 | % Region C 23 | [ap_C, ap_cell] = AP([eye(2); -eye(2)],[10; 10; 0; -5], ap_cell); 24 | 25 | % Region E 26 | [ap_E, ap_cell] = AP([eye(2); -eye(2)],[10; 5; 0; 0], ap_cell); 27 | 28 | % Obstacles 29 | Obs1 = Polytope([eye(2); -eye(2)], [8; 3; -6; -1]); 30 | Obs2 = Polytope([eye(2); -eye(2)], [7; 10; -3; -8]); 31 | Obs3 = Polytope([eye(2); -eye(2)], [7; 7; -3; -5]); 32 | Obs = [Obs1, Obs2, Obs3]; 33 | pause('on') 34 | for t = 1:h 35 | for tt = 1:fps+1 36 | figure(1);clf;hold on; 37 | plot(Polyhedron(Px.A,Px.b), 'color', 'white'); 38 | plot(Polyhedron(ap_A.A,ap_A.b), 'color', 'gray'); 39 | plot(Polyhedron(ap_C.A,ap_C.b), 'color', 'gray'); 40 | plot(Polyhedron(ap_narrow.A,ap_narrow.b), 'color', 'gray'); 41 | plot(Polyhedron(Obs(1).A,Obs(1).b), 'color', 'black'); 42 | plot(Polyhedron(Obs(2).A,Obs(2).b), 'color', 'black'); 43 | plot(Polyhedron(Obs(3).A,Obs(3).b), 'color', 'black'); 44 | for n = 1:N 45 | xx = x{n}(1,t) * (fps+1-tt)/fps + x{n}(1,t+1) * (tt-1)/fps; 46 | yy = x{n}(2,t) * (fps+1-tt)/fps + x{n}(2,t+1) * (tt-1)/fps; 47 | plot(xx,yy,'o', 'color', cmap(n,:), ... 48 | 'markersize', 15, 'MarkerFaceColor', cmap(n,:)) 49 | end 50 | pause(.01); 51 | hold off 52 | end 53 | end -------------------------------------------------------------------------------- /cLTL+/lib/getAndITau.m: -------------------------------------------------------------------------------- 1 | function [fAnd,phi] = getAndITau(formula,args,k) 2 | 3 | global W Wtotal Z zLoop ZLoop bigM epsilon tau; 4 | 5 | % number of agents 6 | N = length(W); 7 | % time horizon 8 | h = size(W{1},2)-1; 9 | 10 | % m*N binvar: a binary variable for each argument and agent 11 | z = []; 12 | 13 | % Constraints 14 | fAnd = []; 15 | 16 | % number of arguments 17 | m = length(args); 18 | 19 | for i=1:m 20 | if ischar(args{i}) % If argument is a formula 21 | % Get its constraints 22 | [fAP,phiAP] = getLTL(args{i},k); 23 | fAnd = [fAnd, fAP]; 24 | z = [z; phiAP]; 25 | else % if argument is atomic proposition 26 | % states 27 | wi = args{i}; 28 | ztemp = getZ(args{i},h,N); 29 | z = [z; ztemp(k,:)]; 30 | for n = 1:N 31 | fAnd = [fAnd, sum(W{n}(wi,k))>=1+epsilon-bigM*(1-z(end,n))]; 32 | fAnd = [fAnd, sum(W{n}(wi,k))<=1-epsilon+bigM*z(end,n)-1]; 33 | end 34 | end 35 | end 36 | 37 | if tau >0 38 | 39 | % a binary variable for each agent 40 | phi2 = getZ(formula,h,N); 41 | % Robust version 42 | phi = getZ(strcat('Robust(', formula, ')'),h,N); 43 | 44 | for t=1:tau 45 | if 46 | end 47 | 48 | % conjunction constraint 49 | for n = 1:N 50 | fAnd = [fAnd, repmat(phi2(k,n),m,1)<=z(:,n), phi2(k,n)>=1-m+sum(z(:,n))]; 51 | fAnd = [fAnd, repmat(phi(k,n),tau,1)<= phi2(k:k+tau,n),... 52 | phi(k,n)>= sum(phi2(k:k+tau,n))-tau]; 53 | end 54 | 55 | phi = phi(k,:); 56 | 57 | else 58 | if m > 1 59 | % a binary variable for each agent 60 | phi = getZ(formula,h,N); 61 | phi = phi(k,:); 62 | % conjunction constraint 63 | for n = 1:N 64 | fAnd = [fAnd, repmat(phi(n),m,1)<=z(:,n), phi(n)>=1-m+sum(z(:,n))]; 65 | end 66 | else 67 | phi = z; 68 | end 69 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getLTL.m: -------------------------------------------------------------------------------- 1 | function [fLTL,phi] = getLTL(formula,k) 2 | 3 | global x u Z zLoop ZLoop bigM epsilon tau; 4 | 5 | if strcmp(formula.type,'inner') 6 | switch formula.Op 7 | case 'AP' 8 | [fLTL,phi] = getAP(formula,k); 9 | case 'And' 10 | [fLTL,phi] = getAndInner(formula,k); 11 | case 'Or' 12 | [fLTL,phi] = getOrInner(formula,k); 13 | case 'Neg' 14 | [fLTL,phi] = getNegInner(formula,k); 15 | case 'U' 16 | [fLTL,phi] = getUInner(formula,k); 17 | case 'F' 18 | [fLTL,phi] = getFInner(formula,k); 19 | case 'G' 20 | [fLTL,phi] = getGInner(formula,k); 21 | case 'FF' 22 | [fLTL,phi] = getFFInner(formula,k); 23 | case 'FG' 24 | [fLTL,phi] = getFGInner(formula,k); 25 | case 'GF' 26 | [fLTL,phi] = getGFInner(formula,k); 27 | case 'GG' 28 | [fLTL,phi] = getGGInner(formula,k); 29 | otherwise 30 | disp('wrong formula'); 31 | end 32 | else 33 | switch formula.Op 34 | case 'TCP' 35 | [fLTL,phi] = getTCPTau(formula,k); 36 | case 'And' 37 | [fLTL,phi] = getAndOuter(formula,k); 38 | case 'Or' 39 | [fLTL,phi] = getOrOuter(formula,k); 40 | case 'Neg' 41 | [fLTL,phi] = getNegOuter(formula,k); 42 | case 'U' 43 | [fLTL,phi] = getUOuter(formula,k); 44 | case 'F' 45 | [fLTL,phi] = getFOuter(formula,k); 46 | case 'G' 47 | [fLTL,phi] = getGOuter(formula,k); 48 | case 'FF' 49 | [fLTL,phi] = getFFOuter(formula,k); 50 | case 'FG' 51 | [fLTL,phi] = getFGOuter(formula,k); 52 | case 'GF' 53 | [fLTL,phi] = getGFOuter(formula,k); 54 | case 'GG' 55 | [fLTL,phi] = getGGOuter(formula,k); 56 | otherwise 57 | disp('wrong formula'); 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /cLTL+/lib/getG.m: -------------------------------------------------------------------------------- 1 | function [fG,phiG] = getG(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=1 7 | disp('G(globally) takes a single argument') 8 | assert(length(args)==1) 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi2 15 | [fG,phi2] = getLTL(args{1},k); 16 | 17 | % G[[phi2]]_i+1 18 | [fG2,phiG2] = getG(formula, args, k+1); 19 | fG = [fG, fG2]; 20 | 21 | % phiG_k = And(phi2_k,phiG_k+1) 22 | phiG = getZ(formula,k); 23 | fG = [fG, phiG<=phi2, phiG<=phiG2, phiG>=phiG2+phi2-1]; 24 | 25 | else 26 | 27 | 28 | % phi2 29 | [fG,phi2] = getLTL(args{1},k); 30 | 31 | % za = << phi1 U phi2 >> 32 | za = []; 33 | 34 | % zb_i = And(zLoop_i,za_i) 35 | zb = []; 36 | 37 | % bigOr in (15) 38 | formulaAnd = 'And('; 39 | for i=1:k 40 | % za_i = << phi1 U phi2 >>_i 41 | za_i = getZ(strcat('~',formula),i); 42 | za = [za;za_i]; 43 | 44 | % zb_i = And(zLoop_i,za_i) 45 | formulaOr = strcat('Or(', ... 46 | '(1-ZLoop)', '[',num2str(i),'],', ... 47 | strcat('~',formula), '[',num2str(i),'])'); 48 | zb_i = getZ(formulaOr,-1); 49 | zb = [zb;zb_i]; 50 | fG = [fG, zb(i)>=za(i), zb(i)>=1-ZLoop(i), zb(i)<=za(i)+1-ZLoop(i)]; 51 | 52 | formulaAnd = strcat(formulaAnd, formulaOr, ','); 53 | 54 | end 55 | formulaAnd = strcat(formulaAnd,')'); 56 | % bigOr, see eq (15) in paper 57 | zAnd2 = getZ(formulaAnd,-1); 58 | fG = [fG, zAnd2>=sum(zb)+1-k, repmat(zAnd2,k,1)<=zb]; 59 | 60 | % finally (15) 61 | phiG = getZ(formula,k); 62 | fG = [fG, phiG>=zAnd2+phi2-1, phiG<=phi2, phiG<=zAnd2]; 63 | 64 | % aux variables see (16) 65 | for i=1:k-1 66 | 67 | phi2_i = getZ(args{1},i); 68 | fG = [fG, za(i)>=za(i+1)+phi2_i-1, za(i)<=phi2_i, za(i)<=za(i+1)]; 69 | 70 | end 71 | 72 | % Last step 73 | phi2_k = getZ(args{1},k); 74 | fG = [fG, za(k)==phi2_k]; 75 | 76 | end 77 | -------------------------------------------------------------------------------- /cLTL/lib/getG.m: -------------------------------------------------------------------------------- 1 | function [fG,phiG] = getG(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=1 7 | disp('G(globally) takes a single argument') 8 | assert(length(args)==1) 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi2 15 | [fG,phi2] = getLTL(args{1},k); 16 | 17 | % G[[phi2]]_i+1 18 | [fG2,phiG2] = getG(formula, args, k+1); 19 | fG = [fG, fG2]; 20 | 21 | % phiG_k = And(phi2_k,phiG_k+1) 22 | phiG = getZ(formula,k); 23 | fG = [fG, phiG<=phi2, phiG<=phiG2, phiG>=phiG2+phi2-1]; 24 | 25 | else 26 | 27 | 28 | % phi2 29 | [fG,phi2] = getLTL(args{1},k); 30 | 31 | % za = << phi1 U phi2 >> 32 | za = []; 33 | 34 | % zb_i = And(zLoop_i,za_i) 35 | zb = []; 36 | 37 | % bigOr in (15) 38 | formulaAnd = 'And('; 39 | for i=1:k 40 | % za_i = << phi1 U phi2 >>_i 41 | za_i = getZ(strcat('~',formula),i); 42 | za = [za;za_i]; 43 | 44 | % zb_i = And(zLoop_i,za_i) 45 | formulaOr = strcat('Or(', ... 46 | '(1-ZLoop)', '[',num2str(i),'],', ... 47 | strcat('~',formula), '[',num2str(i),'])'); 48 | zb_i = getZ(formulaOr,-1); 49 | zb = [zb;zb_i]; 50 | fG = [fG, zb(i)>=za(i), zb(i)>=1-ZLoop(i), zb(i)<=za(i)+1-ZLoop(i)]; 51 | 52 | formulaAnd = strcat(formulaAnd, formulaOr, ','); 53 | 54 | end 55 | formulaAnd = strcat(formulaAnd,')'); 56 | % bigOr, see eq (15) in paper 57 | zAnd2 = getZ(formulaAnd,-1); 58 | fG = [fG, zAnd2>=sum(zb)+1-k, repmat(zAnd2,k,1)<=zb]; 59 | 60 | % finally (15) 61 | phiG = getZ(formula,k); 62 | fG = [fG, phiG>=zAnd2+phi2-1, phiG<=phi2, phiG<=zAnd2]; 63 | 64 | % aux variables see (16) 65 | for i=1:k-1 66 | 67 | phi2_i = getZ(args{1},i); 68 | fG = [fG, za(i)>=za(i+1)+phi2_i-1, za(i)<=phi2_i, za(i)<=za(i+1)]; 69 | 70 | end 71 | 72 | % Last step 73 | phi2_k = getZ(args{1},k); 74 | fG = [fG, za(k)==phi2_k]; 75 | 76 | end 77 | -------------------------------------------------------------------------------- /cLTL+/lib/getF.m: -------------------------------------------------------------------------------- 1 | function [fF,phiF] = getF(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=1 7 | disp('F(eventually) takes a single argument') 8 | assert(length(args)==1) 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi2 15 | [fF,phi2] = getLTL(args{1},k); 16 | 17 | % F[[phi2]]_i+1 18 | [fU2,phiF2] = getF(formula, args, k+1); 19 | fF = [fF, fU2]; 20 | 21 | % phiF_k = Or(phi2_k,phiF_k+1) 22 | phiF = getZ(formula,k); 23 | fF = [fF, phiF>=phi2, phiF>=phiF2, phiF<=phiF2+phi2]; 24 | 25 | else 26 | 27 | % phi1 28 | phi1 = 1; 29 | 30 | % phi2 31 | [fF,phi2] = getLTL(args{1},k); 32 | 33 | % za = << phi1 U phi2 >> 34 | za = []; 35 | 36 | % zb_i = And(zLoop_i,za_i) 37 | zb = []; 38 | 39 | % bigOr in (15) 40 | formulaOr = 'Or('; 41 | for i=1:k 42 | % za_i = << phi1 U phi2 >>_i 43 | za_i = getZ(strcat('~',formula),i); 44 | za = [za;za_i]; 45 | 46 | % zb_i = And(zLoop_i,za_i) 47 | formulaAnd = strcat('And(', ... 48 | 'zLoop', '[',num2str(i),'],', ... 49 | strcat('~',formula), '[',num2str(i),'])'); 50 | zb_i = getZ(formulaAnd,-1); 51 | zb = [zb;zb_i]; 52 | fF = [fF, zb(i)<=za(i), zb(i)<=zLoop(i), zb(i)>=za(i)+zLoop(i)-1]; 53 | 54 | formulaOr = strcat(formulaOr, formulaAnd, ','); 55 | 56 | end 57 | formulaOr = strcat(formulaOr,')'); 58 | % bigOr, see eq (15) in paper 59 | zOr = getZ(formulaOr,-1); 60 | fF = [fF, zOr<=sum(zb), repmat(zOr,k,1)>=zb]; 61 | 62 | % finally (15) 63 | phiF = getZ(formula,k); 64 | fF = [fF, phiF<=zOr+phi2, phiF>=phi2, phiF>=zOr]; 65 | 66 | % aux variables see (16) 67 | for i=1:k-1 68 | 69 | phi2_i = getZ(args{1},i); 70 | fF = [fF, za(i)<=za(i+1)+phi2_i, za(i)>=phi2_i, za(i)>=za(i+1)]; 71 | 72 | end 73 | 74 | % Last step 75 | phi2_k = getZ(args{1},k); 76 | fF = [fF, za(k)==phi2_k]; 77 | 78 | end 79 | -------------------------------------------------------------------------------- /cLTL/lib/getF.m: -------------------------------------------------------------------------------- 1 | function [fF,phiF] = getF(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=1 7 | disp('F(eventually) takes a single argument') 8 | assert(length(args)==1) 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi2 15 | [fF,phi2] = getLTL(args{1},k); 16 | 17 | % F[[phi2]]_i+1 18 | [fU2,phiF2] = getF(formula, args, k+1); 19 | fF = [fF, fU2]; 20 | 21 | % phiF_k = Or(phi2_k,phiF_k+1) 22 | phiF = getZ(formula,k); 23 | fF = [fF, phiF>=phi2, phiF>=phiF2, phiF<=phiF2+phi2]; 24 | 25 | else 26 | 27 | % phi1 28 | phi1 = 1; 29 | 30 | % phi2 31 | [fF,phi2] = getLTL(args{1},k); 32 | 33 | % za = << phi1 U phi2 >> 34 | za = []; 35 | 36 | % zb_i = And(zLoop_i,za_i) 37 | zb = []; 38 | 39 | % bigOr in (15) 40 | formulaOr = 'Or('; 41 | for i=1:k 42 | % za_i = << phi1 U phi2 >>_i 43 | za_i = getZ(strcat('~',formula),i); 44 | za = [za;za_i]; 45 | 46 | % zb_i = And(zLoop_i,za_i) 47 | formulaAnd = strcat('And(', ... 48 | 'zLoop', '[',num2str(i),'],', ... 49 | strcat('~',formula), '[',num2str(i),'])'); 50 | zb_i = getZ(formulaAnd,-1); 51 | zb = [zb;zb_i]; 52 | fF = [fF, zb(i)<=za(i), zb(i)<=zLoop(i), zb(i)>=za(i)+zLoop(i)-1]; 53 | 54 | formulaOr = strcat(formulaOr, formulaAnd, ','); 55 | 56 | end 57 | formulaOr = strcat(formulaOr,')'); 58 | % bigOr, see eq (15) in paper 59 | zOr = getZ(formulaOr,-1); 60 | fF = [fF, zOr<=sum(zb), repmat(zOr,k,1)>=zb]; 61 | 62 | % finally (15) 63 | phiF = getZ(formula,k); 64 | fF = [fF, phiF<=zOr+phi2, phiF>=phi2, phiF>=zOr]; 65 | 66 | % aux variables see (16) 67 | for i=1:k-1 68 | 69 | phi2_i = getZ(args{1},i); 70 | fF = [fF, za(i)<=za(i+1)+phi2_i, za(i)>=phi2_i, za(i)>=za(i+1)]; 71 | 72 | end 73 | 74 | % Last step 75 | phi2_k = getZ(args{1},k); 76 | fF = [fF, za(k)==phi2_k]; 77 | 78 | end 79 | -------------------------------------------------------------------------------- /cLTL/examples/um_goblue.m: -------------------------------------------------------------------------------- 1 | Obs = zeros(13*21,1); 2 | Obs=Obs(:)==1; 3 | 4 | g = [1 1 1 1; 5 | 1 0 0 0; 6 | 1 0 1 1; 7 | 1 0 0 1; 8 | 1 1 1 1]; 9 | 10 | o = [1 1 1 1; 11 | 1 0 0 1; 12 | 1 0 0 1; 13 | 1 0 0 1; 14 | 1 1 1 1]; 15 | 16 | b = [1 1 1 0; 17 | 1 0 0 1; 18 | 1 1 1 1; 19 | 1 0 0 1; 20 | 1 1 1 0]; 21 | 22 | l = [1 0 0 0; 23 | 1 0 0 0; 24 | 1 0 0 0; 25 | 1 0 0 0; 26 | 1 1 1 1]; 27 | 28 | u = [1 0 0 1; 29 | 1 0 0 1; 30 | 1 0 0 1; 31 | 1 0 0 1; 32 | 1 1 1 1]; 33 | 34 | e = [1 1 1 1; 35 | 1 0 0 0; 36 | 1 1 1 1; 37 | 1 0 0 0; 38 | 1 1 1 1]; 39 | 40 | m = [1 0 0 0 1; 41 | 1 1 0 1 1; 42 | 1 0 1 0 1; 43 | 1 0 1 0 1; 44 | 1 0 1 0 1]; 45 | 46 | goblue = [ zeros(1,21); 47 | zeros(5,6), g, zeros(5,1), o, zeros(5,6); 48 | zeros(1,21); 49 | zeros(5,1), b, zeros(5,1), l, zeros(5,1), u,zeros(5,1),e,zeros(5,1); 50 | zeros(1,21)]; 51 | 52 | goblue = flipud(goblue)'; 53 | 54 | um = [zeros(4,21); 55 | zeros(5),u,zeros(5,2),m,zeros(5); 56 | zeros(4,21)]; 57 | 58 | um = flipud(um)'; 59 | 60 | % um = 1:273; 61 | % um = mod(um(:),2); 62 | UM = find(um(:)==1); 63 | nUM = find(um(:)==0)'; 64 | GO = find(goblue(:)==1); 65 | nGO = find(goblue(:)==0)'; 66 | 67 | f_um = 'GF(And('; 68 | f_go = 'GF(And('; 69 | 70 | for i=1:length(UM) 71 | f_um = strcat(f_um, '[',num2str(UM(i)),',',num2str(floor(1000/length(UM))),'],'); 72 | end 73 | 74 | f_um = strcat(f_um, 'Neg([',num2str(nUM),',1])))'); 75 | 76 | for i=1:length(GO) 77 | f_go = strcat(f_go, '[',num2str(GO(i)),',',num2str(floor(1000/length(GO))),'],'); 78 | end 79 | 80 | f_go = strcat(f_go, 'Neg([',num2str(nGO),',1])))'); 81 | 82 | grid_size=[13,21]; 83 | grid = ones(grid_size); 84 | 85 | for i=1:numel(grid) 86 | if mod(i, grid_size(2))~=0 87 | adj(i, i+1) = 1; 88 | end 89 | if mod(i, grid_size(2))~=1 90 | adj(i, i-1) = 1; 91 | end 92 | if i<=grid_size(2)*(grid_size(1)-1); 93 | adj(i, i+grid_size(2)) = 1; 94 | end 95 | if i>grid_size(2); 96 | adj(i, i-grid_size(2)) = 1; 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /cLTL+_continuous/lib/FG.m: -------------------------------------------------------------------------------- 1 | % 2 | % ( RETURN_VARIABLE = FUNCTION_NAME(PARAMETER_1, PARAMETER_2, ETC) ) 3 | % 4 | % Author: YOUR FULL NAME AND CADE EMAIL ADDRESS 5 | % Date: THE CURRENT DATE 6 | % Partner: THE FULL NAME AND CADE EMAIL ADDRESS OF ANYONE YOU WORKED WITH 7 | % Course: Computer Science 1000 8 | % 9 | % Function Description: 10 | % 11 | % ( THIS FUNCTION DOES THE FOLLOWING (WRITE WHAT THE SPECIFIC GOAL OF THIS 12 | % SINGLE FUNCTION IS (_NOT_ WHAT THE GOAL OF THE ENTIRE PROGRAM IS). THIS 13 | % DESCRIPTION SHOULD BE IN HIGH LEVEL ENGLISH AND MAY CONTAIN A LIST OF 14 | % STEPS (E.G.,: 15 | % 1) DO THIS 16 | % 2) THEN DO THIS 17 | % 3) CALCULATE THAT 18 | % 4) RETURN THE FINAL VALUE AS RETURN_VARIABLE) 19 | % ) 20 | % 21 | % 22 | % Input Parameters: (LIST ALL THE PARAMETERS TO THE FUNCTION (OR SAY 23 | % NONE IF THERE ARE NO INPUT PARAMETERS) 24 | % 25 | % PARAMETER_1: Name, Type, Purpose 26 | % PARAMETER_2: Name, Type, Purpose 27 | % PARAMETER_3: Name, Type, Purpose 28 | % ETC 29 | % 30 | % Returned Value: (LIST THE DATA THAT IS _RETURNED_ BY THIS FUNCTION. 31 | % PLEASE NOTE THAT DATA PRINTED TO THE SCREEN IS _NOT_ 32 | % RETURNED. THERE IS A SPECIFIC DIFFERENCE BETWEEN 33 | % THINGS PRINTED TO THE SCREEN AND THOSE RETURNED ) 34 | % 35 | % Returned_Variable_1: Name, Type, Purpose 36 | % ETC 37 | % 38 | % Algorithm: (ADD ANY ADDITIONAL NOTES YOU HAVE ABOUT THE FUNCTION 39 | % HERE, INCLUDING HOW THE DATA IS PROCESSED OR WHAT 40 | % KIND OF DATA STRUCTURES YOU MAY USE) 41 | % 42 | % 43 | % Examples of Use: 44 | % 45 | % (SHOW HOW TO CALL THE FUNCTION) 46 | % 47 | 48 | 49 | function phi = FG(varargin) 50 | % Returns a polytope 51 | assert(nargin == 1, 'FG takes one variable'); 52 | % Returns a polytope 53 | if strcmp(varargin{1}.type, 'inner') || strcmp(varargin{1}.type, 'ap') 54 | phi = struct('type', 'inner', 'Op', 'FG', 'args', {varargin}, ... 55 | 'formula', strcat('FG(', varargin{1}.formula, ')')); 56 | else 57 | phi = struct('type', 'outer', 'Op', 'FG', 'args', {varargin}, ... 58 | 'formula', strcat('FG(', varargin{1}.formula, ')')); 59 | end -------------------------------------------------------------------------------- /cLTL+_continuous/lib/getTCPTau.m: -------------------------------------------------------------------------------- 1 | function [fTCP,phi] = getTCPTau(formula, k) 2 | 3 | global x Z zLoop ZLoop bigM tau; 4 | 5 | assert(strcmp(formula.Op, 'TCP'), 'tcp required'); 6 | 7 | % number of agents 8 | N = length(x); 9 | % time horizon 10 | h = size(x{1},2)-1; 11 | 12 | 13 | if k==1 || tau ==0 14 | [fTCP, r] = getLTL(formula.phi, k); 15 | else 16 | % robust tcp 17 | r = getZ(strcat('Robust( ', formula.formula, ')'), k, N); 18 | [fTCP, zTilde] = getLTL(formula.phi, k); 19 | 20 | for t = 1:tau 21 | if t+k <= h 22 | % If t+k <= h no need to loop around 23 | ztilde = getZ(formula.phi.formula, t+k, N); 24 | zTilde = [zTilde; ztilde]; 25 | else 26 | 27 | % ztilde_{k+t} (one for each agent) 28 | ztilde = getZ(strcat('~(',formula.phi.formula,')'),t+k,N); 29 | % Add to all set of all ztilde 30 | zTilde = [zTilde; ztilde]; 31 | % Or(z^{args{1},n}_{l+k+t-h-1},1-zLoop_{l}) 32 | ZOr = []; 33 | for l = 1:h-t 34 | % Loop around 35 | % z^{\args{1},n}_t for all t,n 36 | zPhi = getZ(formula.phi.formula, l+t+k-h-1, N); 37 | % Or(z^{args{1},n}_{l+k+t-h-1},1-zLoop_{l}) 38 | zOr = getZ(strcat('Or(',formula.phi.formula,... 39 | ', Neg(zLoop))[',num2str(k),',',num2str(t),']'),l,N); 40 | ZOr = [ZOr; zOr]; 41 | for n = 1:N 42 | fTCP = [fTCP, zOr(n)>=1-zLoop(l), zOr(n)>=zPhi(n),... 43 | zOr(n)<= 1-zLoop(l)+zPhi(n)]; 44 | end 45 | end 46 | % ztilde = And(zOr) 47 | for n = 1:N 48 | fTCP = [fTCP, ... 49 | repmat(ztilde(n),h-t,1) <= ZOr(:,n),... 50 | ztilde(n) >= 1-(h-t)+sum(ZOr(:,n))]; 51 | end 52 | 53 | end 54 | end 55 | 56 | % robustified version 57 | %r = getZ(strcat('Robust( ', formula, ')'), h, N); 58 | for n = 1:N 59 | fTCP = [fTCP, repmat(r(n),tau+1,1)<= zTilde(:,n), r(n) >= sum(zTilde(:,n))-tau]; 60 | end 61 | end 62 | 63 | phi = getZ(formula.formula,k,1); 64 | 65 | fTCP = [fTCP, sum(r) >= formula.m - (N+1)*(1-phi)]; 66 | fTCP = [fTCP, sum(r) <= formula.m + (N+1)*phi-1]; 67 | -------------------------------------------------------------------------------- /cLTL+/lib/tight_subplot.m: -------------------------------------------------------------------------------- 1 | function [ha, pos] = tight_subplot(Nh, Nw, gap, marg_h, marg_w) 2 | 3 | % tight_subplot creates "subplot" axes with adjustable gaps and margins 4 | % 5 | % [ha, pos] = tight_subplot(Nh, Nw, gap, marg_h, marg_w) 6 | % 7 | % in: Nh number of axes in hight (vertical direction) 8 | % Nw number of axes in width (horizontaldirection) 9 | % gap gaps between the axes in normalized units (0...1) 10 | % or [gap_h gap_w] for different gaps in height and width 11 | % marg_h margins in height in normalized units (0...1) 12 | % or [lower upper] for different lower and upper margins 13 | % marg_w margins in width in normalized units (0...1) 14 | % or [left right] for different left and right margins 15 | % 16 | % out: ha array of handles of the axes objects 17 | % starting from upper left corner, going row-wise as in 18 | % subplot 19 | % pos positions of the axes objects 20 | % 21 | % Example: ha = tight_subplot(3,2,[.01 .03],[.1 .01],[.01 .01]) 22 | % for ii = 1:6; axes(ha(ii)); plot(randn(10,ii)); end 23 | % set(ha(1:4),'XTickLabel',''); set(ha,'YTickLabel','') 24 | 25 | % Pekka Kumpulainen 21.5.2012 @tut.fi 26 | % Tampere University of Technology / Automation Science and Engineering 27 | 28 | 29 | if nargin<3; gap = .02; end 30 | if nargin<4 || isempty(marg_h); marg_h = .05; end 31 | if nargin<5; marg_w = .05; end 32 | 33 | if numel(gap)==1; 34 | gap = [gap gap]; 35 | end 36 | if numel(marg_w)==1; 37 | marg_w = [marg_w marg_w]; 38 | end 39 | if numel(marg_h)==1; 40 | marg_h = [marg_h marg_h]; 41 | end 42 | 43 | axh = (1-sum(marg_h)-(Nh-1)*gap(1))/Nh; 44 | axw = (1-sum(marg_w)-(Nw-1)*gap(2))/Nw; 45 | 46 | py = 1-marg_h(2)-axh; 47 | 48 | % ha = zeros(Nh*Nw,1); 49 | ii = 0; 50 | for ih = 1:Nh 51 | px = marg_w(1); 52 | 53 | for ix = 1:Nw 54 | ii = ii+1; 55 | ha(ii) = axes('Units','normalized', ... 56 | 'Position',[px py axw axh], ... 57 | 'XTickLabel','', ... 58 | 'YTickLabel',''); 59 | px = px+axw+gap(2); 60 | end 61 | py = py-axh-gap(1); 62 | end 63 | if nargout > 1 64 | pos = get(ha,'Position'); 65 | end 66 | ha = ha(:); 67 | -------------------------------------------------------------------------------- /cLTL+/lib/parseLTL.m: -------------------------------------------------------------------------------- 1 | function [Op,arguments] = parseLTL(formula) 2 | % Returns Operator and arguments 3 | if ~ischar(formula) 4 | Op = 'AndI'; 5 | arguments = {formula}; 6 | return 7 | end 8 | % Temporal operators 9 | Op_list = {'G','F','X','FG','GF','GG','FF','FGI','GFI','GGI','FFI'}; 10 | 11 | % Index of first '(' 12 | i = strfind(formula,'('); 13 | if isempty(i) 14 | Op = 'AndI'; 15 | arguments = {str2num(formula)}; 16 | return 17 | else 18 | i=i(1); 19 | end 20 | % Index of last ')' 21 | j = strfind(formula,')');j=j(end); 22 | 23 | % Big Operator 24 | Op = formula(1:i-1); 25 | 26 | % Now find arguments 27 | formula2 = formula(i+1:j-1); 28 | 29 | if any(ismember(Op_list,Op)) 30 | 31 | % index of first occurence '[' 32 | ap_index = strfind(formula2,'[');ap_index = ap_index(1); 33 | % index of first occurence '(' 34 | phi_index = strfind(formula2,'('); 35 | if isempty(phi_index) 36 | phi_index = inf; 37 | else 38 | phi_index = phi_index(1); 39 | end 40 | if ap_index < phi_index 41 | arguments= {str2num(formula2)}; 42 | else 43 | arguments = {formula2}; 44 | end 45 | return 46 | else 47 | arguments = {}; 48 | end 49 | 50 | lcount = 0; 51 | rcount = 0; 52 | 53 | while ~isempty(formula2) 54 | % index of first occurence '[' 55 | ap_index = strfind(formula2,'[');ap_index = ap_index(1); 56 | % index of first occurence '(' 57 | phi_index = strfind(formula2,'('); 58 | if isempty(phi_index) 59 | phi_index = inf; 60 | else 61 | phi_index = phi_index(1); 62 | end 63 | 64 | if ap_index < phi_index 65 | lbracket = '['; 66 | rbracket = ']'; 67 | else 68 | lbracket = '('; 69 | rbracket = ')'; 70 | end 71 | 72 | for i=1:length(formula2) 73 | if formula2(i) == lbracket 74 | lcount = lcount + 1; 75 | elseif formula2(i) == rbracket 76 | rcount = rcount + 1; 77 | if lcount == rcount 78 | if ap_index < phi_index 79 | arguments{end+1} = str2num(formula2(1:i)); 80 | else 81 | arguments{end+1} = formula2(1:i); 82 | end 83 | formula2 = formula2(i+2:end); 84 | break 85 | end 86 | end 87 | end 88 | end 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /cLTL+/lib/getTPTau.m: -------------------------------------------------------------------------------- 1 | function [fTP,phi] = getTPTau(formula, args, k) 2 | 3 | global W Wtotal Z bigM tau zLoop; 4 | 5 | if length(args) ~= 2 6 | disp('Missing argument'); 7 | asset(length(args)==2); 8 | end 9 | 10 | % number of agents 11 | N = length(W); 12 | % time horizon 13 | h = size(W{1},2)-1; 14 | 15 | r = getZ(strcat('Robust( ', formula, ')'), h, N); 16 | % All constraints created in this function 17 | fTP = []; 18 | % set of all ztilde in paper 19 | zTilde = []; 20 | if k==1 || tau ==0 21 | [fTP, zTP] = getLTL(args{1},k); 22 | fTP = [fTP, r(k,:) == zTP]; 23 | else 24 | [fTPk, ztilde] = getLTL(args{1},k); 25 | fTP = [fTP, fTPk]; 26 | zTilde = [zTilde; ztilde]; 27 | 28 | for t = 1:tau 29 | if t+k <= h 30 | % If t+k <= h no need to loop around 31 | ztilde = getZ(args{1},1,N); 32 | ztilde = ztilde(t+k,:); 33 | zTilde = [zTilde; ztilde]; 34 | else 35 | % Loop around 36 | % z^{\args{1},n}_t for all t,n 37 | zAll = getZ(args{1},0,0); 38 | % ztilde_{k+t} (one for each agent) 39 | ztilde = getZ(strcat('~(',num2str(args{1}),')[',num2str(k),',',num2str(t),']'),1,N); 40 | % Add to all set of all ztilde 41 | zTilde = [zTilde; ztilde]; 42 | % Or(z^{args{1},n}_{l+k+t-h-1},1-zLoop_{l}) 43 | zOr = getZ(strcat('Or(',num2str(args{1}),', Neg(zLoop))[',num2str(k),',',num2str(t),']'),h-t,N); 44 | for l = 1:h-t 45 | for n = 1:N 46 | fTP = [fTP, zOr(l,n)>=1-zLoop(l), zOr(l,n)>=zAll(l+t+k-h-1,n),... 47 | zOr(l,n)<= 1-zLoop(l)+zAll(l+t+k-h-1,n)]; 48 | end 49 | end 50 | % ztilde = And(zOr) 51 | for n = 1:N 52 | fTP = [fTP, ... 53 | repmat(ztilde(n),h-t,1) <= zOr(:,n),... 54 | ztilde(n) >= 1-(h-t)+sum(zOr(:,n))]; 55 | end 56 | 57 | end 58 | end 59 | 60 | % robustified version 61 | %r = getZ(strcat('Robust( ', formula, ')'), h, N); 62 | for n = 1:N 63 | fTP = [fTP, repmat(r(k,n),tau+1,1)<= zTilde(:,n), r(k,n) >= sum(zTilde(:,n))-tau]; 64 | end 65 | end 66 | 67 | phi = getZ(formula,h,1); 68 | phi = phi(k); 69 | 70 | fTP = [fTP, sum(r(k,:)) >= args{2} - bigM*(1-phi)]; 71 | fTP = [fTP, sum(r(k,:)) <= args{2} + bigM*phi-1]; 72 | -------------------------------------------------------------------------------- /cLTL/lib/parseLTL.m: -------------------------------------------------------------------------------- 1 | function [Op,arguments] = parseLTL(formula) 2 | % Returns Operator and arguments 3 | if ~ischar(formula) 4 | Op = 'And'; 5 | arguments = {formula}; 6 | return 7 | end 8 | 9 | %formula = formula(find(~isspace(formula))); 10 | 11 | % Temporal operators 12 | Op_list = {'G','F','X','FG','GF','GG','FF'}; 13 | 14 | % Index of first '(' 15 | i = strfind(formula,'('); 16 | if isempty(i) 17 | Op = 'And'; 18 | arguments = {str2num(formula)}; 19 | return 20 | else 21 | i=i(1); 22 | end 23 | % Index of last ')' 24 | j = strfind(formula,')');j=j(end); 25 | 26 | % Big Operator 27 | Op = formula(1:i-1); 28 | 29 | % Now find arguments 30 | formula2 = formula(i+1:j-1); 31 | 32 | if any(ismember(Op_list,Op)) 33 | 34 | % index of first occurence '[' 35 | ap_index = strfind(formula2,'[');ap_index = ap_index(1); 36 | % index of first occurence '(' 37 | phi_index = strfind(formula2,'('); 38 | if isempty(phi_index) 39 | phi_index = inf; 40 | else 41 | phi_index = phi_index(1); 42 | end 43 | if ap_index < phi_index 44 | arguments= {str2num(formula2)}; 45 | else 46 | arguments = {formula2}; 47 | end 48 | return 49 | else 50 | arguments = {}; 51 | end 52 | 53 | lcount = 0; 54 | rcount = 0; 55 | 56 | while ~isempty(formula2) 57 | % index of first occurence '[' 58 | ap_index = strfind(formula2,'[');ap_index = ap_index(1); 59 | % index of first occurence '(' 60 | phi_index = strfind(formula2,'('); 61 | if isempty(phi_index) 62 | phi_index = inf; 63 | else 64 | phi_index = phi_index(1); 65 | end 66 | 67 | if ap_index < phi_index 68 | lbracket = '['; 69 | rbracket = ']'; 70 | else 71 | lbracket = '('; 72 | rbracket = ')'; 73 | end 74 | 75 | for i=1:length(formula2) 76 | if formula2(i) == lbracket 77 | lcount = lcount + 1; 78 | elseif formula2(i) == rbracket 79 | rcount = rcount + 1; 80 | if lcount == rcount 81 | if ap_index < phi_index 82 | arguments{end+1} = str2num(formula2(1:i)); 83 | else 84 | arguments{end+1} = formula2(1:i); 85 | end 86 | formula2 = formula2(i+2:end); 87 | break 88 | end 89 | end 90 | end 91 | end 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /cLTL/examples/um_goblue2.m: -------------------------------------------------------------------------------- 1 | Obs = zeros(13*21,1); 2 | Obs=Obs(:)==1; 3 | 4 | g = [1 1 1 1; 5 | 1 0 0 0; 6 | 1 0 1 1; 7 | 1 0 0 1; 8 | 1 1 1 1]; 9 | 10 | o = [1 1 1 1; 11 | 1 0 0 1; 12 | 1 0 0 1; 13 | 1 0 0 1; 14 | 1 1 1 1]; 15 | 16 | b = [1 1 1 0; 17 | 1 0 0 1; 18 | 1 1 1 1; 19 | 1 0 0 1; 20 | 1 1 1 0]; 21 | 22 | l = [1 0 0 0; 23 | 1 0 0 0; 24 | 1 0 0 0; 25 | 1 0 0 0; 26 | 1 1 1 1]; 27 | 28 | u = [1 0 0 1; 29 | 1 0 0 1; 30 | 1 0 0 1; 31 | 1 0 0 1; 32 | 1 1 1 1]; 33 | 34 | e = [1 1 1 1; 35 | 1 0 0 0; 36 | 1 1 1 1; 37 | 1 0 0 0; 38 | 1 1 1 1]; 39 | 40 | m = [1 0 0 0 1; 41 | 1 1 1 1 1; 42 | 1 0 1 0 1; 43 | 1 0 1 0 1; 44 | 1 0 1 0 1]; 45 | 46 | goblue = [ zeros(1,21); 47 | zeros(5,6), g, zeros(5,1), o, zeros(5,6); 48 | zeros(1,21); 49 | zeros(5,1), b, zeros(5,1), l, zeros(5,1), u,zeros(5,1),e,zeros(5,1); 50 | zeros(1,21)]; 51 | 52 | goblue = flipud(goblue)'; 53 | 54 | um = [zeros(2,21); 55 | zeros(1,2) ones(1,17),zeros(1,2); 56 | zeros(1,2) 1 zeros(1,15) 1 zeros(1,2); 57 | zeros(5,3), ones(5,1) zeros(5,1),u,zeros(5,2),m,zeros(5,1) ones(5,1) zeros(5,3); 58 | zeros(1,2) 1 zeros(1,15) 1 zeros(1,2); 59 | zeros(1,2) ones(1,17),zeros(1,2); 60 | zeros(2,21)]; 61 | 62 | um = flipud(um)'; 63 | 64 | % um = 1:273; 65 | % um = mod(um(:),2); 66 | UM = find(um(:)==1); 67 | nUM = find(um(:)==0)'; 68 | GO = find(goblue(:)==1); 69 | nGO = find(goblue(:)==0)'; 70 | 71 | f_um = 'G(F(And('; 72 | f_go = 'G(F(And('; 73 | 74 | for i=1:length(UM) 75 | f_um = strcat(f_um, '[',num2str(UM(i)),',1],'); 76 | end 77 | 78 | f_um = strcat(f_um, 'Neg([',num2str(nUM),',1]))))'); 79 | 80 | for i=1:length(GO) 81 | f_go = strcat(f_go, '[',num2str(GO(i)),',1],'); 82 | end 83 | 84 | f_go = strcat(f_go, 'Neg([',num2str(nGO),',1]))))'); 85 | 86 | grid_size=[13,21]; 87 | mygrid = ones(grid_size); 88 | 89 | for i=1:numel(mygrid) 90 | if mod(i, grid_size(2))~=0 91 | adj(i, i+1) = 1; 92 | end 93 | if mod(i, grid_size(2))~=1 94 | adj(i, i-1) = 1; 95 | end 96 | if i<=grid_size(2)*(grid_size(1)-1); 97 | adj(i, i+grid_size(2)) = 1; 98 | end 99 | if i>grid_size(2); 100 | adj(i, i-grid_size(2)) = 1; 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /cLTL+_continuous/examples/example_3D.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | close all; 3 | clc; 4 | addpath(genpath('../')) 5 | 6 | global x u Z zLoop ZLoop bigM epsilon; 7 | bigM = 1000; 8 | % number of robots 9 | N = 5; 10 | 11 | % Time horizon 12 | h = 40; 13 | 14 | % Initial condition 15 | X0 =[0.5*ones(1,N); 16 | 0.5:9/(N-1):9.5; 17 | zeros(1,N)]; 18 | 19 | % Collision avoidence flag, 20 | % 1=collision avoidence enforced, 0=no collision avoidence 21 | CA_flag = 0; 22 | 23 | % system parameters 24 | A = eye(3); 25 | B = eye(3); 26 | 27 | % state constraints 28 | Px = Polytope([eye(3); -eye(3)], [10; 10; 10; 10; 10; 0]); 29 | 30 | % input constraints 31 | Pu = Polytope([eye(3); -eye(3)], [1; 1; 1; 1; 1; 1]); 32 | 33 | % atomic propositions 34 | ap_cell = {}; 35 | 36 | % ap1 37 | [ap1, ap_cell] = AP([eye(3); -eye(3)],[-7; 1; 5; 9; 1; -3], ap_cell); 38 | [ap2, ap_cell] = AP([eye(3); -eye(3)],[ 1; 1; 5; 1; 1; -3], ap_cell); 39 | [ap3, ap_cell] = AP([eye(3); -eye(3)],[ 9; 1; 5; -7; 1; -3], ap_cell); 40 | 41 | 42 | % Obstacles 43 | Obs1 = Polytope([eye(3); -eye(3)], [-4; 7; 7; 6; 7; -3]); 44 | Obs2 = Polytope([eye(3); -eye(3)], [ 6; 7; 7; -4; 7; -3]); 45 | Obs = [Obs1, Obs2]; 46 | %%%%%%%%%%% 47 | 48 | % visualization 49 | if 1 50 | figure(1);clf;hold on; 51 | plot(Polyhedron(Px.A,Px.b), 'color', 'white', 'alpha', 0.1); 52 | plot(Polyhedron(ap1.A,ap1.b), 'color', 'green', 'alpha', 0.1); 53 | plot(Polyhedron(ap2.A,ap2.b), 'color', 'green', 'alpha', 0.1); 54 | plot(Polyhedron(ap3.A,ap3.b), 'color', 'green', 'alpha', 0.1); 55 | plot(Polyhedron(Obs(1).A,Obs(1).b), 'color', 'black', 'alpha', 0.1); 56 | plot(Polyhedron(Obs(2).A,Obs(2).b), 'color', 'black', 'alpha', 0.1); 57 | hold off 58 | end 59 | % Specs 60 | 61 | % surveil two regions by leaving them once in a while 62 | f1 = GF(TCP(ap1, 5)); 63 | f2 = GF(TCP(ap2, 5)); 64 | f3 = GF(TCP(ap3, 5)); 65 | %f = And(f1, f2, f3, f4, f5, f7); 66 | f = And(f1,f2, f3); 67 | 68 | 69 | 70 | [x, u, Z, sol, zLoop] = main_template(f, A, B, Px, Pu, h, X0, Obs, CA_flag); 71 | 72 | loopBegins = find(zLoop==1); 73 | % time = clock; 74 | % filename = ['./data/GOBLUE_' ... 75 | % num2str(time(1)) '_'... % Returns year as character 76 | % num2str(time(2)) '_'... % Returns month as character 77 | % num2str(time(3)) '_'... % Returns day as char 78 | % num2str(time(4)) 'h'... % returns hour as char.. 79 | % num2str(time(5)) 'm'... %returns minute as char 80 | % ]; 81 | % 82 | % save(filename,'W','W','Wtotal','Wtotal','ZLoop','ZLoop','A','A','mygrid','mygrid', 'Z', 'Z','sol','sol'); 83 | 84 | 85 | 86 | plot_continuous_3D(x,Z); 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /cLTL+_continuous/examples/example_3D_double_integrator.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | clc; 4 | 5 | addpath(genpath('../')) 6 | 7 | global x u Z zLoop ZLoop bigM epsilon; 8 | bigM = 1000; 9 | % number of robots 10 | N = 5; 11 | 12 | % Time horizon 13 | h = 40; 14 | 15 | % Initial condition 16 | X0 =[3*ones(1,N); 17 | 0.5:9/(N-1):9.5; 18 | zeros(4,N)]; 19 | 20 | % Collision avoidence flag, 21 | % 1=collision avoidence enforced, 0=no collision avoidence 22 | CA_flag = 0; 23 | 24 | % system parameters 25 | A = [eye(3) eye(3); zeros(3,6)]; 26 | B = [zeros(3); eye(3)]; 27 | 28 | % state constraints 29 | Px = Polytope([eye(3) zeros(3); -eye(3) zeros(3); zeros(3) eye(3); zeros(3) -eye(3)], [10; 10; 10; 10; 10; 0; 1; 1; 1; 1; 1; 1]); 30 | 31 | % input constraints 32 | Pu = Polytope([eye(3); -eye(3)], [1; 1; 1; 1; 1; 1]); 33 | 34 | % atomic propositions 35 | ap_cell = {}; 36 | 37 | % ap1 38 | [ap1, ap_cell] = AP([eye(3) zeros(3); -eye(3) zeros(3)],[-7; 1; 5; 9; 1; -3], ap_cell); 39 | [ap2, ap_cell] = AP([eye(3) zeros(3); -eye(3) zeros(3)],[ 1; 1; 5; 1; 1; -3], ap_cell); 40 | [ap3, ap_cell] = AP([eye(3) zeros(3); -eye(3) zeros(3)],[ 9; 1; 5; -7; 1; -3], ap_cell); 41 | 42 | 43 | % Obstacles 44 | Obs1 = Polytope([eye(3) zeros(3); -eye(3) zeros(3)], [-4; 7; 7; 6; 7; -3]); 45 | Obs2 = Polytope([eye(3) zeros(3); -eye(3) zeros(3)], [ 6; 7; 7; -4; 7; -3]); 46 | Obs = [Obs1, Obs2]; 47 | %%%%%%%%%%% 48 | 49 | % visualization 50 | if 1 51 | figure(1);clf;hold on; 52 | plot(Polyhedron(Px.A,Px.b).projection([1 2 3]), 'color', 'white', 'alpha', 0.1); 53 | plot(Polyhedron(ap1.A,ap1.b).projection([1 2 3]), 'color', 'green', 'alpha', 0.1); 54 | plot(Polyhedron(ap2.A,ap2.b).projection([1 2 3]), 'color', 'green', 'alpha', 0.1); 55 | plot(Polyhedron(ap3.A,ap3.b).projection([1 2 3]), 'color', 'green', 'alpha', 0.1); 56 | plot(Polyhedron(Obs(1).A,Obs(1).b).projection([1 2 3]), 'color', 'black', 'alpha', 0.1); 57 | plot(Polyhedron(Obs(2).A,Obs(2).b).projection([1 2 3]), 'color', 'black', 'alpha', 0.1); 58 | hold off 59 | end 60 | % Specs 61 | 62 | % surveil two regions by leaving them once in a while 63 | f1 = GF(TCP(ap1, 5)); 64 | f2 = GF(TCP(ap2, 5)); 65 | f3 = GF(TCP(ap3, 5)); 66 | %f = And(f1, f2, f3, f4, f5, f7); 67 | f = And(f1,f2, f3); 68 | 69 | 70 | 71 | [x, u, Z, sol, zLoop] = main_template(f, A, B, Px, Pu, h, X0, Obs, CA_flag); 72 | 73 | loopBegins = find(zLoop==1); 74 | % time = clock; 75 | % filename = ['./data/GOBLUE_' ... 76 | % num2str(time(1)) '_'... % Returns year as character 77 | % num2str(time(2)) '_'... % Returns month as character 78 | % num2str(time(3)) '_'... % Returns day as char 79 | % num2str(time(4)) 'h'... % returns hour as char.. 80 | % num2str(time(5)) 'm'... %returns minute as char 81 | % ]; 82 | % 83 | % save(filename,'W','W','Wtotal','Wtotal','ZLoop','ZLoop','A','A','mygrid','mygrid', 'Z', 'Z','sol','sol'); 84 | 85 | 86 | 87 | plot_continuous_3D(x,Z); 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /cLTL+/lib/getU.m: -------------------------------------------------------------------------------- 1 | function [fU,phiU] = getU(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=2 7 | disp('U(until) takes a two argument') 8 | assert(length(args)==2) 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi1 15 | [fU,phi1] = getLTL(args{1},k); 16 | 17 | % phi2 18 | [f2,phi2] = getLTL(args{2},k); 19 | fU = [fU, f2]; 20 | 21 | % [[phi1 U phi2]]_i+1 22 | [fU2,phiU2] = getU(formula, args, k+1); 23 | fU = [fU, fU2]; 24 | 25 | % And(phi1_k, [[phi1 U phi2]]_k+1) 26 | formulaAnd = strcat('And(', ... 27 | num2str(args{1}), '[',num2str(k),'],', ... 28 | formula, '[',num2str(k+1),'])'); 29 | zAnd = getZ(formulaAnd,-1); 30 | fU = [fU, zAnd<=phi1, zAnd<=phiU2, zAnd>=phiU2+phi1-1]; 31 | 32 | % phiU_k = Or(phi2_k,zAnd) 33 | phiU = getZ(formula,k); 34 | fU = [fU, phiU>=phi2, phiU>=zAnd, phiU<=zAnd+phi2]; 35 | 36 | else 37 | 38 | % phi1 39 | [fU,phi1] = getLTL(args{1},k); 40 | 41 | % phi2 42 | [f2,phi2] = getLTL(args{2},k); 43 | fU = [fU, f2]; 44 | 45 | % za = << phi1 U phi2 >> 46 | za = []; 47 | 48 | % zb_i = And(zLoop_i,za_i) 49 | zb = []; 50 | 51 | % bigOr in (15) 52 | formulaOr = 'Or( '; 53 | for i=1:k 54 | % za_i = << phi1 U phi2 >>_i 55 | za_i = getZ(strcat('~',formula),i); 56 | za = [za;za_i]; 57 | 58 | % zb_i = And(zLoop_i,za_i) 59 | formulaAnd = strcat('And(', ... 60 | 'zLoop', '[',num2str(i),'],', ... 61 | strcat('~',formula), '[',num2str(i),'])'); 62 | zb_i = getZ(formulaAnd,-1); 63 | zb = [zb;zb_i]; 64 | fU = [fU, zb(i)<=za(i), zb(i)<=zLoop(i), zb(i)>=za(i)+zLoop(i)-1]; 65 | 66 | formulaOr = strcat(formulaOr, formulaAnd, ','); 67 | 68 | end 69 | formulaOr = strcat(formulaOr,')'); 70 | % bigOr, see eq (15) in paper 71 | zOr = getZ(formulaOr,-1); 72 | fU = [fU, zOr<=sum(zb), repmat(zOr,k,1)>=zb]; 73 | 74 | % second term in paranthesis (15) 75 | formulaAnd = strcat('And( ', ... 76 | num2str(args{1}), '[',num2str(k),'], ', ... 77 | formulaOr, '[-1]'); 78 | zAnd = getZ(formulaAnd,-1); 79 | fU = [fU, zAnd<=zOr, zAnd<=phi1, zAnd>=phi1+zOr-1]; 80 | 81 | % finally (15) 82 | phiU = getZ(formula,k); 83 | fU = [fU, phiU<=zAnd+phi2, phiU>=phi2, phiU>=zAnd]; 84 | 85 | % aux variables see (16) 86 | for i=1:k-1 87 | % second term in paranthesis (16) 88 | formulaAnd = strcat('And( ', ... 89 | num2str(args{1}), '[',num2str(i),'], ', ... 90 | strcat('~',formula), '[', num2str(i+1),'])'); 91 | 92 | zAnd = getZ(formulaAnd,-1); 93 | phi1_i = getZ(args{1},i); 94 | fU = [fU, zAnd<=za(i+1), zAnd<=phi1_i, zAnd>=za(i+1)+phi1_i-1]; 95 | 96 | phi2_i = getZ(args{2},i); 97 | fU = [fU, za(i)<=zAnd+phi2_i, za(i)>=phi2_i, za(i)>=zAnd]; 98 | 99 | end 100 | 101 | % Last step 102 | phi2_k = getZ(args{2},k); 103 | fU = [fU, za(k)==phi2_k]; 104 | 105 | end 106 | -------------------------------------------------------------------------------- /cLTL/lib/getU.m: -------------------------------------------------------------------------------- 1 | function [fU,phiU] = getU(formula, args, k) 2 | 3 | global Mw Z zLoop ZLoop bigM epsilon; 4 | 5 | 6 | if length(args)~=2 7 | disp('U(until) takes a two argument') 8 | assert(length(args)==2) 9 | end 10 | 11 | 12 | if k < length(Mw) 13 | 14 | % phi1 15 | [fU,phi1] = getLTL(args{1},k); 16 | 17 | % phi2 18 | [f2,phi2] = getLTL(args{2},k); 19 | fU = [fU, f2]; 20 | 21 | % [[phi1 U phi2]]_i+1 22 | [fU2,phiU2] = getU(formula, args, k+1); 23 | fU = [fU, fU2]; 24 | 25 | % And(phi1_k, [[phi1 U phi2]]_k+1) 26 | formulaAnd = strcat('And(', ... 27 | num2str(args{1}), '[',num2str(k),'],', ... 28 | formula, '[',num2str(k+1),'])'); 29 | zAnd = getZ(formulaAnd,-1); 30 | fU = [fU, zAnd<=phi1, zAnd<=phiU2, zAnd>=phiU2+phi1-1]; 31 | 32 | % phiU_k = Or(phi2_k,zAnd) 33 | phiU = getZ(formula,k); 34 | fU = [fU, phiU>=phi2, phiU>=zAnd, phiU<=zAnd+phi2]; 35 | 36 | else 37 | 38 | % phi1 39 | [fU,phi1] = getLTL(args{1},k); 40 | 41 | % phi2 42 | [f2,phi2] = getLTL(args{2},k); 43 | fU = [fU, f2]; 44 | 45 | % za = << phi1 U phi2 >> 46 | za = []; 47 | 48 | % zb_i = And(zLoop_i,za_i) 49 | zb = []; 50 | 51 | % bigOr in (15) 52 | formulaOr = 'Or( '; 53 | for i=1:k 54 | % za_i = << phi1 U phi2 >>_i 55 | za_i = getZ(strcat('~',formula),i); 56 | za = [za;za_i]; 57 | 58 | % zb_i = And(zLoop_i,za_i) 59 | formulaAnd = strcat('And(', ... 60 | 'zLoop', '[',num2str(i),'],', ... 61 | strcat('~',formula), '[',num2str(i),'])'); 62 | zb_i = getZ(formulaAnd,-1); 63 | zb = [zb;zb_i]; 64 | fU = [fU, zb(i)<=za(i), zb(i)<=zLoop(i), zb(i)>=za(i)+zLoop(i)-1]; 65 | 66 | formulaOr = strcat(formulaOr, formulaAnd, ','); 67 | 68 | end 69 | formulaOr = strcat(formulaOr,')'); 70 | % bigOr, see eq (15) in paper 71 | zOr = getZ(formulaOr,-1); 72 | fU = [fU, zOr<=sum(zb), repmat(zOr,k,1)>=zb]; 73 | 74 | % second term in paranthesis (15) 75 | formulaAnd = strcat('And( ', ... 76 | num2str(args{1}), '[',num2str(k),'], ', ... 77 | formulaOr, '[-1]'); 78 | zAnd = getZ(formulaAnd,-1); 79 | fU = [fU, zAnd<=zOr, zAnd<=phi1, zAnd>=phi1+zOr-1]; 80 | 81 | % finally (15) 82 | phiU = getZ(formula,k); 83 | fU = [fU, phiU<=zAnd+phi2, phiU>=phi2, phiU>=zAnd]; 84 | 85 | % aux variables see (16) 86 | for i=1:k-1 87 | % second term in paranthesis (16) 88 | formulaAnd = strcat('And( ', ... 89 | num2str(args{1}), '[',num2str(i),'], ', ... 90 | strcat('~',formula), '[', num2str(i+1),'])'); 91 | 92 | zAnd = getZ(formulaAnd,-1); 93 | phi1_i = getZ(args{1},i); 94 | fU = [fU, zAnd<=za(i+1), zAnd<=phi1_i, zAnd>=za(i+1)+phi1_i-1]; 95 | 96 | phi2_i = getZ(args{2},i); 97 | fU = [fU, za(i)<=zAnd+phi2_i, za(i)>=phi2_i, za(i)>=zAnd]; 98 | 99 | end 100 | 101 | % Last step 102 | phi2_k = getZ(args{2},k); 103 | fU = [fU, za(k)==phi2_k]; 104 | 105 | end 106 | -------------------------------------------------------------------------------- /cLTL/examples/earthquake.m: -------------------------------------------------------------------------------- 1 | clear all;close all;clc; 2 | 3 | addpath(genpath('.')) 4 | 5 | global Mw Z zLoop ZLoop bigM epsilon; 6 | 7 | % define a gridworld 8 | grid_size = [10, 10]; 9 | mygrid = ones(grid_size); 10 | 11 | mygrid(1:5, 1:5) = 0.2; 12 | mygrid(1:5, 6:10) = 0.8; 13 | 14 | % narrow passage 15 | mygrid(3, 4:7) = 0.5; 16 | mygrid([1:2,4:5], 5:6) = 0; 17 | mygrid([2,4], [4,7]) = 0; 18 | mygrid([7,8], [7,8]) = 0; 19 | 20 | %%%%%%%%%%% 21 | 22 | % visualization 23 | vis = zeros(size(mygrid)+2); 24 | vis(2:end-1,2:end-1)=mygrid; 25 | %imshow(kron(vis,ones(25,25))) 26 | 27 | state_labels = mygrid(:); 28 | 29 | Pass = find(state_labels(:)==0.5)'; 30 | pass = num2str(Pass); 31 | Room1 = find(state_labels(:)==0.2)'; 32 | room1 = num2str(Room1); 33 | Room2 = find(state_labels(:)==0.8)'; 34 | room2 = num2str(Room2); 35 | Room3 = find(state_labels(:)==1)'; 36 | room3 = num2str(Room3); 37 | 38 | pass_ends = [23,73,Pass]; 39 | 40 | % spec is the conjunction of the following 41 | Obs = state_labels(:)==0; %avoid obstacles 42 | f1 = strcat('G(Neg([',pass,', 2]))'); %not too many robots in narrow passage way 43 | 44 | % surveil two regions by leaving them ones in a while 45 | f2 = strcat('GF([',num2str([Room1, 5]),'])'); % GF([0.2 labels, >=5]) 46 | f3 = strcat('GF([',num2str([Room2, 5]),'])'); % GF([0.8 labels, >=5]) 47 | f4 = strcat('GF(Neg([',num2str([Room1, 1]),']))'); % GF([0.2 labels, <=0]) 48 | f5 = strcat('GF(Neg([',num2str([Room2, 1]),']))'); % GF([0.8 labels, <=0]) 49 | f6 = strcat('FG(Neg([',num2str([Room3, 2]),']))'); % FG([1 labels, <=1]) at steady state at most one robot is left in the lower part 50 | f7 = strcat('U(Neg([',num2str([pass_ends,1]),']),And([',num2str([72 74 1]),'],[',num2str([22 24 1]),']))'); 51 | 52 | %adj = zeros(prod(size(grid))); 53 | adj = eye(numel(mygrid)); %allow self-transition 54 | 55 | for i=1:length(state_labels); 56 | if mod(i, grid_size(1))~=0 57 | adj(i, i+1) = 1; 58 | end 59 | if mod(i, grid_size(1))~=1 60 | adj(i, i-1) = 1; 61 | end 62 | if i<=grid_size(1)*(grid_size(2)-1); 63 | adj(i, i+grid_size(1)) = 1; 64 | end 65 | if i>grid_size(1); 66 | adj(i, i-grid_size(1)) = 1; 67 | end 68 | end 69 | 70 | % Total specs 71 | f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,',',f6,',',f7,')'); 72 | 73 | % Adjacency matrix 74 | A = adj; 75 | 76 | % Time horizon 77 | h = 40; 78 | 79 | % Random initial condition 80 | n = size(A,1); 81 | W0 = [ones(10,1); zeros(n-10,1)]; 82 | 83 | 84 | % robustness number 85 | epsilon = 0; 86 | 87 | % Collision avoidence flag, 88 | % 1=collision avoidence enforced, 0=no collision avoidence 89 | CA_flag = 1; 90 | 91 | [Mw, WT, Z, ~] = cLTL_synth(f,A,h,W0,Obs,CA_flag); 92 | 93 | 94 | time = clock; 95 | filename = ['./data/earthquake' ... 96 | num2str(time(1)) '_'... % Returns year as character 97 | num2str(time(2)) '_'... % Returns month as character 98 | num2str(time(3)) '_'... % Returns day as char 99 | num2str(time(4)) 'h'... % returns hour as char.. 100 | num2str(time(5)) 'm'... %returns minute as char 101 | ]; 102 | 103 | save(filename); 104 | 105 | grid_plot(filename); 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /cLTL+/lib/main_template.m: -------------------------------------------------------------------------------- 1 | function [W, Wtotal, Z, mytimes, sol] = main_template(formula,A,h,W0,Obs,CA_flag) 2 | time = clock; 3 | disp([ 'Started at ', ... 4 | num2str(time(4)), ':',... % Returns year as character 5 | num2str(time(5)), ' on ',... % Returns month as character 6 | num2str(time(3)), '/',... % Returns day as char 7 | num2str(time(2)), '/',... % returns hour as char.. 8 | num2str(time(1))]); 9 | 10 | if h==0 11 | disp('Trajectory must be greater than 0'); 12 | assert(h>0); 13 | end 14 | 15 | tos = tic; 16 | 17 | global W Wtotal Z zLoop ZLoop bigM epsilon tau; 18 | 19 | % Number of agents 20 | N = sum(W0); 21 | 22 | % bigM notation 23 | bigM = N+1; 24 | 25 | % number of states 26 | I = length(A); 27 | 28 | % Control input 29 | W = binvar(repmat(I,1,N),repmat(h+1,1,N),'full'); 30 | 31 | if N == 1 32 | W = {W}; 33 | end 34 | 35 | 36 | % Initial state constraint 37 | %disp('Creating other constraints...') 38 | fInit = getInit(W0); 39 | 40 | % Obstacle Avoidence Constraint 41 | fObs = getObs(Obs); 42 | 43 | % System dynamics constraint 44 | fDyn = getDyn(A,CA_flag); 45 | 46 | % Loop constraint 47 | fLoop= getLoop(); 48 | 49 | % Collision Avoidence Constraint 50 | fCol = getCol(); 51 | 52 | % Timing of other constraints 53 | toe = toc(tos); 54 | disp([' Done with other constraints (',num2str(toe),') seconds']) 55 | 56 | % LTL constraint 57 | %disp('Creating LTL constraints...') 58 | tltls=tic; 59 | Z = {}; 60 | [fLTL,phi] = getLTL(formula,1); 61 | tltle=toc(tltls); 62 | disp([' Done with LTL constraints (',num2str(tltle),') seconds']) 63 | 64 | % All Constraints 65 | %F = [fInit, fDyn, fLoop, fObs, fLTL, phi==1]; 66 | F = [fInit, fDyn, fLoop, fLTL, phi==1, fCol]; 67 | 68 | % if CA_flag 69 | % F = [F fCol]; 70 | % end 71 | disp([' Total number of optimization variables : ', num2str(length(depends(F)))]); 72 | 73 | % Solve the optimization problem 74 | %H = -epsilon; % maximize epsilon 75 | options = sdpsettings('verbose',8,'solver','gurobi'); 76 | options.gurobi.Heuristics = 0.8; 77 | options.gurobi.MIPFocus = 1; 78 | disp('Solving MILP...') 79 | tms=tic; 80 | sol = optimize(F,[],options); 81 | tme=toc(tms); 82 | disp([' Solved (',num2str(sol.solvertime),') seconds']) 83 | 84 | 85 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | % Assign values 87 | 88 | 89 | if sol.problem == 0 90 | % Extract and display value 91 | disp('## Feasible solution exists ##') 92 | % Now get the values 93 | 94 | for n = 1:N 95 | W{n} = value(W{n}); 96 | end 97 | for i=1:length(Z) 98 | Z{i}{1} = value(Z{i}{1}); 99 | if ~isnan(Z{i}{1}) 100 | 1; 101 | else 102 | disp(['#### Careful!! {',num2str(i), '} ', num2str(Z{i}{2}), ' is NaN']); 103 | end 104 | end 105 | Wtotal = value(Wtotal); 106 | % Loop 107 | zLoop = value(zLoop); 108 | ZLoop = value(ZLoop); 109 | LoopBegins = find(zLoop(:)==1); 110 | else 111 | W=0;W=0;WT=0;ZLoop=0;zLoop=0;LoopBegins=0; 112 | sol.info 113 | yalmiperror(sol.problem) 114 | assert(0,'## No feasible solutions found! ##'); 115 | end 116 | 117 | ttotal = toc(tos); 118 | mytimes = [ttotal,toe, tltle, sol.solvertime]; 119 | yalmip('clear') -------------------------------------------------------------------------------- /cLTL/lib/cLTL_synth.m: -------------------------------------------------------------------------------- 1 | function [Mw, WT, Z, mytimes] = cLTL_synth(formula,A,h,W0,Obs,CA_flag) 2 | 3 | tos = tic; 4 | 5 | global Mw Z zLoop ZLoop bigM epsilon; 6 | 7 | % bigM notation 8 | bigM = sum(W0)+1; 9 | 10 | % number of states 11 | I = length(A); 12 | 13 | % Indices of 0's of adjacency matrix 14 | A0 = A(:)==0; 15 | A1 = A(:)==1; 16 | % Control input 17 | Mw = intvar(repmat(I,1,h),repmat(I,1,h),'full'); 18 | 19 | if h==0 20 | disp('Trajectory must be greater than 0'); 21 | assert(h>0); 22 | elseif h==1 23 | Mw = {Mw}; 24 | end 25 | 26 | for i = 1:h 27 | Mw{i}(A0) = 0; 28 | end 29 | % Initial state constraint 30 | disp('Creating other constraints...') 31 | fInit = [Mw{1}*ones(I,1)==W0, Mw{1}(A1)>=0]; 32 | 33 | % System dynamics constraint 34 | fDyn = getDyn(A,h); 35 | 36 | % Loop constraint 37 | fLoop= getLoop(h); 38 | 39 | % Collision Avoidence Constraint 40 | fCol = getCol(); 41 | 42 | % Obstacle Avoidence Constraint 43 | fObs = getObs(Obs,h); 44 | 45 | % Timing of other constraints 46 | toe = toc(tos); 47 | disp([' Done with other constraints (',num2str(toe),') seconds']) 48 | 49 | % LTL constraint 50 | disp('Creating LTL constraints...') 51 | tltls=tic; 52 | Z = {}; 53 | [fLTL,phi] = getLTL(formula,1); 54 | tltle=toc(tltls); 55 | disp([' Done with LTL constraints (',num2str(tltle),') seconds']) 56 | disp([' Number of LTL variables : ', num2str(length(Z))]); 57 | 58 | % All Constraints 59 | F = [fInit, fDyn, fLoop, fLTL, fObs, phi==1]; 60 | 61 | if CA_flag 62 | F = [F fCol]; 63 | end 64 | disp([' Number of constraints : ', num2str(length(F))]); 65 | disp([' Total number of optimization variables : ', num2str(length(depends(F)))]); 66 | 67 | % Solve the optimization problem 68 | %H = -epsilon; % maximize epsilon 69 | options = sdpsettings('verbose',0,'solver','gurobi'); 70 | disp('Solving MILP...') 71 | tms=tic; 72 | sol = optimize(F,[],options); 73 | tme=toc(tms); 74 | disp([' Solved (',num2str(tme),') seconds']) 75 | 76 | 77 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 | % Assign values 79 | 80 | 81 | if sol.problem == 0 82 | % Extract and display value 83 | disp('## Feasible solution exists ##') 84 | % Now get the values 85 | MW = reshape([Mw{:}],I*I*h,1); 86 | vMW = value(MW); 87 | Mw=cell(h,1); 88 | % Trajectory 89 | W = cell(h+1,1); 90 | WT = zeros(I,h+1); 91 | % % epsilon 92 | % epsilon = value(epsilon); 93 | for i = 1:h 94 | Mwi = reshape(vMW((i-1)*I*I+1:i*I*I),I,I); 95 | Mw{i}=Mwi; 96 | W{i} = Mwi * ones(I,1); 97 | WT(:,i) = Mwi * ones(I,1); 98 | end 99 | W{h+1} = transpose(ones(1,I)*Mwi); 100 | WT(:,h+1) = ones(1,I)*Mwi; 101 | 102 | % Loop 103 | zLoop = value(zLoop); 104 | ZLoop = value(ZLoop); 105 | LoopBegins = find(zLoop(:)==1); 106 | else 107 | W=0;Mw=0;WT=0;ZLoop=0;zLoop=0;LoopBegins=0; 108 | display('## No feasible solutions found! ##'); 109 | %sol.info 110 | % yalmiperror(sol.problem) 111 | end 112 | 113 | zz = []; 114 | for i=1:length(Z) 115 | Z{i}{1} = value(Z{i}{1}); 116 | if isnan(Z{i}{1}) 117 | disp(['#### Careful!! ', num2str(Z{i}{2}), ' is NaN']); 118 | end 119 | zz = [zz;Z{i}{1}]; 120 | end 121 | 122 | ttotal = toc(tos); 123 | mytimes = [ttotal,toe, tltle, tme]; 124 | yalmip('clear') -------------------------------------------------------------------------------- /cLTL+_continuous/examples/emergency_example.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | close all; 3 | clc; 4 | addpath(genpath('../')) 5 | 6 | global x u Z zLoop ZLoop bigM tau; 7 | bigM = 100; 8 | tau = 0; 9 | % number of robots 10 | N = 10; 11 | 12 | % Time horizon 13 | h = 50; 14 | 15 | % Initial condition 16 | X0 =[0.5*ones(1,N); 17 | 0.5:1:9.5]; 18 | 19 | % Collision avoidence flag, 20 | % 1=collision avoidence enforced, 0=no collision avoidence 21 | CA_flag = 1; 22 | 23 | % system parameters 24 | A = eye(2); 25 | B = eye(2); 26 | 27 | % state constraints 28 | Px = Polytope([eye(2); -eye(2)], [10; 10; 0; 0]); 29 | 30 | % input constraints 31 | Pu = Polytope([eye(2); -eye(2)], [1; 1; 1; 1]); 32 | 33 | % atomic propositions 34 | ap_cell = {}; 35 | 36 | % narrow passage 37 | [ap_narrow, ap_cell] = AP([eye(2); -eye(2)],[7; 8; -3; -7], ap_cell); 38 | 39 | % Region A 40 | [ap_A, ap_cell] = AP([eye(2); -eye(2)],[3; 10; 0; -5], ap_cell); 41 | 42 | % Region C 43 | [ap_C, ap_cell] = AP([eye(2); -eye(2)],[10; 10; -7; -5], ap_cell); 44 | 45 | % Region E 46 | [ap_E, ap_cell] = AP([eye(2); -eye(2)],[10; 5; 0; 0], ap_cell); 47 | 48 | % Region F 49 | [ap_F1, ap_cell] = AP([eye(2); -eye(2)],[2; 2; 0; 0], ap_cell); 50 | [ap_F2, ap_cell] = AP([eye(2); -eye(2)],[2; 10; 0; -8], ap_cell); 51 | [ap_F3, ap_cell] = AP([eye(2); -eye(2)],[10; 10; -8; -8], ap_cell); 52 | 53 | 54 | % Obstacles 55 | Obs1 = Polytope([eye(2); -eye(2)], [8; 3; -6; -1]); 56 | Obs2 = Polytope([eye(2); -eye(2)], [7; 10; -3; -8]); 57 | Obs3 = Polytope([eye(2); -eye(2)], [7; 7; -3; -5]); 58 | Obs = [Obs1, Obs2, Obs3]; 59 | %%%%%%%%%%% 60 | 61 | % visualization 62 | show_env = 0; 63 | if show_env 64 | figure(1);clf;hold on; 65 | plot(Polyhedron(Px.A,Px.b), 'color', 'white'); 66 | plot(Polyhedron(ap_A.A,ap_A.b), 'color', 'gray'); 67 | plot(Polyhedron(ap_C.A,ap_C.b), 'color', 'gray'); 68 | plot(Polyhedron(ap_narrow.A,ap_narrow.b), 'color', 'gray'); 69 | plot(Polyhedron(Obs(1).A,Obs(1).b), 'color', 'black'); 70 | plot(Polyhedron(Obs(2).A,Obs(2).b), 'color', 'black'); 71 | plot(Polyhedron(Obs(3).A,Obs(3).b), 'color', 'black'); 72 | plot(Polyhedron(ap_F1.A,ap_F1.b), 'color', 'gray'); 73 | hold off 74 | end 75 | 76 | 77 | % Specs 78 | %not too many robots in narrow passage way 79 | f1 = GG(Neg(TCP(ap_narrow,3))); 80 | 81 | % surveil two regions by leaving them once in a while 82 | f2 = GF(TCP(ap_A, 5)); 83 | f3 = GF(TCP(ap_C, 5)); 84 | f4 = GF(Neg(TCP(ap_A, 1))); 85 | f5 = GF(Neg(TCP(ap_C, 1))); 86 | 87 | % no more than 1 robot is allowed in region E after some time 88 | f6 = FG(Neg(TCP(ap_C, 4))); 89 | 90 | % everyone cross the bridge once in a while 91 | f7 = TCP(GF(ap_F1), 10); 92 | 93 | f = And(f1, f2, f3, f4, f5, f6, f7); 94 | 95 | % radius of robots (in x-y dimensions) 96 | epsilon = [0.3 0.3]'; 97 | 98 | [x, u, Z, sol, zLoop] = main_template(f, A, B, Px, Pu, h, X0, Obs, CA_flag, epsilon); 99 | 100 | loopBegins = find(zLoop==1); 101 | time = clock; 102 | filename = ['./data/GOBLUE_' ... 103 | num2str(time(1)) '_'... % Returns year as character 104 | num2str(time(2)) '_'... % Returns month as character 105 | num2str(time(3)) '_'... % Returns day as char 106 | num2str(time(4)) 'h'... % returns hour as char.. 107 | num2str(time(5)) 'm'... %returns minute as char 108 | ]; 109 | 110 | save(filename); 111 | 112 | plot_continuous(x,Z); 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /cLTL+/lib/generate_async_traces.m: -------------------------------------------------------------------------------- 1 | function [traces_async, loopBegins] = generate_async_traces(W, loopBegins, tau, upperLimit, varargin) 2 | 3 | if nargin == 5 4 | stutter_prob = varargin{1}; 5 | else 6 | stutter_prob = 0.1; 7 | end 8 | 9 | % Original time horizon 10 | k = size(W{1},2)-1; 11 | h = k; 12 | 13 | % Gives state vector index in loop at 'time' 14 | time_to_state_pos = @(time) (time<=k)*(time) + (time>k)*(loopBegins + mod(time-k-1, k-loopBegins+1)); 15 | 16 | % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 17 | time_to_control_pos = @(time) (time<=k+1)*(time-1) + (time>k+1)*(loopBegins + mod(time-k-2, k-loopBegins+1)); 18 | 19 | I = size(W{1},1); % num of states 20 | N = length(W); % num of agents 21 | K = ceil(upperLimit/size(W{1},2)+2)*size(W{1},2); % horizon 22 | 23 | % compute long traces 24 | traces_sync = zeros(N, K); 25 | index_sync = zeros(1, K); 26 | % Populate traces 27 | for k=1:K 28 | t = time_to_state_pos(k); 29 | index_sync(k) = t; 30 | for agent=1:N 31 | traces_sync(agent, k) = find(abs(W{agent}(:,t)-1)< 1e-4); 32 | end 33 | end 34 | 35 | % Now introduce asynchrony 36 | traces_async = traces_sync; 37 | index_async = ones(N,upperLimit); 38 | for t=2:upperLimit 39 | prev_index = index_async(:,t-1); 40 | current_index = prev_index; 41 | 42 | % Start with agent1 and move according to stutter probability 43 | if rand(1) > stutter_prob 44 | current_index(1) = prev_index(1)+1 ; 45 | end 46 | 47 | % Now move rest of the agents 48 | for agent = 2:N 49 | if max(current_index(1:agent)) - current_index(agent) > tau 50 | % Agents cannot lag too much 51 | current_index(agent) = current_index(agent) + 1; 52 | elseif current_index(agent) - min(current_index(1:agent)) == tau 53 | % Agents cannot lead too much 54 | continue 55 | elseif rand(1) > stutter_prob 56 | % Other than that move with stutter probability 57 | current_index(agent) = current_index(agent) + 1; 58 | end 59 | end 60 | 61 | index_async(:,t) = current_index; 62 | 63 | for agent = 1:N 64 | traces_async(agent,t) = traces_sync(agent,current_index(agent)); 65 | end 66 | 67 | anchor_time = min(index_async(:,t)); 68 | isLoop = find(ismember(traces_async(:,1:t-1)',traces_async(:,t)','rows'),1); 69 | if anchor_time >= h && ~isempty(isLoop) 70 | % If we repeat an aggregate state after looping once, stop 71 | if t-1-isLoop < h - loopBegins 72 | continue 73 | end 74 | loopBegins = isLoop; 75 | traces_async = traces_async(:,1:t); 76 | return 77 | end 78 | end 79 | 80 | 81 | % If repetation does not occur, move sync after upperLimit until repetation 82 | current_index = index_async(:,upperLimit); 83 | while isempty(find(ismember(traces_async(:,1:end-1)',traces_async(:,end)','rows'),1)) 84 | % Move one step in sync 85 | next_index = current_index + ones(N,1); 86 | next_trace = zeros(N,1); 87 | for agent = 1:N 88 | next_trace(agent) = traces_sync(agent,next_index(agent)); 89 | end 90 | 91 | traces_async = [traces_async next_trace]; 92 | current_index = next_index; 93 | index_async = [index_async next_index]; 94 | end 95 | 96 | loopBegins = find(ismember(traces_async(:,1:end-1)',traces_async(:,end)','rows'),1); -------------------------------------------------------------------------------- /cLTL+_continuous/lib/main_template.m: -------------------------------------------------------------------------------- 1 | function [x, u, Z, sol, zLoop] = main_template(... 2 | formula, A, B, Px, Pu, h, X0, Obs, CA_flag, epsilon) 3 | % x(t+1) = A*x(t) + B*u(t) 4 | % A = dx*dx matrix 5 | % b = dx*du matrix 6 | % Obs = given as a list of convex polytopes 7 | % X0 = d*N matrix 8 | 9 | time = clock; 10 | disp([ 'Started at ', ... 11 | num2str(time(4)), ':',... % Returns year as character 12 | num2str(time(5)), ' on ',... % Returns month as character 13 | num2str(time(3)), '/',... % Returns day as char 14 | num2str(time(2)), '/',... % returns hour as char.. 15 | num2str(time(1))]); 16 | 17 | assert(h>0, 'Trajectory must be greater than 0'); 18 | 19 | tos = tic; 20 | 21 | global x u Z zLoop ZLoop bigM; 22 | 23 | epsilon = 0.1 24 | % Number of agents 25 | N = size(X0,2); 26 | 27 | % bigM notation 28 | bigM = 1000; 29 | 30 | % number of states/ inputs 31 | dx = size(A,1); 32 | du = size(B,2); 33 | 34 | % states 35 | x = cell(1,N); 36 | 37 | % Initial conditions 38 | for n = 1:N 39 | x{n}(:,1) = X0(:,n); 40 | end 41 | fInit = []; 42 | 43 | % Control input u^i(t) = U{i}{t} - vector of dimension du 44 | u = sdpvar(repmat(du,1,N),repmat(h,1,N),'full'); 45 | 46 | % System dynamics constraint 47 | fDyn = getDyn(A, B, X0, Px, Pu); 48 | 49 | % Obstacle Avoidence Constraint 50 | [fObs,zObs] = getObs(Obs, epsilon); 51 | 52 | % Loop constraint 53 | fLoop= getLoop(); 54 | 55 | % Collision Avoidence Constraint ?? 56 | if CA_flag 57 | [fCol, zCol] = getCol(epsilon); 58 | else 59 | fCol = []; 60 | end 61 | % Timing of other constraints 62 | toe = toc(tos); 63 | disp([' Done with other constraints (',num2str(toe),') seconds']) 64 | 65 | % LTL constraint 66 | %disp('Creating LTL constraints...') 67 | tltls=tic; 68 | Z = {}; 69 | [fLTL,phi] = getLTL(formula,1); 70 | tltle=toc(tltls); 71 | disp([' Done with LTL constraints (',num2str(tltle),') seconds']) 72 | 73 | % All Constraints 74 | F = [fInit, fDyn, fLoop, fCol, fLTL, fObs, phi==1]; 75 | %F = [fInit, fDyn, fLoop, fObs]; 76 | %F = [fInit, fDyn, fLoop, fObs, x{1}(:,15) == zeros(6,1)]; 77 | 78 | disp([' Total number of optimization variables : ', num2str(length(depends(F)))]); 79 | 80 | % Solve the optimization problem 81 | %H = -epsilon; % maximize epsilon 82 | options = sdpsettings('verbose',8,'solver','gurobi'); 83 | disp('Solving MILP...') 84 | tms=tic; 85 | sol = optimize(F,[],options); 86 | tme=toc(tms); 87 | disp([' Solved (',num2str(sol.solvertime),') seconds']) 88 | 89 | 90 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 91 | % Assign values 92 | 93 | 94 | if sol.problem == 0 95 | % Extract and display value 96 | disp('## Feasible solution exists ##') 97 | % Now get the values 98 | 99 | for n = 1:N 100 | x{n} = value(x{n}); 101 | u{n} = value(u{n}); 102 | end 103 | for i=1:length(Z) 104 | Z{i}{1} = value(Z{i}{1}); 105 | if ~isnan(Z{i}{1}) 106 | 1; 107 | else 108 | disp(['#### Careful!! ', num2str(Z{i}{2}), ' is NaN']); 109 | end 110 | end 111 | %Wtotal = value(Wtotal); 112 | % Loop 113 | zLoop = value(zLoop); 114 | ZLoop = value(ZLoop); 115 | LoopBegins = find(zLoop(:)==1); 116 | else 117 | W=0;W=0;WT=0;ZLoop=0;zLoop=0;LoopBegins=0; 118 | display('## No feasible solutions found! ##'); 119 | sol.info 120 | yalmiperror(sol.problem) 121 | end 122 | 123 | ttotal = toc(tos); 124 | mytimes = [ttotal,toe, tltle, sol.solvertime]; 125 | yalmip('clear') -------------------------------------------------------------------------------- /cLTL+_continuous/lib/plot_continuous_3D.m: -------------------------------------------------------------------------------- 1 | function plot_continuous_3D(x,Z) 2 | h = size(x{1},2)-1; 3 | N = length(x); 4 | cmap = jet(N); 5 | fps = 3; 6 | 7 | % state constraints 8 | Px = Polytope([eye(3); -eye(3)], [10; 10; 10; 10; 10; 0]); 9 | 10 | % input constraints 11 | Pu = Polytope([eye(3); -eye(3)], [1; 1; 1; 1; 1; 1]); 12 | 13 | % atomic propositions 14 | ap_cell = {}; 15 | 16 | % ap1 17 | [ap1, ap_cell] = AP([eye(3); -eye(3)],[-7; 1; 5; 9; 1; -3], ap_cell); 18 | [ap2, ap_cell] = AP([eye(3); -eye(3)],[ 1; 1; 5; 1; 1; -3], ap_cell); 19 | [ap3, ap_cell] = AP([eye(3); -eye(3)],[ 9; 1; 5; -7; 1; -3], ap_cell); 20 | 21 | 22 | % Obstacles 23 | Obs1 = Polytope([eye(3); -eye(3)], [-4; 7; 7; 6; 7; -3]); 24 | Obs2 = Polytope([eye(3); -eye(3)], [ 6; 7; 7; -4; 7; -3]); 25 | Obs = [Obs1, Obs2]; 26 | %%%%%%%%%%% 27 | 28 | % visualization 29 | 30 | for t = 1:h 31 | for tt = 1:fps+1 32 | figure(1);clf;hold on; 33 | subplot(2,2,1) 34 | hold on; 35 | plot(Polyhedron(Px.A,Px.b), 'color', 'white', 'alpha', 0.1); 36 | plot(Polyhedron(ap1.A,ap1.b), 'color', 'green', 'alpha', 0.1); 37 | plot(Polyhedron(ap2.A,ap2.b), 'color', 'green', 'alpha', 0.1); 38 | plot(Polyhedron(ap3.A,ap3.b), 'color', 'green', 'alpha', 0.1); 39 | plot(Polyhedron(Obs(1).A,Obs(1).b), 'color', 'black', 'alpha', 0.1); 40 | plot(Polyhedron(Obs(2).A,Obs(2).b), 'color', 'black', 'alpha', 0.1); 41 | for n = 1:N 42 | xx = x{n}(1,t) * (fps+1-tt)/fps + x{n}(1,t+1) * (tt-1)/fps; 43 | yy = x{n}(2,t) * (fps+1-tt)/fps + x{n}(2,t+1) * (tt-1)/fps; 44 | zz = x{n}(3,t) * (fps+1-tt)/fps + x{n}(3,t+1) * (tt-1)/fps; 45 | plot3(xx,yy,zz, '.', 'color', cmap(n,:), ... 46 | 'markersize', 25, 'MarkerFaceColor', cmap(n,:)) 47 | end 48 | view(0,0) 49 | subplot(2,2,2) 50 | hold on 51 | plot(Polyhedron(Px.A,Px.b), 'color', 'white', 'alpha', 0.1); 52 | plot(Polyhedron(ap1.A,ap1.b), 'color', 'green', 'alpha', 0.1); 53 | plot(Polyhedron(ap2.A,ap2.b), 'color', 'green', 'alpha', 0.1); 54 | plot(Polyhedron(ap3.A,ap3.b), 'color', 'green', 'alpha', 0.1); 55 | plot(Polyhedron(Obs(1).A,Obs(1).b), 'color', 'black', 'alpha', 0.1); 56 | plot(Polyhedron(Obs(2).A,Obs(2).b), 'color', 'black', 'alpha', 0.1); 57 | for n = 1:N 58 | xx = x{n}(1,t) * (fps+1-tt)/fps + x{n}(1,t+1) * (tt-1)/fps; 59 | yy = x{n}(2,t) * (fps+1-tt)/fps + x{n}(2,t+1) * (tt-1)/fps; 60 | zz = x{n}(3,t) * (fps+1-tt)/fps + x{n}(3,t+1) * (tt-1)/fps; 61 | plot3(xx,yy,zz, '.', 'color', cmap(n,:), ... 62 | 'markersize', 25, 'MarkerFaceColor', cmap(n,:)) 63 | end 64 | view(0,90) 65 | subplot(2,2,3) 66 | hold on; 67 | plot(Polyhedron(Px.A,Px.b), 'color', 'white', 'alpha', 0.1); 68 | plot(Polyhedron(ap1.A,ap1.b), 'color', 'green', 'alpha', 0.1); 69 | plot(Polyhedron(ap2.A,ap2.b), 'color', 'green', 'alpha', 0.1); 70 | plot(Polyhedron(ap3.A,ap3.b), 'color', 'green', 'alpha', 0.1); 71 | plot(Polyhedron(Obs(1).A,Obs(1).b), 'color', 'black', 'alpha', 0.1); 72 | plot(Polyhedron(Obs(2).A,Obs(2).b), 'color', 'black', 'alpha', 0.1); 73 | for n = 1:N 74 | xx = x{n}(1,t) * (fps+1-tt)/fps + x{n}(1,t+1) * (tt-1)/fps; 75 | yy = x{n}(2,t) * (fps+1-tt)/fps + x{n}(2,t+1) * (tt-1)/fps; 76 | zz = x{n}(3,t) * (fps+1-tt)/fps + x{n}(3,t+1) * (tt-1)/fps; 77 | plot3(xx,yy,zz, '.', 'color', cmap(n,:), ... 78 | 'markersize', 25, 'MarkerFaceColor', cmap(n,:)) 79 | end 80 | view(90,0) 81 | pause(.01); 82 | 83 | hold off 84 | end 85 | end -------------------------------------------------------------------------------- /cLTL+/lib/install_mpt3.m: -------------------------------------------------------------------------------- 1 | %% installation of tbxmanager with all submodels required for MPT 2 | % 3 | 4 | clc; 5 | disp('----------------------------------------------'); 6 | disp('Installation of MPT using the Toolbox manager.'); 7 | disp('----------------------------------------------'); 8 | disp(' '); 9 | fprintf(['Choose the installation directory where to install the Toolbox manager.\n',... 10 | 'A new folder "tbxmanager" is going to be created in the specified location.\n',... 11 | 'If you do not specify the folder, the Toolbox manager will be installed in the current directory.\n']); 12 | 13 | % get the installation folder 14 | default_dir = pwd; 15 | c = uigetdir(pwd); 16 | if isequal(c,0); 17 | fprintf(['No directory has been provided.\n',... 18 | 'Installing the toolbox manager in the current directory "%s"?\n'],default_dir); 19 | c = default_dir; 20 | end 21 | 22 | % create a new directory in that folder 23 | d = [c,filesep,'tbxmanager']; 24 | if isequal(exist(d,'dir'),7) 25 | error('The installation directory "%s" already exists.\nPlease, remove or rename the folder or change the installation path.',d); 26 | end 27 | disp('Creating the directory "tbxmanager".'); 28 | out = mkdir(d); 29 | if ~out 30 | error(['An error appear when trying to create the folder "%s".\n',... 31 | 'Please, install the Toolbox manager manually.'],c); 32 | end 33 | 34 | % enter that directory 35 | cd(d); 36 | 37 | % remove MPT2 or YALMIP 38 | disp(' '); 39 | disp('Removing toolboxes that may conflict with MPT from the Matlab path.'); 40 | rmpath(genpath(fileparts(which('mpt_init')))); 41 | rmpath(genpath(fileparts(which('yalmipdemo')))); 42 | 43 | 44 | % download the tbxmanager 45 | disp(' '); 46 | disp('Downloading the Toolbox manager from the internet.'); 47 | [f, c] = urlwrite('http://www.tbxmanager.com/tbxmanager.m', 'tbxmanager.m'); 48 | rehash; 49 | 50 | if isequal(c,0) 51 | error('Could not download the Toolbox manager from the internet. The installation cannot continue.'); 52 | end 53 | 54 | % install all required modules 55 | tbxmanager install mpt mptdoc cddmex fourier glpkmex hysdel lcp sedumi yalmip 56 | 57 | % create the initialization file to set the path 58 | disp(' '); 59 | disp('Creating the initialization file "startup.m".'); 60 | p = which('startup.m'); 61 | if isempty(p) 62 | p = [d,filesep,'startup.m']; 63 | end 64 | fid = fopen(p,'a'); 65 | if isequal(fid,-1) 66 | error(['Could not modify the initialization file "startup.m".',... 67 | 'Edit this file in the folder "%s" manually and insert there the line: tbxmanager restorepath.'],p); 68 | end 69 | fprintf(fid,'tbxmanager restorepath\n'); 70 | fclose(fid); 71 | disp('File has been created.'); 72 | 73 | % get back to the original directory 74 | cd(default_dir); 75 | 76 | % add path to tbxmanager 77 | disp(' '); 78 | disp('Adding path to Matlab.'); 79 | addpath(d); 80 | 81 | % save path for future 82 | disp(' '); 83 | disp('Saving path for future sessions.'); 84 | status = savepath; 85 | 86 | if status 87 | fprintf('Could not save the path to a default location,\nplease provide a location where you want to save the path.'); 88 | cn = uigetdir(pwd); 89 | if isequal(cn,0) 90 | disp(' '); 91 | fprintf('No directory specified, saving the path to the current directory "%s".\n\n',default_dir); 92 | cn = default_dir; 93 | end 94 | sn = savepath([cn,filesep,'pathdef.m']); 95 | if sn 96 | error(['Could not save the path automatically.\n',... 97 | 'Please, open the "Set Path" button in the Matlab menu and save the path manually to some location.']); 98 | end 99 | end 100 | 101 | disp(' '); 102 | disp('Installation finished.'); 103 | disp('Next time you start Matlab the toolboxes will be automatically initialized.'); 104 | 105 | % initialize MPT 106 | disp(' '); 107 | disp('Initializing the MPT.') 108 | mpt_init; -------------------------------------------------------------------------------- /cLTL+/examples/robotarium_example.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | clc; 4 | 5 | global W Wtotal Z zLoop ZLoop bigM epsilon tau; 6 | 7 | % Time horizon 8 | h = 45; 9 | % robustness number 10 | epsilon = 0; 11 | tau = 2; 12 | 13 | % define a gridworld 14 | grid_size = [8, 15]; 15 | mygrid = ones(grid_size); 16 | 17 | mygrid(1:4, 1:5) = 0.8; 18 | mygrid(1:4, 11:15) = 0.6; 19 | 20 | % narrow passage 21 | % mygrid(2, 6:8) = 0.4; 22 | % mygrid(3, 8:10) = 0.4; 23 | mygrid(2:3, 6:10) = 0.4; 24 | 25 | % Obstacles 26 | mygrid([1,4], 6:10) = 0; 27 | % mygrid([2,4], [4,7]) = 0; 28 | mygrid(6:7, 13:14) = 0; 29 | 30 | %%%%%%%%%%% 31 | 32 | state_labels = mygrid(:); 33 | 34 | Pass = find(state_labels(:)==0.4)'; 35 | pass = num2str(Pass); 36 | Room1 = find(state_labels(:)==0.8)'; 37 | room1 = num2str(Room1); 38 | Room2 = find(state_labels(:)==0.6)'; 39 | room2 = num2str(Room2); 40 | Room3 = find(state_labels(:)==1)'; 41 | room3 = num2str(Room3); 42 | 43 | % charging station 44 | mygrid(1:2,1:2) = 0.2; 45 | mygrid(1:2,14:15) = 0.2; 46 | mygrid(7:8,1:2) = 0.2; 47 | %mygrid(9:10,9:10) = 0.2; 48 | state_labels = mygrid(:); 49 | 50 | CS = find(state_labels(:)==.2)'; 51 | CS = num2str(CS); 52 | 53 | % visualization 54 | vis = zeros(size(mygrid)+2); 55 | vis(2:end-1,2:end-1)=mygrid; 56 | imshow(kron(vis,ones(25,25))) 57 | 58 | pass_ends = [23,73,Pass]; 59 | 60 | % spec is the conjunction of the following 61 | Obs = state_labels(:)==0; %avoid obstacles 62 | f1 = strcat('GG(Neg(TP([',pass,'],[2])))'); %not too many robots in narrow passage way 63 | f1 = strcat('GG(TP([',num2str(setdiff(1:100,Pass)),'],[6]))'); %not too many robots in narrow passage way 64 | 65 | % surveil two regions by leaving them once in a while 66 | f2 = strcat('GF(TP([',num2str(Room1),'],[5]))'); % GF([0.2 labels, >=5]) 67 | f3 = strcat('GF(TP([',num2str(Room2),'],[5]))'); % GF([0.8 labels, >=5]) 68 | f4 = strcat('GF(Neg(TP([',num2str(Room1),'],[1])))'); % GF([0.2 labels, <=0]) 69 | f5 = strcat('GF(Neg(TP([',num2str(Room2),'],[1])))'); % GF([0.8 labels, <=0]) 70 | f6 = strcat('FG(Neg(TP([',num2str(Room3),'],[2])))'); % FG([1 labels, <= 1]) at steady state at most one robot is left in the lower part 71 | 72 | f4 = strcat('GF(TP([',num2str(setdiff(1:100,Room1)),'],[8]))'); % GF([0.2 labels, <=0]) 73 | f5 = strcat('GF(TP([',num2str(setdiff(1:100,Room2)),'],[8]))'); % GF([0.8 labels, <=0]) 74 | f6 = strcat('FG(TP([',num2str(setdiff(1:100,Room3)),'],[6]))'); 75 | 76 | %f7 = strcat('U(Neg([',num2str([pass_ends,1]),']),And([',num2str([72 74 1]),'],[',num2str([22 24 1]),']))'); 77 | f7 = strcat('TP(GFI([', num2str(CS), ']),[8])'); 78 | %adj = zeros(prod(size(grid))); 79 | adj = eye(numel(mygrid)); %allow self-transition 80 | 81 | for i=1:length(state_labels) 82 | if mod(i, grid_size(1))~=0 83 | adj(i, i+1) = 1; 84 | end 85 | if mod(i, grid_size(1))~=1 86 | adj(i, i-1) = 1; 87 | end 88 | if i<=grid_size(1)*(grid_size(2)-1) 89 | adj(i, i+grid_size(1)) = 1; 90 | end 91 | if i>grid_size(1) 92 | adj(i, i-grid_size(1)) = 1; 93 | end 94 | end 95 | %ll = 21:30; 96 | % Total specs 97 | %f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,')'); 98 | f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,',',f6,',',f7,')'); 99 | f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,',',f7,')'); 100 | 101 | %f = strcat('And(',f2,',',f3,',',f7,')'); 102 | %f = strcat('TP(FGI([', num2str(ll),']),[10])'); 103 | % Adjacency matrix 104 | A = adj; 105 | 106 | 107 | 108 | % Random initial condition 109 | n = size(A,1); 110 | W0=zeros(n,1); 111 | for i=1:n 112 | if ~Obs(i) 113 | W0(i) = round(rand(1)*0.65); 114 | end 115 | end 116 | W0 = [ones(4,1); ones(4,1); zeros(n-8,1)]; 117 | 118 | 119 | 120 | % Collision avoidence flag, 121 | % 1=collision avoidence enforced, 0=no collision avoidence 122 | CA_flag = 1; 123 | 124 | [W, Wtotal, Z, mytimes, sol] = main_template(f,A,h,W0,Obs,CA_flag); 125 | 126 | 127 | time = clock; 128 | filename = ['./data/GOBLUE_' ... 129 | num2str(h) 'horizon_'... 130 | num2str(tau) 'tau_'... 131 | num2str(time(1)) '_'... % Returns year as character 132 | num2str(time(2)) '_'... % Returns month as character 133 | num2str(time(3)) '_'... % Returns day as char 134 | num2str(time(4)) 'h'... % returns hour as char.. 135 | num2str(time(5)) 'm'... %returns minute as char 136 | ]; 137 | 138 | save(filename,'W','W','Wtotal','Wtotal','ZLoop','ZLoop','A','A','mygrid','mygrid', 'Z', 'Z','sol','sol'); 139 | 140 | 141 | 142 | grid_plot(filename); 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /cLTL+/examples/emergency_example.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | clc; 4 | addpath(genpath('../')) 5 | 6 | global W Wtotal Z zLoop ZLoop bigM epsilon tau; 7 | 8 | % Time horizon 9 | h = 40; 10 | % robustness number 11 | epsilon = 0; 12 | tau = 0; 13 | 14 | % define a gridworld 15 | grid_size = [10, 10]; 16 | mygrid = ones(grid_size); 17 | 18 | mygrid(1:5, 1:5) = 0.8; 19 | mygrid(1:5, 6:10) = 0.6; 20 | 21 | % narrow passage 22 | mygrid(3, 4:7) = 0.4; 23 | 24 | 25 | % Obstacles 26 | mygrid([1:2,4:5], 5:6) = 0; 27 | mygrid([2,4], [4,7]) = 0; 28 | %mygrid([1:2,4:5], 4:7) = 0; 29 | mygrid([8,9], [7,8]) = 0; 30 | 31 | %%%%%%%%%%% 32 | 33 | state_labels = mygrid(:); 34 | 35 | Pass = find(state_labels(:)==0.4)'; 36 | pass = num2str(Pass); 37 | Room1 = find(state_labels(:)==0.8)'; 38 | room1 = num2str(Room1); 39 | Room2 = find(state_labels(:)==0.6)'; 40 | room2 = num2str(Room2); 41 | Room3 = find(state_labels(:)==1)'; 42 | room3 = num2str(Room3); 43 | 44 | % charging station 45 | mygrid(1:2,1:2) = 0.2; 46 | mygrid(1:2,9:10) = 0.2; 47 | mygrid(9:10,1:2) = 0.2; 48 | %mygrid(9:10,9:10) = 0.2; 49 | state_labels = mygrid(:); 50 | 51 | CS = find(state_labels(:)==.2)'; 52 | CS = num2str(CS); 53 | 54 | % visualization 55 | vis = zeros(size(mygrid)+2); 56 | vis(2:end-1,2:end-1)=mygrid; 57 | imshow(kron(vis,ones(25,25))) 58 | 59 | pass_ends = [23,73,Pass]; 60 | 61 | % spec is the conjunction of the following 62 | Obs = state_labels(:)==0; %avoid obstacles 63 | f1 = strcat('GG(Neg(TP([',pass,'],[3])))'); %not too many robots in narrow passage way 64 | f1 = strcat('GG(TP([',num2str(setdiff(1:100,Pass)),'],[8]))'); %not too many robots in narrow passage way 65 | 66 | % surveil two regions by leaving them once in a while 67 | f2 = strcat('GF(TP([',num2str(Room1),'],[5]))'); % GF([0.2 labels, >=5]) 68 | f3 = strcat('GF(TP([',num2str(Room2),'],[5]))'); % GF([0.8 labels, >=5]) 69 | f4 = strcat('GF(Neg(TP([',num2str(Room1),'],[1])))'); % GF([0.2 labels, <=0]) 70 | f5 = strcat('GF(Neg(TP([',num2str(Room2),'],[1])))'); % GF([0.8 labels, <=0]) 71 | f6 = strcat('FG(Neg(TP([',num2str(Room3),'],[2])))'); % FG([1 labels, <= 1]) at steady state at most one robot is left in the lower part 72 | 73 | f4 = strcat('GF(TP([',num2str(setdiff(1:100,Room1)),'],[10]))'); % GF([0.2 labels, <=0]) 74 | f5 = strcat('GF(TP([',num2str(setdiff(1:100,Room2)),'],[10]))'); % GF([0.8 labels, <=0]) 75 | f6 = strcat('FG(TP([',num2str(setdiff(1:100,Room3)),'],[8]))'); 76 | 77 | %f7 = strcat('U(Neg([',num2str([pass_ends,1]),']),And([',num2str([72 74 1]),'],[',num2str([22 24 1]),']))'); 78 | f7 = strcat('TP(GFI([', num2str(CS), ']),[10])'); 79 | %adj = zeros(prod(size(grid))); 80 | adj = eye(numel(mygrid)); %allow self-transition 81 | 82 | for i=1:length(state_labels) 83 | if mod(i, grid_size(1))~=0 84 | adj(i, i+1) = 1; 85 | end 86 | if mod(i, grid_size(1))~=1 87 | adj(i, i-1) = 1; 88 | end 89 | if i<=grid_size(1)*(grid_size(2)-1) 90 | adj(i, i+grid_size(1)) = 1; 91 | end 92 | if i>grid_size(1) 93 | adj(i, i-grid_size(1)) = 1; 94 | end 95 | end 96 | %ll = 21:30; 97 | % Total specs 98 | %f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,')'); 99 | f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,',',f6,',',f7,')'); 100 | f = strcat('And(',f1,',',f2,',',f3,',',f4,',',f5,',',f7,')'); 101 | 102 | %f = strcat('And(',f2,',',f3,',',f7,')'); 103 | %f = strcat('TP(FGI([', num2str(ll),']),[10])'); 104 | % Adjacency matrix 105 | A = adj; 106 | 107 | 108 | 109 | % Random initial condition 110 | n = size(A,1); 111 | W0=zeros(n,1); 112 | for i=1:n 113 | if ~Obs(i) 114 | W0(i) = round(rand(1)*0.65); 115 | end 116 | end 117 | W0 = [ones(5,1); ones(5,1); zeros(n-10,1)]; 118 | 119 | 120 | 121 | % Collision avoidence flag, 122 | % 1=collision avoidence enforced, 0=no collision avoidence 123 | CA_flag = 0; 124 | 125 | [W, Wtotal, Z, mytimes, sol] = main_template(f,A,h,W0,Obs,CA_flag); 126 | 127 | 128 | time = clock; 129 | filename = ['./data/GOBLUE_' ... 130 | num2str(h) 'horizon_'... 131 | num2str(tau) 'tau_'... 132 | num2str(time(1)) '_'... % Returns year as character 133 | num2str(time(2)) '_'... % Returns month as character 134 | num2str(time(3)) '_'... % Returns day as char 135 | num2str(time(4)) 'h'... % returns hour as char.. 136 | num2str(time(5)) 'm'... %returns minute as char 137 | ]; 138 | 139 | save(filename,'W','W','Wtotal','Wtotal','ZLoop','ZLoop','A','A','mygrid','mygrid', 'Z', 'Z','sol','sol'); 140 | 141 | 142 | 143 | grid_plot(filename); 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /cLTL+/lib/plot_trace.m: -------------------------------------------------------------------------------- 1 | function plot_trace(filename,fps) 2 | filename = strcat('./data/',filename); 3 | load(filename) 4 | Mw = noSwapping(Mw); 5 | [size1,size2] = size(mygrid); 6 | k = length(ZLoop); 7 | loopBegins = find(ZLoop(:)==1,1); 8 | 9 | % Gives state vector index in loop at 'time' 10 | time_to_state_pos = @(time) (time<=k)*(time) + (time>k)*(loopBegins + mod(time-k-1, k-loopBegins+1)); 11 | 12 | % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 13 | time_to_control_pos = @(time) (time<=k+1)*(time-1) + (time>k+1)*(loopBegins + mod(time-k-2, k-loopBegins+1)); 14 | 15 | % Return coordinates in a grid world 16 | ind_to_pos_x = @(ind) (1+floor((ind-1)/size2)); 17 | ind_to_pos_y = @(ind) (1+mod((ind-1),size2)); 18 | 19 | I = size1*size2; % num of states 20 | N = round(sum(WT(:,1))); % num of agents 21 | K = k*2; % horizon 22 | 23 | traces = zeros(round(N), round(K)); 24 | WT = round(WT); 25 | % Populate initial conditions 26 | num_trace = 1; 27 | for state = 1:I 28 | for i = 1:WT(state,1) 29 | traces(num_trace, 1) = state; 30 | num_trace = num_trace + 1; 31 | end 32 | end 33 | 34 | % Populate rest of traces 35 | for i=2:K 36 | control_time = time_to_control_pos(i); 37 | control = Mw{control_time}; 38 | for agent=1:N 39 | % Find a feasible destination 40 | current_state = traces(agent, i-1); 41 | destination = find(control(current_state,:) > 0.1, 1); 42 | control(current_state, destination) = control(current_state, destination) - 1; 43 | 44 | % Assign destination 45 | traces(agent, i) = destination; 46 | end 47 | end 48 | 49 | % Test that it worked 50 | % w_test = zeros(I,K); 51 | % for i=1:K 52 | % for agent=1:N 53 | % state = traces(agent,i); 54 | % w_test(state,i) = w_test(state,i) + 1; 55 | % end 56 | % end 57 | % for i=1:5 58 | % assert(sum(abs(w_test(:,i) - WT(:,i))) == 0) 59 | % end 60 | cmap = jet(N); 61 | 62 | clf; 63 | T = 1:K-1; 64 | Xpos = ind_to_pos_x(traces(:,1))-.5;%1+rand(N,1); 65 | Ypos = ind_to_pos_y(traces(:,1))-.5;%1+rand(N,1); 66 | %axis off 67 | %ha = tight_subplot(3,4, [0.05 0.01], [0.01 0.04], 0.01); 68 | for i=1:length(T) 69 | NXpos = ind_to_pos_x(traces(:,i+1))-.5;%1+rand(N,1); 70 | NYpos = ind_to_pos_y(traces(:,i+1))-.5;%%+rand(N,1); 71 | for f=1:fps 72 | figure(1) 73 | clf;hold on; grid on; 74 | xlim([0, size2]); ylim([0, size1]); 75 | set(gca,'xtick',0:size2),set(gca,'ytick',0:size1); 76 | for g = 1:I 77 | xpos = ind_to_pos_x(g); 78 | ypos = ind_to_pos_y(g); 79 | rectangle('position',[xpos-1 ypos-1 xpos ypos],'LineWidth',.5); 80 | if mygrid(xpos,ypos)==0 81 | rectangle('position',[xpos-1 ypos-1 1 1],'FaceColor',[0 0 0]); 82 | elseif mygrid(xpos,ypos)==.2 83 | rectangle('position',[xpos-1 ypos-1 1 1],'FaceColor',[0.2 0.2 0.2]); 84 | elseif mygrid(xpos,ypos)==.8 85 | rectangle('position',[xpos-1 ypos-1 1 1],'FaceColor',[0.8 0.8 0.8]); 86 | elseif mygrid(xpos,ypos)==.5 87 | rectangle('position',[xpos-1 ypos-1 1 1],'FaceColor',[0.5 0.5 0.5]); 88 | end 89 | end 90 | rectangle('position',[0 0 size2 size1],'LineWidth',2); 91 | 92 | %occup = ones(100,1); 93 | for agent=1:N 94 | %current_state = traces(agent, T(i)); 95 | %diff_ = pos_diff(occup(current_state),:); 96 | xpos = Xpos(agent); 97 | ypos = Ypos(agent); 98 | nxpos = NXpos(agent); 99 | nypos = NYpos(agent); 100 | myxpos = (fps+1-f)*xpos/fps + (f-1)*nxpos/fps; 101 | myypos = (fps+1-f)*ypos/fps + (f-1)*nypos/fps; 102 | %occup(current_state) = occup(current_state) + 1; 103 | plot(myxpos, myypos, 'o', 'color', cmap(n,:), ... 104 | 'markersize', 5, 'MarkerFaceColor', cmap(n,:)); 105 | % if current_state ~= traces(n, T(i)+1) 106 | % arrow_dest_x = xpos + (ind_to_pos_x(traces(n, T(i)+1))+ diff_(1) - xpos)*0.75; 107 | % arrow_dest_y = ypos + (ind_to_pos_y(traces(n, T(i)+1))+ diff_(2) - ypos)*0.75; 108 | % arrow([xpos, ypos], [arrow_dest_x, arrow_dest_y], 'length', 4, 'baseangle', 90, 'tipangle', 30, 'color', cmap(n,:)); 109 | % end 110 | end 111 | title(['$$t=', num2str(T(i)+(f-1)/fps), '$$'],'Interpreter','latex') 112 | hold off 113 | filename2 = sprintf('./plots/%s_%03d.png', filename, f+fps*(i-1)); 114 | %print(filename2, '-dpng'); 115 | end 116 | Xpos = NXpos; 117 | Ypos = NYpos; 118 | end 119 | -------------------------------------------------------------------------------- /cLTL+/lib/grid_plot.m: -------------------------------------------------------------------------------- 1 | function grid_plot(filename) 2 | load(filename) 3 | % % Loop closes at 10 4 | % 5 | % % Gives state vector index in loop at 'time' 6 | % time_to_state_pos = @(time) (time<=20)*(time) + (time>20)*(10 + mod(time-10, 11)); 7 | % 8 | % % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 9 | % time_to_control_pos = @(time) (time<=19)*(time-1) + (time>19)*(10 + mod(time-11, 11)); 10 | 11 | 12 | k = length(ZLoop); 13 | loopBegins = find(ZLoop(:)==1,1); 14 | 15 | % Gives state vector index in loop at 'time' 16 | time_to_state_pos = @(time) (time<=k)*(time) + (time>k)*(loopBegins + mod(time-k-1, k-loopBegins+1)); 17 | 18 | % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 19 | time_to_control_pos = @(time) (time<=k+1)*(time-1) + (time>k+1)*(loopBegins + mod(time-k-2, k-loopBegins+1)); 20 | 21 | 22 | % Return coordinates in a grid world 23 | ind_to_pos_x = @(ind) (1+floor((ind-1)/8)); 24 | ind_to_pos_y = @(ind) (1+mod((ind-1),8)); 25 | 26 | I = size(A,2); % num of states 27 | N = length(W); % num of agents 28 | K = 2*size(W{1},2); % horizon 29 | 30 | traces = zeros(N, K); 31 | 32 | 33 | % Populate rest of traces 34 | for k=1:K 35 | t = time_to_state_pos(k); 36 | for agent=1:N 37 | % Find a feasible destination 38 | %if isempty(find(W{agent}(:,t)==1)) 39 | %disp(['agent: ', num2str(agent), ' time: ', num2str(t)]) 40 | %end 41 | traces(agent, k) = find(abs(W{agent}(:,t)-1)< 1e-4); 42 | end 43 | end 44 | 45 | % % Test that it worked 46 | % w_test = zeros(I,K); 47 | % for k=1:K 48 | % for n=1:N 49 | % state = traces(n,k); 50 | % w_test(state,k) = w_test(state,k) + 1; 51 | % end 52 | % end 53 | % for k=1:5 54 | % assert(sum(abs(w_test(:,k) - WT(:,k))) == 0) 55 | % end 56 | 57 | clf; 58 | set(gca, 'LooseInset', get(gca,'TightInset')) 59 | 60 | % define a gridworld 61 | grid_size = [8, 15]; 62 | mygrid = ones(grid_size); 63 | 64 | mygrid(1:4, 1:5) = 0.8; 65 | mygrid(1:4, 11:15) = 0.6; 66 | 67 | % narrow passage 68 | % mygrid(2, 6:8) = 0.4; 69 | % mygrid(3, 8:10) = 0.4; 70 | mygrid(2:3, 6:10) = 0.4; 71 | 72 | % Obstacles 73 | mygrid([1,4], 6:10) = 0; 74 | % mygrid([2,4], [4,7]) = 0; 75 | mygrid(6:7, 13:14) = 0; 76 | 77 | %%%%%%%%%%% 78 | 79 | state_labels = mygrid(:); 80 | 81 | Pass = find(state_labels(:)==0.4)'; 82 | pass = num2str(Pass); 83 | Room1 = find(state_labels(:)==0.8)'; 84 | room1 = num2str(Room1); 85 | Room2 = find(state_labels(:)==0.6)'; 86 | room2 = num2str(Room2); 87 | Room3 = find(state_labels(:)==1)'; 88 | room3 = num2str(Room3); 89 | 90 | % charging station 91 | mygrid(1:2,1:2) = 0.2; 92 | mygrid(1:2,14:15) = 0.2; 93 | mygrid(7:8,1:2) = 0.2; 94 | %mygrid(9:10,9:10) = 0.2; 95 | state_labels = mygrid(:); 96 | 97 | CS = find(state_labels(:)==.2)'; 98 | CS = num2str(CS); 99 | 100 | 101 | vis = zeros(size(mygrid)+2); 102 | vis(2:end-1,2:end-1)=mygrid; 103 | 104 | % 105 | % T = [1 6 10 11 12 20 33 41];% 106 | T= [1 9 10 13 14 15 17 20 21 22 23 31]; 107 | T = 1:40;%[1 2 3 6 7 8 14 15 16 20 30 31]; 108 | cmap = jet(N); 109 | pos_diff = [[0., 0.]; [0.3,0.3]; [0.3,-0.3]; [-0.3,-0.3]; [-0.3,0.3]]; 110 | 111 | axis off 112 | ha = tight_subplot(4,10, [0.05 0.01], [0.01 0.04], 0.01); 113 | for i=1:length(T) 114 | axes(ha(i)) 115 | hold on; xlim([0.5, 15.5]); ylim([0.5, 8.5]) 116 | imshow(kron(mygrid,ones(25,25)), 'xdata', [0.5,15.5], 'ydata', [0.5,8.5]) 117 | rectangle('position',[0.5 0.5 15 8],'LineWidth',2); 118 | % if i == loopBegins || i == length(ZLoop)+1 119 | % rectangle('position',[0.5 0.5 10 10],'LineWidth',2,'EdgeColor','r'); 120 | % end 121 | %occup = ones(100,1); 122 | for n=1:N 123 | current_state = traces(n, T(i)); 124 | diff_ = [0 0];%pos_diff(occup(current_state),:); 125 | xpos = ind_to_pos_x(current_state) + diff_(1); 126 | ypos = ind_to_pos_y(current_state) + diff_(2); 127 | %occup(current_state) = occup(current_state) + 1; 128 | plot(xpos, ypos, 'o', 'color', cmap(n,:), ... 129 | 'markersize', 5, 'MarkerFaceColor', cmap(n,:)) 130 | if current_state ~= traces(n, T(i)+1) 131 | arrow_dest_x = xpos + (ind_to_pos_x(traces(n, T(i)+1))+ diff_(1) - xpos)*0.75; 132 | arrow_dest_y = ypos + (ind_to_pos_y(traces(n, T(i)+1))+ diff_(2) - ypos)*0.75; 133 | arrow([xpos, ypos], [arrow_dest_x, arrow_dest_y], 'length', 4, 'baseangle', 90, 'tipangle', 30, 'color', cmap(n,:)); 134 | end 135 | end 136 | title(['$$t=', num2str(T(i)), '$$'],'Interpreter','latex') 137 | end 138 | print -depsc traces.eps 139 | 140 | fig = gcf; 141 | fig.PaperPositionMode = 'auto' 142 | fig_pos = fig.PaperPosition; 143 | fig.PaperSize = [fig_pos(3) fig_pos(4)]; 144 | print(fig,filename,'-dpdf') 145 | 146 | 147 | -------------------------------------------------------------------------------- /cLTL+/lib/plot_robotarium.m: -------------------------------------------------------------------------------- 1 | function plot_robotarium(filename) 2 | load(filename) 3 | % % Loop closes at 10 4 | % 5 | % % Gives state vector index in loop at 'time' 6 | % time_to_state_pos = @(time) (time<=20)*(time) + (time>20)*(10 + mod(time-10, 11)); 7 | % 8 | % % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 9 | % time_to_control_pos = @(time) (time<=19)*(time-1) + (time>19)*(10 + mod(time-11, 11)); 10 | 11 | 12 | k = length(ZLoop); 13 | loopBegins = find(ZLoop(:)==1,1); 14 | 15 | % Gives state vector index in loop at 'time' 16 | time_to_state_pos = @(time) (time<=k)*(time) + (time>k)*(loopBegins + mod(time-k-1, k-loopBegins+1)); 17 | 18 | % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 19 | time_to_control_pos = @(time) (time<=k+1)*(time-1) + (time>k+1)*(loopBegins + mod(time-k-2, k-loopBegins+1)); 20 | 21 | 22 | % Return coordinates in a grid world 23 | ind_to_pos_x = @(ind) (1+floor((ind-1)/8)); 24 | ind_to_pos_y = @(ind) (1+mod((ind-1),8)); 25 | 26 | I = size(A,2); % num of states 27 | N = length(W); % num of agents 28 | K = 2*size(W{1},2); % horizon 29 | 30 | traces = zeros(N, K); 31 | 32 | 33 | % Populate rest of traces 34 | for k=1:K 35 | t = time_to_state_pos(k); 36 | for agent=1:N 37 | % Find a feasible destination 38 | %if isempty(find(W{agent}(:,t)==1)) 39 | %disp(['agent: ', num2str(agent), ' time: ', num2str(t)]) 40 | %end 41 | traces(agent, k) = find(abs(W{agent}(:,t)-1)< 1e-4); 42 | end 43 | end 44 | 45 | % % Test that it worked 46 | % w_test = zeros(I,K); 47 | % for k=1:K 48 | % for n=1:N 49 | % state = traces(n,k); 50 | % w_test(state,k) = w_test(state,k) + 1; 51 | % end 52 | % end 53 | % for k=1:5 54 | % assert(sum(abs(w_test(:,k) - WT(:,k))) == 0) 55 | % end 56 | 57 | clf; 58 | set(gca, 'LooseInset', get(gca,'TightInset')) 59 | 60 | % define a gridworld 61 | grid_size = [8, 15]; 62 | mygrid = ones(grid_size); 63 | 64 | mygrid(1:4, 1:5) = 0.8; 65 | mygrid(1:4, 11:15) = 0.6; 66 | 67 | % narrow passage 68 | % mygrid(2, 6:8) = 0.4; 69 | % mygrid(3, 8:10) = 0.4; 70 | mygrid(2:3, 6:10) = 0.4; 71 | 72 | % Obstacles 73 | mygrid([1,4], 6:10) = 0; 74 | % mygrid([2,4], [4,7]) = 0; 75 | mygrid(6:7, 13:14) = 0; 76 | 77 | %%%%%%%%%%% 78 | 79 | state_labels = mygrid(:); 80 | 81 | Pass = find(state_labels(:)==0.4)'; 82 | pass = num2str(Pass); 83 | Room1 = find(state_labels(:)==0.8)'; 84 | room1 = num2str(Room1); 85 | Room2 = find(state_labels(:)==0.6)'; 86 | room2 = num2str(Room2); 87 | Room3 = find(state_labels(:)==1)'; 88 | room3 = num2str(Room3); 89 | 90 | % charging station 91 | mygrid(1:2,1:2) = 0.2; 92 | mygrid(1:2,14:15) = 0.2; 93 | mygrid(7:8,1:2) = 0.2; 94 | %mygrid(9:10,9:10) = 0.2; 95 | state_labels = mygrid(:); 96 | 97 | CS = find(state_labels(:)==.2)'; 98 | CS = num2str(CS); 99 | 100 | % visualization 101 | vis = zeros(size(mygrid)+2); 102 | vis(2:end-1,2:end-1)=mygrid; 103 | %imshow(kron(vis,ones(25,25))) 104 | 105 | pass_ends = [23,73,Pass]; 106 | 107 | % spec is the conjunction of the following 108 | Obs = state_labels(:)==0; 109 | % 110 | % T = [1 6 10 11 12 20 33 41];% 111 | T= [1 9 10 13 14 15 17 20 21 22 23 31]; 112 | T = 1:40;%[1 2 3 6 7 8 14 15 16 20 30 31]; 113 | cmap = jet(N); 114 | pos_diff = [[0., 0.]; [0.3,0.3]; [0.3,-0.3]; [-0.3,-0.3]; [-0.3,0.3]]; 115 | 116 | axis off 117 | clf; 118 | ha = tight_subplot(4,10, [0.05 0.01], [0.01 0.04], 0.01); 119 | for i=1:length(T) 120 | axes(ha(i)) 121 | hold on; xlim([0.5, 15.5]); ylim([0.5, 8.5]) 122 | imshow(kron(mygrid,ones(25,25)), 'xdata', [0.5,15.5], 'ydata', [0.5,8.5]) 123 | rectangle('position',[0.5 0.5 15 8],'LineWidth',2); 124 | % if i == loopBegins || i == length(ZLoop)+1 125 | % rectangle('position',[0.5 0.5 10 10],'LineWidth',2,'EdgeColor','r'); 126 | % end 127 | %occup = ones(100,1); 128 | for n=1:N 129 | current_state = traces(n, T(i)); 130 | diff_ = [0 0];%pos_diff(occup(current_state),:); 131 | xpos = ind_to_pos_x(current_state) + diff_(1); 132 | ypos = ind_to_pos_y(current_state) + diff_(2); 133 | %occup(current_state) = occup(current_state) + 1; 134 | plot(xpos, ypos, 'o', 'color', cmap(n,:), ... 135 | 'markersize', 5, 'MarkerFaceColor', cmap(n,:)) 136 | if current_state ~= traces(n, T(i)+1) 137 | arrow_dest_x = xpos + (ind_to_pos_x(traces(n, T(i)+1))+ diff_(1) - xpos)*0.75; 138 | arrow_dest_y = ypos + (ind_to_pos_y(traces(n, T(i)+1))+ diff_(2) - ypos)*0.75; 139 | arrow([xpos, ypos], [arrow_dest_x, arrow_dest_y], 'length', 4, 'baseangle', 90, 'tipangle', 30, 'color', cmap(n,:)); 140 | end 141 | end 142 | title(['$$t=', num2str(T(i)), '$$'],'Interpreter','latex') 143 | end 144 | print -depsc traces.eps 145 | 146 | fig = gcf; 147 | fig.PaperPositionMode = 'auto' 148 | fig_pos = fig.PaperPosition; 149 | fig.PaperSize = [fig_pos(3) fig_pos(4)]; 150 | print(fig,filename,'-dpdf') 151 | 152 | 153 | -------------------------------------------------------------------------------- /cLTL+/lib/plot_trace_grid.m: -------------------------------------------------------------------------------- 1 | clear all 2 | %filename = './data/GOBLUE_40horizon_2tau_2017_3_20_21h32m'; 3 | load(filename) 4 | %Mw = noSwapping(Mw); 5 | fps = 12; 6 | 7 | % % Loop closes at 10 8 | % 9 | % % Gives state vector index in loop at 'time' 10 | % time_to_state_pos = @(time) (time<=20)*(time) + (time>20)*(10 + mod(time-10, 11)); 11 | % 12 | % % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 13 | % time_to_control_pos = @(time) (time<=19)*(time-1) + (time>19)*(10 + mod(time-11, 11)); 14 | 15 | k = length(ZLoop); 16 | loopBegins = find(ZLoop(:)==1,1); 17 | 18 | % Gives state vector index in loop at 'time' 19 | time_to_state_pos = @(time) (time<=k)*(time) + (time>k)*(loopBegins + mod(time-k-1, k-loopBegins+1)); 20 | 21 | % Gives control index in loop at 'time'-1 (to be used to obtain state at 'time') 22 | time_to_control_pos = @(time) (time<=k+1)*(time-1) + (time>k+1)*(loopBegins + mod(time-k-2, k-loopBegins+1)); 23 | 24 | 25 | % Return coordinates in a grid world 26 | ind_to_pos_x = @(ind) (1+floor((ind-1)/10)); 27 | ind_to_pos_y = @(ind) (1+mod((ind-1),10)); 28 | 29 | I = size(A,2); % num of states 30 | N = length(W); % num of agents 31 | K = 2*size(W{1},2); % horizon 32 | 33 | traces = zeros(N, K); 34 | 35 | 36 | % Populate rest of traces 37 | for k=1:K 38 | t = time_to_state_pos(k); 39 | for agent=1:N 40 | % Find a feasible destination 41 | %if isempty(find(W{agent}(:,t)==1)) 42 | %disp(['agent: ', num2str(agent), ' time: ', num2str(t)]) 43 | %end 44 | traces(agent, k) = find(abs(W{agent}(:,t)-1)< 1e-4); 45 | end 46 | end 47 | 48 | % % Test that it worked 49 | % w_test = zeros(I,K); 50 | % for k=1:K 51 | % for n=1:N 52 | % state = traces(n,k); 53 | % w_test(state,k) = w_test(state,k) + 1; 54 | % end 55 | % end 56 | % for k=1:5 57 | % assert(sum(abs(w_test(:,k) - WT(:,k))) == 0) 58 | % end 59 | 60 | clf; 61 | set(gca, 'LooseInset', get(gca,'TightInset')) 62 | 63 | % NO's gridworld 64 | grid_size = [10 10]; 65 | grid = ones(grid_size); 66 | 67 | grid(1:5, 1:5) = 0.8; 68 | grid(1:5, 6:10) = 0.6; 69 | 70 | % narrow passage 71 | grid(3, 4:7) = 0.4; 72 | 73 | 74 | % Obstacles 75 | grid([1:2,4:5], 5:6) = 0; 76 | grid([2,4], [4,7]) = 0; 77 | %mygrid([1:2,4:5], 4:7) = 0; 78 | grid([8,9], [7,8]) = 0; 79 | 80 | % charging station 81 | grid(1:2,1:2) = 0.2; 82 | grid(1:2,9:10) = 0.2; 83 | grid(9:10,1:2) = 0.2; 84 | 85 | vis = zeros(size(grid)+2); 86 | vis(2:end-1,2:end-1)=grid; 87 | 88 | T = 1:70;%[1 2 9 10 11 12 13 14 18 19 20 21]; 89 | cmap = jet(N); 90 | pos_diff = [[0., 0.]; [0.3,0.3]; [0.3,-0.3]; [-0.3,-0.3]; [-0.3,0.3]]; 91 | v = VideoWriter('newmovie.avi'); 92 | v.FrameRate = 2*fps; 93 | open(v); 94 | %axis off 95 | %ha = tight_subplot(3,7, [0.05 0.01], [0.01 0.04], 0.01); 96 | for i=1:length(T)-1 97 | %axes(ha(i)) 98 | for f = 1:fps 99 | figure(1) 100 | clf; 101 | hold on; xlim([0.5, 10.5]); ylim([0.5, 10.5]) 102 | imshow(kron(grid,ones(250,250)), 'xdata', [0.5,10.5], 'ydata', [0.5,10.5]) 103 | hold on; 104 | rectangle('position',[0.5 0.5 10 10],'LineWidth',2); 105 | % if (i == loopBegins || i == size(WT,2) || i == 2*size(WT,2) - loopBegins) && (f == 1) 106 | % rectangle('position',[0.5 0.5 10 10],'LineWidth',2,'EdgeColor','r'); 107 | % end 108 | occup = ones(100,1); 109 | for n=1:N 110 | current_state = traces(n, T(i)); 111 | next_state = traces(n, T(i+1)); 112 | diff_ = pos_diff(occup(current_state),:); 113 | xpos = ind_to_pos_x(current_state) + diff_(1); 114 | ypos = ind_to_pos_y(current_state) + diff_(2); 115 | xposn = ind_to_pos_x(next_state) + diff_(1); 116 | yposn = ind_to_pos_y(next_state) + diff_(2); 117 | Xpos = (fps-f+1)*xpos/fps + (f-1)*xposn/fps; 118 | Ypos = (fps-f+1)*ypos/fps + (f-1)*yposn/fps; 119 | occup(current_state) = occup(current_state) + 1; 120 | plot(Xpos, Ypos, 'o', 'color', cmap(n,:), ... 121 | 'markersize', 25, 'MarkerFaceColor', cmap(n,:)) 122 | % if current_state ~= traces(n, T(i)+1) 123 | % arrow_dest_x = Xpos + (ind_to_pos_x(traces(n, T(i)+1))+ diff_(1) - Xpos)*0.75; 124 | % arrow_dest_y = Ypos + (ind_to_pos_y(traces(n, T(i)+1))+ diff_(2) - Ypos)*0.75; 125 | % arrow([Xpos, Ypos], [arrow_dest_x, arrow_dest_y], 'length', 4, 'baseangle', 90, 'tipangle', 30, 'color', cmap(n,:)); 126 | % end 127 | end 128 | title(['$$t=', num2str((T(i)-1)+(f-1)/fps), '$$'],'Interpreter','latex') 129 | hold off 130 | filename2 = sprintf('/Users/ysahin/Dropbox/MultiAgent - LTL counting/Vfinal/plots/%s_%03d.png', 'Earthquake', (T(i)-1)*fps+f-1); 131 | %print(filename2, '-dpng'); 132 | frame = getframe; 133 | writeVideo(v,frame); 134 | end 135 | end 136 | close(v) 137 | %print -depsc traces.eps -------------------------------------------------------------------------------- /cLTL/examples/simulations.m: -------------------------------------------------------------------------------- 1 | clear all;close all;clc; 2 | time = clock; 3 | filename = ['simResults' ... 4 | num2str(time(1)) '_'... % Returns year as character 5 | num2str(time(2)) '_'... % Returns month as character 6 | num2str(time(3)) '_'... % Returns day as char 7 | num2str(time(4)) 'h'... % returns hour as char.. 8 | num2str(time(5)) 'm'... %returns minute as char 9 | ]; 10 | 11 | numTrial = 10; 12 | edgeprob = (2/3); 13 | 14 | numAgents = [20, 100, 500, 1000]; 15 | %numAgents =[]; 16 | TAgents = cell(5,length(numAgents)); 17 | 18 | numStates = [100, 200];%numStates=[]; 19 | TStates = cell(5,length(numStates)); 20 | 21 | timeHorizon = [20,50,100, 200]; 22 | Th = cell(5,length(timeHorizon)); 23 | 24 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 25 | disp(' ...................Changing number of States........................') 26 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 27 | 28 | nAgent=20; 29 | h=20; 30 | 31 | for i=1:length(numStates) 32 | disp(['--------------------- #States............................',num2str(numStates(i)),]); 33 | ti = tic; 34 | nState = numStates(i); 35 | S = randperm(nState); 36 | S1 = S(1:nState/2); 37 | S2 = S(nState/2+1:end); 38 | G = S(datasample(S,3*nState/10)); 39 | G1 = G(1:nState/10); 40 | G2 = G(nState/10+1:2*nState/10); 41 | G3 = G(2*nState/10+1:3*nState/10); 42 | f1 = strcat('F(G([',num2str(S2),',',num2str(nAgent/2),']))'); 43 | fg1 = strcat('G(F([',num2str(G1),',',num2str(nAgent/3),']))'); 44 | fg2 = strcat('G(F([',num2str(G2),',',num2str(nAgent/3),']))'); 45 | fg3 = strcat('G(F([',num2str(G3),',',num2str(nAgent/3),']))'); 46 | f = strcat('And(',f1,',',fg1,',',fg2,',',fg3,')'); 47 | Obs = ones(nState,1); 48 | Obs = Obs(:) == 0; 49 | CA_flag=0; 50 | te=0; 51 | for j=1:numTrial 52 | clear Mw Z zLoop ZLoop bigM epsilon; 53 | global Mw Z zLoop ZLoop bigM epsilon; 54 | epsilon=0; 55 | tj = tic; 56 | disp(['----- #Trial................................',num2str(j)]); 57 | A = round(edgeprob*rand(nState)); 58 | W0S1 = diff([0,sort(randperm(nAgent+nState/2-1,nState/2-1)),nAgent+nState/2])-ones(1,nState/2); 59 | W0 = zeros(nState,1); 60 | W0(S1) = W0S1'; 61 | [~,~,~,mytimes] = main_template(f,A,h,W0,Obs,CA_flag); 62 | TStates{i,j} = mytimes; 63 | disp(['Time spent in main function: ', num2str(mytimes(1)) ,' seconds: (',num2str(mytimes(2:end)),')']) 64 | te = toc(tj); 65 | disp(['Time spent in trial #',num2str(j) ,': ',num2str(te),' seconds']); 66 | save(filename,'TAgents','TAgents','TStates','TStates','Th','Th'); 67 | end 68 | te = te + toc(ti); 69 | disp(['Avg Time spent in ', num2str(numTrial),' trial(s): ',num2str(te/numTrial), ' seconds']); 70 | end 71 | 72 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 73 | disp('...................Changing number of Agents........................') 74 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 75 | h=20; 76 | nState=100; 77 | S = randperm(nState); 78 | S1 = S(1:nState/2); 79 | S2 = S(nState/2+1:end); 80 | G = S(datasample(S,3*nState/10)); 81 | G1 = G(1:nState/10); 82 | G2 = G(nState/10+1:2*nState/10); 83 | G3 = G(2*nState/10+1:3*nState/10); 84 | Obs = ones(nState,1); 85 | Obs = Obs(:) == 0; 86 | CA_flag=0; 87 | 88 | for i=1:length(numAgents) 89 | ti=tic; 90 | disp(['#################### Agents............................',num2str(numAgents(i)),]); 91 | nAgent = numAgents(i); 92 | f1 = strcat('F(G([',num2str(S2),',',num2str(nAgent/2),']))'); 93 | fg1 = strcat('G(F([',num2str(G1),',',num2str(round(nAgent/5)),']))'); 94 | fg2 = strcat('G(F([',num2str(G2),',',num2str(round(nAgent/5)),']))'); 95 | fg3 = strcat('G(F([',num2str(G3),',',num2str(round(nAgent/5)),']))'); 96 | f = strcat('And(',f1,',',fg1,',',fg2,',',fg3,')'); 97 | te = 0; 98 | for j=1:numTrial 99 | clear Mw Z zLoop ZLoop bigM epsilon; 100 | global Mw Z zLoop ZLoop bigM epsilon; 101 | epsilon=0; 102 | tj=tic; 103 | disp(['######Trial................................',num2str(j)]); 104 | A = round(edgeprob*rand(nState)); 105 | W0S1 = diff([0,sort(randperm(nAgent+nState/2-1,nState/2-1)),nAgent+nState/2])-ones(1,nState/2); 106 | W0 = zeros(nState,1); 107 | W0(S1) = W0S1'; 108 | [~,~,~,mytimes] = main_template(f,A,h,W0,Obs,CA_flag); 109 | TAgents{i,j} = mytimes; 110 | disp(['Time spent in main function: ', num2str(mytimes(1)) ,' seconds: (',num2str(mytimes(2:end)),')']) 111 | te = toc(tj); 112 | disp(['Time elapsed in trial #',num2str(j) ,': ',num2str(te),' seconds']); 113 | save(filename,'TAgents','TAgents','TStates','TStates','Th','Th'); 114 | end 115 | te = te+ toc(ti); 116 | disp(['Time elapsed in ', num2str(numTrial),' trial(s): ',num2str(te/numTrial), ' seconds']); 117 | end 118 | 119 | 120 | 121 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 122 | disp(' ...................Changing k.......................................') 123 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 124 | 125 | nAgent=20; 126 | nState=100; 127 | S = randperm(nState); 128 | S1 = S(1:nState/2); 129 | S2 = S(nState/2+1:end); 130 | G = S(datasample(S,5*nState/10)); 131 | G1 = G(1:nState/10); 132 | G2 = G(nState/10+1:2*nState/10); 133 | G3 = G(2*nState/10+1:3*nState/10); 134 | G4 = G(3*nState/10+1:4*nState/10); 135 | G5 = G(4*nState/10+1:5*nState/10); 136 | f1 = strcat('F(G([',num2str(S2),',',num2str(nAgent/2),'])'); 137 | fg1 = strcat('G(F([',num2str(G1),',',num2str(round(nAgent/5)),']))'); 138 | fg2 = strcat('G(F([',num2str(G2),',',num2str(round(nAgent/5)),']))'); 139 | fg3 = strcat('G(F([',num2str(G3),',',num2str(round(nAgent/5)),']))'); 140 | ff = strcat('F(And([',num2str(G1),',',num2str(3),']'); 141 | %ff = strcat(ff,',F(And([',num2str(G2),',',num2str(3),']'); 142 | Obs = ones(nState,1); 143 | Obs = Obs(:) == 0; 144 | CA_flag=0; 145 | 146 | for i=1:length(timeHorizon) 147 | ti = tic; 148 | disp(['#################### k............................',num2str(timeHorizon(i)),]); 149 | h = timeHorizon(2); 150 | if h == timeHorizon(2) || h==timeHorizon(3) 151 | ff2 = strcat(ff,',F(And([',num2str(G3),',',num2str(3),']))'); 152 | %ff2 = strcat(ff2,',F(And([',num2str(G4),',',num2str(3),']))))'); 153 | elseif h==timeHorizon(4) 154 | ff2 = strcat(ff,',F(And([',num2str(G3),',',num2str(3),']'); 155 | ff2 = strcat(ff2,',F(And([',num2str(G4),',',num2str(3),']'); 156 | ff2 = strcat(ff2,',F(And([',num2str(G5),',',num2str(3),']))))))'); 157 | else 158 | ff2 = ff; 159 | end 160 | ff3 = strcat(ff2,'))'); 161 | f = strcat('And(',f1,',',fg1,',',fg2,',',fg3,',',ff3,')'); 162 | te = 0; 163 | for j=1:numTrial 164 | clear Mw Z zLoop ZLoop bigM epsilon; 165 | global Mw Z zLoop ZLoop bigM epsilon; 166 | epsilon=0; 167 | disp(['######Trial................................',num2str(j)]); 168 | tj =tic; 169 | A = round(edgeprob*rand(nState)); 170 | W0S1 = diff([0,sort(randperm(nAgent+nState/2-1,nState/2-1)),nAgent+nState/2])-ones(1,nState/2); 171 | W0 = zeros(nState,1); 172 | W0(S1) = W0S1'; 173 | [~,~,~,mytimes] = main_template(f,A,h,W0,Obs,CA_flag); 174 | Th{i,j} = mytimes; 175 | disp(['Time spent in main function: ', num2str(mytimes(1)) ,' seconds: (',num2str(mytimes(2:end)),')']) 176 | te = toc(tj); 177 | disp(['Time elapsed in trial #',num2str(j) ,': ',num2str(te),' seconds']); 178 | end 179 | te = te+ toc(ti); 180 | disp(['Time elapsed in ', num2str(numTrial),' trial(s): ',num2str(te/numTrial), ' seconds']); 181 | save(filename,'TAgents','TAgents','TStates','TStates','Th','Th'); 182 | end 183 | 184 | 185 | pause; 186 | 187 | -------------------------------------------------------------------------------- /cLTL/examples/simulationsTemplates.m: -------------------------------------------------------------------------------- 1 | clear all;close all;clc; 2 | time = clock; 3 | filename = ['simTempResults' ... 4 | num2str(time(1)) '_'... % Returns year as character 5 | num2str(time(2)) '_'... % Returns month as character 6 | num2str(time(3)) '_'... % Returns day as char 7 | num2str(time(4)) 'h'... % returns hour as char.. 8 | num2str(time(5)) 'm'... %returns minute as char 9 | ]; 10 | 11 | numTrial = 10; 12 | edgeprob = (2/3); 13 | 14 | numAgents = [20, 100, 5000, 100000];%numAgents=[]; 15 | TAgents = cell(5,length(numAgents)); 16 | 17 | numStates = [100, 200, 500]; 18 | %numStates=[]; 19 | TStates = cell(5,length(numStates)); 20 | 21 | timeHorizon = [20,50,100,200]; 22 | Th = cell(5,length(timeHorizon)); 23 | 24 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 25 | disp(' ...................Changing number of States........................') 26 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 27 | 28 | nAgent=20; 29 | h=20; 30 | 31 | for i=1:length(numStates) 32 | disp(['--------------------- #States............................',num2str(numStates(i)),]); 33 | ti = tic; 34 | nState = numStates(i); 35 | S = randperm(nState); 36 | S1 = S(1:nState/2); 37 | S2 = S(nState/2+1:end); 38 | G = S(datasample(S,3*nState/10)); 39 | G1 = G(1:nState/10); 40 | G2 = G(nState/10+1:2*nState/10); 41 | G3 = G(2*nState/10+1:3*nState/10); 42 | f1 = strcat('FG([',num2str(S2),',',num2str(nAgent/2),'])'); 43 | fg1 = strcat('GF([',num2str(G1),',',num2str(nAgent/3),'])'); 44 | fg2 = strcat('GF([',num2str(G2),',',num2str(nAgent/3),'])'); 45 | fg3 = strcat('GF([',num2str(G3),',',num2str(nAgent/3),'])'); 46 | f = strcat('And(',f1,',',fg1,',',fg2,',',fg3,')'); 47 | Obs = ones(nState,1); 48 | Obs = Obs(:) == 0; 49 | CA_flag=0; 50 | te=0; 51 | for j=1:numTrial 52 | clear Mw Z zLoop ZLoop bigM epsilon; 53 | global Mw Z zLoop ZLoop bigM epsilon; 54 | epsilon=0; 55 | tj = tic; 56 | disp(['----- #Trial................................',num2str(j)]); 57 | A = round(edgeprob*rand(nState)); 58 | W0S1 = diff([0,sort(randperm(nAgent+nState/2-1,nState/2-1)),nAgent+nState/2])-ones(1,nState/2); 59 | W0 = zeros(nState,1); 60 | W0(S1) = W0S1'; 61 | [~,~,~,mytimes] = main_template(f,A,h,W0,Obs,CA_flag); 62 | TStates{i,j} = mytimes; 63 | disp(['Time spent in main function: ', num2str(mytimes(1)) ,' seconds: (',num2str(mytimes(2:end)),')']) 64 | te = toc(tj); 65 | disp(['Time spent in trial #',num2str(j) ,': ',num2str(te),' seconds']); 66 | save(filename,'TAgents','TAgents','TStates','TStates','Th','Th'); 67 | end 68 | te = te + toc(ti); 69 | disp(['Avg Time spent in ', num2str(numTrial),' trial(s): ',num2str(te/numTrial), ' seconds']); 70 | end 71 | 72 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 73 | disp('...................Changing number of Agents........................') 74 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 75 | h=20; 76 | nState=100; 77 | S = randperm(nState); 78 | S1 = S(1:nState/2); 79 | S2 = S(nState/2+1:end); 80 | G = S(datasample(S,3*nState/10)); 81 | G1 = G(1:nState/10); 82 | G2 = G(nState/10+1:2*nState/10); 83 | G3 = G(2*nState/10+1:3*nState/10); 84 | Obs = ones(nState,1); 85 | Obs = Obs(:) == 0; 86 | CA_flag=0; 87 | 88 | for i=1:length(numAgents) 89 | ti=tic; 90 | disp(['#################### Agents............................',num2str(numAgents(i)),]); 91 | nAgent = numAgents(i); 92 | f1 = strcat('FG([',num2str(S2),',',num2str(nAgent/2),'])'); 93 | fg1 = strcat('GF([',num2str(G1),',',num2str(round(nAgent/5)),'])'); 94 | fg2 = strcat('GF([',num2str(G2),',',num2str(round(nAgent/5)),'])'); 95 | fg3 = strcat('GF([',num2str(G3),',',num2str(round(nAgent/5)),'])'); 96 | f = strcat('And(',f1,',',fg1,',',fg2,',',fg3,')'); 97 | te = 0; 98 | for j=1:numTrial 99 | clear Mw Z zLoop ZLoop bigM epsilon; 100 | global Mw Z zLoop ZLoop bigM epsilon; 101 | epsilon=0; 102 | tj=tic; 103 | disp(['######Trial................................',num2str(j)]); 104 | A = round(edgeprob*rand(nState)); 105 | W0S1 = diff([0,sort(randperm(nAgent+nState/2-1,nState/2-1)),nAgent+nState/2])-ones(1,nState/2); 106 | W0 = zeros(nState,1); 107 | W0(S1) = W0S1'; 108 | [~,~,~,mytimes] = main_template(f,A,h,W0,Obs,CA_flag); 109 | TAgents{i,j} = mytimes; 110 | disp(['Time spent in main function: ', num2str(mytimes(1)) ,' seconds: (',num2str(mytimes(2:end)),')']) 111 | te = toc(tj); 112 | disp(['Time elapsed in trial #',num2str(j) ,': ',num2str(te),' seconds']); 113 | save(filename,'TAgents','TAgents','TStates','TStates','Th','Th'); 114 | end 115 | te = te+ toc(ti); 116 | disp(['Time elapsed in ', num2str(numTrial),' trial(s): ',num2str(te/numTrial), ' seconds']); 117 | end 118 | 119 | 120 | 121 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 122 | disp(' ...................Changing k.......................................') 123 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 124 | 125 | nAgent=20; 126 | nState=100; 127 | S = randperm(nState); 128 | S1 = S(1:nState/2); 129 | S2 = S(nState/2+1:end); 130 | G = S(datasample(S,5*nState/10)); 131 | G1 = G(1:nState/10); 132 | G2 = G(nState/10+1:2*nState/10); 133 | G3 = G(2*nState/10+1:3*nState/10); 134 | G4 = G(3*nState/10+1:4*nState/10); 135 | G5 = G(4*nState/10+1:5*nState/10); 136 | f1 = strcat('FG([',num2str(S2),',',num2str(nAgent/2),'])'); 137 | fg1 = strcat('GF([',num2str(G1),',',num2str(round(nAgent/5)),'])'); 138 | fg2 = strcat('GF([',num2str(G2),',',num2str(round(nAgent/5)),'])'); 139 | fg3 = strcat('GF([',num2str(G3),',',num2str(round(nAgent/5)),'])'); 140 | ff = strcat('F(And([',num2str(G1),',',num2str(3),']'); 141 | %ff = strcat(ff,',F(And([',num2str(G2),',',num2str(3),']'); 142 | Obs = ones(nState,1); 143 | Obs = Obs(:) == 0; 144 | CA_flag=0; 145 | 146 | for i=1:length(timeHorizon) 147 | ti = tic; 148 | disp(['#################### k............................',num2str(timeHorizon(i)),]); 149 | h = timeHorizon(i); 150 | if h == timeHorizon(2) || h==timeHorizon(3) 151 | ff2 = strcat(ff,',F(And([',num2str(G3),',',num2str(3),']))'); 152 | %ff2 = strcat(ff2,',F(And([',num2str(G4),',',num2str(3),']))))'); 153 | elseif h==timeHorizon(4) 154 | ff2 = strcat(ff,',F(And([',num2str(G3),',',num2str(3),']'); 155 | ff2 = strcat(ff2,',F(And([',num2str(G4),',',num2str(3),']'); 156 | ff2 = strcat(ff2,',F(And([',num2str(G5),',',num2str(3),']))))))'); 157 | else 158 | ff2 = ff; 159 | end 160 | ff3 = strcat(ff2,'))'); 161 | f = strcat('And(',f1,',',fg1,',',fg2,',',fg3,',',ff3,')'); 162 | te = 0; 163 | for j=1:numTrial 164 | clear Mw Z zLoop ZLoop bigM epsilon; 165 | global Mw Z zLoop ZLoop bigM epsilon; 166 | epsilon=0; 167 | disp(['######Trial................................',num2str(j)]); 168 | tj =tic; 169 | A = round(edgeprob*rand(nState)); 170 | W0S1 = diff([0,sort(randperm(nAgent+nState/2-1,nState/2-1)),nAgent+nState/2])-ones(1,nState/2); 171 | W0 = zeros(nState,1); 172 | W0(S1) = W0S1'; 173 | [~,~,~,mytimes] = main_template(f,A,h,W0,Obs,CA_flag); 174 | Th{i,j} = mytimes; 175 | disp(['Time spent in main function: ', num2str(mytimes(1)) ,' seconds: (',num2str(mytimes(2:end)),')']) 176 | te = toc(tj); 177 | disp(['Time elapsed in trial #',num2str(j) ,': ',num2str(te),' seconds']); 178 | end 179 | te = te+ toc(ti); 180 | disp(['Time elapsed in ', num2str(numTrial),' trial(s): ',num2str(te/numTrial), ' seconds']); 181 | save(filename,'TAgents','TAgents','TStates','TStates','Th','Th'); 182 | end 183 | 184 | 185 | disp(['--------------------------------------------']); 186 | disp(['--------------------------------------------']) 187 | 188 | disp(['--------------------------------------------']) 189 | 190 | disp(['--------------------------------------------']) 191 | 192 | 193 | simulations; 194 | 195 | --------------------------------------------------------------------------------