Workflow Description#
Note
This description assumes the reader has a foundation in Bonsai that is built on the Trigger Workflow Description. Start there if you have not already.
Commutator GroupWorkflow#
The
Quarternion
node connects to theCommutator
node. TheCommutator
node represents aGroupWorkflow
operator named Commutator. AGroupWorkflow
operator encapsulates a workflow fragment inside a single node. To inspect the encapsulated workflow fragment, double left-click theCommutator
node.A node’s border represents the scope of the corresponding operator. For instance, the dashed grey line around the
Commutator
node indicates it shares a scope with the “main” workflow. In contrast, a solid line would indicates it defines its own scope. For more information, refer to the Bonsai documentation on this subject.
Note
To learn more about a respective node, refer to the desciption in the Properties pane that appears after left-clicking the respective node. If the node has a name that is different from the name of the operator it represents, the operator name is presented in parenthesis after the node name.
Sample Quarternion Data#
The
Source1
node represents aWorkflowInput
operator. AWorkflowInput
operator is a source operator that emits items passed to theGroupWorkflow
from the parent workflow. In this case,Source1
emits quarternion data that is what is passed to the input ofCommutator
.The
Source1
andTimer
nodes connect to theSample
node. TheSample
node emits the most recent upstream data at an interval specified by setting thePeriod
value that appears in the Properties pane after left-clicking theTimer
node (in this case, 100ms).
Generate Automated Commutator Command#
The
Sample
node connects to theHeading
node. TheHeading
node represents aPythonTransform
operator namedHeading
. APythonTransform
operator contains a Python script for transforming items in an observable sequence. The script contained inHeading
transforms quarternion data to a single quantity that represents direction the UCLA Miniscope v4 is heading. To inspect the script that performs this computation, double left-click theHeading
node.The
Heading
node connects toZip
andSkip
nodes. TheSkip
node also connects to the theZip
node. TheSkip
operator skips a number of items in the observable sequence or upstream data as specified by theCount
value that appears in the Properties pane after left-clicking theSkip
node (in this case, 1). TheZip
operator emits a combination of two inputs. In this case, theZip
operator emits the most recently sampled heading data and the sample before that. In other words, if theHeading
emits the \(nth\) item in an observable sequence,Zip
emits items \((n, n-1)\).The
Zip
node connects to theAutomatedCommutatorCommand
node. TheAutomatedCommutatorCommand
node represents aPythonTransform
operator named AutomatedCommutatorCommand. The script contained inAutomatedCommutatorCommand
transforms current and previous heading data to a commutator command. To inspect the script that performs this computation, double left-click theAutomatedCommutatorCommand
node.
Generate Manual Commutator Command#
The
KeyDown
node represents aKeyDown
operator. AKeyDown
operator emits an item anytime a key/key combination specified by theFilter
value that appears after left-clicking theKeyDown
node (in this case,Alt+Right
andAlt+Left
) is pressed.The
KeyDown
nodes each connect to theString
node.The
String
node represents aString
operator. AString
operator emits a string specified by theValue
value that appears after left-clicking theString
node (in this case,"{turn : 0.1}"
and"{turn : -0.1}"
) anytime it receives an item from upstream item.
Send Commutator Command Over Serial#
The two
String
nodes andAutomatedCommutatorCommand
each connect to theMerge
node. TheMerge
node represents aMerge
operator AMerge
operator merges multiple observable sequences into one.The
Merge
node connects to aSerialWriteLine
node. TheSerialWriteLine
node represents aSerialWriteLine
operator. ASerialWriteLine
operator writes serial messages appended with specified by theNewLine
value that appears afer left-clicking theSerialWriteLine
node.
Note
Because SerialWriteLine
operator is a sink operator, it doesn’t transform data. In other words, its output is equivalent its input, and the SerialWriteLine
operator passes that data to the WorkflowOutput
as-is to the downstream operator.
The
SerialWriteLine
node connects to aWorkOutput
node. TheWorkOutput
node represents aWorkOutput
operator. Items passed to theWorkOutput
operator are emitted by the corresponding group workflow’s node (in our case,Commutator
in the main workflow). This can be seen by double-clicking theCommutator
node while the workflow is running.