Browse Source

Feat: support step mode and edge mode for hand controller

dk 1 year ago
parent
commit
9c17d931c6
3 changed files with 21 additions and 5 deletions
  1. 17 1
      backend/device/fubo_pneumatic_finger.py
  2. 2 2
      backend/free_grasp.psyexp
  3. 2 2
      backend/free_grasp.py

+ 17 - 1
backend/device/fubo_pneumatic_finger.py

@@ -15,11 +15,27 @@ def get_serial_ports():
 
 
 class FingerController:
-    def __init__(self, init_params):
+    def __init__(self, mode='step', init_params=dict()):
         self.hand = FuboPneumaticFingerClient(init_params)
         self.current_state = 'rest'
+        if mode not in ['edge', 'step']:
+            raise ValueError('mode must be in \{"edge", "step"\}')
+        self.mode = mode
 
     def move(self, action='flex'):
+        if self.mode == 'edge':
+            self._edge(action)
+        elif self.mode == 'step':
+            self._step(action)
+    
+    def _step(self, action='flex'):
+        if action == 'rest':
+            self.hand.start('extend')
+        else:
+            self.hand.start(action)
+        self.current_state = action
+
+    def _edge(self, action='flex'):
         if self.current_state == 'extend':
             self.hand.start(action)
             self.current_state = action

+ 2 - 2
backend/free_grasp.psyexp

@@ -95,7 +95,7 @@
         <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="# state changed&amp;#10;if decision &gt; 0:&amp;#10;    trigger.send_trigger(int(decision))&amp;#10;    hand_device.move(action=fingermodel_ids_inverse[decision])&amp;#10;    " valType="extendedCode" updates="constant" name="Begin Routine"/>
+        <Param val="# state changed&amp;#10;if decision &gt; 0:&amp;#10;    trigger.send_trigger(int(decision))&amp;#10;    hand_device.move(action=fingermodel_ids_inverse[decision])&amp;#10;" 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="" valType="extendedCode" updates="constant" name="Each JS Frame"/>
@@ -244,7 +244,7 @@
         <Param val="parameter_inputs" valType="code" updates="None" name="name"/>
       </CodeComponent>
       <CodeComponent name="device" plugin="None">
-        <Param val="# connect neo&amp;#10;receiver = NeuracleDataClient(n_channel=len(config_info['channel_labels']), &amp;#10;                               samplerate=config_info['sample_rate'],&amp;#10;                               host=config_info['host'],&amp;#10;                               port=config_info['port'],&amp;#10;                               buffer_len=config_info['buffer_length'])&amp;#10;&amp;#10;# connect to trigger box&amp;#10;trigger = TriggerNeuracle()&amp;#10;&amp;#10;# connect to mechanical hand&amp;#10;hand_device = FingerController({'port': args.com})&amp;#10;" valType="extendedCode" updates="constant" name="Before Experiment"/>
+        <Param val="# connect neo&amp;#10;receiver = NeuracleDataClient(n_channel=len(config_info['channel_labels']), &amp;#10;                               samplerate=config_info['sample_rate'],&amp;#10;                               host=config_info['host'],&amp;#10;                               port=config_info['port'],&amp;#10;                               buffer_len=config_info['buffer_length'])&amp;#10;&amp;#10;# connect to trigger box&amp;#10;trigger = TriggerNeuracle()&amp;#10;&amp;#10;# connect to mechanical hand&amp;#10;hand_device = FingerController(mode='step', init_params={'port': args.com})&amp;#10;" valType="extendedCode" updates="constant" name="Before Experiment"/>
         <Param val="receiver = new NeuracleDataClient({&quot;n_channel&quot;: config_info[&quot;channel_labels&quot;].length, &quot;samplerate&quot;: config_info[&quot;sample_rate&quot;], &quot;host&quot;: config_info[&quot;host&quot;], &quot;port&quot;: config_info[&quot;port&quot;]});&amp;#10;trigger = new TriggerNeuracle();&amp;#10;hand_device = new FuboPneumaticFingerClient({&quot;port&quot;: args.com});&amp;#10;controller = new Controller(0.0, args.model_path, {&quot;state_change_threshold&quot;: 0.8});&amp;#10;" 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"/>

+ 2 - 2
backend/free_grasp.py

@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 """
 This experiment was created using PsychoPy3 Experiment Builder (v2023.2.3),
-    on Tue Jan  9 10:50:47 2024
+    on Fri Jan 12 12:38:40 2024
 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) 
@@ -122,7 +122,7 @@ receiver = NeuracleDataClient(n_channel=len(config_info['channel_labels']),
 trigger = TriggerNeuracle()
 
 # connect to mechanical hand
-hand_device = FingerController({'port': args.com})
+hand_device = FingerController(mode='step', init_params={'port': args.com})
 
 # --- Setup global variables (available in all functions) ---
 # Ensure that relative paths start from the same directory as this script