Explorar el Código

set random hold time and delete blank screen

lfs___ hace 1 año
padre
commit
f3ac82d9d7

+ 1 - 1
.vscode/launch.json

@@ -25,7 +25,7 @@
             "name": "Grasp training",
             "type": "python",
             "request": "launch",
-            "program": "grasp_data_collection.py",
+            "program": "grasp_data_collection_no_release.py",
             "console": "integratedTerminal",
             "cwd": "${workspaceFolder}/backend",
             "justMyCode": true,

+ 8 - 8
backend/grasp_data_collection_no_release.psyexp

@@ -134,7 +134,7 @@
         <Param val="True" valType="bool" updates="constant" name="syncScreenRefresh"/>
       </KeyboardComponent>
       <CodeComponent name="config" plugin="None">
-        <Param val="import argparse&amp;#10;import time&amp;#10;from device.fubo_pneumatic_finger import FuboPneumaticFingerClient&amp;#10;from device.trigger_box import TriggerNeuracle&amp;#10;from settings.config import settings&amp;#10;&amp;#10;&amp;#10;# get train params&amp;#10;&amp;#10;def parse_args():&amp;#10;&amp;#10;    parser = argparse.ArgumentParser(&amp;#10;&amp;#10;        description='Grasp training'&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    parser.add_argument(&amp;#10;&amp;#10;        '--n-trials',&amp;#10;&amp;#10;        dest='n_trials',&amp;#10;&amp;#10;        help='Trial number',&amp;#10;&amp;#10;        type=int,&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    parser.add_argument(&amp;#10;&amp;#10;        '--com',&amp;#10;&amp;#10;        dest='com',&amp;#10;&amp;#10;        help='Peripheral serial port',&amp;#10;&amp;#10;        type=str&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    parser.add_argument(&amp;#10;&amp;#10;        '--finger-model',&amp;#10;&amp;#10;        '-fm',&amp;#10;&amp;#10;        dest='finger_model',&amp;#10;&amp;#10;        help='Gesture to train',&amp;#10;&amp;#10;        type=str&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    return parser.parse_args()&amp;#10;&amp;#10;&amp;#10;&amp;#10;args = parse_args()&amp;#10;&amp;#10;hand_device = FuboPneumaticFingerClient({'port': args.com})&amp;#10;&amp;#10;# connect to trigger box&amp;#10;trigger = TriggerNeuracle()&amp;#10;" valType="extendedCode" updates="constant" name="Before Experiment"/>
+        <Param val="import argparse&amp;#10;import time&amp;#10;from device.fubo_pneumatic_finger import FuboPneumaticFingerClient&amp;#10;from device.trigger_box import TriggerNeuracle&amp;#10;from settings.config import settings&amp;#10;import random&amp;#10;&amp;#10;# get train params&amp;#10;&amp;#10;def parse_args():&amp;#10;&amp;#10;    parser = argparse.ArgumentParser(&amp;#10;&amp;#10;        description='Grasp training'&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    parser.add_argument(&amp;#10;&amp;#10;        '--n-trials',&amp;#10;&amp;#10;        dest='n_trials',&amp;#10;&amp;#10;        help='Trial number',&amp;#10;&amp;#10;        type=int,&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    parser.add_argument(&amp;#10;&amp;#10;        '--com',&amp;#10;&amp;#10;        dest='com',&amp;#10;&amp;#10;        help='Peripheral serial port',&amp;#10;&amp;#10;        type=str&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    parser.add_argument(&amp;#10;&amp;#10;        '--finger-model',&amp;#10;&amp;#10;        '-fm',&amp;#10;&amp;#10;        dest='finger_model',&amp;#10;&amp;#10;        help='Gesture to train',&amp;#10;&amp;#10;        type=str&amp;#10;&amp;#10;    )&amp;#10;&amp;#10;    return parser.parse_args()&amp;#10;&amp;#10;&amp;#10;&amp;#10;args = parse_args()&amp;#10;&amp;#10;hand_device = FuboPneumaticFingerClient({'port': args.com})&amp;#10;&amp;#10;# connect to trigger box&amp;#10;trigger = TriggerNeuracle()&amp;#10;" valType="extendedCode" updates="constant" name="Before Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="Before JS Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="Begin Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="Begin JS Experiment"/>
@@ -231,7 +231,7 @@
         <Param val="time (s)" valType="str" updates="None" name="startType"/>
         <Param val="0.0" valType="code" updates="None" name="startVal"/>
         <Param val="duration (s)" valType="str" updates="None" name="stopType"/>
-        <Param val="5" valType="code" updates="constant" name="stopVal"/>
+        <Param val="" valType="code" updates="constant" name="stopVal"/>
         <Param val="True" valType="bool" updates="None" name="syncScreenRefresh"/>
         <Param val="128" valType="num" updates="constant" name="texture resolution"/>
         <Param val="from exp settings" valType="str" updates="None" name="units"/>
@@ -242,9 +242,9 @@
         <Param val="" valType="extendedCode" updates="constant" name="Begin Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="Begin JS Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="Begin JS Routine"/>
-        <Param val="win.callOnFlip(trigger.send_trigger, settings.FINGERMODEL_IDS['hold'])&amp;#10;# hold trigger(图片)后5s,出现extend图片" valType="extendedCode" updates="constant" name="Begin Routine"/>
+        <Param val="win.callOnFlip(trigger.send_trigger, settings.FINGERMODEL_IDS['hold'])&amp;#10;# hold trigger(图片)后5s,出现extend图片&amp;#10;random_duration = random.uniform(3, 10)&amp;#10;thisExp.addData('random_duration', random_duration)" valType="extendedCode" updates="constant" name="Begin Routine"/>
         <Param val="Py" valType="str" updates="None" name="Code Type"/>
-        <Param val="" valType="extendedCode" updates="constant" name="Each Frame"/>
+        <Param val="current_time = t&amp;#10;&amp;#10;if current_time &lt; random_duration:&amp;#10;    continueRoutine = True&amp;#10;else:&amp;#10;    continueRoutine = False" valType="extendedCode" updates="constant" name="Each Frame"/>
         <Param val="" valType="extendedCode" updates="constant" name="Each JS Frame"/>
         <Param val="" valType="extendedCode" updates="constant" name="End Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="End JS Experiment"/>
@@ -502,7 +502,7 @@
         <Param val="(0.5, 0.5)" valType="list" updates="constant" name="size"/>
         <Param val="" valType="code" updates="None" name="startEstim"/>
         <Param val="time (s)" valType="str" updates="None" name="startType"/>
-        <Param val="1" valType="code" updates="None" name="startVal"/>
+        <Param val="0" valType="code" updates="None" name="startVal"/>
         <Param val="duration (s)" valType="str" updates="None" name="stopType"/>
         <Param val="6" valType="code" updates="constant" name="stopVal"/>
         <Param val="True" valType="bool" updates="None" name="syncScreenRefresh"/>
@@ -517,7 +517,7 @@
         <Param val="" valType="extendedCode" updates="constant" name="Begin JS Routine"/>
         <Param val="i = 0&amp;#10;" valType="extendedCode" updates="constant" name="Begin Routine"/>
         <Param val="Py" valType="str" updates="None" name="Code Type"/>
-        <Param val="if i == 119:&amp;#10;    hand_device.start(args.finger_model)&amp;#10;    # trigger&amp;#10;    current_true_label = settings.FINGERMODEL_IDS[args.finger_model]&amp;#10;    win.callOnFlip(trigger.send_trigger, current_true_label)&amp;#10;&amp;#10;i += 1&amp;#10;&amp;#10;# 每轮开始前空白等待1s + 反应时1s + 新版flex时间4.5s + 0.5s裕量 = 7s。&amp;#10;# flex trigger打出5s(flex图片显示7s)后,hold图片显示。&amp;#10;" valType="extendedCode" updates="constant" name="Each Frame"/>
+        <Param val="if i == 59:&amp;#10;    hand_device.start(args.finger_model)&amp;#10;    # trigger&amp;#10;    current_true_label = settings.FINGERMODEL_IDS[args.finger_model]&amp;#10;    win.callOnFlip(trigger.send_trigger, current_true_label)&amp;#10;&amp;#10;i += 1&amp;#10;&amp;#10;# 反应时1s + 新版flex时间4.5s + 0.5s裕量 = 6s。&amp;#10;# flex trigger打出5s(flex图片显示6s)后,hold图片显示。&amp;#10;" valType="extendedCode" updates="constant" name="Each Frame"/>
         <Param val="" valType="extendedCode" updates="constant" name="Each JS Frame"/>
         <Param val="" valType="extendedCode" updates="constant" name="End Experiment"/>
         <Param val="" valType="extendedCode" updates="constant" name="End JS Experiment"/>
@@ -535,7 +535,7 @@
         <Param val="static/audios/flex.wav" valType="str" updates="constant" name="sound"/>
         <Param val="" valType="code" updates="None" name="startEstim"/>
         <Param val="time (s)" valType="str" updates="None" name="startType"/>
-        <Param val="1.8" valType="code" updates="None" name="startVal"/>
+        <Param val="0.8" valType="code" updates="None" name="startVal"/>
         <Param val="duration (s)" valType="str" updates="None" name="stopType"/>
         <Param val="2" valType="code" updates="constant" name="stopVal"/>
         <Param val="True" valType="bool" updates="constant" name="stopWithRoutine"/>
@@ -551,7 +551,7 @@
         <Param val="static/audios/ding.wav" valType="str" updates="constant" name="sound"/>
         <Param val="" valType="code" updates="None" name="startEstim"/>
         <Param val="time (s)" valType="str" updates="None" name="startType"/>
-        <Param val="1" valType="code" updates="None" name="startVal"/>
+        <Param val="0" valType="code" updates="None" name="startVal"/>
         <Param val="duration (s)" valType="str" updates="None" name="stopType"/>
         <Param val="1.0" valType="code" updates="constant" name="stopVal"/>
         <Param val="True" valType="bool" updates="constant" name="stopWithRoutine"/>

+ 22 - 29
backend/grasp_data_collection_no_release.py

@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 """
 This experiment was created using PsychoPy3 Experiment Builder (v2023.2.3),
-    on 十二月 18, 2023, at 10:48
+    on 十二月 21, 2023, at 23:15
 If you publish work using this script the most relevant publication is:
 
     Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) 
@@ -39,7 +39,7 @@ import time
 from device.fubo_pneumatic_finger import FuboPneumaticFingerClient
 from device.trigger_box import TriggerNeuracle
 from settings.config import settings
-
+import random
 
 # get train params
 
@@ -177,7 +177,7 @@ def setupData(expInfo, dataDir=None):
     thisExp = data.ExperimentHandler(
         name=expName, version='',
         extraInfo=expInfo, runtimeInfo=None,
-        originPath='D:\\Graduate\\kraken\\backend\\grasp_data_collection_no_release.py',
+        originPath='D:\\Graduate\\Research\\kraken_project\\backend\\grasp_data_collection_no_release.py',
         savePickle=True, saveWideText=True,
         dataFileName=dataDir + os.sep + filename, sortColumns='time'
     )
@@ -748,7 +748,7 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
         
         # --- Run Routine "flex" ---
         routineForceEnded = not continueRoutine
-        while continueRoutine and routineTimer.getTime() < 7.0:
+        while continueRoutine and routineTimer.getTime() < 6.0:
             # get current time
             t = routineTimer.getTime()
             tThisFlip = win.getFutureFlipTime(clock=routineTimer)
@@ -759,7 +759,7 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
             # *flex_img* updates
             
             # if flex_img is starting this frame...
-            if flex_img.status == NOT_STARTED and tThisFlip >= 1-frameTolerance:
+            if flex_img.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
                 # keep track of start time/frame for later
                 flex_img.frameNStart = frameN  # exact frame index
                 flex_img.tStart = t  # local t and not account for scr refresh
@@ -789,7 +789,7 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
                     flex_img.status = FINISHED
                     flex_img.setAutoDraw(False)
             # Run 'Each Frame' code from code_2
-            if i == 119:
+            if i == 59:
                 hand_device.start(args.finger_model)
                 # trigger
                 current_true_label = settings.FINGERMODEL_IDS[args.finger_model]
@@ -797,12 +797,12 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
             
             i += 1
             
-            # 每轮开始前空白等待1s + 反应时1s + 新版flex时间4.5s + 0.5s裕量 = 7s。
-            # flex trigger打出5s(flex图片显示7s)后,hold图片显示。
+            # 反应时1s + 新版flex时间4.5s + 0.5s裕量 = 6s。
+            # flex trigger打出5s(flex图片显示6s)后,hold图片显示。
             
             
             # if flex_wav is starting this frame...
-            if flex_wav.status == NOT_STARTED and tThisFlip >= 1.8-frameTolerance:
+            if flex_wav.status == NOT_STARTED and tThisFlip >= 0.8-frameTolerance:
                 # keep track of start time/frame for later
                 flex_wav.frameNStart = frameN  # exact frame index
                 flex_wav.tStart = t  # local t and not account for scr refresh
@@ -832,7 +832,7 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
                 flex_wav.status = FINISHED
             
             # if attention is starting this frame...
-            if attention.status == NOT_STARTED and tThisFlip >= 1-frameTolerance:
+            if attention.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
                 # keep track of start time/frame for later
                 attention.frameNStart = frameN  # exact frame index
                 attention.tStart = t  # local t and not account for scr refresh
@@ -893,7 +893,7 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
         if routineForceEnded:
             routineTimer.reset()
         else:
-            routineTimer.addTime(-7.000000)
+            routineTimer.addTime(-6.000000)
         
         # --- Prepare to start Routine "hold" ---
         continueRoutine = True
@@ -902,6 +902,8 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
         # Run 'Begin Routine' code from code_3
         win.callOnFlip(trigger.send_trigger, settings.FINGERMODEL_IDS['hold'])
         # hold trigger(图片)后5s,出现extend图片
+        random_duration = random.uniform(3, 10)
+        thisExp.addData('random_duration', random_duration)
         hold_wav.setSound('static/audios/hold.wav', secs=2.5, hamming=True)
         hold_wav.setVolume(1.0, log=False)
         hold_wav.seek(0)
@@ -921,7 +923,7 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
         
         # --- Run Routine "hold" ---
         routineForceEnded = not continueRoutine
-        while continueRoutine and routineTimer.getTime() < 5.0:
+        while continueRoutine:
             # get current time
             t = routineTimer.getTime()
             tThisFlip = win.getFutureFlipTime(clock=routineTimer)
@@ -948,19 +950,13 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
             if hold_img.status == STARTED:
                 # update params
                 pass
+            # Run 'Each Frame' code from code_3
+            current_time = t
             
-            # if hold_img is stopping this frame...
-            if hold_img.status == STARTED:
-                # is it time to stop? (based on global clock, using actual start)
-                if tThisFlipGlobal > hold_img.tStartRefresh + 5-frameTolerance:
-                    # keep track of stop time/frame for later
-                    hold_img.tStop = t  # not accounting for scr refresh
-                    hold_img.frameNStop = frameN  # exact frame index
-                    # add timestamp to datafile
-                    thisExp.timestampOnFlip(win, 'hold_img.stopped')
-                    # update status
-                    hold_img.status = FINISHED
-                    hold_img.setAutoDraw(False)
+            if current_time < random_duration:
+                continueRoutine = True
+            else:
+                continueRoutine = False
             
             # if hold_wav is starting this frame...
             if hold_wav.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
@@ -1019,11 +1015,8 @@ def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
                 thisComponent.setAutoDraw(False)
         thisExp.addData('hold.stopped', globalClock.getTime())
         hold_wav.pause()  # ensure sound has stopped at end of Routine
-        # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
-        if routineForceEnded:
-            routineTimer.reset()
-        else:
-            routineTimer.addTime(-5.000000)
+        # the Routine "hold" was not non-slip safe, so reset the non-slip timer
+        routineTimer.reset()
         
         # --- Prepare to start Routine "extend" ---
         continueRoutine = True