StateServer 1.6.9
Compiled `c` application to handle task state logging and timing.
|
Compiled c
application to handle task state logging and timing.
The wrist center-out task state machine for the NHP task runs as shown by the following image generated using graphviz
:
.
To modify this image, you need to update the corresponding lines in state_transition_flowchart.dot
(which is located in the project root of this repository). After modifying state_transition_flowchart.dot
, you must regenerate the static image file that is used in the documentation. To do so, first make sure that graphviz
is installed on your device and that the associated binaries folder (e.g. C:/Program Files/graphviz/bin
) is in your environment PATH
variable. With graphviz
installed and on the PATH
, issue the following command from a Windows Terminal:
This application launches the State Server on a Windows host. It should be run on some other machine than the Plexon rig computer, but preferably still a good computer. Important: config.yaml
must be present in whichever folder contains the NHP_Wrist_State_Server.exe
when it is run. Therefore, if you copy the executable out of that folder make sure you copy config.yaml
along with it. You must properly set up config.yaml
according to the current configuration of devices in your task network, or this executable will not work!
To re-compile the executable bin/NHP_Wrist_State_Server.exe
use the following command:
Note 1: it is critically important to link ws2_32
only after Network
; also, since the other libraries include <Windows.h>
, -lws2_32
must precede any of the other libraries.
Note 2: during the compilation and linking of the static lib/Network.lib
(in NetworkUtilities
), please make sure to not link -lws2_32
in the gcc static object file generation step. The static library does not require external libraries; the external libraries should only be linked in the final compilation step (i.e. when producing a .dll
dynamic link library or when producing a .exe
executable to run the application).
More Details on State Server
NHP_Wrist_State_Server.exe
has 5 main threads: a "Clock" thread, a "Controller" thread, an "Input" thread, a "State" thread, and an "Output" thread. The threads are managed using pthread_mutex_t
and pthread_cond_t
to ensure proper synchronization, cycling in the sequence Clock > Controller > Input > State > Output > Clock > ...
in a manner that is guaranteed to complete one full cycle before any other thread completes another round of handling its duties.
Clock
thread. Essentially the only job of this thread is to wait for the specified amount of time (currently set to 0.001s) upon waking with control of the mutex
(which is when it starts the desired timer). On a Windows 64-bit machine, the timer resolution for this wait cycle should typically be dictated by a clock with 100MHz precision (i.e. it can be as fast to update as 10-us although that is really not recommended).Controller
handler thread receives inputs from a "Controller" network device, which could be the same as the device running this state machine but might have to be a separate computer. The "Controller" computer can likely be a "light-weight" machine as it really just serves as a user interface/front-end. The Control
commands do things like put the task into an Idle state, Enable/Disable Logging, or Shutdown the entire interface. This is also the phase where parameter updates are taken (again from the "Controller" computer). Any parameter updates that need to be relayed to the "Renderer" device are also forwarded at this stage. Finally, any experimentally-relevant metadata that breaks up files, like changing Subject or starting a new "Set" (i.e. swapping Orientation or other behavioral variable) is handled in this stage and sets flags in the event that logging is enabled.Input
handler thread receives new cursor positions (e.g. from PotentiometerClient.exe
running on the Plexon rig or other networked machine connected to the Omniplex network streams). This allows flexibility in the way the inputs are treated. No transformation on the Input
position happens; it is purely a relay to the TaskRender
machine that ensures concurrency for logging the state of the task, including the cursor. State
handler thread is where state checks occur. These checks include calculations like determining if the cursor is within a specific target, or if sufficient time has proceeded to allow a hold state to advance to the next task state.Output
handler thread mediates sending the cursor position to the "Renderer" device. It also sends the target locations to the "Renderer" device. Target positions are updated during the ADVANCE
transition into T1_MOVE
; additional target messages are generated during T2_SHOW
and T1_GO
states to show T2 and hide T1, respectively. Output
handling, the current state is logged along with its timestamp. This includes the cursor position, task state, transition state, and some other details.To re-compile all test executables, use the following bash command:
This should be run after starting NHP_Wrist_State_Server.exe
. It sends a few test commands to the server, checking that the controllerHandlerThread
correctly receives the control commands to enter the idle state, exit the idle state, and shut down.
To re-compile the executable bin/tests/NHP_Wrist_Controller_Test.exe
use the following command:
This should be run after starting NHP_Wrist_State_Server.exe
. It sends an example parameter message to the server, checking that the controllerHandlerThread
correctly updates the received parameters message.
To re-compile the executable bin/tests/NHP_Wrist_Parameters_Test.exe
use the following command:
This should be run after starting NHP_Wrist_State_Server.exe
. It sends an example parameter message to the server, checking that the outputHandlerThread
correctly issues a sound request message (i.e. as would occur on different task cues in the corresponding state) and finally that it correctly issues a reward request message (which prompts sending back a message with updated target locations).
To re-compile the executable bin/tests/NHP_Wrist_Log_Reader_Test.exe
use the following command:
Note that to use gcc
on a Windows 64-bit architecture, the simplest way is to download msys2
, which will allow you to use pacman
from an msys2
terminal. You can first check to see if you already have gcc
installed:
If you see anything in the terminal following this command, it means you already have gcc
. Otherwise, you need to install it (and probably the rest of the toolchain, such as a linker etc.):
This will give several options for what you can install. If you are unsure what to do, just install all of them.
Finally, you may also want a toolchain for compiling 32-bit applications from your 64-bit Windows operating system. In that case, you can try:
The last step is to make sure the folder with the correct binaries are on your PATH
environment variable. Probably the best strategy here, on a Windows device, is as follows:
MINGW_PATH
. If you installed msys2
in the default location, then go to C:/mingw64
. You will be looking for the sub-folder containing binaries. In my install, that is located at C:\msys64\mingw64\bin
– so that is my MINGW_PATH
environment variable. Path
. Click Edit...
with Path
selected. New
to add a new Path
value. Enter MINGW_PATH%
. Now, you can add or remove MINGW_PATH%
from the user Path
variable depending on what compiler needs you have. Click on the newly added value, and click Move Up
until it is at the top of the list. This ensures we don't accidentally find gcc
somewhere else and use a different unintended version. Note that if you want to switch between i.e. C:\msys64\mingw32\bin
and C:\msys64\mingw64\bin
it might just be easiest to change the value of MINGW_PATH
environment variable.