Difference between revisions of "Code for very simple state machine (standalone)"

From Bcontrol
Line 20: Line 20:
% Written by Carlos Brody 2007
% Written by Carlos Brody 2007
% Edited by Praveen Nov. 2010

Revision as of 22:04, 8 November 2010

% This is an example script showing how to use the @StateMachineAssembler
% object. It is an extremely simple example, to start off with. Like all
% RTLSM state machines, it starts at state 0. By convention, we don't use
% state 0, but jump as fast as we can to the start of our program (given
% the RTLSM's 6KHz cycle, that's 1/6th of a ms). Then, in "my_start" we
% wait for the subject to poke into the center poke, with no time limit for
% how long we wait. Poking into the center poke takes us to "light_on,"
% where we turn the center light on. If the subject pokes again in the
% center within 2 secs after the light was turned on, they get a 200 ms
% water reward. If they don't poke in time, the light will turn off and
% they get a 1 sec white noise punishment. And then the whole cycle starts
% again.   
% To make this standalone, we don't use the @soundmanager plugin, which
% requires Dispatcher. But, if you are using Dispatcher, we recommend that
% plugin instead of the native commands to the SoundServer used here.

% Written by Carlos Brody 2007
% Edited by Praveen Nov. 2010

% To get started to be able to run this script, (1) Get the ExperPort code
% from the CVS sever. Assuming you've already done this, (2) Start Matlab
% and change directory to the main ExperPort directory. (3) At the prompt,
% type 
%    >> flush ; mystartup
% You should be good to go! NOTE: If you're going to run sounds on the Mac,
% also see Modules/@softsound/README.txt
% (4) If you using an emulator, go to /Setting/Settings_Custom.conf and set 
% the parameters 'state_machine_server' and 'sound_machine_server' to 'localhost'

% The following two lines are just to clear and close stuff in case
% you ran this script previously.
if exist('sm'),   Close(sm); clear sm; end;
if exist('sma'),  clear sma;  end;

% This variable acquires its proper values in
% ExperPort/mystartup.m;

global state_machine_server;

% Now set up the State Machine:
if isempty(state_machine_server); sm = RTLSM(state_machine_server);

sm = Initialize(sm);

% Set up the sound machine:
if isempty(sound_machine_server)  
   sndm = softsound;
   % The virtual rig state machine needs to be told to talk to sound machine:
   sm   = SetTrigoutCallback(sm, @playsound, sndm);   
   sndm = RTLSoundMachine(sound_machine_server);

% Define sound 1 on the SoundServer to be a 1-sec white noise sound. We
% include the 0.1 factor so it isn't too loud.

srate = GetSampleRate(sndm);
LoadSound(sndm, 1, 0.1*(2*rand(1, srate)-1), 'both');


% Ok, now set up an assembler:
sma = StateMachineAssembler;

sma = add_state(sma, 'name', 'STATE_0', 'self_timer', 0.0001, ...
   'input_to_statechange', {'Tup', 'my_start'});

sma = add_state(sma, 'name', 'MY_START', ...
   'input_to_statechange', {'Cin', 'light_on'});

sma = add_state(sma, 'name', 'LIGHT_ON', 'self_timer', 2, ...
   'input_to_statechange', {'Tup', 'punish' ; 'Cin', 'reward'}, ...
   'output_actions', {'DOut', center1led});

sma = add_state(sma, 'name', 'REWARD', 'self_timer', 0.2, ...
   'output_actions', {'DOut', left1water}, ...
   'input_to_statechange', {'Tup', 'state_0'});

sma = add_state(sma, 'name', 'PUNISH', 'self_timer', 1, ...
   'output_actions', {'SoundOut', 1}, ...
   'input_to_statechange', {'Tup', 'state_0'});

% Tell the assembler (sma) to assemble and send the program to the
% state machine (sm):
send(sma, sm);

% Ok! Start it up, and start at state 0 --standard intialization calls.
sm = Run(sm); sm = ForceState0(sm);

% Now run for 100 secs or so
for i=1:1000, 
   % Virtual state machine needs to periodically process its stuff:
   stevs = GetTimeEventsAndState(sm, 1);
   newevs = stevs.event_ct;
   if newevs ~= oldevs
        fprintf(1, 'FSM time is %g, and %d events have happened\n', stevs.time, newevs);
   oldevs = newevs;