I'm using Psychtoolbox in MATLAB to run a behavioral psychology paradigm. As part of the paradigm, users have to view a visual stimulus and respond to it using some input mechanism. For a keyboard, this works as follows:
show stimulus
poll keyboard for response
if no response detected, loop back to 1
if response detected, break and move on with script
This works fine for a keyboard, as step 2 takes between 1-2 ms. The problem comes when I use an alternate input mechanism; in that case, step 2 takes ~20 ms. (I need this alternate input to run the study, and that should be considered immutable fact.) As the stimulus changes with a very short timespan, this added delay breaks the task.
My current thought is to try to use the parallel processing, such that one thread shows the stimulus, and another thread polls the keyboard. I'm currently using the Parallel Computing Toolbox to do this. The problem I'm having is that I don't know how to direct keyboard input to a "parallelized" thread. Does anyone know (1) whether it's possible to direct keyboard input to a thread / have a thread send a visual signal to a monitor, and if yes, (2) how to do it?
Also, if anyone has any better ideas as to how to approach this problem, I'm all ears.
According to this MATLAB newsgroup thread, it appears that threads can't modify graphics objects. Only the desktop MATLAB client can do that. This means that you can't handle updating of graphics from a thread, and I can confirm this as I tried it and wasn't able to modify figures or even the root object from a thread.
However, I think you may be able to do the main graphics updating in MATLAB while a thread handles polling for your input. Here's a sample function for continuously updating a display until a thread waiting for input from KbCheck is finished running:
function varargout = plot_until_input
obj = createJob(); %# Create a job
task = createTask(obj,#get_input,4,{deviceNumber}); %# Create a task
submit(obj); %# Submit the job
waitForState(task,'running'); %# Wait for the task to start running
%# Initialize your stimulus display here
while ~strcmp(get(task,'State'),'finished') %# Loop while the task is running
%# Update your stimulus display here
end
varargout = get(task,'OutputArguments'); %# Get the outputs from the task
destroy(obj); %# Remove the job from memory
%#---Nested functions below---
function [keyIsDown,secs,keyCode,deltaSecs] = get_input(deviceNumber)
keyIsDown = false;
while ~keyIsDown %# Keep looping until a key is pressed
[keyIsDown,secs,keyCode,deltaSecs] = KbCheck(deviceNumber);
end
end
end
I was able to successfully run the above function with some simple plotting routines and replacing the code in get_input with a simple pause statement and a return value. I'm unsure whether KbCheck will work in a thread, but hopefully you will be able to adapt this for your needs.
Here's the documentation for the Parallel Computing Toolbox functions used in the above code: createJob, createTask, submit, waitForState, destroy.
I don't know of a way how you could do this with parallel processing.
However, a feature you might be able to use is the timer object. You would set up the timer object to poll the input mechanism, and, if anything is detected, change the value of a global variable. Then, you start your stimulus routine. In the while-loop in which you're updating the display, you keep checking the global variable for a change from the timer object.
You have to tackle the 20ms latency in your input device. If it's too slow then get another input device. You can get good sub-millisecond timing with proper response boxes.
All this talk about threading is misguided and not applicable to the PTB framework.
Related
As a student I am currently working on a Matlab Simulink project. I am quite new to using Matlab/Simulink (few weeks).
I want to implement and run a Matlab “.m” file with which I can open Simulink and start the simulation. The aim is to do a 24h Test with a load cell cut into 1h “pieces” and to save the data to different sheets of an excel file each hour. So my simulation runs for 1h, stops and starts again, and so on. Through Matlab and a “for” loop I do the measures 24 times.
Between measuring steps I have to wait for simulink to finish its measures and saving the file in order for the Simulink window to be able to get closed by close_system('Thesis_SerDatTransm_Simulink').
So I tried to implement the delay with a while loop and by checking if the measures I get fit into an array of the size bigger than 449 (I measure 449 values):
for k=0:1:24
% Load Simulink
load_system('Thesis_SerDatTransm_Simulink.slx')
% Open Simulink
open_system('Thesis_SerDatTransm_Simulink.slx')
% Start Simulation
set_param('Thesis_SerDatTransm_Simulink', 'SimulationCommand', 'Start');
% Save Data
my_cell = sprintf('A%d',k);
xlswrite('file.xlsx',y,my_cell)
% Wait for Simulation
while 1
test=size(y)>=449;
if (test)
close_system('Thesis_SerDatTransm_Simulink')
break
end
end
end
The Problem now is, that program gets stuck at the while loop. Simulink is started, but no simulation or data gathering is done.
So I wondered if anyone could check if something is wrong with my While loop, since the rest of the programm works all fine without the loop (but receiving an error message, that during the simulation, Simulink window can't be closed).
I know there is a way to create a delay with waitforin matlab and create another function which I could call, but I couldn't figure out how to do this yet.
thanks
Regards
hohmchri
The right way to do this is to use the sim function to run your model (not the sequence of load_system, open_system and set_param that you have).
sim will block the execution of m-code until the model completes executing. Data can either be returned into the workspace (when used with no output arguments) or returned as an output from the call to sim. (And then you can write it to Excel as you've done.)
The only reason not to use sim, and perhaps use the commands you have, is if the model takes a long time to initialize, and you don't want to to open and close it every time through the loop. However, even in this case your code isn't correct. The load_system would be outside the loop; the open_system is not required; in your while loop you would poll the model's SimulationStatus property to see if it is still running (not the size of the y variable); and the close_system would be after the loop (as indicated by #m_power in one of the comments).
As written you should use the matlab pause command. This stops your execution for X seconds.
You should also look to optimize your code as m_power states
I have written a matlab program for a simulink model and taking control through it programmatically, but I am facing one problem while using set_param('testmodel11', 'SimulationCommand', 'start');.
It gives all the values at once, that is gives the entire scope and workplace values all at the same time, but I don't want this. I would like to run the program and execute at that point, seeing only rest of the values should be zero. How can I stop the simulation at that point and fetch plots and values from that point only, the rest should be zero. And ideally have this same behavior for the next break points too?
There is a way to pause the simulation at certain breakpoints (simulation points), plot the output or do whatever is desired of it, and then continue the simulation until the next breakpoint.
However, at any breakpoint, you will get output data from all the time samples till the breakpoint is reached. To isolate data from a certain timestamp, you can calculate its index based on the sample time and extract it from the workspace (output data is stored as an array)
Here is the link to my answer which will be helpful, pls go through it:
https://stackoverflow.com/a/38348315/6580313
Now, in the m-file which you will run when the simulation is paused, you can change the value of the constant block which specifies the next simulation time at which simulation needs to be paused. In the m-file, you can also write a code snippet to access the output data.
Once the simulation continues, it will be paused at the new simulation time specified in the constant block.
Let me know in case you have any queries.
It sounds like you want to use the Simulink Debugger. Check out the documentation for more details on how to use it. The main command-line interface to it is sldebug.
I have a system with some embedded Matlab blocks where I'd like to perform some actions after a certain amount of time, in this case turn on lights and switches in an interface to which I send signals from Simulink.
The problem is that I thought I'd use "tic"-"toc" and "while" in a Matlab function block to perform these actions, say one parameter becoming 1 after 5 seconds, the following parameter becoming 1 after 12 seconds and so on, but I noticed that tic-toc apparently doesn't work in Simulink for embedded functions.
Is there any similar functions that could be used in Simulink for embedded functions or is there any other way to do this?
Edit: I've tried to get the clock's time as well, but it's a growing value. Is there any way to "lock" the time as a parameter when the block's function is executed?
You shouldn't be using absolute time in an embedded system, which is at least one of the reasons why tic-toc and clock from MATLAB don't work with Simulink Coder.
You should create your own counter, which you start and stop when you need to.
This is pretty easy to do using a Unit Delay and Summation block.
If you need to be able to enable and/or reset the counter then use the appropriate block from the Additional Discrete library.
I created a timer that executes every 0.1 seconds. It calls a function that reads data and then updates the property of an object. When I start the timer, MATLAB displays the "Busy" signal at the bottom of the command window. MATLAB becomes unresponsive and I cannot halt the timer using the stop() function. My only recourse is to use Ctrl-C.
I determined the problem to be the processing time of the timer callback function was longer than the calling period and I presume no other MATLAB code could squeak into the stack/queue. This makes me somewhat worried about relying upon timers. My goal is to continuously make measurements from several devices, store them in an object, and need MATLAB to do other things in between these measurements. Also, I cannot afford to miss a measurement.
I am creating an app that responds to user input and provides the user with real time information, so I chose a fast period thinking it would produce a snapping UX. Since I am committed to using MATLAB I could not think of a better way of implementing this functionality than using a timer object. So the first question is, do timer objects seem like the right tool for the job I describe above?
Second, if I am to use timer objects would someone please share their experience about common mistakes or pitfalls using timers? Or has someone any advice on how to best implement timer objects? Is there a practical limit to the number of timer objects that can be used simultaneously? What is the best way to determine the optimal frequency of a timer object?
Thanks!
I would think that 0.1 seconds is pushing it for reliability, especially if you have multiple timers going at once, and especially if you want a user interface to be responsive at the same time as well.
MATLAB is basically single-threaded. There are exceptions, for example the lower level math routines call BLAS in a multithreaded way that speeds them up a lot. You can also write MEX code in C that is multithreaded, and call that from MATLAB. But there's basically one true thread that all your code runs on.
Timer objects are also an exception in a way. When you create a timer object, underneath that there's a java timer object, which is running on a separate java thread. But when any of its callbacks fire, it calls back into MATLAB to execute them, which happens on the one true thread.
If you cannot afford to miss a measurement, you'll need to set the BusyMode property of your timers to queue rather than the default drop, which will mean that if any of the callbacks take longer than 0.1 seconds to execute, they will back up - and you have to fit in any user interface actions as well.
In addition, MATLAB doesn't (and couldn't) make any real guarantees about the precision of how fast or regularly the timer callbacks will execute. If Windows suddenly decides to run a virus scan, or update itself etc, MATLAB will lose priority and that will mess things up. If you were firing timers every 10 seconds, or even every 1 second, it's in all likelihood going to be roughly accurate. But if you're firing them every millisecond, you can't expect it to be reliable - you'd need a proper real time environment for that. 0.1 seconds seems borderline to me, and I'd expect its reliability to depend on what exactly you were doing in those 0.1 seconds, and what else was going on as well (and what computer you're running, as well).
To answer your last questions (max number of timers, optimal timer frequency etc) - there's no general answer, just try it and work out what happens with a range of values in your particular situation.
If it turns out that it's not reliable enough, you could either try:
Doing the data acquisition in another faster way (e.g. in C), maybe in a separate process, then calling that from MATLAB via MEX, perhaps with some sort of buffering to smooth things out.
Turning to some the other MathWorks products (e.g. Simulink, Simulink Coder, some of the System Toolboxes) that are designed for developing properly real time systems.
Hope that helps!
I have a matlab function block (which is not relevant) whose input is his previous output (loop). For example, if in a sample period the output is X, his input in the next sample period will be X, and so on.
This image shows a simplification of my simulation. I initialize the input of my function for the first loop.
The problem is that matlab functions recieves an event based signal from de initialization block in the first sample period (zero-duration), which I must convert to a timed based signal (so I can apply the unit delay that avoids an inifite loop, and allows to generate the next input as explained before). So, when I do so, I lose the information contained in the event-based signal (due to the zero-duration values) and the loop does not work.
If there was a way to intialize the loop in the time-based domain (green part of the image) so, in the first sample time, it is not a zero-duration signal, it would avoid the problem.
Is there any way to do so? Or, a different approach for this problem?
Two approaches come to mind
The initial condition can be set in the Unit Delay block, so it's not clear from your simplified example why you need the specific Initialization block.
You could just use a persistent variable inside the MATLAB Function block to maintain the state from one execution of the block to the next (noting that since it is event driven the block may not get called at every time step, only at each event triggger).