Skip to content

Commit

Permalink
Add emulator support
Browse files Browse the repository at this point in the history
- Add Emulator object that emulates bpod hardware behavior and reference
  it in the BpodBase class
- Modify bpod classes to accommodate emulator functionality
- Add emulator examples to showcase its usage
  • Loading branch information
ckaraneen committed Sep 13, 2020
1 parent 4c9ced5 commit c84c302
Show file tree
Hide file tree
Showing 36 changed files with 2,403 additions and 196 deletions.
55 changes: 55 additions & 0 deletions examples/emulator_examples/10_state_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from pybpodapi.protocol import Bpod, StateMachine
my_bpod = Bpod(emulator_mode=True)
sma = StateMachine(my_bpod)
sma.add_state(
state_name='State1',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State2'},
output_actions=[])
sma.add_state(
state_name='State2',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State3'},
output_actions=[])
sma.add_state(
state_name='State3',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State4'},
output_actions=[])
sma.add_state(
state_name='State4',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State5'},
output_actions=[])
sma.add_state(
state_name='State5',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State6'},
output_actions=[])
sma.add_state(
state_name='State6',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State7'},
output_actions=[])
sma.add_state(
state_name='State7',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State8'},
output_actions=[])
sma.add_state(
state_name='State8',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State9'},
output_actions=[])
sma.add_state(
state_name='State9',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State10'},
output_actions=[])
sma.add_state(
state_name='State10',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'exit'},
output_actions=[])
my_bpod.send_state_machine(sma)
my_bpod.run_state_machine(sma)
55 changes: 55 additions & 0 deletions examples/emulator_examples/10_state_example_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from pybpodapi.protocol import Bpod, StateMachine
my_bpod = Bpod(emulator_mode=True)
sma = StateMachine(my_bpod)
sma.add_state(
state_name='State1',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State2'},
output_actions=[])
sma.add_state(
state_name='State2',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State3'},
output_actions=[])
sma.add_state(
state_name='State3',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State4'},
output_actions=[])
sma.add_state(
state_name='State4',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State5'},
output_actions=[])
sma.add_state(
state_name='State5',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State6'},
output_actions=[])
sma.add_state(
state_name='State6',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State7'},
output_actions=[])
sma.add_state(
state_name='State7',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State8'},
output_actions=[])
sma.add_state(
state_name='State8',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State9'},
output_actions=[])
sma.add_state(
state_name='State9',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State10'},
output_actions=[])
sma.add_state(
state_name='State10',
state_timer=1,
state_change_conditions={Bpod.Events.GlobalTimer1_Start: 'exit'},
output_actions=[])
my_bpod.send_state_machine(sma)
my_bpod.run_state_machine(sma)
59 changes: 59 additions & 0 deletions examples/emulator_examples/10_state_example_2_unblock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from pybpodapi.protocol import Bpod, StateMachine
my_bpod = Bpod(emulator_mode=True)
sma = StateMachine(my_bpod)
# Set global timer 1 for 3 seconds, following a 1.5 second onset delay after
# trigger. Link to LED of port 2.
sma.set_global_timer(timer_id=1, timer_duration=0, on_set_delay=1.5,
channel=Bpod.OutputChannels.PWM2, on_message=255)
sma.add_state(
state_name='State1',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State2'},
output_actions=[])
sma.add_state(
state_name='State2',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State3'},
output_actions=[])
sma.add_state(
state_name='State3',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State4'},
output_actions=[])
sma.add_state(
state_name='State4',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State5'},
output_actions=[])
sma.add_state(
state_name='State5',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State6'},
output_actions=[])
sma.add_state(
state_name='State6',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State7'},
output_actions=[])
sma.add_state(
state_name='State7',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State8'},
output_actions=[])
sma.add_state(
state_name='State8',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State9'},
output_actions=[])
sma.add_state(
state_name='State9',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'State10'},
output_actions=[('GlobalTimerTrig', 1)])
sma.add_state(
state_name='State10',
state_timer=1,
state_change_conditions={Bpod.Events.GlobalTimer1_Start: 'exit'},
output_actions=[])
my_bpod.send_state_machine(sma)
my_bpod.run_state_machine(sma)
10 changes: 10 additions & 0 deletions examples/emulator_examples/1_state_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pybpodapi.protocol import Bpod, StateMachine
my_bpod = Bpod(emulator_mode=True)
sma = StateMachine(my_bpod)
sma.add_state(
state_name='myState',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'exit'},
output_actions=[])
my_bpod.send_state_machine(sma)
my_bpod.run_state_machine(sma)
2 changes: 2 additions & 0 deletions examples/emulator_examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# !/usr/bin/python3
# -*- coding: utf-8 -*-
58 changes: 58 additions & 0 deletions examples/emulator_examples/add_trial_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import secrets
from pybpodapi.protocol import Bpod, StateMachine
my_bpod = Bpod(emulator_mode=True)
nTrials = 5
trialTypes = [1, 2] # 1 (rewarded left) or 2 (rewarded right)
for i in range(nTrials): # Main loop
print('Trial: ', i + 1)
thisTrialType = secrets.choice(trialTypes) # Randomly choose trial type
if thisTrialType == 1:
# set stimulus channel for trial type 1
stimulus = Bpod.OutputChannels.PWM1
leftAction = 'Reward'
rightAction = 'Punish'
rewardValve = 1
elif thisTrialType == 2:
# set stimulus channel for trial type 1
stimulus = Bpod.OutputChannels.PWM3
leftAction = 'Punish'
rightAction = 'Reward'
rewardValve = 3
sma = StateMachine(my_bpod)
sma.add_state(
state_name='WaitForPort2Poke',
state_timer=1,
state_change_conditions={Bpod.Events.Port2In: 'FlashStimulus'},
output_actions=[(Bpod.OutputChannels.PWM2, 255)])
sma.add_state(
state_name='FlashStimulus',
state_timer=0.1,
state_change_conditions={Bpod.Events.Tup: 'WaitForResponse'},
output_actions=[(stimulus, 255)])
sma.add_state(
state_name='WaitForResponse',
state_timer=1,
state_change_conditions={
Bpod.Events.Port1In: leftAction, Bpod.Events.Port3In: rightAction},
output_actions=[])
sma.add_state(
state_name='Reward',
state_timer=0.1,
state_change_conditions={Bpod.Events.Tup: 'exit'},
# Reward correct choice
output_actions=[(Bpod.OutputChannels.Valve, rewardValve)])
sma.add_state(
state_name='Punish',
state_timer=3,
state_change_conditions={Bpod.Events.Tup: 'exit'},
# Signal incorrect choice
output_actions=[(Bpod.OutputChannels.LED, 1),
(Bpod.OutputChannels.LED, 2),
(Bpod.OutputChannels.LED, 3)])
# Send state machine description to Bpod device
my_bpod.send_state_machine(sma)
print("Waiting for poke. Reward: ",
'left' if thisTrialType == 1 else 'right')
my_bpod.run_state_machine(sma) # Run state machine
print("Current trial info: {0}".format(my_bpod.session.current_trial))
my_bpod.close() # Disconnect Bpod
81 changes: 81 additions & 0 deletions examples/emulator_examples/add_trial_events_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import secrets
from pybpodapi.protocol import Bpod, StateMachine
my_bpod = Bpod(emulator_mode=True)
nTrials = 5
graceTime = 5
trialTypes = [1, 2] # 1 (rewarded left) or 2 (rewarded right)
for i in range(nTrials): # Main loop
print('Trial: ', i + 1)
thisTrialType = secrets.choice(trialTypes) # Randomly choose trial type
if thisTrialType == 1:
# set stimulus channel for trial type 1
stimulus = Bpod.OutputChannels.PWM1
leftAction = 'Reward'
rightAction = 'Punish'
rewardValve = 1
elif thisTrialType == 2:
# set stimulus channel for trial type 1
stimulus = Bpod.OutputChannels.PWM3
leftAction = 'Punish'
rightAction = 'Reward'
rewardValve = 3
sma = StateMachine(my_bpod)
sma.set_global_timer_legacy(
timer_id=1, timer_duration=graceTime) # Set timeout
sma.add_state(
state_name='WaitForPort2Poke',
state_timer=1,
state_change_conditions={Bpod.Events.Port2In: 'FlashStimulus'},
output_actions=[('PWM2', 255)])
sma.add_state(
state_name='FlashStimulus',
state_timer=0.1,
state_change_conditions={Bpod.Events.Tup: 'WaitForResponse'},
output_actions=[(stimulus, 255),
(Bpod.OutputChannels.GlobalTimerTrig, 1)])
sma.add_state(
state_name='WaitForResponse',
state_timer=1,
state_change_conditions={Bpod.Events.Port1In: leftAction,
Bpod.Events.Port3In: rightAction,
Bpod.Events.Port2In: 'Warning',
Bpod.Events.GlobalTimer1_End: 'MiniPunish'},
output_actions=[])
sma.add_state(
state_name='Warning',
state_timer=0.1,
state_change_conditions={Bpod.Events.Tup: 'WaitForResponse',
Bpod.Events.GlobalTimer1_End: 'MiniPunish'},
output_actions=[(Bpod.OutputChannels.LED, 1),
(Bpod.OutputChannels.LED, 2),
(Bpod.OutputChannels.LED, 3)]) # Reward correct choice
sma.add_state(
state_name='Reward',
state_timer=0.1,
state_change_conditions={Bpod.Events.Tup: 'exit'},
# Reward correct choice
output_actions=[(Bpod.OutputChannels.Valve, rewardValve)])
sma.add_state(
state_name='Punish',
state_timer=3,
state_change_conditions={Bpod.Events.Tup: 'exit'},
# Signal incorrect choice
output_actions=[(Bpod.OutputChannels.LED, 1),
(Bpod.OutputChannels.LED, 2),
(Bpod.OutputChannels.LED, 3)])
sma.add_state(
state_name='MiniPunish',
state_timer=1,
state_change_conditions={Bpod.Events.Tup: 'exit'},
# Signal incorrect choice
output_actions=[(Bpod.OutputChannels.LED, 1),
(Bpod.OutputChannels.LED, 2),
(Bpod.OutputChannels.LED, 3)])
# Send state machine description to Bpod device
my_bpod.send_state_machine(sma)
print("Waiting for poke. Reward: ",
'left' if thisTrialType == 1 else 'right')
# Run state machine
my_bpod.run_state_machine(sma)
print("Current trial info: {0}".format(my_bpod.session.current_trial))
my_bpod.close() # Disconnect Bpod
Loading

0 comments on commit c84c302

Please sign in to comment.