I am near finishing a custom application based on the Feedback Demo Task, but I am having a problem. I need to listen to what keys the user is pressing and give a response in the program based on their key presses. Right now I am trying to do this by using the --LogKeyboard=1 command line option, and then in the DoFeedback method using a switch statement with the KeyDown state. This gives shoddy responses, as I have to continually press the key I want when running my application and get lucky to get the program to move on to the next phase. Needless to say this is inadequate for my purposes. How should I be implementing responses based on keys pressed?
As a somewhat unrelated question, I want there to be a pause before I display a picture to the subject. How would I do this without throwing off the timing (without exceeding a block time accidentally)?
Logging and Using Input
-
gschalk
- Posts: 615
- Joined: 28 Jan 2003, 12:37
Re: Logging and Using Input
Hi,
You need to check all keyboard state values for a particular sample block, not just the first one (the key may be pressed at any time during the sample block).
Gerv
You need to check all keyboard state values for a particular sample block, not just the first one (the key may be pressed at any time during the sample block).
Gerv
-
bburgess
- Posts: 7
- Joined: 08 Jun 2011, 15:46
Re: Logging and Using Input
I thought that's what I was doing...
Let me post the code for my DoPreFeedback method, which to my understanding is called at least once per sample block (it is called in the Process method for the FeedbackTask Class):
Edit: I just thought of some potentially helpful info. When I first tried my code the application threw an exception telling me that I was trying to access the KeyDown state without first checking it in preflight (I did check for "--LogKeyboard=1" in OnPreflight, however). So I just added State("KeyDown"); to my OnPreflight and the error wasn't there anymore. I just thought it was a little odd.
Let me post the code for my DoPreFeedback method, which to my understanding is called at least once per sample block (it is called in the Process method for the FeedbackTask Class):
Edit: I just thought of some potentially helpful info. When I first tried my code the application threw an exception telling me that I was trying to access the KeyDown state without first checking it in preflight (I did check for "--LogKeyboard=1" in OnPreflight, however). So I just added State("KeyDown"); to my OnPreflight and the error wasn't there anymore. I just thought it was a little odd.
Code: Select all
void
BalloonTask::DoPreFeedback( const GenericSignal&, bool& doProgress )
{
switch (State("KeyDown"))
{
case 0x5a://Z
State("BalloonCode")=balloonLocs[0];
doProgress = true;
break;
case 0x58://X
State("BalloonCode")=balloonLocs[1];
doProgress = true;
break;
case 0x4e://N
State("BalloonCode")=balloonLocs[2];
doProgress = true;
break;
case 0x4d://M
State("BalloonCode")=balloonLocs[3];
doProgress = true;
break;
default:
doProgress = false;
}
}-
bburgess
- Posts: 7
- Joined: 08 Jun 2011, 15:46
Re: Logging and Using Input
I am still working on this problem. At the moment I am attempting to poll for the entire duration of the sample block. I don't think this is right, and I am getting the same behavior in the program (very shoddy response). I will post my current code. If someone could help I would greatly appreciate it.
Code: Select all
void
BalloonTask::DoPreFeedback( const GenericSignal&, bool& doProgress )
{
int msPerSample(1000/Parameter("SamplingRate"));
int msPerBlock(msPerSample*Parameter("SampleBlockSize"));
int startTime = PrecisionTime::Now();
while (!(doProgress || (int)PrecisionTime::Now()-startTime >= msPerBlock - msPerSample)){
Sleep( 0 );
switch ((int)State("KeyDown"))
{
case 0x5a://z
//statements that set doProgress to true if the correct key is down...
}
}
}-
bburgess
- Posts: 7
- Joined: 08 Jun 2011, 15:46
Re: Logging and Using Input
Success! The problem was that I was not iterating through each sample. This was where I was confused, since I thought that the state vector was only attached to the whole data block, instead of individual samples (which in retrospect is kind of silly, since states are supposed to represent events. Hindsight, 20/20, etc.) I will post the code in case anyone else wants to know how. I know that these forums are a good repository of info:
Code: Select all
void
BalloonTask::DoPreFeedback( const GenericSignal& input, bool& doProgress )
{
for(int sample=0; sample < input.Elements() ; sample++ ){
switch (Statevector->StateValue("KeyDown",sample))
{
case 0x5a://z
State("BalloonCode")=balloonLocs[0];
doProgress = true;
break;
case 0x58://x
State("BalloonCode")=balloonLocs[1];
doProgress = true;
break;
case 0x4e://n
State("BalloonCode")=balloonLocs[2];
doProgress = true;
break;
case 0x4d://m
State("BalloonCode")=balloonLocs[3];
doProgress = true;
break;
}
}
}-
gschalk
- Posts: 615
- Joined: 28 Jan 2003, 12:37
Re: Logging and Using Input
Awesome.
Congratulations!
Thanks for posting the code.
Gerv
Congratulations!
Thanks for posting the code.
Gerv
-
mellinger
- Posts: 1341
- Joined: 12 Feb 2003, 11:06
Re: Logging and Using Input
It's not quite as odd as it seems. Imagine what happens when the "KeyDown" state does not exist in the system when it is accessed from your code: A run-time error will occur, resulting in an abort while running an experiment. To avoid this situation, BCI2000 forces you to test the "KeyDown" state for existence during OnPreflight(). This way, the user gets an error message when clicking SetConfig rather than in the middle of an experimental run.Edit: I just thought of some potentially helpful info. When I first tried my code the application threw an exception telling me that I was trying to access the KeyDown state without first checking it in preflight (I did check for "--LogKeyboard=1" in OnPreflight, however). So I just added State("KeyDown"); to my OnPreflight and the error wasn't there anymore. I just thought it was a little odd.
For more about this, please check
http://www.bci2000.org/wiki/index.php/P ... ate_access
--Juergen
Who is online
Users browsing this forum: No registered users and 0 guests
