%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% GPS sensor dynamics %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%STATE  is a struct (called sensor) with the following fields
%  state   -[string]the current proceural state: no_info, cold_start, read_ephemeris,
%                   position_available, warm_start_avaialable, warm_start
%  fetchfp -[double]at what time freq and phase will be fetched (according to the random extraction)
%  geteph  -[double]at what time eph data will be acquired (according to the random extraction)
%  ephExp  -[double]expiration time of ephemeris data
%  fp      -[int]number of tracked satelliets
%  eph     -[int]number of satellites for which ephemeris data are available

%INPUTS
%  -time
%  -state
%  -turn on/off (true=turn_ON, false=turn_OFF)
%  -visible satellites

%OUTPUTS
%  -state

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function sensor=gps_randomized(time,sensor_in,turn,sv)

%% parameters
%define how many satellites you need to track given the accuracy requirements
required_sv= 4;
%define how long ephemeris data last
ephDuration=1800.0;
%bounds for time required for fetching freq and phase
fp_lower=0.2;
fp_upper=1.2;%500.5;

%% initialize output
sensor = sensor_in;

%% equations
%you cannot track satellites that you dont see
sensor.fp=min(sensor_in.fp,sv);
sensor.eph=min(sensor_in.eph,sv);

%% events
ephemeris_expired=(time>sensor.ephExp)||(sensor.eph<required_sv);   %ephemeris data are expired
lost_visibility=(sensor.fp<required_sv);
fetched_fp=(time>sensor.fetchfp);
get_ephemeris=(time>sensor.geteph);

%% transitions and updates
%for each of the states handle eventual transitions and updates
%updates depend on the spefic transition that is fired
if strcmp(sensor_in.state,'no_info')
    if(turn)
        sensor.state='cold_start';
        sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
    end
end
if strcmp(sensor_in.state,'position_available')
    if(get_ephemeris)
        sensor.state='position_available';
        sensor.geteph=time+random('uniform',30,60);
        sensor.eph=sv;
        sensor.ephExp=time+ephDuration;
    end
    if(lost_visibility)
        sensor.state='warm_start';
        sensor.fp=0;
        sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
        %might have to go on to cold_start
            if(ephemeris_expired)
                sensor.state='cold_start';
                sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
                sensor.eph=0;
            end
    end
    if(ephemeris_expired)
        sensor.state='read_ephemeris';
        sensor.eph=0;
        sensor.geteph=time+random('uniform',30,60);
        %might have to go on to cold_start
            if(lost_visibility)
                sensor.state='cold_start';
                sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
            end
    end
    if(~turn)
        sensor.state='warm_start_available';
        sensor.fp=0;
    end
end
if strcmp(sensor_in.state,'read_ephemeris')
    if(lost_visibility)
        sensor.state='cold_start';
        sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
    end
    if(get_ephemeris)
        sensor.state='position_available';
        sensor.geteph=time+random('uniform',30,60);
        sensor.eph=sv;
        sensor.ephExp=time+ephDuration;
    end
    if(~turn)
        sensor.state='no_info';
        sensor.fp=0;
    end
end
if strcmp(sensor_in.state,'warm_start')
    if(fetched_fp)
        sensor.state='position_available';
        sensor.geteph=time+random('uniform',30,60);
        sensor.fp=sv;
    end
    if(ephemeris_expired)
        sensor.state='cold_start';
        sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
        sensor.eph=0;
    end
    if(~turn)
        sensor.state='warm_start_available';
        sensor.fp=0;
    end
end
if strcmp(sensor_in.state,'cold_start')
    if(fetched_fp)
        sensor.state='read_ephemeris';
        sensor.geteph=time+random('uniform',30,60);
        sensor.fp=sv;
    end
    if(~turn)
        sensor.state='no_info';
        sensor.howLong=time;
        sensor.fp=0;
    end
end
if strcmp(sensor_in.state,'warm_start_available')
    if(turn)
        sensor.state='warm_start';
        sensor.fetchfp=time+random('uniform',fp_lower,fp_upper);
    end
    if(ephemeris_expired)
        sensor.state='no_info';
        sensor.eph=0;
    end
end

end