%% Write Custom Transform Functions for Map Layers
% The mapLayer object enables you to apply custom element-wise transformations when setting and getting data in the map. To transform data you set or get from the map, specify function handles for the GetTransfomFcn and SetTransformFcn properties. This example shows how to implement a log-odds probabilitistic map layer by creating a lookup table for probability and log-odds values. The transform functions use these lookup tables to convert between these values when setting or getting data.
%
%% Create Lookup Tables
% Generate a full lookup table of values that map the probability values to the minimum and maximum limits of int16 values.
% Create an array of int16 values from intmin to intmax. Define the probablilty limits.

intType = 'int16';
intLinSpace = intmin(intType):intmax(intType);
numOfPoints = length(intLinSpace);
probLimits = [0.001 .999];

% The exampleHelperProbToLogodds and examplerHelperLogoddsToProb functions covert between the log-odds and probability values. Use the helper functions to get the log-odds limits and generate the array for looking up log-odds values. Create an interpolated grid for the entire lookup table.

logOddsLimits = exampleHelperProbToLogodds([0.001 .999]);
logOddsLookup = single(exampleHelperLogoddsToProb(linspace(logOddsLimits(1),logOddsLimits(2),numOfPoints)));
interpTable = griddedInterpolant(logOddsLookup,single(intLinSpace),'nearest');

%
%% Specify Transform Function Handles
% The transform function handles utilize example helpers that define how to convert between log-odds integer values and the probability values with an applied saturation limit. The probability saturation limits are [0.001 .999] as previously specified. This behavior is similar to the occupanyMap object.

getXformFcn = @(obj,logodds,varargin)...
    exampleHelperIntLogoddsToProb(logodds,logOddsLookup(:),intLinSpace);

setXformFcn = @(obj,prob,varargin)...
    exampleHelperProbToIntLogodds(prob,interpTable,logOddsLookup(:),intLinSpace,probLimits);

%
%% Create Map Layer
% Generate an occupancy map layer object from a matrix of probability values. Specify the get and set transform functions.

occupancyLayer = mapLayer(repmat(0.5,10,10),...
                           'LayerName','Occupancy',...
                           'GetTransformFcn',getXformFcn,...
                           'SetTransformFcn',setXformFcn);

% Notice that when you create the map, the default value is 0.001 instead of 0. This difference is because the SetTransformFcn function has been applied to the default value of 0 when you create the object, which saturates the value to 0.001.

disp(occupancyLayer.DefaultValue)

%
%% Get and Set Map Data
% The map data matches the matrix you set on creation.

extData = getMapData(occupancyLayer) 

% Set specific map locations to values that are:
% Outside of the probability saturation limits.
% Higher precision than the resolution of the lookup tables.

setMapData(occupancyLayer,[0 0],0.00001)
setMapData(occupancyLayer,[5 5],0.25999)

% For the first location, the probability is bound to the saturation limits.

extData = getMapData(occupancyLayer,[0 0])

% The second location returns the value closest to the probability value in the lookup table.

extData2 = getMapData(occupancyLayer,[5 5])

% The generated map layer can now be used for updating a probability occupany map that are stored as int16 values. To combine this map with other layers or map types, see the multiLayerMap object.
% Copyright 2020 The MathWorks, Inc.