classdef TGaxResidential < rfprop.PropagationModel
%TGaxResidential Propagation model for WLAN TGax Residential scenario.
%   PM = TGaxResidential creates a propagation model of type
%   TGaxResidential
%
%   PM = creates a propagation model for TGaxResidential scenario, with
%   additional properties specified by one or more name-value pair
%   arguments. Properties you do not specify retain their default values.
%
%   TGaxResidential properties:
%
%      RoomSize    - Room size [x y z] in meters
%      ShadowSigma - Large-scale shadow fading standard deviation id dB
%
%   TGaxResidential methods:
%
%      pathloss - Path loss of radio wave propagation

%   Copyright 2019-2020 The MathWorks, Inc.  
        
    properties
        %RoomSize Room size [x y z] in meters
        %   Specify the room size [x y z] in meters. The default is [10 10
        %   3].
        RoomSize(1,3) double {mustBeFinite, mustBeReal, mustBeNonnegative, mustBeNonsparse} = [10 10 3];
        %ShadowSigma Large-scale shadow fading standard deviation id dB
        %   Specify the large scale shadow fading standard deviation in dB.
        %   The default is 5 dB.
        ShadowSigma(1,1) double {mustBeFinite, mustBeReal, mustBeNonnegative, mustBeNonsparse} = 5;
    end

    methods(Access = protected)
        function pl = pathlossOverDistance(pm, rxs, tx, d, ~)        
            % Path loss
            pl = wlanresidentialpl(pm,d,tx.TransmitterFrequency);

            tmpA = [tx.AntennaPosition]';
            tmpB = [rxs.AntennaPosition]';

            xA = tmpA(:,1);
            yA = tmpA(:,2);
            zA = tmpA(:,3);
            
            xB = tmpB(:,1);
            yB = tmpB(:,2);
            zB = tmpB(:,3);

            % Penetration loss
            pnl = wlanresidentialpnl(pm,xA,yA,zA,xB,yB,zB);
            
            % Large-scale shadow fading
            sf = pm.ShadowSigma*randn(size(pl));
            
            pl = pl + pnl + sf;
        end 
         
    end
    
    methods (Access = protected)
        
        function L = wlanresidentialpl(~,R,freq)
            %wlanresidentialpl     wlanresidential path loss
            %   L = wlanresidential() returns the WLAN Residential scenario path loss  in dB.
            %
            %   Note that the best case is lossless so the loss is always greater than
            %   or equal to 0 dB.
            
            R = max(R,1); % minimum distance is 1 meter
            L = 40.05+20*log10(freq/2.4e9) + 20*log10(min(R,5)) + 35*(R>5).*log10(R/5);
            
        end
        
        function L = wlanresidentialpnl(pm,xA,yA,zA,xB,yB,zB)
            %wlanresidentialpnl     wlanresidential penetration loss
            %   L = wlanresidentialpnl() returns the WLAN Residential scenario path loss  in dB.
            %
            %   Note that the best case is lossless so the loss is always greater than
            %   or equal to 0 dB.
            
            numSitesA = length(xA);
            numSitesB = length(xB);
            
            % replicate arrays
            xA = repmat(xA(:),[1,numSitesB]);
            yA = repmat(yA(:),[1,numSitesB]);
            zA = repmat(zA(:),[1,numSitesB]);
            xB = repmat(xB(:).',[numSitesA,1]);
            yB = repmat(yB(:).',[numSitesA,1]);
            zB = repmat(zB(:).',[numSitesA,1]);
            
            % number of walls/floors traversed
            numWallsX = abs(floor(xB/pm.RoomSize(1)) - floor(xA/pm.RoomSize(1)));
            numWallsY = abs(floor(yB/pm.RoomSize(2)) - floor(yA/pm.RoomSize(2)));
            numWalls = numWallsX + numWallsY;
            
            numFloors = abs(floor(zB/pm.RoomSize(3)) - floor(zA/pm.RoomSize(3)));
            
            % penetration loss
            L = 18.3*numFloors.^((numFloors+2)./(numFloors+1) -0.46) + 5*numWalls;
            
        end
        
    end
    
end

