classdef FreeSpace < rfprop.PropagationModel
%FreeSpace   Free space propagation model
%   PM = propagationModel('freespace') creates a free space propagation
%   model.
%
%   FreeSpace methods:
%
%      add      - Add propagation models
%      pathloss - Path loss of radio wave propagation
%      range    - Range of radio wave propagation 

%   Copyright 2017-2019 The MathWorks, Inc.   

    methods(Access = protected)
        function pl = pathlossOverDistance(~, ~, tx, d, ~)
            lambda = rfprop.Constants.LightSpeed/tx.TransmitterFrequency;
            pl = fspl(d,lambda);
        end
    end
    
    methods
        function r = range(pm, txs, pl)
            %range   Range of radio wave propagation
            %   R = range(PROPMODEL,TX,PL) returns the range of radio wave propagation
            %   from transmitter site TX. The range is the maximum distance in meters
            %   for which path loss does not exceed PL, assuming no obstacles. The path
            %   loss PL is specified in dB as a numeric scalar.
            %
            %   The input TX can be scalar or an array. The output R is an array of
            %   size M-by-1, where M is the number of sites in TX.
            %
            %   See also pathloss, txsite/coverage
            
            % Override range since model has equation to compute instead of
            % using fzero to find answer
            
            % Validate inputs
            validateattributes(pm,{'rfprop.FreeSpace'}, ...
                {'scalar'},'range','',1);
            validateattributes(txs,{'txsite'},{'nonempty'},'range','',2);
            validateattributes(pl,{'numeric'}, ...
                {'real','finite','nonnan','nonsparse','scalar'},'range','',3);
            
            numTx = numel(txs);
            r = zeros(numTx,1);
            for txInd = 1:numel(txs)
                tx = txs(txInd);
                maxrange = pm.fsrange(tx.TransmitterFrequency, pl);
                r(txInd) = validateRange(pm, maxrange);
            end
        end
    end
    
    % Use static method for range computation so it can be called by
    % rfprop.PropagationModel.range
    methods(Static, Hidden)
        function d = fsrange(fq,pl)
            lambda = rfprop.Constants.LightSpeed/fq;
            d = (lambda*(10^(pl/20)))/(4*pi);
        end
    end
end

