Jump to content

FEP VisuomotorJoystickTask: Difference between revisions

From BCI2000 Wiki
Aes2376 (talk | contribs)
Created page with "==Synopsis== '''FEP_VisuomotorJoystickTask''' is a BCI2000 application module that implements a center-out visuomotor reaching task controlled with a USB HID joystick. The task presents hidden changes in the relationship between joystick movement and cursor movement while recording behavioral responses synchronized with the BCI2000 data stream. The task includes: * Normal and inverted joystick-to-cursor mappings. * Unannounced mapping changes between trials. * Six seq..."
 
Aes2376 (talk | contribs)
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
==Synopsis==
==Synopsis==


'''FEP_VisuomotorJoystickTask''' is a BCI2000 application module that implements a center-out visuomotor reaching task controlled with a USB HID joystick. The task presents hidden changes in the relationship between joystick movement and cursor movement while recording behavioral responses synchronized with the BCI2000 data stream.
'''FEP_VisuomotorJoystickTask''' is a BCI2000 application module implementing a center-out visuomotor reaching task designed to investigate how participants adapt their behavior when the relationship between their actions and sensory consequences changes unexpectedly.


The task includes:
Participants control a cursor using a USB HID joystick and repeatedly move from a central starting location to peripheral targets. The joystick-to-cursor mapping is treated as a hidden environmental state: on a given trial, joystick movement may produce either a normal cursor movement or an inverted cursor movement. These mappings are not explicitly cued to the participant.
 
The task was developed in the context of the '''Free Energy Principle (FEP)''' and related theories of predictive processing and active inference. In this framework, an agent maintains an internal model of the causes of its sensory observations and uses incoming evidence to update that model. When observations conflict with the agent's expectations, the agent may need to revise its estimate of the current hidden state.
 
The present task operationalizes this problem using a simple visuomotor environment. The hidden state is the current joystick-to-cursor mapping. Participants first accumulate experience with particular mappings and mapping frequencies, creating different histories of prior exposure. The mapping can then change without warning, requiring the participant to infer from the resulting cursor behavior that the current sensorimotor relationship has changed.
 
The task therefore allows behavioral measurements to be related to three major features of inference:
 
* '''Prior experience''': Different experimental blocks expose participants to different frequencies of Normal and Inverted mappings.
* '''Unexpected state changes''': Mapping changes may occur between trials without an explicit visual cue.
* '''Behavioral updating''': Reaction time, movement time, total time, and cursor trajectory may be examined following mapping switches and across subsequent trials.
 
The experiment also includes a cursor-gain manipulation. High-gain trials change the magnitude of the relationship between joystick displacement and cursor displacement. In the current implementation this is represented explicitly as a cursor-gain condition rather than as a formal sensory-reliability variable.
 
Importantly, the software does not itself compute free energy, prediction error, posterior probability, Bayesian belief, or another formal FEP quantity. Instead, it creates a controlled hidden-state visuomotor task whose behavioral and neural data may be used to investigate questions motivated by those theories.
 
The current implementation includes:


* Normal and inverted joystick-to-cursor mappings.
* Normal and inverted joystick-to-cursor mappings.
Line 10: Line 26:
* Normal and configurable high cursor-gain conditions.
* Normal and configurable high cursor-gain conditions.
* Mapping-switch, prior-condition, and trials-since-switch state logging.
* Mapping-switch, prior-condition, and trials-since-switch state logging.
* A mandatory minimal introduction.
* A minimal participant introduction.
* A normal-mapping sandbox for joystick familiarization.
* A Normal-mapping joystick sandbox.
* Reaction-time, movement-time, total-time, cursor, joystick, target, condition, and gain logging in the BCI2000 <code>.dat</code> file.
* Reaction-time, movement-time, total-time, cursor, joystick, target, mapping, and gain logging in the BCI2000 data stream.


The participant is not informed that the joystick-to-cursor mapping, cursor gain, mapping probabilities, or block structure may change. Targets are displayed identically across conditions so that the current mapping is not visually cued.
The participant is not informed that the mapping, gain, mapping probabilities, or experimental block structure may change.
 
The current implementation does not calculate free energy, posterior probability, prediction error, or another explicit computational quantity associated with the Free Energy Principle. The application instead provides an experimental framework for manipulating hidden visuomotor mappings, recent mapping history, mapping frequency, and cursor gain while measuring behavioral adaptation.


==Location==
==Location==


The source code for the FEP Visuomotor Joystick Task is located in:
Upon the completion of an SVN update, the source code for the FEP Visuomotor Joystick Task is located in:


<code>src/custom/FEP_VisuomotorJoystickTask/</code>
<pre>
src/private/Application/FEP_VisuomotorJoystickTask/
</pre>


The main implementation is contained in:
The main implementation is contained in:


<code>FEP_VisuomotorJoystickTask.cpp</code>
<pre>
FEP_VisuomotorJoystickTask.cpp
</pre>


with the corresponding header and build configuration in:
with the corresponding header and build configuration in:
Line 33: Line 51:
* <code>CMakeLists.txt</code>
* <code>CMakeLists.txt</code>


The application is included from:
The application is included from (prog folder):


<code>src/custom/CMakeLists.txt</code>
<pre>
src/private/Application/CMakeLists.txt
</pre>


The CMake target and Windows executable are:
The CMake target is:


<pre>
<pre>
FEP_VisuomotorJoystickTask
FEP_VisuomotorJoystickTask
</pre>
The Windows executable is:
<pre>
FEP_VisuomotorJoystickTask.exe
FEP_VisuomotorJoystickTask.exe
</pre>
</pre>
Line 56: Line 81:
Developed in the Friedman Lab.
Developed in the Friedman Lab.


Contact: [speer@wustl.edu](mailto:speer@wustl.edu)
Contact: speer@wustl.edu


===Version History===
===Version History===


The FEP module is currently maintained under <code>src/custom</code> and does not have independent Git or SVN revision history in the inspected development checkout.
The current FEP task is maintained under <code>src/custom</code>. In the inspected development checkout, the module does not currently have independent Git or SVN revision history.


Build metadata associated with the inspected implementation reports:
The inspected build was produced using:


* BCI2000 framework: '''3.6.9535'''
* BCI2000 framework 3.6.9535
* BCI2000 source revision: '''9535'''
* BCI2000 source revision 9535
* Release configuration: '''x64'''
* Visual Studio 2022 / MSVC 19.35
* Compiler: '''MSVC 19.35.32215.0'''
* Release x64 configuration
* Build date of inspected Release build: '''September 18, 2026'''


These values describe the BCI2000 build containing the module and should not be interpreted as an independent revision number for <code>FEP_VisuomotorJoystickTask</code>.
These values refer to the BCI2000 build containing the module rather than an independent revision number for the FEP task.


No task-specific <code>.prm</code> or <code>.bat</code> file was found in the inspected source tree.
==Scientific Motivation==


==Functional Description==
===Free Energy Principle===
 
The Free Energy Principle proposes that biological agents maintain internal models of the causes of their sensory inputs and continually update those models in order to reduce discrepancies between predicted and observed sensory states.
 
A useful way to interpret the present task is as a hidden-state inference problem.
 
The participant directly observes:


===Scientific Motivation===
* Joystick movement.
* Cursor movement.
* Target position.
* The sensory consequences of each movement.


The task repeatedly requires participants to make center-out joystick movements toward peripheral visual targets.
The participant is not directly told:


Across trials, the application manipulates:
* Which joystick-to-cursor mapping is currently active.
* Whether the mapping has changed.
* The probability of a mapping occurring.
* The current experimental block.
* Whether cursor gain has changed.


* Whether joystick displacement moves the cursor in the same or opposite direction.
The current mapping therefore acts as a hidden environmental state that must be inferred from the relationship between action and observed cursor movement.
* Whether cursor displacement uses normal gain or increased gain.
* The frequency of normal and inverted mappings within a block.
* The sequence of mapping exposure across blocks.
* Whether a trial immediately follows a change in mapping.


The resulting data may be used to examine behavioral consequences of recent mapping history, mapping changes, mapping frequency, and cursor gain.
For example, after many Normal trials, a participant may expect the cursor to move in the same direction as the joystick. If the next trial unexpectedly uses the Inverted mapping, the observed cursor movement conflicts with that expectation. Subsequent behavior can then be examined to determine how rapidly the participant adjusts to the new mapping.


Examples of behavioral quantities available from the recorded data include:
===Why the Task Was Developed===


* Reaction time.
The task was designed to create an experimentally controlled situation in which prior experience and new sensory evidence can come into conflict.
* Movement time.
* Total target-acquisition time.
* Cursor trajectory.
* Initial movement direction.
* Trajectory curvature.
* Performance immediately following a mapping switch.
* Performance as a function of the number of trials since a mapping switch.
* Differences between normal-dominant and approximately balanced mapping contexts.
* Interactions between mapping and cursor gain.


The current implementation does not contain an explicit Bayesian model, posterior estimate, prediction-error calculation, adaptation score, or free-energy calculation.
Several aspects of the experiment make this possible.


===Condition Terminology===
First, the frequency of Normal and Inverted mappings changes across blocks. This changes the participant's recent history of mapping exposure.


The FEP task uses the terms '''Normal''' and '''Inverted''' rather than the '''Automatic''' and '''Controlled''' terminology used by the earlier USBHIDJoystickTask.
Second, mapping changes are not announced. Participants therefore cannot simply follow an explicit instruction telling them which mapping to use.


{| class="wikitable"
Third, the task records the exact trials on which the mapping changes and the number of trials that have occurred since the most recent switch.
! <code>TaskCondition</code>
! Mapping


| ! Description                                                                  |
This makes it possible to compare behavior:
| ------------------------------------------------------------------------------ |
| 0                                                                              |
| Normal                                                                        |
| Joystick displacement moves the cursor in the corresponding direction.        |
| -                                                                              |
| 1                                                                              |
| Inverted                                                                      |
| Joystick displacement moves the cursor in the opposite direction on both axes. |
| }                                                                              |


The current condition is not shown to the participant.
* Before and after an unexpected mapping change.
* On switch versus non-switch trials.
* Across successive trials following a switch.
* Under different histories of Normal and Inverted mapping exposure.
* Under Normal versus High cursor gain.


==Experiment Overview==
The task can therefore be used to investigate how prior experience influences behavioral adaptation to unexpected changes in sensorimotor contingencies.


Each run begins with:
===Implementation Versus Theory===


# A minimal introduction screen.
The current application implements the experimental manipulations required for this type of analysis, but it does not contain an explicit computational model of the participant.


# A free-movement joystick sandbox.
In particular, the software does not calculate:


# The first active experimental block.
* Variational free energy.
* Prediction error.
* Posterior probability.
* Belief distributions.
* Bayesian surprise.
* Learning rate.
* Adaptation score.


# Sequential experimental trials across as many as six block roles.
These quantities, if used, must be estimated during offline behavioral or neural analysis.


# A completion screen when all configured trials have finished.
==Functional Description==


There are no participant-facing block announcements between experimental blocks.
===Mapping Conditions===


The standard experimental trial sequence is:
The FEP task uses two joystick-to-cursor mappings:


# Waiting for center.
{| class="wikitable"
! <code>TaskCondition</code>
! Mapping
! Description
|-
| 0
| Normal
| Joystick displacement moves the cursor in the corresponding direction.
|-
| 1
| Inverted
| Joystick displacement moves the cursor in the opposite direction on both axes.
|}


# Holding center.
The current mapping is not visually indicated to the participant.


# Warning.
Unlike the earlier USBHIDJoystickTask, the FEP task does not use the terms '''Automatic''' and '''Controlled''' in its implementation.


# Pre-target delay.
===Behavioral Measurements===


# Target appearance.
The task records information that may be used to examine:


# Target-directed movement.
* Reaction time.
* Movement time.
* Total target-acquisition time.
* Cursor trajectory.
* Initial movement direction.
* Trajectory curvature.
* Performance immediately following a mapping switch.
* Performance as a function of trials since the previous switch.
* Effects of different mapping-frequency contexts.
* Effects of Normal versus High cursor gain.


# Target acquisition.
==Experiment Structure==


# Feedback.
Each run proceeds in the following order:


# Advance to the next trial or block.
# Introduction.
# Joystick sandbox.
# Experimental block 1, if enabled.
# Experimental block 2, if enabled.
# Experimental block 3, if enabled.
# Experimental block 4, if enabled.
# Experimental block 5, if enabled.
# Experimental block 6, if enabled.
# Experiment completion.


A new target is generated after each successfully completed non-final trial.
Experimental block transitions are not announced to the participant.


==Introduction==
Each experimental trial proceeds as follows:


The introduction is mandatory in the current implementation.
# The participant returns the cursor to the center.
# The participant holds the cursor within the center region.
# A yellow warning cue appears.
# A pre-target delay occurs.
# A peripheral target appears.
# The participant moves the cursor toward the target.
# The target is acquired.
# A short feedback interval occurs.
# The task advances to the next trial.


During the introduction:
==Introduction==


* <code>Introduction=1</code>
The introduction provides only the minimum information needed to operate the task.
* <code>TutorialPhase=1</code>
* <code>TaskPhase=0</code>
* The cursor is hidden.
* The center marker is hidden.
* The warning cue is hidden.
* The target is hidden.
* The fixation cross is hidden.
* The progress bar is hidden.
* Experimental block, trial, target, mapping, gain, switch, prior, and timing states are zeroed.


The participant is shown:
The participant is shown:
Line 195: Line 246:
</pre>
</pre>


A rising press of <code>JoystickButtons1</code> advances the participant to the sandbox.
During the introduction:


Holding the button does not repeatedly advance the introduction because continuation uses rising-edge detection.
* <code>Introduction=1</code>
* <code>TutorialPhase=1</code>
* <code>TaskPhase=0</code>
* The cursor is hidden.
* The center marker is hidden.
* The warning cue is hidden.
* The target is hidden.
* The central cross is hidden.
* The progress bar is hidden.
 
A rising press of <code>JoystickButtons1</code> advances to the sandbox.


The diagnostic window does not contain a separate introduction-continuation button.
The participant is not told about:
 
* Normal versus Inverted mappings.
* Mapping switches.
* Cursor-gain changes.
* Mapping probabilities.
* Experimental blocks.
* Prior conditions.


==Sandbox==
==Sandbox==
Line 207: Line 275:
The participant sees:
The participant sees:


* The black cursor.
* A black cursor.
* The gray center.
* A gray center marker.
* The central cross.
* A black center cross.
* No peripheral target.
* No peripheral target.
* No warning cue.
* No warning cue.
* No experimental progress bar.
* No progress bar.


The screen displays:
The participant is shown:


<pre>
<pre>
Line 235: Line 303:
* No experimental timing phases occur.
* No experimental timing phases occur.


The sandbox ends only when:
The sandbox ends when both of the following conditions are satisfied:


# The cursor is inside the center tolerance region.
# The cursor is inside the center tolerance region.
# A new joystick-button press occurs.
# A new joystick-button press occurs.


The participant must release the button after leaving the introduction screen and press it again to leave the sandbox.
Because continuation uses rising-edge detection, the participant must release the button after leaving the introduction screen before pressing it again to leave the sandbox.


When the sandbox finishes:
When the sandbox finishes:


* <code>Introduction</code> changes to 0.
* <code>Introduction</code> becomes 0.
* <code>TutorialPhase</code> changes to 0.
* <code>TutorialPhase</code> becomes 0.
* <code>TaskPhase</code> becomes 1.
* <code>TaskPhase</code> becomes 1.
* Experimental block and trial states become active.
* Experimental block and trial states become active.
The introduction and sandbox do not tell the participant about:
* Inverted mappings.
* Mapping switches.
* Cursor-gain changes.
* Mapping probabilities.
* Experimental blocks.
* Prior conditions.


==Experimental Blocks==
==Experimental Blocks==


The task uses a fixed sequence of six possible block roles.
The task contains six predefined block roles.


There is no <code>ExperimentMode</code> parameter.
There is no <code>ExperimentMode</code> parameter.


Any block whose trial-count parameter is set to 0 is omitted. <code>TaskBlock</code> retains the original block-role number, so block numbers may skip values when blocks are disabled.
A block may be omitted by setting its trial-count parameter to 0.
 
<code>TaskBlock</code> retains the original block-role number, so block numbers may skip values when one or more blocks are disabled.


{| class="wikitable"
{| class="wikitable"
Line 271: Line 331:
! Trial-count parameter
! Trial-count parameter
! <code>PriorCondition</code>
! <code>PriorCondition</code>
! Mapping composition
|-
| 1
| <code>BaselineTrials</code>
| 0, Fixed
| 100% Normal
|-
| 2
| <code>InitialInvertedTrials</code>
| 0, Fixed
| 100% Inverted
|-
| 3
| <code>ReturnNormalTrials</code>
| 0, Fixed
| 100% Normal
|-
| 4
| <code>MixedTrials</code>
| 1, HiddenMixed
| Approximately 50% Normal and 50% Inverted
|-
| 5
| <code>StrongPriorTrials</code>
| 2, StrongNormal
| Approximately 90% Normal and 10% Inverted
|-
| 6
| <code>BalancedPriorTrials</code>
| 3, Balanced
| Approximately 50% Normal and 50% Inverted
|}


| ! Mapping composition                  |
===Blocks 4 and 6===
| --------------------------------------- |
| 1                                      |
| <code>BaselineTrials</code>            |
| 0, Fixed                                |
| 100% Normal                            |
| -                                      |
| 2                                      |
| <code>InitialInvertedTrials</code>      |
| 0, Fixed                                |
| 100% Inverted                          |
| -                                      |
| 3                                      |
| <code>ReturnNormalTrials</code>        |
| 0, Fixed                                |
| 100% Normal                            |
| -                                      |
| 4                                       |
| <code>MixedTrials</code>                |
| 1, HiddenMixed                          |
| Approximately 50% Normal / 50% Inverted |
| -                                      |
| 5                                      |
| <code>StrongPriorTrials</code>          |
| 2, StrongNormal                        |
| Approximately 90% Normal / 10% Inverted |
| -                                      |
| 6                                       |
| <code>BalancedPriorTrials</code>        |
| 3, Balanced                            |
| Approximately 50% Normal / 50% Inverted |
| }                                      |


For blocks 4 and 6:
For blocks 4 and 6:


* <code>floor(N/2)</code> trials are assigned the Inverted mapping.
* <code>floor(N/2)</code> trials are assigned the Inverted mapping.
* Remaining trials use the Normal mapping.
* All remaining trials are assigned the Normal mapping.
* If the trial count is odd, Normal receives the additional trial.
* If the number of trials is odd, the additional trial is Normal.
 
===Block 5===
 
Block 5 contains a strongly Normal-dominant mapping distribution.
 
Approximately 10% of trials are assigned the Inverted mapping, using a rounded fixed trial count.


For block 5:
The remaining trials are Normal.


* The number of Inverted trials is computed as approximately 10% of the block using rounding.
This is not implemented as an independent 10% switch probability on each trial.
* Remaining trials are Normal.
* This is a fixed-count composition rather than an independent 10% probability on every trial.


===Pseudorandomization===
===Pseudorandomization===


Mappings in blocks 4 through 6 are pseudorandomized.
For blocks 4 through 6, mapping order is pseudorandomized.


The task attempts up to 64 shuffles and prefers sequences that:
The task attempts up to 64 candidate shuffles.


* Do not strictly alternate when the sequence contains at least four trials.
A candidate is preferred when:
* Avoid excessively long runs of one mapping.


The maximum preferred run length is:
* It does not strictly alternate throughout sequences of at least four trials.
* It does not contain excessively long runs of one mapping.
 
The preferred maximum run length is:


<pre>
<pre>
Line 340: Line 407:
using integer division.
using integer division.


These restrictions are attempted rather than absolutely guaranteed. If no acceptable sequence is found after 64 attempts, the final generated sequence is used.
If no candidate satisfies the constraints after 64 attempts, the final generated sequence is used.


Cursor-gain conditions are shuffled independently from mapping conditions. Mapping-by-gain combinations are therefore not explicitly balanced.
Cursor-gain order is shuffled independently from mapping order.


==Prior Conditions==
==Prior Conditions==


<code>PriorCondition</code> identifies the block-level mapping context.
<code>PriorCondition</code> represents the mapping-frequency context associated with the current block.


It does '''not''' represent the mapping used on the immediately preceding trial.
It does not represent the immediately preceding trial's mapping.


{| class="wikitable"
{| class="wikitable"
! Value
! Value
! Code label
! Name
! Meaning
|-
| 0
| Fixed
| Fixed-mapping context used in blocks 1 through 3.
|-
| 1
| HiddenMixed
| Approximately balanced hidden mapping context used in block 4.
|-
| 2
| StrongNormal
| Strongly Normal-dominant mapping context used in block 5.
|-
| 3
| Balanced
| Approximately balanced mapping context used in block 6.
|}


| ! Meaning                                    |
The mapping used on the preceding trial may be determined offline from the previous trial's <code>TaskCondition</code>.
| --------------------------------------------- |
| 0                                            |
| Fixed                                        |
| Fixed-mapping blocks 1 through 3              |
| -                                            |
| 1                                            |
| HiddenMixed                                  |
| Approximately balanced hidden-mapping block 4 |
| -                                            |
| 2                                            |
| StrongNormal                                  |
| Normal-dominant block 5                      |
| -                                            |
| 3                                            |
| Balanced                                      |
| Approximately balanced block 6                |
| }                                            |
 
The previous trial's mapping may be reconstructed offline from the preceding trial's <code>TaskCondition</code>.


==Joystick Input==
==Joystick Input==


Joystick input is supplied through BCI2000's [[User Reference:Logging Input|input logging]] system.
Joystick input is provided through BCI2000's [[User Reference:Logging Input|input logging]] system.


The application expects:
The application reads:


* <code>JoystickXpos</code>
* <code>JoystickXpos</code>
Line 385: Line 451:
* <code>JoystickButtons1</code>
* <code>JoystickButtons1</code>


The X and Y joystick states are expected to range from 0 through 32767.
Joystick X and Y values normally range from 0 through 32767.


Each axis is converted into the task's 0-through-1023 coordinate system:
Each axis is converted into the task's 0-through-1023 coordinate system:
Line 393: Line 459:
</pre>
</pre>


and normalized internally:
The converted value is normalized internally:


<pre>
<pre>
Line 399: Line 465:
</pre>
</pre>


The FEP application does not itself publish or enable <code>LogJoystick</code>. Joystick input logging must therefore be enabled in the BCI2000 configuration.
The FEP application does not itself enable joystick logging.
 
Joystick logging should therefore be enabled using BCI2000's <code>LogJoystick</code> option.


See [[User Reference:Logging Input#LogJoystick|LogJoystick]].
See [[User Reference:Logging Input#LogJoystick|LogJoystick]].


==Joystick-to-Cursor Mappings==
==Joystick-to-Cursor Mapping==


Before target onset, the cursor normally follows direct absolute joystick position:
Before target onset, cursor position normally follows direct absolute joystick position:


<pre>
<pre>
Line 412: Line 480:
</pre>
</pre>


The current trial's mapping and gain conditions are already represented in their corresponding BCI2000 states during the preparation phases, but transformed movement normally begins only when the target appears.
The mapping transformation used for target-directed movement is activated at target onset.


===Anchor Capture===
===Anchor Capture===


At target onset, the application records:
When the target appears, the application stores:


* Current joystick X position.
* Current joystick X position.
Line 425: Line 493:
* Current cursor gain.
* Current cursor gain.


These values form the anchor for transformed target-directed movement.
These values form the anchor for transformed movement.


Because joystick displacement relative to the new anchor is initially zero, activating a transformed mapping does not produce an immediate cursor jump at target onset.
Because joystick displacement relative to the anchor is initially zero, activating the transformed mapping does not cause an immediate cursor jump.


===Normal Mapping, Normal Gain===
===Normal Mapping, Normal Gain===


For a Normal trial with normal gain, cursor position remains direct and absolute:
For a Normal trial with gain 1.0:


<pre>
<pre>
Line 447: Line 515:
</pre>
</pre>


Both axes are inverted. This corresponds to a 180-degree reversal of joystick displacement around the target-onset anchor.
Both axes are inverted.


===Normal Mapping, High Gain===
===Normal Mapping, High Gain===
Line 473: Line 541:
</pre>
</pre>


Cursor position is constrained to the valid participant-display coordinate range.
Cursor coordinates are constrained to the valid display range.


==Cursor Gain==
==Cursor Gain==


The task implements two cursor-gain conditions:
The task contains two cursor-gain conditions.


{| class="wikitable"
{| class="wikitable"
! <code>CursorGainCondition</code>
! <code>CursorGainCondition</code>
! Condition
! Condition
 
! Gain
| ! Gain                     |
|-
| --------------------------- |
| 0
| 0                           |
| Normal
| Normal                     |
| 1.0
| 1.0                         |
|-
| -                           |
| 1
| 1                           |
| High
| High                       |
| <code>HighCursorGain</code>
| <code>HighCursorGain</code> |
|}
| }                           |


The default value of <code>HighCursorGain</code> is:
The default value of <code>HighCursorGain</code> is:
Line 500: Line 567:
</pre>
</pre>


The high-gain transformation multiplies joystick displacement relative to the target-onset anchor.
High gain:
 
It applies to both the X and Y axes.
 
High-gain conditions occur in randomized blocks 4 through 6 and are shuffled independently from the mapping sequence.


Gain condition is not visually cued to the participant.
* Applies to both X and Y axes.
* Multiplies joystick displacement relative to the target-onset anchor.
* Is used only in randomized blocks 4 through 6.
* Is shuffled independently from mapping condition.
* Is not visually cued to the participant.


The current implementation does not define a <code>SensoryReliability</code> parameter or state. Earlier development versions included sensory-reliability and cursor-jitter mechanisms, but these are not part of the current implementation.
The current implementation does not define a <code>SensoryReliability</code> state or parameter.


==Return-to-Anchor Behavior==
==Return-to-Anchor Behavior==


After an Inverted or high-gain trial, the anchored transform may remain active temporarily while the participant returns the joystick toward its target-onset anchor.
After an Inverted or High-gain trial, the previous transformed mapping may temporarily remain active while the participant returns the joystick toward its previous anchor.


The previous anchor, direction, and gain remain active until both joystick axes return within 8 task-coordinate units of the previous joystick anchor.
The stored transformation is released once both joystick axes are within 8 task-coordinate units of the previous joystick anchor.


The application then returns to direct absolute mapping for ordinary trial centering.
Normal direct mapping is then restored for ordinary centering.


This behavior reduces abrupt cursor jumps when leaving an inverted or high-gain mapping.
This behavior reduces abrupt cursor jumps between transformed target movement and subsequent centering.
 
The 8-unit deadzone is used for:
 
* Movement-onset detection.
* Return-to-anchor detection.
 
It is not used as a continuous joystick smoothing filter.


==Mapping Switches==
==Mapping Switches==
Line 535: Line 595:
</pre>
</pre>


Gain changes alone do not count as mapping switches.
Gain changes alone do not produce mapping-switch events.
 
Mapping switches occur only at trial boundaries.


Mapping switches are evaluated after the completed trial's feedback interval while advancing to the next trial.
They do not occur:


Therefore:
* During target-directed movement.
* During the Feedback phase before the feedback interval ends.


* Mapping does not switch during target-directed movement.
The new mapping is selected when the task advances into the next trial.
* Mapping does not switch during the active feedback interval.
* The new condition becomes active when the next trial is selected.
* The new trial begins in <code>WaitingForCenter</code>.
* The new trial's mapping transformation normally affects cursor movement beginning at target onset.


===MappingSwitch State===
===MappingSwitch===


<code>MappingSwitch</code> is an event-like state.
<code>MappingSwitch</code> is an event-like state.
Line 553: Line 612:
It is:
It is:


* 1 on the processing block that advances into a trial whose mapping differs from the completed trial.
* 1 on the processing block that advances into a new trial whose mapping differs from the completed trial.
* 0 on the following processing block.
* 0 on the following processing block.
* 0 when no mapping change occurs.
* 0 when no mapping change occurred.


It should therefore be treated as a one-processing-block pulse.
It should therefore be interpreted as a one-processing-block pulse.


===TrialsSinceMappingSwitch===
===TrialsSinceMappingSwitch===


<code>TrialsSinceMappingSwitch</code> is a persistent counter.
<code>TrialsSinceMappingSwitch</code> records how many consecutive no-switch trial transitions have occurred since the most recent mapping change.


Behavior:
Behavior is:


* First experimental trial: 0.
* First experimental trial: 0.
* Trial immediately following a mapping switch: 0.
* First trial following a mapping switch: 0.
* Next trial with the same mapping: 1.
* Next same-mapping trial: 1.
* Next same-mapping trial: 2.
* Next same-mapping trial: 2.
* And so forth.
* And so forth.


Because the first trial of the experiment also begins with a value of 0, <code>TrialsSinceMappingSwitch==0</code> alone does not prove that a switch occurred.
Because the first experimental trial also begins at 0, <code>TrialsSinceMappingSwitch==0</code> by itself does not identify a switch.


Use <code>MappingSwitch</code>, a change in <code>TaskCondition</code>, or exclusion of the first experimental trial when identifying actual switch events.
Use <code>MappingSwitch</code> or a transition in <code>TaskCondition</code> to identify mapping changes.


===Example===
===Example===


Suppose a portion of block 4 contains:
Consider the following mapping sequence:


<pre>
<pre>
Line 583: Line 642:
</pre>
</pre>


Then:
Within block 4, the corresponding states would behave approximately as follows:


{| class="wikitable"
{| class="wikitable"
Line 590: Line 649:
! <code>MappingSwitch</code>
! <code>MappingSwitch</code>
! <code>TrialsSinceMappingSwitch</code>
! <code>TrialsSinceMappingSwitch</code>
 
! <code>PriorCondition</code>
| ! <code>PriorCondition</code> |
|-
| ----------------------------- |
| Normal
| First Normal                 |
| 0
| 0                             |
| 0
| 0                             |
| Depends on previous trial history
| Depends on preceding sequence |
| 1
| 1                             |
|-
| -                             |
| Normal
| Second Normal                 |
| 0
| 0                             |
| 0
| 0                             |
| Previous value + 1
| Previous value + 1           |
| 1
| 1                             |
|-
| -                             |
| Inverted
| First Inverted               |
| 1
| 1                             |
| 1 on the transition processing block
| 1 during transition block     |
| 0
| 0                             |
| 1
| 1                             |
|-
| -                             |
| Inverted
| Second Inverted               |
| 1
| 1                             |
| 0
| 0                             |
| 1
| 1                             |
| 1
| 1                             |
|}
| }                             |
 
<code>PriorCondition</code> remains 1 because all four trials occur within the HiddenMixed block.


==Target Generation==
==Target Generation==


A new target angle is generated for every new experimental trial.
A new target angle is generated for each new experimental trial.


The generator produces an integer from:
<code>TargetAngle</code> ranges from:


<pre>
<pre>
Line 630: Line 686:
</pre>
</pre>


<code>TargetAngle</code> is expressed in tenths of a degree:
The value represents tenths of a degree:


<pre>
<pre>
Line 642: Line 698:
</pre>
</pre>


in 0.1-degree increments.
Target coordinates are generated according to:
 
Target position is computed using:


<pre>
<pre>
Line 651: Line 705:
</pre>
</pre>


The unequal normalized X and Y radii correspond to a nominal circular target radius of approximately 300 pixels in the application's 1000 x 750 reference geometry.
The unequal normalized X and Y radii correspond to an approximately circular 300-pixel radius in the nominal 1000 by 750 design.
 
Approximate 0-through-1023 target-state ranges are:
 
* <code>TargetX</code>: 205 through 818.
* <code>TargetY</code>: 102 through 921.


Targets:
Targets:


* Are generated continuously around the center rather than from a small fixed set of positions.
* Are black.
* Are not selected according to mapping condition.
* Are visually identical across all mapping conditions.
* Are not selected according to gain condition.
* Are visually identical across gain conditions.
* Are not selected according to mapping-switch status.
* Are not determined by mapping condition.
* Are not determined by gain condition.
* Are not determined by mapping-switch status.
* May repeat.
* May repeat.
* Are not explicitly angularly balanced.
* Are not explicitly angularly balanced.
* Are black in every experimental condition.
* Do not appear during the introduction.
* Do not appear during the introduction or sandbox.
* Do not appear during the sandbox.


A target is generated:
A new target is generated:


* For the first experimental trial.
* For the first experimental trial.
* After each completed non-final trial.
* After each completed non-final trial.


Resetting the current trial does not generate a new target.
Resetting a trial does not generate a new target.


==Experimental Trial Sequence==
==Trial Phases==
 
===Waiting for Center===
 
<code>TaskPhase=1</code>
 
The participant moves the cursor into the center region.
 
The participant sees:
 
* Cursor.
* Gray center marker.
* Central cross.
 
Normal direct mapping is normally used during centering, except while completing return-to-anchor behavior from a previous transformed trial.
 
===Holding Center===
 
<code>TaskPhase=2</code>
 
Once centered, the participant must remain within the center tolerance region for <code>CenterHoldSeconds</code>.
 
Leaving the center before the hold completes restarts center acquisition.
 
During this phase, the application also accumulates the joystick baseline used for later movement-onset detection.
 
===Warning===
 
<code>TaskPhase=3</code>
 
A larger yellow warning marker is displayed for <code>WarningSeconds</code>.
 
The participant must remain centered.
 
Leaving the center restarts the preparation sequence.
 
===Pre-Target Delay===
 
<code>TaskPhase=4</code>
 
The warning cue is removed and the task waits for <code>PreTargetDelaySeconds</code>.
 
The participant must remain centered.


===Target Visible===
The current experimental phase is stored in <code>TaskPhase</code>.
 
<code>TaskPhase=5</code>
 
The peripheral black target appears.
 
At target onset:
 
* The joystick anchor is captured.
* The cursor anchor is captured.
* The selected mapping becomes behaviorally active.
* The selected gain becomes behaviorally active.
* The target-onset timestamp is recorded.
 
The participant then moves the cursor toward the target.
 
===Feedback===
 
<code>TaskPhase=6</code>
 
When the cursor reaches the target:
 
* <code>TargetHit</code> pulses.
* Timing measurements are calculated.
* The target disappears.
* The task remains in feedback for <code>FeedbackSeconds</code>.
 
After feedback expires, the application advances to the next trial or finishes the experiment.
 
===Finished===
 
<code>TaskPhase=7</code>
 
The participant display shows an end message and the run terminates by setting the standard BCI2000 <code>Running</code> state to 0.
 
==Trial Phases==


{| class="wikitable"
{| class="wikitable"
! Value
! Value
! Phase
! Phase
! Meaning
! Description
 
! Participant display
| ! Participant display                     |
|-
| ----------------------------------------- |
| 0
| 0                                         |
| Introduction / Sandbox
| Introduction / Sandbox                   |
| No active experimental trial
| No active experimental trial phase        |
| Introduction text or sandbox
| Introduction text or sandbox display      |
|-
| -                                         |
| 1
| 1                                         |
| WaitingForCenter
| WaitingForCenter                         |
| Waiting for cursor to enter the center region
| Waiting for cursor to enter center region |
| Cursor, gray center, cross
| Cursor, gray center, cross               |
|-
| -                                         |
| 2
| 2                                         |
| HoldingCenter
| HoldingCenter                             |
| Required uninterrupted center hold
| Required uninterrupted center hold       |
| Cursor, gray center, cross
| Cursor, gray center, cross               |
|-
| -                                         |
| 3
| 3                                         |
| Warning
| Warning                                   |
| Warning interval
| Warning interval                         |
| Cursor, yellow warning marker, cross
| Cursor, yellow warning marker, cross     |
|-
| -                                         |
| 4
| 4                                         |
| PreTargetDelay
| PreTargetDelay                           |
| Delay immediately before target appearance
| Delay immediately before target onset    |
| Cursor, gray center, cross
| Cursor, gray center, cross               |
|-
| -                                         |
| 5
| 5                                         |
| TargetVisible
| TargetVisible                             |
| Target-directed movement
| Target-directed movement                 |
| Cursor, black target, cross
| Cursor, black target, cross               |
|-
| -                                         |
| 6
| 6                                         |
| Feedback
| Feedback                                 |
| Post-acquisition interval
| Post-acquisition interval                 |
| Cursor and cross
| Cursor and cross; target hidden          |
|-
| -                                         |
| 7
| 7                                         |
| Finished
| Finished                                 |
| Experiment complete
| Experiment complete                       |
| End message
| End message                               |
|}
| }                                         |


An experimental target onset may be identified by transition into:
An experimental target onset may be identified by a transition into:


<pre>
<pre>
Line 825: Line 798:
==Participant Display==
==Participant Display==


The participant-facing application window contains:
The participant-facing window contains:
 
* Cursor.
* Central fixation cross.
* Gray center marker.
* Larger yellow warning marker.
* Black peripheral target.
* Experimental progress indicator.
* Introduction and sandbox text.
* Experiment-completion text.


The black target is identical across mapping and gain conditions.
* A light background.
* A black cursor.
* A black central cross.
* A gray center marker.
* A larger yellow warning marker.
* A black peripheral target.
* An experimental progress indicator.
* Introduction and sandbox instructions.
* An experiment-completion message.


The participant receives no visual indication of:
The participant receives no explicit visual indication of:


* Normal versus Inverted mapping.
* Current mapping.
* Normal versus High gain.
* Current gain.
* Mapping switches.
* Mapping switches.
* <code>PriorCondition</code>.
* <code>PriorCondition</code>.
Line 849: Line 821:
* Mapping probabilities.
* Mapping probabilities.


The experimental progress bar spans the complete run rather than restarting at individual block boundaries.
The target remains black across conditions.


There is no explicit success color or target-color change during feedback. The target disappears when acquired.
There is no explicit success-color cue. The target disappears after successful acquisition.


==Diagnostic Window==
==Diagnostic Window==
Line 863: Line 835:
is displayed to the experimenter.
is displayed to the experimenter.


During the experiment it displays information including:
During experimental trials it displays information including:


* Current stage.
* Current task stage.
* Original block number out of six.
* Original block number.
* Overall trial number.
* Overall trial number.
* Total number of active trials.
* Total number of active trials.
* Trial number within the current block.
* Trial number within the current block.
* Current mapping: Normal or Inverted.
* Current Normal or Inverted mapping.
* Cursor-gain condition: Normal or High.
* Current Normal or High cursor-gain condition.
* Actual cursor gain.
* Actual gain value.
* Whether the current trial followed a mapping switch.
* Whether the current trial followed a mapping switch.
* Trials since the most recent mapping switch.
* Trials since the most recent mapping switch.
Line 887: Line 859:
* Reset/status information.
* Reset/status information.


The diagnostic window does not currently display <code>PriorCondition</code>, although that value is recorded as a BCI2000 state.
<code>PriorCondition</code> is recorded in the data stream but is not currently displayed in the diagnostic window.
 
During the introduction and sandbox, the window reports:
 
* Current introduction stage.
* Block/trial as not yet started.
* Normal mapping.
* Normal 1.0 gain.
* No mapping switch.
* Counter value 0.
* No experimental target.
* Joystick coordinates.
* Cursor coordinates.
* Zero timing values.


===Diagnostic Controls===
===Diagnostic Controls===


The current diagnostic window provides:
The diagnostic window provides:


'''RESET CURRENT TRIAL'''
<pre>
 
RESET CURRENT TRIAL
There is no diagnostic introduction-continuation button.
</pre>


The reset control is enabled only during the experimental portion of the run before the Feedback phase.
There is no diagnostic Continue button for the introduction or sandbox.


==Trial Reset==
==Trial Reset==


Experimental trials may be manually reset during:
A trial may be manually reset during:


* Waiting for center.
* Waiting for center.
Line 933: Line 892:
* Returns the task to <code>WaitingForCenter</code>.
* Returns the task to <code>WaitingForCenter</code>.
* Restarts the phase timer.
* Restarts the phase timer.
* Clears target-appearance timing.
* Clears movement-onset timing.
* Clears movement-onset timing.
* Clears target-onset timing.
* Clears <code>MovementStarted</code>.
* Clears <code>MovementStarted</code>.
* Clears <code>TargetHit</code>.
* Clears <code>TargetHit</code>.
* Produces a <code>TrialReset</code> pulse.
* Produces a <code>TrialReset</code> pulse.
* Clears reaction-time state.
* Clears timing states.
* Clears movement-time state.
* Resets baseline accumulation.
* Clears total-time state.
* Resets movement-baseline accumulation.
* Keeps the same target.
* Keeps the same target.
* Keeps the same mapping.
* Keeps the same mapping.
Line 947: Line 904:
* Keeps the same block number.
* Keeps the same block number.
* Keeps the same trial number.
* Keeps the same trial number.
* Keeps the same <code>PriorCondition</code>.
* Keeps <code>PriorCondition</code>.
* Keeps the same <code>TrialsSinceMappingSwitch</code>.
* Keeps <code>TrialsSinceMappingSwitch</code>.
* Does not rebuild or reshuffle the experimental sequence.
* Does not rebuild or reshuffle the experimental sequence.


<code>TrialReset</code> is cleared on the next processing block and should therefore be interpreted as a one-processing-block event.
<code>TrialReset</code> lasts for one processing block.
 
A reset does not generate a new <code>MappingSwitch</code> event.


==Timing Measurements==
==Timing Measurements==


Timing is measured using <code>std::chrono::steady_clock</code>.
Timing uses <code>std::chrono::steady_clock</code>.


Events are detected within BCI2000 <code>Process()</code> calls, so effective event timing resolution is limited by the BCI2000 processing-block interval.
Events are detected during BCI2000 <code>Process()</code> calls, so effective timing resolution is limited by the signal-processing block interval.


===Movement Onset===
===Movement Onset===


The joystick baseline is initialized when center holding begins and updated during the center-hold phase.
The joystick baseline is initialized when the center-hold phase begins and updated during center holding.


Movement onset occurs when either joystick axis differs from this baseline by more than 8 task-coordinate units:
Movement onset is detected when either joystick axis differs from the center-hold baseline by more than 8 task-coordinate units.


<pre>
<pre>
Line 982: Line 937:


<pre>
<pre>
target onset -> detected movement onset
target onset -> movement onset
</pre>
</pre>


and recorded in:
and stored in:


<code>ReactionTimeMs</code>
<code>ReactionTimeMs</code>
Line 994: Line 949:


<pre>
<pre>
detected movement onset -> target acquisition
movement onset -> target acquisition
</pre>
</pre>


and recorded in:
and stored in:


<code>MovementTimeMs</code>
<code>MovementTimeMs</code>
Line 1,009: Line 964:
</pre>
</pre>


and recorded in:
and stored in:


<code>TotalTimeMs</code>
<code>TotalTimeMs</code>


Timing values are expressed as rounded milliseconds.
Timing values are expressed in rounded milliseconds.
 
The timing states:
 
* Are populated when the target is acquired.
* Remain populated through the Feedback phase.
* Are cleared when advancing to an ordinary subsequent trial.
* Are cleared after a manual reset.
* Remain populated after completion of the final trial.
* Are zero during the introduction and sandbox.


If target acquisition occurs without a detected movement onset, reaction time and movement time are written as zero while total time is still recorded.
Timing states remain populated through the Feedback phase.


==Parameters==
==Parameters==
Line 1,035: Line 981:
! Default
! Default
! Range
! Range
 
! Description
| ! Meaning                                                          |
|-
| ------------------------------------------------------------------- |
| <code>BaselineTrials</code>
| <code>BaselineTrials</code>                                         |
| Integer
| Integer                                                             |
| 20
| 20                                                                 |
| 0-10000
| 0-10000                                                             |
| Number of Normal trials in block 1
| Number of Normal trials in block 1.                                |
|-
| -                                                                   |
| <code>InitialInvertedTrials</code>
| <code>InitialInvertedTrials</code>                                 |
| Integer
| Integer                                                             |
| 5
| 5                                                                   |
| 0-10000
| 0-10000                                                             |
| Number of Inverted trials in block 2
| Number of Inverted trials in block 2.                              |
|-
| -                                                                   |
| <code>ReturnNormalTrials</code>
| <code>ReturnNormalTrials</code>                                     |
| Integer
| Integer                                                             |
| 5
| 5                                                                   |
| 0-10000
| 0-10000                                                             |
| Number of Normal trials in block 3
| Number of Normal trials in block 3.                                |
|-
| -                                                                   |
| <code>MixedTrials</code>
| <code>MixedTrials</code>                                           |
| Integer
| Integer                                                             |
| 20
| 20                                                                 |
| 0-10000
| 0-10000                                                             |
| Number of approximately balanced trials in block 4
| Number of approximately balanced Normal/Inverted trials in block 4. |
|-
| -                                                                   |
| <code>StrongPriorTrials</code>
| <code>StrongPriorTrials</code>                                     |
| Integer
| Integer                                                             |
| 20
| 20                                                                 |
| 0-10000
| 0-10000                                                             |
| Number of Normal-dominant trials in block 5
| Number of predominantly Normal trials in block 5.                  |
|-
| -                                                                   |
| <code>BalancedPriorTrials</code>
| <code>BalancedPriorTrials</code>                                   |
| Integer
| Integer                                                             |
| 20
| 20                                                                 |
| 0-10000
| 0-10000                                                             |
| Number of approximately balanced trials in block 6
| Number of approximately balanced trials in block 6.                |
|}
| }                                                                   |


At least one trial must be configured across the six block parameters.
At least one trial must be configured across the six block parameters.


===Cursor Gain===
===HighCursorGain===
 
====HighCursorGain====


Gain applied during High cursor-gain trials.
Gain used during High cursor-gain trials.


Type: floating point
Type: floating point
Line 1,087: Line 1,030:
Default:
Default:


<code>1.5</code>
<pre>
1.5
</pre>


Range:
Range:


<code>1.0-5.0</code>
<pre>
1.0-5.0
</pre>


Normal gain is fixed at 1.0.
Normal gain is fixed at 1.0.


===Trial Timing===
===CenterHoldSeconds===


====CenterHoldSeconds====
Required center-hold duration.
 
Time the participant must remain within the center region.


Type: floating point
Type: floating point
Line 1,105: Line 1,050:
Default:
Default:


<code>3.0</code> seconds
<pre>
3.0
</pre>
 
seconds.


Range:
Range:


<code>0.0-60.0</code> seconds
<pre>
0.0-60.0
</pre>


====WarningSeconds====
seconds.


Duration of the yellow warning cue.
===WarningSeconds===


Type: floating point
Duration of the yellow warning interval.


Default:
Default:


<code>0.5</code> seconds
<pre>
 
0.5
Range:
</pre>
 
<code>0.0-60.0</code> seconds


====PreTargetDelaySeconds====
seconds.


Delay between the end of the warning cue and target onset.
===PreTargetDelaySeconds===


Type: floating point
Delay between the warning interval and target onset.


Default:
Default:


<code>0.5</code> seconds
<pre>
0.5
</pre>


Range:
seconds.


<code>0.0-60.0</code> seconds
===FeedbackSeconds===


====FeedbackSeconds====
Duration of the feedback interval following target acquisition.
 
Duration of the feedback phase after successful target acquisition.
 
Type: floating point


Default:
Default:


<code>0.5</code> seconds
<pre>
 
0.5
Range:
</pre>
 
<code>0.0-60.0</code> seconds
 
===Display===


====StimulusDisplay====
seconds.


Selects the physical display used for the participant-facing application window.
===StimulusDisplay===


Type: integer enumeration
Selects the physical monitor used for the participant-facing application window.


Default:
Default:


<code>0</code>
<pre>
 
0
On Windows, available displays are enumerated by the application.
</pre>
 
===Parameters Not Defined by This Application===


The current implementation does not define:
On Windows systems, available monitors are enumerated by the application.
 
* <code>ExperimentMode</code>
* Initial mapping selector
* Mapping-switch probability
* Introduction enable/disable parameter
* Sandbox duration
* <code>SensoryReliability</code>
* Cursor-noise parameter
* <code>ResultsFile</code>
* CSV-output parameter


==States==
==States==
The following states are defined by <code>FEP_VisuomotorJoystickTask</code>.


{| class="wikitable"
{| class="wikitable"
! State
! State
! Width
! Width
! Initial
! Initial Value
! Produced values
! Meaning
 
|-
| ! Meaning                                                                 |
| <code>CursorX</code>
| -------------------------------------------------------------------------- |
| 10 bit
| <code>CursorX</code>                                                       |
| 512
| 10 bit                                                                     |
| Participant-visible horizontal cursor coordinate
| 512                                                                       |
|-
| 0-1023                                                                    |
| <code>CursorY</code>
| Participant-visible horizontal cursor coordinate.                          |
| 10 bit
| -                                                                         |
| 512
| <code>CursorY</code>                                                       |
| Participant-visible vertical cursor coordinate
| 10 bit                                                                     |
|-
| 512                                                                       |
| <code>TaskPhase</code>
| 0-1023                                                                    |
| 3 bit
| Participant-visible vertical cursor coordinate.                            |
| 0
| -                                                                         |
| Current task phase
| <code>TaskPhase</code>                                                     |
|-
| 3 bit                                                                     |
| <code>TaskCondition</code>
| 0                                                                          |
| 1 bit
| 0-7                                                                        |
| 0
| Current introduction or experimental phase.                                |
| 0 Normal, 1 Inverted
| -                                                                         |
|-
| <code>TaskCondition</code>                                                 |
| <code>TargetAngle</code>
| 1 bit                                                                     |
| 12 bit
| 0                                                                         |
| 0
| 0-1                                                                        |
| Target angle in tenths of a degree
| 0 Normal, 1 Inverted.                                                      |
|-
| -                                                                         |
| <code>TargetX</code>
| <code>TargetAngle</code>                                                   |
| 10 bit
| 12 bit                                                                     |
| 512
| 0                                                                          |
| Horizontal target coordinate
| 0-3599                                                                    |
|-
| Target angle in tenths of a degree.                                        |
| <code>TargetY</code>
| -                                                                         |
| 10 bit
| <code>TargetX</code>                                                       |
| 512
| 10 bit                                                                     |
| Vertical target coordinate
| 512                                                                       |
|-
| Experimental target coordinate                                            |
| <code>TaskBlock</code>
| Horizontal target coordinate.                                              |
| 8 bit
| -                                                                         |
| 0
| <code>TargetY</code>                                                       |
| Current experimental block role
| 10 bit                                                                     |
|-
| 512                                                                       |
| <code>TaskTrial</code>
| Experimental target coordinate                                            |
| 16 bit
| Vertical target coordinate.                                                |
| 0
| -                                                                         |
| Overall experimental trial number
| <code>TaskBlock</code>                                                     |
|-
| 8 bit                                                                     |
| <code>MovementStarted</code>
| 0                                                                         |
| 1 bit
| 0-6                                                                        |
| 0
| Original experimental block-role number.                                  |
| Indicates detected movement onset
| -                                                                         |
|-
| <code>TaskTrial</code>                                                     |
| <code>TargetHit</code>
| 16 bit                                                                     |
| 1 bit
| 0                                                                         |
| 0
| One-based experimental trial                                              |
| Target-acquisition event
| Overall trial number across active blocks.                                |
|-
| -                                                                         |
| <code>TrialReset</code>
| <code>MovementStarted</code>                                               |
| 1 bit
| 1 bit                                                                     |
| 0
| 0                                                                          |
| Manual-reset event
| 0-1                                                                        |
|-
| Indicates detected movement onset.                                        |
| <code>MappingSwitch</code>
| -                                                                         |
| 1 bit
| <code>TargetHit</code>                                                     |
| 0
| 1 bit                                                                     |
| Mapping-change event
| 0                                                                         |
|-
| 0-1                                                                        |
| <code>TrialsSinceMappingSwitch</code>
| One-processing-block target-acquisition event.                            |
| 16 bit
| -                                                                         |
| 0
| <code>TrialReset</code>                                                   |
| Trials since the most recent mapping switch
| 1 bit                                                                     |
|-
| 0                                                                          |
| <code>PriorCondition</code>
| 0-1                                                                        |
| 2 bit
| One-processing-block manual-reset event.                                  |
| 0
| -                                                                         |
| Current block-level prior context
| <code>MappingSwitch</code>                                                 |
|-
| 1 bit                                                                     |
| <code>CursorGainCondition</code>
| 0                                                                         |
| 1 bit
| 0-1                                                                        |
| 0
| One-processing-block mapping-change event.                                |
| 0 Normal gain, 1 High gain
| -                                                                         |
|-
| <code>TrialsSinceMappingSwitch</code>                                     |
| <code>Introduction</code>
| 16 bit                                                                     |
| 1 bit
| 0                                                                         |
| 0
| 0 upward                                                                  |
| 1 during introduction or sandbox
| Number of consecutive no-switch transitions since the last mapping switch. |
|-
| -                                                                         |
| <code>TutorialPhase</code>
| <code>PriorCondition</code>                                               |
| 4 bit
| 2 bit                                                                     |
| 0
| 0                                                                         |
| 0 experiment, 1 introduction, 2 sandbox
| 0-3                                                                        |
|-
| Current block-level prior category.                                        |
| <code>ReactionTimeMs</code>
| -                                                                         |
| 32 bit
| <code>CursorGainCondition</code>                                           |
| 0
| 1 bit                                                                     |
| Reaction time in milliseconds
| 0                                                                         |
|-
| 0-1                                                                        |
| <code>MovementTimeMs</code>
| 0 Normal gain, 1 High gain.                                                |
| 32 bit
| -                                                                         |
| 0
| <code>Introduction</code>                                                 |
| Movement time in milliseconds
| 1 bit                                                                     |
|-
| 0                                                                          |
| <code>TotalTimeMs</code>
| 0-1                                                                        |
| 32 bit
| 1 during introduction or sandbox; 0 during experiment.                    |
| 0
| -                                                                         |
| Total target-directed time in milliseconds
| <code>TutorialPhase</code>                                                 |
|}
| 4 bit                                                                     |
| 0                                                                         |
| 0-2                                                                        |
| 0 experiment, 1 introduction, 2 sandbox.                                  |
| -                                                                         |
| <code>ReactionTimeMs</code>                                               |
| 32 bit                                                                     |
| 0                                                                         |
| Nonnegative milliseconds                                                   |
| Target onset to detected movement onset.                                  |
| -                                                                         |
| <code>MovementTimeMs</code>                                               |
| 32 bit                                                                     |
| 0                                                                         |
| Nonnegative milliseconds                                                   |
| Detected movement onset to target acquisition.                            |
| -                                                                         |
| <code>TotalTimeMs</code>                                                   |
| 32 bit                                                                     |
| 0                                                                         |
| Nonnegative milliseconds                                                   |
| Target onset to target acquisition.                                        |
| }                                                                         |


===External Joystick States===
===External Joystick States===
The application also reads states supplied by BCI2000's joystick logging system.


{| class="wikitable"
{| class="wikitable"
! State
! State
! Description
|-
| <code>JoystickXpos</code>
| Raw horizontal joystick position
|-
| <code>JoystickYpos</code>
| Raw vertical joystick position
|-
| <code>JoystickButtons1</code>
| Joystick button used to advance the introduction and sandbox
|}


| ! Description                                                            |
The application also accesses the standard BCI2000 <code>Running</code> state when ending the experiment.
| ------------------------------------------------------------------------ |
| <code>JoystickXpos</code>                                                |
| Raw horizontal joystick position, normally ranging from 0 through 32767. |
| -                                                                        |
| <code>JoystickYpos</code>                                               |
| Raw vertical joystick position, normally ranging from 0 through 32767.  |
| -                                                                        |
| <code>JoystickButtons1</code>                                            |
| Joystick button 1. Used to advance the introduction and sandbox.         |
| }                                                                        |


The application also accesses the standard BCI2000:
===States Not Present in the Current Implementation===
 
<code>Running</code>
 
state when ending the experiment.
 
===States Not Present===


The current implementation does not define:
The current implementation does not define:
Line 1,357: Line 1,256:
==Cursor Coordinates==
==Cursor Coordinates==


<code>CursorX</code> and <code>CursorY</code> represent the final cursor coordinates actually displayed to the participant after any:
<code>CursorX</code> and <code>CursorY</code> represent the final cursor coordinates actually displayed to the participant.
 
These coordinates include any:


* Mapping inversion.
* Mapping inversion.
Line 1,366: Line 1,267:
The same coordinates are used for:
The same coordinates are used for:


* Participant cursor rendering.
* Drawing the participant-visible cursor.
* Center detection.
* Center detection.
* Target-hit detection.
* Target-hit detection.
* BCI2000 state output.
* BCI2000 state recording.
* Diagnostic display.
* Diagnostic display.


They should therefore be used when analyzing the participant-visible cursor trajectory.
The application does not record a separate untransformed cursor trajectory.
 
The task does not record a separate latent or untransformed cursor trajectory.
 
The direct joystick-equivalent trajectory may be reconstructed offline from:


* <code>JoystickXpos</code>
A direct joystick-equivalent trajectory may be reconstructed offline from <code>JoystickXpos</code> and <code>JoystickYpos</code>.
* <code>JoystickYpos</code>
 
using the same conversion logic as the task.
 
Raw joystick and displayed cursor coordinates match during:
 
* The sandbox.
* Ordinary centering.
* Normal 1x trials.
* The instant a transformed movement anchor is captured.
 
They diverge during:
 
* Inverted movement.
* High-gain movement.
* Inverted plus high-gain movement.
* Return-to-anchor behavior following a transformed trial.


==Data Recording==
==Data Recording==


Task variables are recorded as BCI2000 states in the ordinary BCI2000 <code>.dat</code> data stream.
The task records its behavioral variables as synchronized BCI2000 states in the standard <code>.dat</code> file.


The application records information sufficient to recover:
Recorded information includes:


* Participant-visible cursor trajectory.
* Participant-visible cursor trajectory.
* Joystick trajectory, when joystick logging is enabled.
* Trial phase.
* Trial phase.
* Mapping condition.
* Mapping condition.
Line 1,409: Line 1,290:
* Target angle.
* Target angle.
* Target coordinates.
* Target coordinates.
* Block number.
* Experimental block.
* Trial number.
* Experimental trial number.
* Movement onset.
* Movement onset.
* Target acquisition.
* Target acquisition.
Line 1,417: Line 1,298:
* Trials since the most recent mapping switch.
* Trials since the most recent mapping switch.
* Prior-condition category.
* Prior-condition category.
* Introduction/sandbox status.
* Introduction and sandbox status.
* Reaction time.
* Reaction time.
* Movement time.
* Movement time.
* Total time.
* Total time.


Joystick trajectories are recorded through BCI2000 input logging when joystick logging is enabled.
The application passes signal channels through unchanged.
 
The application passes signal channels through unchanged:


<pre>
<pre>
Line 1,432: Line 1,311:
===Secondary Output===
===Secondary Output===


The current FEP implementation does not write an application-specific:
The current implementation does not write an application-specific:


* CSV file.
* CSV file.
Line 1,440: Line 1,319:


There is no <code>ResultsFile</code> parameter.
There is no <code>ResultsFile</code> parameter.
Successful trials generate diagnostic/log output, but this is not a structured secondary results file.


==Offline Analysis Notes==
==Offline Analysis Notes==


{| class="wikitable"
{| class="wikitable"
! Measurement / Event
! Measurement or Event
 
! Recommended Identification
| ! Recommended identification                                                                      |
|-
| -------------------------------------------------------------------------------------------------- |
| Experimental samples
| Experimental samples                                                                               |
| <code>Introduction == 0</code>
| <code>Introduction == 0</code>                                                                     |
|-
| -                                                                                                 |
| Introduction
| Introduction screen                                                                                |
| <code>Introduction == 1</code> and <code>TutorialPhase == 1</code>
| <code>Introduction == 1</code> and <code>TutorialPhase == 1</code>                                 |
|-
| -                                                                                                 |
| Sandbox
| Sandbox                                                                                           |
| <code>Introduction == 1</code> and <code>TutorialPhase == 2</code>
| <code>Introduction == 1</code> and <code>TutorialPhase == 2</code>                                 |
|-
| -                                                                                                 |
| Active experimental trial
| Active experimental trial                                                                         |
| <code>Introduction == 0</code>, <code>TaskTrial > 0</code>, and <code>TaskPhase</code> from 1 through 6
| <code>Introduction == 0</code>, <code>TaskTrial > 0</code>, and <code>TaskPhase</code> 1 through 6 |
|-
| -                                                                                                 |
| Target onset
| Target onset                                                                                       |
| Transition into <code>TaskPhase == 5</code>
| Transition into <code>TaskPhase == 5</code>                                                       |
|-
| -                                                                                                 |
| Movement onset
| Movement onset                                                                                     |
| Rising transition of <code>MovementStarted</code>
| Rising transition of <code>MovementStarted</code>                                                 |
|-
| -                                                                                                 |
| Target acquisition
| Target acquisition                                                                                 |
| <code>TargetHit == 1</code>
| <code>TargetHit == 1</code>                                                                       |
|-
| -                                                                                                 |
| Normal mapping
| Normal mapping                                                                                     |
| <code>TaskCondition == 0</code>
| <code>TaskCondition == 0</code>                                                                   |
|-
| -                                                                                                 |
| Inverted mapping
| Inverted mapping                                                                                   |
| <code>TaskCondition == 1</code>
| <code>TaskCondition == 1</code>                                                                   |
|-
| -                                                                                                 |
| Normal gain
| Normal cursor gain                                                                                 |
| <code>CursorGainCondition == 0</code>
| <code>CursorGainCondition == 0</code>                                                             |
|-
| -                                                                                                 |
| High gain
| High cursor gain                                                                                   |
| <code>CursorGainCondition == 1</code>
| <code>CursorGainCondition == 1</code>                                                             |
|-
| -                                                                                                 |
| Mapping switch
| Mapping switch                                                                                     |
| <code>MappingSwitch == 1</code>
| <code>MappingSwitch == 1</code>                                                                   |
|-
| -                                                                                                 |
| Trials since switch
| First trial after switch                                                                          |
| <code>TrialsSinceMappingSwitch</code>
| Trial receiving the <code>MappingSwitch</code> event                                              |
|-
| -                                                                                                  |
| Previous mapping
| Trials since switch                                                                               |
| Previous trial's <code>TaskCondition</code>
| <code>TrialsSinceMappingSwitch</code>                                                             |
|-
| -                                                                                                 |
| Prior context
| Previous mapping                                                                                   |
| <code>PriorCondition</code>
| Derive from the preceding trial's <code>TaskCondition</code>                                       |
|-
| -                                                                                                 |
| Experimental block
| Prior category                                                                                    |
| <code>TaskBlock</code>
| <code>PriorCondition</code>                                                                       |
|-
| -                                                                                                 |
| Overall trial
| Block                                                                                              |
| <code>TaskTrial</code>
| <code>TaskBlock</code>                                                                             |
|-
| -                                                                                                 |
| Target angle
| Overall trial                                                                                     |
| <code>TargetAngle / 10</code> degrees
| <code>TaskTrial</code>                                                                             |
|-
| -                                                                                                 |
| Target position
| Target angle                                                                                       |
| <code>TargetX</code> and <code>TargetY</code>
| <code>TargetAngle / 10</code> degrees                                                             |
|-
| -                                                                                                 |
| Joystick trajectory
| Target position                                                                                   |
| <code>JoystickXpos</code> and <code>JoystickYpos</code>
| <code>TargetX</code> and <code>TargetY</code>                                                     |
|-
| -                                                                                                 |
| Participant-visible cursor trajectory
| Raw joystick trajectory                                                                           |
| <code>CursorX</code> and <code>CursorY</code>
| <code>JoystickXpos</code> and <code>JoystickYpos</code>                                           |
|-
| -                                                                                                 |
| Reaction time
| Participant-visible cursor trajectory                                                             |
| <code>ReactionTimeMs</code>
| <code>CursorX</code> and <code>CursorY</code>                                                     |
|-
| -                                                                                                 |
| Movement time
| Reaction time                                                                                     |
| <code>MovementTimeMs</code>
| <code>ReactionTimeMs</code>, preferably sampled at target acquisition or during feedback          |
|-
| -                                                                                                 |
| Total time
| Movement time                                                                                     |
| <code>TotalTimeMs</code>
| <code>MovementTimeMs</code>, preferably sampled at target acquisition or during feedback          |
|-
| -                                                                                                 |
| Manual reset
| Total time                                                                                         |
| <code>TrialReset == 1</code>
| <code>TotalTimeMs</code>, preferably sampled at target acquisition or during feedback              |
|-
| -                                                                                                 |
| Experiment completion
| Manual reset                                                                                       |
| <code>TaskPhase == 7</code>
| <code>TrialReset == 1</code>                                                                       |
|}
| -                                                                                                 |
| Experiment completion                                                                             |
| <code>TaskPhase == 7</code>, followed by <code>Running == 0</code>                                |
| }                                                                                                 |


===Event-Like and Persistent States===
===Event-Like States===


{| class="wikitable"
The following states are one-processing-block events:
! State


| ! Behavior                                        |
* <code>MappingSwitch</code>
| ------------------------------------------------- |
* <code>TargetHit</code>
| <code>MappingSwitch</code>                       |
* <code>TrialReset</code>
| One processing block                              |
| -                                                |
| <code>TargetHit</code>                           |
| One processing block                              |
| -                                                |
| <code>TrialReset</code>                           |
| One processing block                              |
| -                                                |
| <code>MovementStarted</code>                      |
| Remains high from movement onset through feedback |
| -                                                |
| <code>TrialsSinceMappingSwitch</code>            |
| Persistent counter                                |
| -                                                |
| <code>TaskCondition</code>                        |
| Persistent for current trial                      |
| -                                                |
| <code>CursorGainCondition</code>                  |
| Persistent for current trial                      |
| -                                                |
| <code>PriorCondition</code>                      |
| Persistent for current block                      |
| -                                                |
| Timing states                                    |
| Remain populated through feedback                |
| }                                                |


An event state that lasts one BCI2000 processing block will ordinarily be represented across the samples belonging to that signal block rather than necessarily appearing as a single sample in the final data file.
<code>MovementStarted</code> differs from these states because it remains high from movement onset through the remainder of the trial and Feedback phase.


==Differences from USBHIDJoystickTask==
==Differences from USBHIDJoystickTask==
The FEP task retains much of the center-out reaching and data-recording infrastructure of the earlier USBHIDJoystickTask while substantially changing the participant-facing experimental structure.


===Retained===
===Retained===


* BCI2000 <code>ApplicationBase</code> application module.
* BCI2000 <code>ApplicationBase</code> structure.
* USB joystick input through BCI2000 input logging.
* USB joystick input.
* Center-out reaching behavior.
* Center-out reaching.
* Center hold.
* Center hold.
* Yellow warning period.
* Warning interval.
* Pre-target delay.
* Pre-target delay.
* Target-directed movement.
* Target-directed movement.
Line 1,587: Line 1,431:
* Movement-time measurement.
* Movement-time measurement.
* Total-time measurement.
* Total-time measurement.
* Movement-onset deadzone.
* Participant application window.
* Experimenter diagnostic window.
* Manual trial reset.
* Manual trial reset.
* Experimental progress bar.
* Progress bar.
* BCI2000 state logging.
* BCI2000 state logging.
* Direct and inverted joystick-control concepts.
* Direct and inverted joystick-control mappings.


===Removed===
===Removed===


The FEP task does not use the older task's:
The FEP task removes the earlier task's:


* <code>ExperimentMode</code>.
* <code>ExperimentMode</code>.
* Automatic-only mode.
* Automatic-only and Controlled-only modes.
* Controlled-only mode.
* Ordered-start condition.
* Ordered-mode selector.
* Configurable ordered starting condition.
* <code>TaskBlockType</code>.
* <code>TaskBlockType</code>.
* Green Automatic targets.
* Green versus red condition-specific targets.
* Red Controlled targets.
* Explicit condition instructions.
* Condition-specific target-color cues.
* Detailed Automatic/Controlled tutorial.
* Explicit teaching of the inverted mapping.
* Explicit teaching of the inverted mapping.
* Condition-specific practice trials.
* Condition-specific practice trials.
* <code>PracticeTrial</code>.
* <code>PracticeTrial</code>.
* Optional tutorial enable/disable parameter.
* Optional tutorial setting.
* Diagnostic tutorial-continuation button.
* Diagnostic Continue button.
* Condition-specific run-summary statistics.
* Secondary CSV results file.
* <code>ResultsFile</code>.
* Secondary CSV output.
* Participant-facing block announcements.
* Participant-facing block announcements.


Line 1,623: Line 1,458:
The FEP task adds:
The FEP task adds:


* Fixed six-role experimental sequence.
* Six predefined experimental block roles.
* Hidden Normal and Inverted mappings.
* Hidden Normal and Inverted mappings.
* Unannounced mapping switches.
* <code>MappingSwitch</code>.
* <code>MappingSwitch</code>.
* <code>TrialsSinceMappingSwitch</code>.
* <code>TrialsSinceMappingSwitch</code>.
Line 1,630: Line 1,466:
* <code>CursorGainCondition</code>.
* <code>CursorGainCondition</code>.
* <code>HighCursorGain</code>.
* <code>HighCursorGain</code>.
* Normal versus high-gain trials.
* Normal versus High cursor gain.
* Hidden mapping switches.
* A minimal Normal-mapping sandbox.
* Minimal participant introduction.
* Black targets across all mapping conditions.
* Free-movement sandbox.
* Normal-dominant and approximately balanced mapping contexts.
* Black targets in all conditions.
* Approximately balanced and Normal-dominant mapping blocks.
 
===Changed Condition Terminology===
 
The earlier USB task used:
 
* Automatic
* Controlled
 
The FEP task uses:
 
* Normal
* Inverted
 
===Changed Trial Organization===
 
The USB task supports selectable experimental modes and explicit ordered or pseudorandom block structures.
 
The FEP task instead constructs a predefined six-role sequence and omits individual blocks only when their configured trial count is zero.
 
===Changed Participant Information===
 
The earlier task explicitly explains its mappings and provides condition-specific practice.
 
The FEP task deliberately provides only generic joystick instructions and a Normal-mapping sandbox.
 
It does not disclose:
 
* Inversion.
* Gain manipulation.
* Mapping switches.
* Mapping probabilities.
* Block transitions.


==Known Limitations and Analysis Considerations==
==Known Limitations and Analysis Considerations==


* The FEP module currently has no independent source-control revision.
* The current module does not implement an explicit computational Free Energy Principle model.
* There is no task-specific saved parameter file in the inspected source tree.
* <code>PriorCondition</code> represents experimental block context rather than an inferred participant belief.
* There is no task-specific launch batch file in the inspected source tree.
* Participant surprise or expectation is not measured directly by the application.
* The participant's subjective expectation or surprise cannot be inferred directly from the software.
* Blocks 4 and 6 use similar approximately balanced mapping-generation rules but occur after different preceding mapping histories.
* <code>PriorCondition</code> describes block context rather than an inferred participant belief.
* Mapping pseudorandomization constraints are attempted but are not guaranteed if all 64 candidate sequences fail.
* Blocks 4 and 6 use the same approximately balanced mapping-generation rule and differ principally in their sequence position and <code>PriorCondition</code> value.
* The mapping pseudorandomization restrictions are not guaranteed if all 64 candidate shuffles fail.
* There is no unsuccessful-trial timeout.
* There is no unsuccessful-trial timeout.
* The source contains no explicit formal Free Energy Principle model.
* High cursor gain is implemented as a gain manipulation rather than as a state explicitly named sensory reliability.
* High cursor gain is implemented as a gain manipulation. The source itself does not label it sensory reliability.
* There is no separately recorded latent or untransformed cursor trajectory.
* There is no separately recorded untransformed cursor trajectory.
* Physical display geometry depends on the configured participant monitor and BCI2000 window dimensions.
* Analyses requiring the direct joystick-equivalent trajectory should reconstruct it from joystick states.
* Display geometry is normalized from a nominal 1000 x 750 design and physical appearance may depend on monitor geometry and BCI2000 window configuration.


==Scientific References==
==References==


No FEP-specific paper, DOI, PMID, arXiv identifier, or other scientific reference is currently cited in the <code>FEP_VisuomotorJoystickTask</code> source code or supporting files inspected for this documentation.
Friston, K. The free-energy principle: a unified brain theory?. Nat Rev Neurosci 11, 127–138 (2010). https://doi.org/10.1038/nrn2787
 
The current implementation should therefore be described in terms of its implemented experimental manipulations rather than attributed to a specific formal Free Energy Principle model unless an appropriate study protocol or scientific reference is added separately.


==See also==
==See also==


* [[VisuomotorJoystickTask|Visuomotor Joystick Task]]
* [[User Reference:Logging Input|Logging Input]]
* [[User Reference:Logging Input|Logging Input]]
* [[User Reference:Logging Input#LogJoystick|LogJoystick]]
* [[User Reference:Logging Input#LogJoystick|LogJoystick]]
Line 1,699: Line 1,496:
* [[Technical Reference:BCI2000 File Format|BCI2000 File Format]]
* [[Technical Reference:BCI2000 File Format|BCI2000 File Format]]
* [[Programming Reference:ApplicationBase Class|ApplicationBase Class]]
* [[Programming Reference:ApplicationBase Class|ApplicationBase Class]]
* [[Category:User Application]]

Latest revision as of 19:54, 22 September 2026

Synopsis

FEP_VisuomotorJoystickTask is a BCI2000 application module implementing a center-out visuomotor reaching task designed to investigate how participants adapt their behavior when the relationship between their actions and sensory consequences changes unexpectedly.

Participants control a cursor using a USB HID joystick and repeatedly move from a central starting location to peripheral targets. The joystick-to-cursor mapping is treated as a hidden environmental state: on a given trial, joystick movement may produce either a normal cursor movement or an inverted cursor movement. These mappings are not explicitly cued to the participant.

The task was developed in the context of the Free Energy Principle (FEP) and related theories of predictive processing and active inference. In this framework, an agent maintains an internal model of the causes of its sensory observations and uses incoming evidence to update that model. When observations conflict with the agent's expectations, the agent may need to revise its estimate of the current hidden state.

The present task operationalizes this problem using a simple visuomotor environment. The hidden state is the current joystick-to-cursor mapping. Participants first accumulate experience with particular mappings and mapping frequencies, creating different histories of prior exposure. The mapping can then change without warning, requiring the participant to infer from the resulting cursor behavior that the current sensorimotor relationship has changed.

The task therefore allows behavioral measurements to be related to three major features of inference:

  • Prior experience: Different experimental blocks expose participants to different frequencies of Normal and Inverted mappings.
  • Unexpected state changes: Mapping changes may occur between trials without an explicit visual cue.
  • Behavioral updating: Reaction time, movement time, total time, and cursor trajectory may be examined following mapping switches and across subsequent trials.

The experiment also includes a cursor-gain manipulation. High-gain trials change the magnitude of the relationship between joystick displacement and cursor displacement. In the current implementation this is represented explicitly as a cursor-gain condition rather than as a formal sensory-reliability variable.

Importantly, the software does not itself compute free energy, prediction error, posterior probability, Bayesian belief, or another formal FEP quantity. Instead, it creates a controlled hidden-state visuomotor task whose behavioral and neural data may be used to investigate questions motivated by those theories.

The current implementation includes:

  • Normal and inverted joystick-to-cursor mappings.
  • Unannounced mapping changes between trials.
  • Six sequential experimental block roles with different mapping frequencies.
  • Normal and configurable high cursor-gain conditions.
  • Mapping-switch, prior-condition, and trials-since-switch state logging.
  • A minimal participant introduction.
  • A Normal-mapping joystick sandbox.
  • Reaction-time, movement-time, total-time, cursor, joystick, target, mapping, and gain logging in the BCI2000 data stream.

The participant is not informed that the mapping, gain, mapping probabilities, or experimental block structure may change.

Location

Upon the completion of an SVN update, the source code for the FEP Visuomotor Joystick Task is located in:

src/private/Application/FEP_VisuomotorJoystickTask/

The main implementation is contained in:

FEP_VisuomotorJoystickTask.cpp

with the corresponding header and build configuration in:

  • FEP_VisuomotorJoystickTask.h
  • CMakeLists.txt

The application is included from (prog folder):

src/private/Application/CMakeLists.txt

The CMake target is:

FEP_VisuomotorJoystickTask

The Windows executable is:

FEP_VisuomotorJoystickTask.exe

Versioning

Author

Alexander Speer

Friedman Lab, Department of Neurosurgery

Washington University in St. Louis

Developed in the Friedman Lab.

Contact: speer@wustl.edu

Version History

The current FEP task is maintained under src/custom. In the inspected development checkout, the module does not currently have independent Git or SVN revision history.

The inspected build was produced using:

  • BCI2000 framework 3.6.9535
  • BCI2000 source revision 9535
  • Visual Studio 2022 / MSVC 19.35
  • Release x64 configuration

These values refer to the BCI2000 build containing the module rather than an independent revision number for the FEP task.

Scientific Motivation

Free Energy Principle

The Free Energy Principle proposes that biological agents maintain internal models of the causes of their sensory inputs and continually update those models in order to reduce discrepancies between predicted and observed sensory states.

A useful way to interpret the present task is as a hidden-state inference problem.

The participant directly observes:

  • Joystick movement.
  • Cursor movement.
  • Target position.
  • The sensory consequences of each movement.

The participant is not directly told:

  • Which joystick-to-cursor mapping is currently active.
  • Whether the mapping has changed.
  • The probability of a mapping occurring.
  • The current experimental block.
  • Whether cursor gain has changed.

The current mapping therefore acts as a hidden environmental state that must be inferred from the relationship between action and observed cursor movement.

For example, after many Normal trials, a participant may expect the cursor to move in the same direction as the joystick. If the next trial unexpectedly uses the Inverted mapping, the observed cursor movement conflicts with that expectation. Subsequent behavior can then be examined to determine how rapidly the participant adjusts to the new mapping.

Why the Task Was Developed

The task was designed to create an experimentally controlled situation in which prior experience and new sensory evidence can come into conflict.

Several aspects of the experiment make this possible.

First, the frequency of Normal and Inverted mappings changes across blocks. This changes the participant's recent history of mapping exposure.

Second, mapping changes are not announced. Participants therefore cannot simply follow an explicit instruction telling them which mapping to use.

Third, the task records the exact trials on which the mapping changes and the number of trials that have occurred since the most recent switch.

This makes it possible to compare behavior:

  • Before and after an unexpected mapping change.
  • On switch versus non-switch trials.
  • Across successive trials following a switch.
  • Under different histories of Normal and Inverted mapping exposure.
  • Under Normal versus High cursor gain.

The task can therefore be used to investigate how prior experience influences behavioral adaptation to unexpected changes in sensorimotor contingencies.

Implementation Versus Theory

The current application implements the experimental manipulations required for this type of analysis, but it does not contain an explicit computational model of the participant.

In particular, the software does not calculate:

  • Variational free energy.
  • Prediction error.
  • Posterior probability.
  • Belief distributions.
  • Bayesian surprise.
  • Learning rate.
  • Adaptation score.

These quantities, if used, must be estimated during offline behavioral or neural analysis.

Functional Description

Mapping Conditions

The FEP task uses two joystick-to-cursor mappings:

TaskCondition Mapping Description
0 Normal Joystick displacement moves the cursor in the corresponding direction.
1 Inverted Joystick displacement moves the cursor in the opposite direction on both axes.

The current mapping is not visually indicated to the participant.

Unlike the earlier USBHIDJoystickTask, the FEP task does not use the terms Automatic and Controlled in its implementation.

Behavioral Measurements

The task records information that may be used to examine:

  • Reaction time.
  • Movement time.
  • Total target-acquisition time.
  • Cursor trajectory.
  • Initial movement direction.
  • Trajectory curvature.
  • Performance immediately following a mapping switch.
  • Performance as a function of trials since the previous switch.
  • Effects of different mapping-frequency contexts.
  • Effects of Normal versus High cursor gain.

Experiment Structure

Each run proceeds in the following order:

  1. Introduction.
  2. Joystick sandbox.
  3. Experimental block 1, if enabled.
  4. Experimental block 2, if enabled.
  5. Experimental block 3, if enabled.
  6. Experimental block 4, if enabled.
  7. Experimental block 5, if enabled.
  8. Experimental block 6, if enabled.
  9. Experiment completion.

Experimental block transitions are not announced to the participant.

Each experimental trial proceeds as follows:

  1. The participant returns the cursor to the center.
  2. The participant holds the cursor within the center region.
  3. A yellow warning cue appears.
  4. A pre-target delay occurs.
  5. A peripheral target appears.
  6. The participant moves the cursor toward the target.
  7. The target is acquired.
  8. A short feedback interval occurs.
  9. The task advances to the next trial.

Introduction

The introduction provides only the minimum information needed to operate the task.

The participant is shown:

Use the joystick to control the cursor.

At the beginning of each trial, return the cursor to the center and hold it there.

The center will turn yellow before the target appears.

Once the target appears, move the cursor to the target.

Press the joystick button to continue.

During the introduction:

  • Introduction=1
  • TutorialPhase=1
  • TaskPhase=0
  • The cursor is hidden.
  • The center marker is hidden.
  • The warning cue is hidden.
  • The target is hidden.
  • The central cross is hidden.
  • The progress bar is hidden.

A rising press of JoystickButtons1 advances to the sandbox.

The participant is not told about:

  • Normal versus Inverted mappings.
  • Mapping switches.
  • Cursor-gain changes.
  • Mapping probabilities.
  • Experimental blocks.
  • Prior conditions.

Sandbox

After the introduction, the participant enters a free-movement sandbox.

The participant sees:

  • A black cursor.
  • A gray center marker.
  • A black center cross.
  • No peripheral target.
  • No warning cue.
  • No progress bar.

The participant is shown:

Practice moving the cursor with the joystick.

When you are ready to begin, return the cursor to the center and press the joystick button.

During the sandbox:

  • Introduction=1
  • TutorialPhase=2
  • TaskPhase=0
  • TaskBlock=0
  • TaskTrial=0
  • TaskCondition=0
  • Normal direct mapping is used.
  • Cursor gain is 1.0.
  • No targets are generated.
  • No experimental timing phases occur.

The sandbox ends when both of the following conditions are satisfied:

  1. The cursor is inside the center tolerance region.
  2. A new joystick-button press occurs.

Because continuation uses rising-edge detection, the participant must release the button after leaving the introduction screen before pressing it again to leave the sandbox.

When the sandbox finishes:

  • Introduction becomes 0.
  • TutorialPhase becomes 0.
  • TaskPhase becomes 1.
  • Experimental block and trial states become active.

Experimental Blocks

The task contains six predefined block roles.

There is no ExperimentMode parameter.

A block may be omitted by setting its trial-count parameter to 0.

TaskBlock retains the original block-role number, so block numbers may skip values when one or more blocks are disabled.

Block Trial-count parameter PriorCondition Mapping composition
1 BaselineTrials 0, Fixed 100% Normal
2 InitialInvertedTrials 0, Fixed 100% Inverted
3 ReturnNormalTrials 0, Fixed 100% Normal
4 MixedTrials 1, HiddenMixed Approximately 50% Normal and 50% Inverted
5 StrongPriorTrials 2, StrongNormal Approximately 90% Normal and 10% Inverted
6 BalancedPriorTrials 3, Balanced Approximately 50% Normal and 50% Inverted

Blocks 4 and 6

For blocks 4 and 6:

  • floor(N/2) trials are assigned the Inverted mapping.
  • All remaining trials are assigned the Normal mapping.
  • If the number of trials is odd, the additional trial is Normal.

Block 5

Block 5 contains a strongly Normal-dominant mapping distribution.

Approximately 10% of trials are assigned the Inverted mapping, using a rounded fixed trial count.

The remaining trials are Normal.

This is not implemented as an independent 10% switch probability on each trial.

Pseudorandomization

For blocks 4 through 6, mapping order is pseudorandomized.

The task attempts up to 64 candidate shuffles.

A candidate is preferred when:

  • It does not strictly alternate throughout sequences of at least four trials.
  • It does not contain excessively long runs of one mapping.

The preferred maximum run length is:

max(3, unavoidableRun + 1)

where:

unavoidableRun = (majority + minority) / (minority + 1)

using integer division.

If no candidate satisfies the constraints after 64 attempts, the final generated sequence is used.

Cursor-gain order is shuffled independently from mapping order.

Prior Conditions

PriorCondition represents the mapping-frequency context associated with the current block.

It does not represent the immediately preceding trial's mapping.

Value Name Meaning
0 Fixed Fixed-mapping context used in blocks 1 through 3.
1 HiddenMixed Approximately balanced hidden mapping context used in block 4.
2 StrongNormal Strongly Normal-dominant mapping context used in block 5.
3 Balanced Approximately balanced mapping context used in block 6.

The mapping used on the preceding trial may be determined offline from the previous trial's TaskCondition.

Joystick Input

Joystick input is provided through BCI2000's input logging system.

The application reads:

  • JoystickXpos
  • JoystickYpos
  • JoystickButtons1

Joystick X and Y values normally range from 0 through 32767.

Each axis is converted into the task's 0-through-1023 coordinate system:

taskJoystick = round(BCIJoystick * 1023 / 32767)

The converted value is normalized internally:

rawPosition = taskJoystick / 1023

The FEP application does not itself enable joystick logging.

Joystick logging should therefore be enabled using BCI2000's LogJoystick option.

See LogJoystick.

Joystick-to-Cursor Mapping

Before target onset, cursor position normally follows direct absolute joystick position:

cursorX = rawX
cursorY = rawY

The mapping transformation used for target-directed movement is activated at target onset.

Anchor Capture

When the target appears, the application stores:

  • Current joystick X position.
  • Current joystick Y position.
  • Current cursor X position.
  • Current cursor Y position.
  • Current mapping direction.
  • Current cursor gain.

These values form the anchor for transformed movement.

Because joystick displacement relative to the anchor is initially zero, activating the transformed mapping does not cause an immediate cursor jump.

Normal Mapping, Normal Gain

For a Normal trial with gain 1.0:

cursorX = joystickX / 1023
cursorY = joystickY / 1023

Inverted Mapping, Normal Gain

For an Inverted trial:

cursorX = anchorCursorX - (joystickX - anchorJoystickX) / 1023
cursorY = anchorCursorY - (joystickY - anchorJoystickY) / 1023

Both axes are inverted.

Normal Mapping, High Gain

For a Normal high-gain trial:

cursorX = anchorCursorX
          + HighCursorGain * (joystickX - anchorJoystickX) / 1023

cursorY = anchorCursorY
          + HighCursorGain * (joystickY - anchorJoystickY) / 1023

Inverted Mapping, High Gain

For an Inverted high-gain trial:

cursorX = anchorCursorX
          - HighCursorGain * (joystickX - anchorJoystickX) / 1023

cursorY = anchorCursorY
          - HighCursorGain * (joystickY - anchorJoystickY) / 1023

Cursor coordinates are constrained to the valid display range.

Cursor Gain

The task contains two cursor-gain conditions.

CursorGainCondition Condition Gain
0 Normal 1.0
1 High HighCursorGain

The default value of HighCursorGain is:

1.5

High gain:

  • Applies to both X and Y axes.
  • Multiplies joystick displacement relative to the target-onset anchor.
  • Is used only in randomized blocks 4 through 6.
  • Is shuffled independently from mapping condition.
  • Is not visually cued to the participant.

The current implementation does not define a SensoryReliability state or parameter.

Return-to-Anchor Behavior

After an Inverted or High-gain trial, the previous transformed mapping may temporarily remain active while the participant returns the joystick toward its previous anchor.

The stored transformation is released once both joystick axes are within 8 task-coordinate units of the previous joystick anchor.

Normal direct mapping is then restored for ordinary centering.

This behavior reduces abrupt cursor jumps between transformed target movement and subsequent centering.

Mapping Switches

A mapping switch occurs when:

next trial TaskCondition != completed trial TaskCondition

Gain changes alone do not produce mapping-switch events.

Mapping switches occur only at trial boundaries.

They do not occur:

  • During target-directed movement.
  • During the Feedback phase before the feedback interval ends.

The new mapping is selected when the task advances into the next trial.

MappingSwitch

MappingSwitch is an event-like state.

It is:

  • 1 on the processing block that advances into a new trial whose mapping differs from the completed trial.
  • 0 on the following processing block.
  • 0 when no mapping change occurred.

It should therefore be interpreted as a one-processing-block pulse.

TrialsSinceMappingSwitch

TrialsSinceMappingSwitch records how many consecutive no-switch trial transitions have occurred since the most recent mapping change.

Behavior is:

  • First experimental trial: 0.
  • First trial following a mapping switch: 0.
  • Next same-mapping trial: 1.
  • Next same-mapping trial: 2.
  • And so forth.

Because the first experimental trial also begins at 0, TrialsSinceMappingSwitch==0 by itself does not identify a switch.

Use MappingSwitch or a transition in TaskCondition to identify mapping changes.

Example

Consider the following mapping sequence:

Normal -> Normal -> Inverted -> Inverted

Within block 4, the corresponding states would behave approximately as follows:

Trial TaskCondition MappingSwitch TrialsSinceMappingSwitch PriorCondition
Normal 0 0 Depends on previous trial history 1
Normal 0 0 Previous value + 1 1
Inverted 1 1 on the transition processing block 0 1
Inverted 1 0 1 1

Target Generation

A new target angle is generated for each new experimental trial.

TargetAngle ranges from:

0 through 3599

The value represents tenths of a degree:

angle in degrees = TargetAngle / 10

Targets therefore span:

0.0 through 359.9 degrees

Target coordinates are generated according to:

TargetX = 0.5 + 0.3 * cos(angle)
TargetY = 0.5 + 0.4 * sin(angle)

The unequal normalized X and Y radii correspond to an approximately circular 300-pixel radius in the nominal 1000 by 750 design.

Targets:

  • Are black.
  • Are visually identical across all mapping conditions.
  • Are visually identical across gain conditions.
  • Are not determined by mapping condition.
  • Are not determined by gain condition.
  • Are not determined by mapping-switch status.
  • May repeat.
  • Are not explicitly angularly balanced.
  • Do not appear during the introduction.
  • Do not appear during the sandbox.

A new target is generated:

  • For the first experimental trial.
  • After each completed non-final trial.

Resetting a trial does not generate a new target.

Trial Phases

The current experimental phase is stored in TaskPhase.

Value Phase Description Participant display
0 Introduction / Sandbox No active experimental trial Introduction text or sandbox
1 WaitingForCenter Waiting for cursor to enter the center region Cursor, gray center, cross
2 HoldingCenter Required uninterrupted center hold Cursor, gray center, cross
3 Warning Warning interval Cursor, yellow warning marker, cross
4 PreTargetDelay Delay immediately before target appearance Cursor, gray center, cross
5 TargetVisible Target-directed movement Cursor, black target, cross
6 Feedback Post-acquisition interval Cursor and cross
7 Finished Experiment complete End message

An experimental target onset may be identified by a transition into:

TaskPhase == 5

Movement onset may be identified by a rising transition of:

MovementStarted

Target acquisition is identified by:

TargetHit == 1

Participant Display

The participant-facing window contains:

  • A light background.
  • A black cursor.
  • A black central cross.
  • A gray center marker.
  • A larger yellow warning marker.
  • A black peripheral target.
  • An experimental progress indicator.
  • Introduction and sandbox instructions.
  • An experiment-completion message.

The participant receives no explicit visual indication of:

  • Current mapping.
  • Current gain.
  • Mapping switches.
  • PriorCondition.
  • Block number.
  • Trial number.
  • Block transitions.
  • Mapping probabilities.

The target remains black across conditions.

There is no explicit success-color cue. The target disappears after successful acquisition.

Diagnostic Window

A separate Qt diagnostic window titled:

FEP Visuomotor Joystick Diagnostics

is displayed to the experimenter.

During experimental trials it displays information including:

  • Current task stage.
  • Original block number.
  • Overall trial number.
  • Total number of active trials.
  • Trial number within the current block.
  • Current Normal or Inverted mapping.
  • Current Normal or High cursor-gain condition.
  • Actual gain value.
  • Whether the current trial followed a mapping switch.
  • Trials since the most recent mapping switch.
  • Current task phase.
  • Target angle.
  • Target coordinates.
  • Raw BCI2000 joystick states.
  • Converted joystick coordinates.
  • Current cursor coordinates.
  • Movement-started status.
  • Reaction time.
  • Movement time.
  • Total time.
  • Reset/status information.

PriorCondition is recorded in the data stream but is not currently displayed in the diagnostic window.

Diagnostic Controls

The diagnostic window provides:

RESET CURRENT TRIAL

There is no diagnostic Continue button for the introduction or sandbox.

Trial Reset

A trial may be manually reset during:

  • Waiting for center.
  • Holding center.
  • Warning.
  • Pre-target delay.
  • Target-visible movement.

Reset is unavailable during:

  • Feedback.
  • Finished.
  • Introduction.
  • Sandbox.

Resetting a trial:

  • Returns the task to WaitingForCenter.
  • Restarts the phase timer.
  • Clears movement-onset timing.
  • Clears target-onset timing.
  • Clears MovementStarted.
  • Clears TargetHit.
  • Produces a TrialReset pulse.
  • Clears timing states.
  • Resets baseline accumulation.
  • Keeps the same target.
  • Keeps the same mapping.
  • Keeps the same gain.
  • Keeps the same block number.
  • Keeps the same trial number.
  • Keeps PriorCondition.
  • Keeps TrialsSinceMappingSwitch.
  • Does not rebuild or reshuffle the experimental sequence.

TrialReset lasts for one processing block.

Timing Measurements

Timing uses std::chrono::steady_clock.

Events are detected during BCI2000 Process() calls, so effective timing resolution is limited by the signal-processing block interval.

Movement Onset

The joystick baseline is initialized when the center-hold phase begins and updated during center holding.

Movement onset is detected when either joystick axis differs from the center-hold baseline by more than 8 task-coordinate units.

abs(currentX - baselineX) > 8

or:

abs(currentY - baselineY) > 8

Reaction Time

Reaction time is measured from:

target onset -> movement onset

and stored in:

ReactionTimeMs

Movement Time

Movement time is measured from:

movement onset -> target acquisition

and stored in:

MovementTimeMs

Total Time

Total time is measured from:

target onset -> target acquisition

and stored in:

TotalTimeMs

Timing values are expressed in rounded milliseconds.

Timing states remain populated through the Feedback phase.

Parameters

Experiment Structure

Parameter Type Default Range Description
BaselineTrials Integer 20 0-10000 Number of Normal trials in block 1
InitialInvertedTrials Integer 5 0-10000 Number of Inverted trials in block 2
ReturnNormalTrials Integer 5 0-10000 Number of Normal trials in block 3
MixedTrials Integer 20 0-10000 Number of approximately balanced trials in block 4
StrongPriorTrials Integer 20 0-10000 Number of Normal-dominant trials in block 5
BalancedPriorTrials Integer 20 0-10000 Number of approximately balanced trials in block 6

At least one trial must be configured across the six block parameters.

HighCursorGain

Gain used during High cursor-gain trials.

Type: floating point

Default:

1.5

Range:

1.0-5.0

Normal gain is fixed at 1.0.

CenterHoldSeconds

Required center-hold duration.

Type: floating point

Default:

3.0

seconds.

Range:

0.0-60.0

seconds.

WarningSeconds

Duration of the yellow warning interval.

Default:

0.5

seconds.

PreTargetDelaySeconds

Delay between the warning interval and target onset.

Default:

0.5

seconds.

FeedbackSeconds

Duration of the feedback interval following target acquisition.

Default:

0.5

seconds.

StimulusDisplay

Selects the physical monitor used for the participant-facing application window.

Default:

0

On Windows systems, available monitors are enumerated by the application.

States

State Width Initial Value Meaning
CursorX 10 bit 512 Participant-visible horizontal cursor coordinate
CursorY 10 bit 512 Participant-visible vertical cursor coordinate
TaskPhase 3 bit 0 Current task phase
TaskCondition 1 bit 0 0 Normal, 1 Inverted
TargetAngle 12 bit 0 Target angle in tenths of a degree
TargetX 10 bit 512 Horizontal target coordinate
TargetY 10 bit 512 Vertical target coordinate
TaskBlock 8 bit 0 Current experimental block role
TaskTrial 16 bit 0 Overall experimental trial number
MovementStarted 1 bit 0 Indicates detected movement onset
TargetHit 1 bit 0 Target-acquisition event
TrialReset 1 bit 0 Manual-reset event
MappingSwitch 1 bit 0 Mapping-change event
TrialsSinceMappingSwitch 16 bit 0 Trials since the most recent mapping switch
PriorCondition 2 bit 0 Current block-level prior context
CursorGainCondition 1 bit 0 0 Normal gain, 1 High gain
Introduction 1 bit 0 1 during introduction or sandbox
TutorialPhase 4 bit 0 0 experiment, 1 introduction, 2 sandbox
ReactionTimeMs 32 bit 0 Reaction time in milliseconds
MovementTimeMs 32 bit 0 Movement time in milliseconds
TotalTimeMs 32 bit 0 Total target-directed time in milliseconds

External Joystick States

State Description
JoystickXpos Raw horizontal joystick position
JoystickYpos Raw vertical joystick position
JoystickButtons1 Joystick button used to advance the introduction and sandbox

The application also accesses the standard BCI2000 Running state when ending the experiment.

States Not Present in the Current Implementation

The current implementation does not define:

  • DisplayedCursorX
  • DisplayedCursorY
  • SensoryReliability
  • PracticeTrial
  • TaskBlockType

Cursor Coordinates

CursorX and CursorY represent the final cursor coordinates actually displayed to the participant.

These coordinates include any:

  • Mapping inversion.
  • High-gain transformation.
  • Return-to-anchor transformation.
  • Display-boundary clipping.

The same coordinates are used for:

  • Drawing the participant-visible cursor.
  • Center detection.
  • Target-hit detection.
  • BCI2000 state recording.
  • Diagnostic display.

The application does not record a separate untransformed cursor trajectory.

A direct joystick-equivalent trajectory may be reconstructed offline from JoystickXpos and JoystickYpos.

Data Recording

The task records its behavioral variables as synchronized BCI2000 states in the standard .dat file.

Recorded information includes:

  • Participant-visible cursor trajectory.
  • Joystick trajectory, when joystick logging is enabled.
  • Trial phase.
  • Mapping condition.
  • Cursor-gain condition.
  • Target angle.
  • Target coordinates.
  • Experimental block.
  • Experimental trial number.
  • Movement onset.
  • Target acquisition.
  • Trial resets.
  • Mapping switches.
  • Trials since the most recent mapping switch.
  • Prior-condition category.
  • Introduction and sandbox status.
  • Reaction time.
  • Movement time.
  • Total time.

The application passes signal channels through unchanged.

Output = Input;

Secondary Output

The current implementation does not write an application-specific:

  • CSV file.
  • JSON file.
  • Text results file.
  • Database.

There is no ResultsFile parameter.

Offline Analysis Notes

Measurement or Event Recommended Identification
Experimental samples Introduction == 0
Introduction Introduction == 1 and TutorialPhase == 1
Sandbox Introduction == 1 and TutorialPhase == 2
Active experimental trial Introduction == 0, TaskTrial > 0, and TaskPhase from 1 through 6
Target onset Transition into TaskPhase == 5
Movement onset Rising transition of MovementStarted
Target acquisition TargetHit == 1
Normal mapping TaskCondition == 0
Inverted mapping TaskCondition == 1
Normal gain CursorGainCondition == 0
High gain CursorGainCondition == 1
Mapping switch MappingSwitch == 1
Trials since switch TrialsSinceMappingSwitch
Previous mapping Previous trial's TaskCondition
Prior context PriorCondition
Experimental block TaskBlock
Overall trial TaskTrial
Target angle TargetAngle / 10 degrees
Target position TargetX and TargetY
Joystick trajectory JoystickXpos and JoystickYpos
Participant-visible cursor trajectory CursorX and CursorY
Reaction time ReactionTimeMs
Movement time MovementTimeMs
Total time TotalTimeMs
Manual reset TrialReset == 1
Experiment completion TaskPhase == 7

Event-Like States

The following states are one-processing-block events:

  • MappingSwitch
  • TargetHit
  • TrialReset

MovementStarted differs from these states because it remains high from movement onset through the remainder of the trial and Feedback phase.

Differences from USBHIDJoystickTask

Retained

  • BCI2000 ApplicationBase structure.
  • USB joystick input.
  • Center-out reaching.
  • Center hold.
  • Warning interval.
  • Pre-target delay.
  • Target-directed movement.
  • Feedback interval.
  • Continuous target-angle generation.
  • Reaction-time measurement.
  • Movement-time measurement.
  • Total-time measurement.
  • Manual trial reset.
  • Progress bar.
  • BCI2000 state logging.
  • Direct and inverted joystick-control mappings.

Removed

The FEP task removes the earlier task's:

  • ExperimentMode.
  • Automatic-only and Controlled-only modes.
  • Ordered-start condition.
  • TaskBlockType.
  • Green versus red condition-specific targets.
  • Explicit condition instructions.
  • Explicit teaching of the inverted mapping.
  • Condition-specific practice trials.
  • PracticeTrial.
  • Optional tutorial setting.
  • Diagnostic Continue button.
  • Secondary CSV results file.
  • Participant-facing block announcements.

Added

The FEP task adds:

  • Six predefined experimental block roles.
  • Hidden Normal and Inverted mappings.
  • Unannounced mapping switches.
  • MappingSwitch.
  • TrialsSinceMappingSwitch.
  • PriorCondition.
  • CursorGainCondition.
  • HighCursorGain.
  • Normal versus High cursor gain.
  • A minimal Normal-mapping sandbox.
  • Black targets across all mapping conditions.
  • Normal-dominant and approximately balanced mapping contexts.

Known Limitations and Analysis Considerations

  • The current module does not implement an explicit computational Free Energy Principle model.
  • PriorCondition represents experimental block context rather than an inferred participant belief.
  • Participant surprise or expectation is not measured directly by the application.
  • Blocks 4 and 6 use similar approximately balanced mapping-generation rules but occur after different preceding mapping histories.
  • Mapping pseudorandomization constraints are attempted but are not guaranteed if all 64 candidate sequences fail.
  • There is no unsuccessful-trial timeout.
  • High cursor gain is implemented as a gain manipulation rather than as a state explicitly named sensory reliability.
  • There is no separately recorded latent or untransformed cursor trajectory.
  • Physical display geometry depends on the configured participant monitor and BCI2000 window dimensions.

References

Friston, K. The free-energy principle: a unified brain theory?. Nat Rev Neurosci 11, 127–138 (2010). https://doi.org/10.1038/nrn2787

See also