function [otherVehicles, globalPlanPoints, stateValidator] = exampleHelperUrbanSetup()
%exampleHelperSetup creates data for 'Optimal Trajectory Generation for Urban Driving' Example
%
% Initializes Optimal Trajectory Generation for Urban Driving Example by
% creating data in base workspace also creates the figure window for
% plotting both occupancyMap with trajectory and ego and other vehicles

% Outputs
%   otherVehicles:
%     - Structure array containing
%      (Position, Yaw, Velocity, SimulationTime) of each other vehicle
%      in the scenario other than ego vehicle
%   globalPlanPoints:
%     - Matrix contains precomputed global plan consisting of
%      eighteen waypoints, each representing a position in the scenario
%   stateValidator:
%     -  This is an object of validatorOccupancyMap.
%        validatorOccupancyMap is a State validator based on 2-D grip map
%        An fully occupied ego centric occupancy map is used to
%        initialize this state validator. This ego centric occupancy map
%        is later updated based on obstacle information and road boundaries

% This is a helper script for example purposes and may be removed or
% modified in the future.

% Copyright 2019 The MathWorks, Inc.

%% Clear the workspace before creating the required veriables
clear exampleHelperExecuteAndVisualize;
%% Check if the urbanScenarioData.mat file exists.
% Display error and return if the file not found.
if ~isfile('urbanScenarioData.mat')
    disp(' Error: urbanScenarioData.mat file not found');
    return;
else
    %
    % Load the urbanScenarioData.mat file that contains the data that
    % is required for the example
    % The file contains :
    %              1. otherVehicles
    %              2. globalPlanPoints
    %              3. staticOccupancyMap
    %              4. laneBoundaries
    urbanScenarioData = load('urbanScenarioData.mat');
    
    % otherVehicles: [1 x 4] Structure array containing
    % (Position, Yaw, Velocity, SimulationTime) of each vehicle
    % in the scenario other than ego vehicle.
    otherVehicles = urbanScenarioData.otherVehicles;
    
    % Matrix contains precomputed global plan consisting of
    % eighteen waypoints, each representing a position in the scenario
    globalPlanPoints = urbanScenarioData.globalPlanPoints;
    
    % Defining the Vehicle dimensions.
    % The same dimensions are used through out the example to represent all
    % vehicles including ego vehicle in the scenario.
    carPolygon = [3.7, 0.8; 3.7, -0.8; -1, -0.8; -1, 0.8]';
    
    assignin('base','otherVehicles',urbanScenarioData.otherVehicles);
    assignin('base','globalPlanPoints',urbanScenarioData.globalPlanPoints);
    assignin('base','staticOccupancyMap',urbanScenarioData.staticOccupancyMap);
    assignin('base','laneBoundaries',urbanScenarioData.laneBoundaries);
    assignin('base','carPolygon',carPolygon);
    
    %%
    % Create an ego centric occupancy map using binaryOccupancyMap
    % Size: 100 x 100 meters with a resolution of 2 cells per meter.
    occupancyMapMaxXLimit = 100;
    occupancyMapMaxYLimit = 100;
    occupancyMapResolution = 2;
    egoMap = binaryOccupancyMap(occupancyMapMaxXLimit,occupancyMapMaxXLimit,...
        occupancyMapResolution);
    egoMap.GridOriginInLocal = [-egoMap.XLocalLimits(2)/2 ...
        -egoMap.YLocalLimits(2)/2];
    
    % Initially updating occupancy map as fully occupied
    % 1(one) represents occupied
    % 0(zero) represents unoccupied
    egoMap.setOccupancy(ones(occupancyMapMaxXLimit*occupancyMapResolution,...
        occupancyMapMaxYLimit*occupancyMapResolution));
    
    % Initialize state validator for the trajectoryOptimalFrenet
    stateValidator = validatorOccupancyMap;
    stateValidator.Map = egoMap;
    
    % Update state bounds for validator
    stateValidator.StateSpace.StateBounds(1:2,:) = [-20 160; -200 100];
    
    assignin('base','egoMap',egoMap);
    
    % Initialize egoPoses that is used to log ego positions
    egoPoses = [];
    assignin('base','egoPoses',egoPoses);
end
end