function varargout = sinr(txs, varargin)
%sinr Display or compute signal-to-interference-plus-noise (SINR) ratio
% sinr(TXS) displays an SINR map in the current Site Viewer given
% transmitter sites TXS. Each colored contour of the map defines the area
% of the corresponding SINR in dB for a mobile receiver. The map contours
% are generated using SINR values computed for receiver site locations on
% the map. For each location, the signal source is the transmitter site
% in TXS with the greatest signal strength. The remaining transmitter
% sites in TXS with the same TransmitterFrequency as the signal source
% act as sources of interference. If TXS is scalar or there are no
% sources of interference, the resultant map displays signal-to-noise
% ratio (SNR).
%
% sinr(TXS,PROPMODEL) displays an SINR map with the PropagationModel
% argument set to PROPMODEL. The default value depends on the coordinate
% system in use by the input sites:
%
% CoordinateSystem | Default PropagationModel value
% --------------------------------------------------------------------
% 'geographic' | 'longley-rice' when terrain is in use or else
% | 'freespace' when terrain is not in use
% --------------------------------------------------------------------
% 'cartesian' | 'freespace' when Map is 'none' or else
% | 'raytracing' when Map is an STL file or
% | triangulation object
%
% sinr(___,Name,Value) plots SINR on a map with additional options
% specified by one or more Name-Value pairs.
%
% This function only supports plotting antenna sites with
% CoordinateSystem set to 'geographic'.
%
% PD = sinr(TXS,___) returns computed SINR data in propagation data
% object PD. No plot is displayed and any graphical-only Name-value pairs
% are ignored. This syntax is only supported for antenna sites with
% CoordinateSystem set to 'geographic'.
%
% R = sinr(RXS,TXS,___) returns the SINR in dB computed at receiver sites
% RXS due to transmitter sites TXS.
%
% sinr Name-Value pairs:
%
% SignalSource - Source of signal of interest, specified as 'strongest'
% (the default value) or as a txsite scalar. When SignalSource is
% 'strongest', the transmitter site with the greatest signal strength
% for each location is selected as the signal source for that
% location. When computing SINR, SignalSource may be a txsite array of
% equal number of elements as RXS, where each txsite element defines
% the signal source for the corresponding rxsite.
%
% PropagationModel - Propagation model for path loss calculation,
% specified as an object created with propagationModel or as one of
% the following options:
%
% 'freespace' - Free space propagation model
% 'rain' - Propagation model for rain
% 'gas' - Propagation model for gas
% 'fog' - Propagation model for fog
% 'close-in' - Close-In propagation model
% 'longley-rice' - Longley-Rice propagation model
% 'tirem' - Terrain Integrated Rough Earth Model (TIREM)
% 'raytracing' - Ray tracing propagation model
%
% Terrain propagation models, including the 'longley-rice' and 'tirem'
% options, are only supported for sites with CoordinateSystem set to
% 'geographic'. The default value is described in the main help above.
%
% ReceiverNoisePower - Total noise power of receiver in dBm, specified
% as a numeric scalar. The default value is -107, which assumes
% receiver bandwidth of 1 MHz and receiver noise figure of 7 dB.
%
% ReceiverGain - Receiver's gain in dB, specified as a numeric scalar.
% ReceiverGain includes the receiver's antenna gain and system loss.
% If the function is called with an output argument, the default value
% is computed using RXS. Otherwise, the default value is 2.1.
%
% ReceiverAntennaHeight - Receiver's antenna height above ground
% elevation in meters, specified as a numeric scalar. If the function
% is called with an output argument, the default value is computed
% using RXS. Otherwise, the default value is 1.
%
% Map - Map for visualization and/or surface geometry data. Valid and
% default values depend on the coordinate system in use by the input
% sites:
%
% Coordinate
% system | Valid Map values | Default Map value
% --------------------------------------------------------------------
% 'geographic' | siteviewer object or terrain | current siteviewer or
% | name if called with an output | else new siteviewer
% | ('none', 'gmted2010', or the | if none is open, or
% | name of custom terrain data | 'gmted2010' if called
% | previously added with | with an output
% | addCustomTerrain) |
% --------------------------------------------------------------------
% 'cartesian' | 'none', triangulation object, | 'none'
% | or the name of an STL file |
%
% sinr Name-Value pairs applicable when plotting SINR:
%
% Values - Values of SINR to plot, specified as a numeric vector. Each
% value is displayed as a different colored, filled contour on a map.
% The contour colors are derived using Colormap and ColorLimits.
% The default value is [-5:20].
%
% MaxRange - Maximum range of SINR plot from each transmitter site,
% specified as a positive numeric scalar in meters representing great
% circle distance. MaxRange defines the region of interest on the map
% to plot. The default value is automatically computed based on the
% propagation model model type as shown:
%
% Propagation model type | MaxRange
% ------------------------------------------------------------
% Atmospheric or Empirical | 30 km
% Terrain | 30 km or distance to furthest building
% Ray Tracing | 500 m
%
% Resolution - Resolution of receiver site locations used to compute SINR
% values, specified as 'auto' (the default value) or a numeric scalar.
% The resolution defines the maximum distance between locations. A
% Resolution of 'auto' computes the value using MaxRange. A numeric
% Resolution is expressed as a distance in meters. Decreasing the
% Resolution value increases both the quality of the SINR map and the
% time required to create it.
%
% Colormap - Colormap for coloring filled contours, specified as a
% predefined colormap name or an M-by-3 array of RGB (red, green,
% blue) triplets that define M individual colors. The default value is
% 'jet'.
%
% ColorLimits - Color limits for colormap, specified as a two-element
% vector of the form [min max]. The color limits indicate the SINR
% values that map to the first and last colors in the colormap.
% The default value is [-5 20].
%
% ShowLegend - Show signal strength color legend on map, specified as
% true or false. The default value is true.
%
% Transparency - Transparency of SINR map, specified as a numeric scalar
% in range 0 to 1, where 0 is completely transparent and 1 is opaque.
% The default value is 0.4.
%
% % Example 1: Plot SINR and compute value at a site
%
% % Define names and locations of sites around Boston
% names = ["Fenway Park","Faneuil Hall","Bunker Hill Monument"];
% lats = [42.3467,42.3598,42.3763];
% lons = [-71.0972,-71.0545,-71.0611];
%
% % Create transmitter site array
% txs = txsite("Name", names,...
% "Latitude",lats,...
% "Longitude",lons, ...
% "TransmitterFrequency",2.5e9);
% show(txs)
%
% % Create receiver site in middle of transmitter sites
% rx = rxsite("Name","Frog Pond", ...
% "Latitude",42.3562, ...
% "Longitude",-71.0658);
% show(rx)
%
% % Display SINR map, where signal source for each location is selected
% % as transmitter site with strongest signal
% sinr(txs,"close-in","MaxRange", 10000)
%
% % Calculate SINR at receiver site
% r1 = sinr(rx,txs,"close-in","ReceiverGain",2.1)
%
% % Calculate SINR with increased total noise power, specified in dBm
% r2 = sinr(rx,txs,"close-in","ReceiverGain",2.1,"ReceiverNoisePower",-90)
%
% % Example 2: Compute SINR at receiver sites due to transmitter sites in
% % an urban environment using ray tracing
%
% % Launch Site Viewer with buildings in Chicago
% viewer = siteviewer("Basemap","streets-light",...
% "Buildings","chicago.osm");
%
% % Create three transmitter sites on buildings
% txs = txsite("Latitude",[41.8800 41.8805 41.8803], ...
% "Longitude",[-87.6295,-87.6300 -87.6271], ...
% "TransmitterFrequency",2.5e9);
% show(txs)
%
% % Create two receiver sites above ground
% rxs = rxsite("Latitude", [41.8807 41.8795], ...
% "Longitude", [-87.6284 -87.6287]);
% show(rxs);
%
% % Create a ray tracing propagation model using the SBR method with up
% % to 5 reflections
% pm = propagationModel("raytracing", ...
% "Method", "sbr", ...
% "MaxNumReflections", 5);
%
% % Perform ray tracing for each pair of transmitter and receiver sites
% raytrace(txs, rxs, pm);
%
% % Compute SINR at both receiver sites using ray tracing
% r = sinr(rxs, txs, pm);
%
% See also <a href="matlab:help txsite.coverage">coverage</a>, propagationModel
% Copyright 2017-2021 The MathWorks, Inc.
% Validate number of output arguments
nargoutchk(0,1)
% Validate site
validateattributes(txs,{'txsite'},{'nonempty'},'sinr','',1);
% Add parameters
p = inputParser;
if mod(numel(varargin),2) % Odd number of inputs
% Validator function is necessary for inputParser to allow string
% option instead of treating it like parameter name
p.addOptional('PropagationModel', [], @(x)ischar(x)||isstring(x)||isa(x,'rfprop.PropagationModel'));
else
p.addParameter('PropagationModel', []);
end
p.addParameter('SignalSource', 'strongest');
p.addParameter('Values', -5:20);
p.addParameter('Resolution', 'auto');
p.addParameter('ReceiverGain', 2.1);
p.addParameter('ReceiverAntennaHeight', 1);
p.addParameter('ReceiverNoisePower', -107);
p.addParameter('Animation', '');
p.addParameter('MaxRange', []);
p.addParameter('Colormap', 'jet');
p.addParameter('ColorLimits', []);
p.addParameter('Transparency', 0.4);
p.addParameter('ShowLegend', true);
p.addParameter('ReceiverLocationsLayout', []);
p.addParameter('MaxImageResolutionFactor', 5);
p.addParameter('RadialResolutionFactor', 2);
p.addParameter('Map', []);
p.parse(varargin{:});
% Validate CoordinateSystem
usingCartesian = rfprop.internal.Validators.validateCoordinateSystem(txs);
% Get Site Viewer and validate web graphics
outputRequested = nargout > 0;
if ~outputRequested
viewer = rfprop.internal.Validators.validateMap(p, 'sinr', usingCartesian);
isViewerInitiallyVisible = viewer.Visible;
else
isViewerInitiallyVisible = false;
end
% Create vector array of all txs
sigSource = validateSignalSource(p);
txs = txs(:);
if isa(sigSource,'txsite')
if ~ismember(sigSource,txs)
txs = [txs; sigSource];
end
end
numTx = numel(txs);
if usingCartesian
error(message('shared_channel:rfprop:CoordinateSystemCartesianSINRNotSupported'));
end
% Validate parameters
map = rfprop.internal.Validators.validateMapTerrainSource(p, 'sinr');
terrainSource = rfprop.internal.Validators.validateTerrainSource(map, 'sinr');
animation = rfprop.internal.Validators.validateGraphicsControls(p, isViewerInitiallyVisible, 'sinr');
values = validateValues(p);
clim = rfprop.internal.Validators.validateColorLimits(p, [-5 20], 'sinr');
cmap = rfprop.internal.Validators.validateColorMap(p, 'sinr');
transparency = rfprop.internal.Validators.validateTransparency(p, 'sinr');
showLegend = rfprop.internal.Validators.validateShowLegend(p, 'sinr');
pm = rfprop.internal.Validators.validateGeographicPropagationModel(p, map, 'sinr');
rfprop.internal.Validators.validateMaxNumReflections(pm, 'sinr');
rxGain = rfprop.internal.Validators.validateReceiverGain(p, 'sinr');
rxAntennaHeight = rfprop.internal.Validators.validateReceiverAntennaHeight(p, 'sinr');
noisePower = validateReceiverNoisePower(p);
maxImageResFactor = p.Results.MaxImageResolutionFactor;
radialResFactor = p.Results.RadialResolutionFactor;
% Get site coordinates
txsCoords = rfprop.internal.AntennaSiteCoordinates.createFromAntennaSites(txs, map);
txslatlon = txsCoords.LatitudeLongitude;
% Validate dependent parameters
if ismember('MaxRange', p.UsingDefaults)
maxrange = rfprop.internal.Validators.defaultMaxRange(txslatlon, pm, map);
else
maxrange = rfprop.internal.Validators.validateNumericMaxRange(p.Results.MaxRange, pm, numTx, map, 'sinr');
end
[res, isAutoRes] = rfprop.internal.Validators.validateResolution(p, maxrange, 'sinr');
datarange = rfprop.internal.Validators.validateDataRange(txslatlon, maxrange, res, ~strcmp(terrainSource,'none'));
rxLocationsLayout = rfprop.internal.Validators.validateReceiverLocationsLayout(p, pm, txslatlon, 'sinr');
if outputRequested
% Do not show progress dialog
generatingMapMsg = '';
computingDataMsg = '';
else
% Clear old contour color info for each site. This is because a site can
% never conflict with itself (since a site will replot it's own contour if
% coverage is called on a site multiple times)
% Also mark the contour graphics to be removed
graphicsToRemove = {};
for k = 1:numTx
oldContourID = viewer.getGraphic(txs(k).UID, 'contour');
if (~isempty(oldContourID))
viewer.removeColorData(oldContourID);
graphicsToRemove = [graphicsToRemove; oldContourID]; %#ok<AGROW>
end
end
if ~isempty(viewer.LegendID)
graphicsToRemove = [graphicsToRemove; viewer.LegendID];
end
% Generate a new ID so old IDs don't conflict with new images
idNum = viewer.getId(1);
contourID = ['contour' num2str(idNum{1})];
% Validate image for color conflicts. This must be done before calculations
% occur to avoid wasting the user's time when color conflict occurs.
oldColorGraphics = viewer.ColorGraphics;
colorData = struct('Colormap',cmap,'ColorLimits',clim);
viewer.checkForGraphicsConflict('sinr', contourID, colorData);
resetColorGraphics = rfprop.internal.onExit(@()setColorGraphics(viewer,oldColorGraphics));
% Show txsites. If Site Viewer is already open, keep current camera view.
if isViewerInitiallyVisible && ~viewer.Visible
return % Abort if Site Viewer has been closed
end
if isViewerInitiallyVisible
showAnimation = 'none';
else
showAnimation = 'zoom';
end
show(txs,'Map',viewer,'Animation',showAnimation, ...
'AntennaSiteCoordinates', txsCoords);
% Show progress dialog. Use cleanup object to close dialog if a forced
% exit occurs (error or Ctrl-C). Use three-stage dialog if using ray
% tracing and single-stage dialog if not a terrain model. If using a
% terrain model, dialog is launched in radialReceiverLocationsLayoutData.
resetProgressDialog = rfprop.internal.onExit(@()hideProgressDialog(viewer));
showWaitbar = pm.isMultipathModel;
generatingMapMsg = message('shared_channel:rfprop:ProgressDialogGeneratingSINRMap').getString;
computingDataMsg = message('shared_channel:rfprop:ProgressDialogComputingSINR').getString;
if ~pm.requiresTerrain || strcmp(rxLocationsLayout,'grid')
if showWaitbar
msg = message('shared_channel:rfprop:ProgressDialogPreparingMapData').getString;
else
msg = generatingMapMsg;
end
viewer.showProgressDialog('Message', msg, ...
'Indeterminate', true, ...
'Cancelable', false);
end
end
% Generate location grid containing data range from each transmitter site
if isa(map,'siteviewer')
maxImageSize = map.MaxImageSize;
else
maxImageSize = rfprop.Constants.DefaultMaxImageSize;
end
[latNorth, latSouth, lonEast, lonWest, animation] = ...
rfprop.internal.MapUtils.geobounds(txslatlon, datarange, animation);
[gridlats, gridlons, res] = rfprop.internal.MapUtils.geogrid(...
latNorth, latSouth, lonEast, lonWest, res, isAutoRes, maxrange, maxImageSize, 'sinr');
gridSize = size(gridlats);
% Compute and validate image size for SINR map
imageSize = rfprop.internal.Validators.validateImageSize(...
gridSize, maxImageResFactor, maxImageSize, res, 'sinr');
% Trim grid locations to those which are within data range
[datalats, datalons] = rfprop.internal.MapUtils.georange(...
txs, gridlats(:), gridlons(:), datarange, terrainSource);
if ~outputRequested && siteViewerWasClosed(viewer)
return % Abort if Site Viewer has been closed
end
if isempty(datalats)
warning(message('shared_channel:rfprop:NoSINRMapArea'))
if outputRequested
varargout = {[]};
else
viewer.removeColorData(viewer.SiteGraphics.(txs(k).UID).contour);
viewer.remove(graphicsToRemove);
end
return
end
% Use try/catch in case cancel error thrown from waitbar dialog
try
type = 'power';
if strcmp(rxLocationsLayout,'grid')
% Define rxsites at grid locations within data range
rxs = rxsite(...
'Name', 'internal.sinrsite', ... % Specify to avoid default site naming
'Latitude', datalats, ...
'Longitude', datalons, ...
'AntennaHeight', rxAntennaHeight);
% Launch waitbar phase of dialog
if ~outputRequested && showWaitbar
viewer.showProgressDialog('Message', computingDataMsg, ...
'Value', 0, ...
'ShowPercentage', true, ...
'Indeterminate', false, ...
'Cancelable', true);
end
% Compute signal strength at each rxsite in the grid
ss = sigstrength(rxs, txs, pm, ...
'Type', type, ...
'ReceiverGain', rxGain, ...
'Map', map, ...
'TransmitterAntennaSiteCoordinates', txsCoords);
else
% Compute data and corresponding locations using radial layout
[datalats, datalons, rxs, ss] = radialReceiverLocationsLayoutData(txs, txsCoords, type, ...
generatingMapMsg, computingDataMsg, pm, map, res, radialResFactor, datarange, ...
lonWest, lonEast, latSouth, latNorth, rxGain, rxAntennaHeight);
end
catch e
if strcmp(e.identifier, "shared_channel:rfprop:ProgressDialogCancelled")
return
else
rethrow(e)
end
end
% Launch final phase of status dialog
if ~outputRequested
viewer.showProgressDialog('Message', generatingMapMsg, ...
'Indeterminate', true, ...
'Cancelable', false);
end
% Cache signal strength on site coordinates
txsCoords.addCustomData('SignalStrength', ss);
if (numTx > 1) && strcmp(rxLocationsLayout,'radial')
% Compute SINR at each rxsite in data grid, which is the same size as
% the image grid. Create a dummy rxsite to call the method, but the
% data used to compute values is passed as SignalStrength.
dummyrx = rxsite(...
'Name', 'internal.sinrsite', ...
'Latitude', datalats(1), ...
'Longitude', datalons(1));
data = sinr(dummyrx, txs, ...
'SignalSource', sigSource, ...
'ReceiverNoisePower', noisePower, ...
'PropagationModel', pm, ...
'ReceiverGain', rxGain, ...
'TransmitterAntennaSiteCoordinates', txsCoords, ...
'Map', map);
else
% Compute SINR at each rxsite in the grid
data = sinr(rxs, txs, ...
'SignalSource', sigSource, ...
'ReceiverNoisePower', noisePower, ...
'PropagationModel', pm, ...
'ReceiverGain', rxGain, ...
'TransmitterAntennaSiteCoordinates', txsCoords, ...
'Map', map);
end
if ~outputRequested && siteViewerWasClosed(viewer)
return
end
% Remove NaN-data
isnn = ~isnan(data);
data = data(isnn);
datalats = datalats(isnn);
datalons = datalons(isnn);
% Create propagation data container
pd = propagationData(datalats, datalons, ...
'Name', message('shared_channel:rfprop:SINRPropagationDataTitle').getString, ...
'SINR', data(:));
if outputRequested
% Return propagationData with contour properties set except for ID,
% which is not set since there is no plot to associate with
pd = pd.setContourProperties(txslatlon(:,1),txslatlon(:,2),maxrange,imageSize);
varargout = {pd};
return
end
% It is now safe to remove old contours associated with sites
viewer.remove(graphicsToRemove);
% Return early if no SINR map data meets minimum SINR value
minvalue = min(values,[],"all");
[mindata, maxdata] = bounds(data,"all");
if maxdata < minvalue
warning(message("shared_channel:rfprop:NoSINRMapAreaMeetsMinValue", ...
num2str(minvalue),num2str(mindata),num2str(maxdata)))
return
end
% Create contour map
pd = pd.setContourProperties(txslatlon(:,1),txslatlon(:,2),maxrange,imageSize,contourID);
contour(pd, ...
'Type','sinr', ...
'Animation', animation, ...
'Map', viewer, ...
'Levels', values, ...
'ColorLimits', clim, ...
'Colormap', cmap, ...
'Transparency', transparency, ...
'ShowLegend', showLegend, ...
'ImageSize', imageSize, ...
'ValidateColorConflicts', false);
% Set the IDs of the appropriate Site Graphics
for i = 1:numel(txs)
viewer.SiteGraphics.(txs(i).UID).contour = contourID;
if (showLegend)
viewer.SiteGraphics.(txs(i).UID).legend = ['legend' contourID];
end
end
% Hide progress dialog
viewer.hideProgressDialog;
% Cancel forced exit cleanup, since normal execution has completed
cancel(resetProgressDialog);
if ~outputRequested
cancel(resetColorGraphics);
end
end
function wasClosed = siteViewerWasClosed(viewer)
wasClosed = viewer.LaunchWebWindow && ~viewer.Visible;
end
function sigsource = validateSignalSource(p)
try
sigsource = p.Results.SignalSource;
if ischar(sigsource) || isstring(sigsource)
sigsource = validatestring(sigsource, {'strongest'}, ...
'sinr','SignalSource');
else
validateattributes(sigsource,{'txsite'}, {'scalar'}, ...
'sinr','SignalSource');
end
catch e
throwAsCaller(e);
end
end
function values = validateValues(p)
try
values = p.Results.Values;
validateattributes(values, {'numeric'}, ...
{'real','nonnan','nonsparse','vector','nonempty'}, 'sinr', 'Values');
if ~iscolumn(values)
values = values(:);
end
values = double(values);
catch e
throwAsCaller(e);
end
end
function noisePower = validateReceiverNoisePower(p)
try
noisePower = p.Results.ReceiverNoisePower;
validateattributes(noisePower, {'numeric'}, {'real','finite','nonnan','nonsparse','scalar'}, ...
'sinr', 'ReceiverNoisePower');
catch e
throwAsCaller(e);
end
end
function setColorGraphics(viewer,imageGraphics)
viewer.ColorGraphics = imageGraphics;
end
sinr 代码
最新推荐文章于 2024-09-12 08:45:24 发布