problems using KbCheck and KbName (writing a matlab script) - matlab

I am currently writing code for a study using matlab and psychtoolbox on a Ubuntu system.
I'm currently trying to write a code snippet where the subject presses either the up or down key in response to a task and then metadata is collected.
However, while my code works fine on my own pc it doesn't work in the lab.
It looks like this:
ListenChar(1)
while 1
[keyIsDown, seconds, keyCode ] = KbCheck;
if keyIsDown
if keyCode(KbName('up'))
disp('up key was pressed');
break;
end
if keyCode(KbName('down'))
disp('you pressed the down key');
break;
end
end
end
I have also tried using just keyCode with numbers I got from here: https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes which didn't work either.
The Key Name 'up' I got from using KbName('KeyNamesLinux'). I also tried 'KP_Up' and 'UP_ARROW'.
When using 'space' (and using the space key respectively) everything works fine.
If anyone has an idea I'll be thankful for any input!
Best,
Anna

Related

While loop stuck

I have written a callback function in Matlab. My laptop is communicating with another laptop that is sending it bytes every few seconds that are recorded in a text file. For e.g. the laptop sends "66" and my laptop writes to the file Event_Markers.txt "66" continuously until the other laptop sends something else. The code is below.
The problem that I am currently facing is that in my callback function (below) I use a while loop to continuously write the same "information" (e.g. "66") to the text file until the other laptop sends something else. But this while loop gets stuck. This part is of a larger script that is acquiring data from a spectrometer and adding it to my script and causes everything to become stuck and the rest of the script is not executed. I tried to use an if loop instead of while and it only writes "66" twice instead of writing it continuously. It is, however, writing to the text file as I want it to.
Does anybody know if I need to add some other line of code to stop it becoming stuck?
Thanks!
appenderFile=fopen('Event_Markers.txt','a+t');
s=serial('COM3');
set(s,'BytesAvailable',{#myCallback,appenderFile});
set(s,'BytesAvailableFcnCount',1);
set(s,'BytesAvailableFcnMode','byte');
fopen(s);
function myCallback(s,~,appenderFile)
bytes=(s,'BytesAvailable')
if(bytes==1)
[data count msg] = fread(s,bytes);
end
fprintf(appenderFile,'%d \n',data);
bytes=(s,'BytesAvailable');
while bytes==0
fprintf(appenderFile,'%d \n',data);
bytes=get(s,'BytesAvailable');
end
end
You need to break out of the loop when "something else is sent", something like:
while bytes==0
fprintf(appenderFile,'%d \n',data);
bytes=get(s,'BytesAvailable');
if s ~= 66
break
end
end

WindowKeyPressFcn stops being called

I am working on some modifications to EEGlab's eegplot function (things like vim-style navigation etc.) that need to work through WindowKeyPressFcn.
However, the callback is not being called for some reason. I have been debugging the issue for some time and am a bit lost. I am looking for suggestions on what might be wrong. Unfortunatelly the eegplot function is big, complex and somewhat convoluted and I was unable to reproduce the issue in a simple example. Therefore I am looking for general suggestions on why a function handle that is clearly present in WindowKeyPressFcn might stop being used at some point.
Here is what I have learned so far:
If I go to debug mode in eegplot (set a breakpoint near the end of the setup function [the first half of eegplot]) I am able to run the WindowKeyPressFcn at least once.
However - the function stops being called at some point during debug (sometimes even after being called only once).
If I run eegplot without debug (that is wait for it to finish and return control to me) I am unable to call WindowKeyPressFcn by pressing a key. The function handle is still present in WindowKeyPressFcn property of the figure.
Whener the WindowKeyPressFcn is not being used when I press a key, I can still call it with:
figh = gcf;
fun = get(figh, 'WindowKeyPressFcn');
ev.Key = 'rightarrow';
ev.Character = ' ';
ev.Modifier = [];
feval(fun, figh, ev);
So the function handle is 'healthy' so to speak, but for some reason it is not being used any more when a key is pressed and the figure has focus. When and why something like this could happen? Any ideas on things I should check to understand this issue?
Update:
I found out that WindowKeyPressFcn callback can sometimes be blocked by some window listeners, and tried out the following solution:
hManager = uigetmodemanager(gcf);
set(hManager.WindowListenerHandles,'Enable','off');
It doesn't work - WindowKeyPressFcn is still not called when I press a key. :(
Update 2:
Another thing that does not work:
chld = get(gcf, 'Children');
tp = get(chld, 'type');
chld = chld(strcmp(tp, 'uicontrol'));
set(chld, 'KeyPressFcn', #eegplot_readkey_new)
(eegplot_readkey_new is the function I use for reacting to keypresses)
Update 3:
And another one not working:
addlistener(gcf, 'WindowKeyPress', #eegplot_readkey_new);
Ok - I fiugred it out, although the solution is weird to say the least.
For some mysterious reason using linesmoothing undocummented property prevents WindowKeyPressFcn from being called. I have absolutely no idea why...

KbWait won't register key press

I'm trying to collect keyboard data, but I can't get KbWait to work. In the following code, I'm trying to wait for the participant to respond, check if their response is one of two acceptable answers, and then continue. It should only continue when the participant presses 'j' or 'f'.
response = [];
while isempty(response)&&(GetSecs - FlipTimestamp) < 10
[keyIsDown, RTsecs, RTkeyCode, deltaSecs] = KbWait;
if keyIsDown
r=find(RTkeyCode);%this should be the code for the key pressed
response=KbName(r);%Figure out what key was pressed
rt=num2str(RTsecs-time); %subtract off timestamp from when window was flipped
if response == 'f'
match_response= false;
end
if response == 'j'
match_response= true;
end
end
end
However, KbWait never returns. When I try to run it from the command line, it doesn't work either. It just hangs up and refuses to return, and I have to interrupt the program.
It's been nine months since you posted this, so I imagine you've already found some sort of solution. But I was also having this problem, and here's what I discovered:
I went through my entire HID list: devices = PsychHID('Devices')
As I examined each one's 'usageName' property, I found that multiple devices were considered to be 'Keyboard', even though I only have one actual keyboard connected.
I then tried each one's index as an argument for KbWait. When I got to the correct one, KbWait worked.
Hi there I think your problem is the KbWait function.
you used KbWait like ist KbCheck but the output of those functions is different
[secs, keyCode, deltaSecs] = KbWait([deviceNumber][, forWhat=0][, untilTime=inf])
[keyIsDown, secs, keyCode, deltaSecs] = KbCheck([deviceNumber])
Try KbCheck its more exact than KbWait, because KbWait checks the keyboard only every 5 ms
Here is a Function I wrote sometimes ago: working KbCheck

Ros publisher not working with V-Rep after saving

I've started using V-Rep to simulate some robots (Pioneers and quadrotors, initially), but I've been having problems when I try to connect it with ROS. I tried to replicate the example from RosTopicPublisherAndSubscriber.ttt and it only works the first time, after I close it and load it again, it doesn't work anymore, my code is practically identical to the example, except that I use getPose and it's a Pioneer (the one that comes with V-Rep), here's my code:
if (simGetScriptExecutionCount()==0) then
-- Check if the required plugin is there (libv_repExtRos.so or libv_repExtRos.dylib):
local moduleName=0
local moduleVersion=0
local index=0
local pluginNotFound=true
while moduleName do
moduleName,moduleVersion=simGetModuleName(index)
if (moduleName=='Ros') then
pluginNotFound=false
end
index=index+1
end
if (pluginNotFound) then
simDisplayDialog('Error','ROS plugin was not found.&&nSimulation will not run properly',sim_dlgstyle_ok,false,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
else
-- Retrive the handle of the vision sensor we wish to stream:
lHandle=simGetObjectHandle('Pioneer_p3dx')
-- Now enable topic publishing and streaming of the vision sensor's data:
topicName=simExtROS_enablePublisher('p3dx',1,simros_strmcmd_get_object_pose,lHandle,0,'')
if (topicName == nil) then
simDisplayDialog('Error','Nil',sim_dlgstyle_ok,false,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
else
simDisplayDialog('Error','Not Nil',sim_dlgstyle_ok,false,nil,{0.8,0,0,0,0,0},{0.5,0,0,1,1,1})
end
-- Retrive the handle of the passive vision sensor. We will use the passive vision sensor
end
end
Any idea is welcome! Thanks in advance!
PS: Also, if anyone with 1500 reputation points could create the v-rep tag, that would be great!
Ok, the people at V-REP helped me solve it. So basically I should used the argument as -1 instead of 0.
So basically, a should have done this
topicName=simExtROS_enablePublisher('p3dx',1,simros_strmcmd_get_object_pose,lHandle,-1,'')
instead of
topicName=simExtROS_enablePublisher('p3dx',1,simros_strmcmd_get_object_pose,lHandle,0,'')

Save the debug state in matlab

I am looking for a way to save 'everything' in the matlab session when it is stopped for debugging.
Example
function funmain
a=1;
if a>1
funsub(1)
end
funsub(2)
end
function funsub(c)
b = c + 1;
funsubsub(c)
end
function funsubsub(c)
c = c + 2; %Line with breakpoint
end
When I finally reach the line with the breakpoint, I can easily navigate all workspaces and see where all function calls are made.
The question
How can I preserve this situation?
When debugging nested programs that take a long time to run, I often find myself waiting for a long time to reach a breakpoint. And sometimes I just have to close matlab, or want to try some stuff and later return to this point, so therefore finding a way to store this state would be quite desirable. I work in Windows Server 2008, but would prefer a platform independant solution that does not require installation of any software.
What have I tried
1. Saving all variables in the workspace: This works sometimes, but often I will also need to navigate other workspaces
2. Saving all variables in the calling workspace: This is already better as I can run the lowest function again, but may still be insufficient. Doing this for all nested workspaces is not very convenient, and navigating the saved workspaces may be even worse.
Besides the mentioned inconveniences, this also doesn't allow me to see the exact route via which the breakpoint is reached. Therefore I hope there is a better solution!
Code structure example
The code looks a bit like this
function fmain
fsub1()
fsub2()
fsub3()
end
function fsub1
fsubsub11
fsubsub12
...
fsubsub19
end
function fsub2
fsubsub21
fsubsub22
...
fsubsub29
end
function fsub3
fsubsub31
fsubsub32
...
fsubsub39
end
function fsubsub29
fsubsubsub291
fsubsubsub292% The break may occur in here
...
fsubsubsub299
The break can of course occur anywhere, and normally I would be able to navigate the workspace and all those above it.
Checkpointing
What you're looking to implement is known as checkpointing code. This can be very useful on pieces of code that run for a very long time. Let's take a very simple example:
f=zeros(1e6,1);
for i=1:1e6
f(i) = g(i) + i*2+5; % //do some stuff with f, not important for this example
end
This would obviously take a while on most machines so it would be a pain if it ran half way, and then you had to restart. So let's add a checkpoint!
f=zeros(1e6,1);
i=1; % //start at 1
% //unless there is a previous checkpoint, in which case skip all those iterations
if exist('checkpoint.mat')==2
load('checkpoint.mat'); % //this will load f and i
end
while i<1e6+1
f(i) = g(i) + i*2+5;
i=i+1;
if mod(i,1000)==0 % //let's save our state every 1000 iterations
save('checkpoint.mat','f','i');
end
end
delete('checkpoint.mat') % //make sure to remove it when we're done!
This allows you to quit your code midway through processing without losing all of that computation time. Deciding when and how often to checkpoint is the balance between performance and lost time!
Sample Code Implementation
Your Sample code would need to be updated as follows:
function fmain
sub1done=false; % //These really wouldn't be necessary if each function returns
sub2done=false; % //something, you could just check if the return exists
sub3done=false;
if exist('checkpoint_main.mat')==2, load('checkpoint_main.mat');end
if ~sub1done
fprintf('Entering fsub1\n');
fsub1()
fprintf('Finished with fsub1\n');
sub1done=true;
save('checkpoint_main.mat');
end
if ~sub2done
fprintf('Entering fsub2\n');
fsub2()
fprintf('Finished with fsub2\n');
sub2done=true;
save('checkpoint_main.mat');
end
if ~sub3done
fprintf('Entering fsub3\n');
fsub3()
fprintf('Finished with fsub3\n');
sub3done=true;
save('checkpoint_main.mat');
end
delete('checkpoint_main.mat');
end
function fsub2
subsub21_done=false;subsub22_done=false;...subsub29_done=false;
if exist('checkpoint_fsub2')==2, load('checkpoint_fsub2');end
if ~subsub21_done
fprintf('\tEntering fsubsub21\n');
fsubsub21
fprintf('\tFinished with fsubsub21\n');
subsub21_done=true;
save('checkpoint_fsub2.mat');
end
...
if ~subsub29_done
fprintf('\tEntering fsubsub29\n');
fsubsub29
fprintf('\tFinished with fsubsub29\n');
subsub29_done=true;
save('checkpoint_fsub2.mat');
end
delete('checkpoint_fsub2.mat');
end
function fsubsub29
subsubsub291_done=false;...subsubsub299_done=false;
if exist('checkpoint_fsubsub29.mat')==2,load('checkpoint_fsubsub29.mat');end
if ~subsubsub291_done
fprintf('\t\tEntering fsubsubsub291\n');
fsubsubsub291
fprintf('\t\tFinished with fsubsubsub291\n');
subsubsub291_done=true;
save('checkpoint_fsubsub29.mat');
end
if ~subsubsub292_done
fprintf('\t\tEntering fsubsubsub292\n');
fsubsubsub292% The break may occur in here
fprintf('\t\tFinished with fsubsubsub292\n')
subsubsub292_done=true;
save(checkpoint_fsubsub29.mat');
end
delete('checkpoint_fsubsub29.mat');
end
So in this structure if you restarted the program after it was killed it would resume back to the last saved checkpoint. So for example if the program died in subsubsub291, the program would skip fsub1 altogether, just loading the result. And then it would skip subsub21 all the way down to subsub29 where it would enter subsub29. Then it would skip subsubsub291 and enter 292 where it left off, having loaded all of the variables in that workspace and in previous workspaces. So if you backed out of 292 into 29 you would have the same workspace as if the code just ran. Note that this will also print a nice tree structure as it enters and exits functions to help debug execution order.
Reference:
https://wiki.hpcc.msu.edu/pages/viewpage.action?pageId=14781653
After a bit of googling, I found that using putvar (custom function from here: http://au.mathworks.com/matlabcentral/fileexchange/27106-putvar--uigetvar ) solved this.