fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Mon Oct 01 14:54:37 2018 +0000
Revision:
29:1fb060aab1f8
Parent:
28:797536a42b9f
Child:
30:5f975f572ffb
update task structure

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gwappa 2:0c241937eabd 1 #include "trial.h"
gwappa 11:897ecd5413e0 2 #include "rig.h"
gwappa 2:0c241937eabd 3 #include "IO.h"
gwappa 2:0c241937eabd 4 #include "random.h"
gwappa 2:0c241937eabd 5
gwappa 11:897ecd5413e0 6 const uint64_t MicrosecondsInSecond = 1000000;
gwappa 11:897ecd5413e0 7
gwappa 20:4c06d3041337 8 inline uint64_t calc_blink_duration(const uint16_t& freq) {
gwappa 20:4c06d3041337 9 return (freq == 0)? 0 : (MicrosecondsInSecond/(freq * 2));
gwappa 20:4c06d3041337 10 }
gwappa 20:4c06d3041337 11
gwappa 20:4c06d3041337 12 void TrialFlag::clear() {
gwappa 19:50663f8815b8 13 cued = false;
gwappa 19:50663f8815b8 14 responded = false;
gwappa 29:1fb060aab1f8 15 rewarded = false;
gwappa 19:50663f8815b8 16 reset = false;
gwappa 19:50663f8815b8 17 }
gwappa 19:50663f8815b8 18
gwappa 29:1fb060aab1f8 19 void TrialFlag::writeToSerial(const Task& task) {
gwappa 29:1fb060aab1f8 20 if (task.mode.value == Condition)
gwappa 29:1fb060aab1f8 21 {
gwappa 29:1fb060aab1f8 22 if (rewarded) {
gwappa 29:1fb060aab1f8 23 IO::write(responded? "resp":"noresp");
gwappa 29:1fb060aab1f8 24 } else {
gwappa 29:1fb060aab1f8 25 IO::write(responded? "hit":"miss");
gwappa 29:1fb060aab1f8 26 }
gwappa 29:1fb060aab1f8 27 }
gwappa 29:1fb060aab1f8 28 else
gwappa 29:1fb060aab1f8 29 {
gwappa 29:1fb060aab1f8 30 if (reset) {
gwappa 29:1fb060aab1f8 31 IO::write("reset");
gwappa 29:1fb060aab1f8 32 } else if (cued) {
gwappa 29:1fb060aab1f8 33 IO::write(responded? "hit":"miss");
gwappa 29:1fb060aab1f8 34 } else {
gwappa 29:1fb060aab1f8 35 IO::write(responded? "catch":"reject");
gwappa 29:1fb060aab1f8 36 }
gwappa 19:50663f8815b8 37 }
gwappa 19:50663f8815b8 38 }
gwappa 19:50663f8815b8 39
gwappa 2:0c241937eabd 40 void Trial::reset(const Task& task){
gwappa 2:0c241937eabd 41 // reset score
gwappa 20:4c06d3041337 42 flag.clear();
gwappa 2:0c241937eabd 43
gwappa 2:0c241937eabd 44 // set delay duration
gwappa 5:849446d19406 45 delay_dur_ms = task.delay_min_ms.value
gwappa 5:849446d19406 46 + random::exponential(task.delay_var_ms.value, task.delay_var_ms.value*3);
gwappa 11:897ecd5413e0 47
gwappa 24:e236faf66935 48 // reset cues
gwappa 20:4c06d3041337 49 audioOut.setEnabled(false);
gwappa 15:20f7f737c256 50 visualOut.setEnabled(false);
gwappa 16:33c17c62840e 51 vis_onset_us = 0;
gwappa 15:20f7f737c256 52
gwappa 24:e236faf66935 53 // configure reward
gwappa 24:e236faf66935 54 rewardOut.setOnset(0);
gwappa 24:e236faf66935 55 rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value));
gwappa 24:e236faf66935 56
gwappa 24:e236faf66935 57 // configure cued state duration + visual stimulus position (if any)
gwappa 15:20f7f737c256 58 switch (task.mode.value) {
gwappa 28:797536a42b9f 59 case Condition:
gwappa 29:1fb060aab1f8 60 case Report:
gwappa 29:1fb060aab1f8 61 // TODO: check for testing
gwappa 29:1fb060aab1f8 62 visualOut.setOnset(0);
gwappa 29:1fb060aab1f8 63 visualOut.setDuration(ms_to_us(task.vis_dur_ms.value));
gwappa 28:797536a42b9f 64 break;
gwappa 15:20f7f737c256 65 case Associate:
gwappa 29:1fb060aab1f8 66 assignAssociative(task);
gwappa 24:e236faf66935 67 break;
gwappa 16:33c17c62840e 68 case Motion:
gwappa 16:33c17c62840e 69 case MotionAlt:
gwappa 29:1fb060aab1f8 70 assignForFeedback(task);
gwappa 24:e236faf66935 71 break;
gwappa 24:e236faf66935 72 }
gwappa 24:e236faf66935 73
gwappa 24:e236faf66935 74 // assign Auditory cues (if any)
gwappa 24:e236faf66935 75 switch (task.mode.value) {
gwappa 28:797536a42b9f 76 case Condition:
gwappa 24:e236faf66935 77 case Report:
gwappa 24:e236faf66935 78 break;
gwappa 24:e236faf66935 79 case Associate:
gwappa 24:e236faf66935 80 case Motion:
gwappa 24:e236faf66935 81 case MotionAlt:
gwappa 24:e236faf66935 82 audioOut.setEnabled(true);
gwappa 24:e236faf66935 83 audioOut.setOnset(0);
gwappa 29:1fb060aab1f8 84 audioOut.setDuration(task.aud_dur_ms.value);
gwappa 24:e236faf66935 85 audioOut.setBlinkDuration( calc_blink_duration(task.aud_tick_hz.value) );
gwappa 15:20f7f737c256 86 break;
gwappa 13:8ea85a33e37a 87 }
gwappa 2:0c241937eabd 88
gwappa 3:991c6d5ce19d 89 // reset interrupt events
gwappa 26:b4421d1ee57a 90 lickIn.reset(task.lick_debounce_ms.value, true);
gwappa 26:b4421d1ee57a 91 whiskIn.reset(task.whisk_debounce_ms.value, true);
gwappa 26:b4421d1ee57a 92 gateIn.reset(-1, true);
gwappa 2:0c241937eabd 93 }
gwappa 2:0c241937eabd 94
gwappa 29:1fb060aab1f8 95 void Trial::assignForFeedback(const Task& task)
gwappa 13:8ea85a33e37a 96 {
gwappa 29:1fb060aab1f8 97 visualOut.setEnabled(false);
gwappa 29:1fb060aab1f8 98 visualOut.direct(true);
gwappa 29:1fb060aab1f8 99 vis_onset_us = 0;
gwappa 29:1fb060aab1f8 100 }
gwappa 29:1fb060aab1f8 101
gwappa 29:1fb060aab1f8 102 void Trial::assignAssociative(const Task& task)
gwappa 29:1fb060aab1f8 103 {
gwappa 29:1fb060aab1f8 104 // TODO check for test trial
gwappa 13:8ea85a33e37a 105
gwappa 29:1fb060aab1f8 106 // if not...
gwappa 29:1fb060aab1f8 107 const uint32_t phasedur_us = ms_to_us(task.aud_dur_ms.value);
gwappa 29:1fb060aab1f8 108 const uint32_t minonset_us = ms_to_us(task.onset_min_ms.value);
gwappa 29:1fb060aab1f8 109 const uint32_t respdur_us = ms_to_us(task.resp_dur_ms.value);
gwappa 29:1fb060aab1f8 110 const uint32_t visdur_us = ms_to_us(task.vis_dur_ms.value);
gwappa 13:8ea85a33e37a 111
gwappa 29:1fb060aab1f8 112 const double onset_vrng = (double)(phasedur_us - minonset_us - respdur_us - visdur_us);
gwappa 29:1fb060aab1f8 113 const uint16_t nsteps = task.onset_steps_n.value;
gwappa 29:1fb060aab1f8 114 const uint32_t onset_step = random::unif(nsteps);
gwappa 29:1fb060aab1f8 115
gwappa 29:1fb060aab1f8 116 vis_onset_us = (uint32_t)(onset_vrng*onset_step/nsteps);
gwappa 13:8ea85a33e37a 117 }
gwappa 13:8ea85a33e37a 118
gwappa 11:897ecd5413e0 119 void Trial::markTrialStart() {
gwappa 26:b4421d1ee57a 120 starting = TrialTimer.read_ms();
gwappa 12:06ea96546af1 121 trialStart.run();
gwappa 26:b4421d1ee57a 122 TrialTimer.start();
gwappa 11:897ecd5413e0 123 }
gwappa 11:897ecd5413e0 124
gwappa 11:897ecd5413e0 125 void Trial::markEndOfWait() {
gwappa 26:b4421d1ee57a 126 cuestarting = TrialTimer.read_ms();
gwappa 11:897ecd5413e0 127 waiting = cuestarting - starting;
gwappa 11:897ecd5413e0 128 }
gwappa 11:897ecd5413e0 129
gwappa 29:1fb060aab1f8 130 void Trial::markTrialEnd(const Task& task) {
gwappa 12:06ea96546af1 131 trialEnd.run();
gwappa 11:897ecd5413e0 132 trialEnd.wait();
gwappa 29:1fb060aab1f8 133 writeToSerial(task);
gwappa 26:b4421d1ee57a 134 TrialTimer.stop();
gwappa 26:b4421d1ee57a 135 TrialTimer.reset();
gwappa 27:b31ea8d74f9e 136 visualOut.direct(false); // if any
gwappa 11:897ecd5413e0 137 }
gwappa 11:897ecd5413e0 138
gwappa 29:1fb060aab1f8 139 void Trial::writeToSerial(const Task& task) {
gwappa 19:50663f8815b8 140 IO::write("%c",IO::RESULT_HEADER);
gwappa 29:1fb060aab1f8 141 flag.writeToSerial(task);
gwappa 2:0c241937eabd 142
gwappa 19:50663f8815b8 143 IO::write(";wait%u", waiting);
gwappa 13:8ea85a33e37a 144
gwappa 29:1fb060aab1f8 145 if ((task.mode.value == Associate) && visualOut.isEnabled() && (!flag.reset)) {
gwappa 29:1fb060aab1f8 146 IO::write(";visual(onset%s)",
gwappa 29:1fb060aab1f8 147 uint64_to_str(vis_onset_us).c_str());
gwappa 13:8ea85a33e37a 148 }
gwappa 13:8ea85a33e37a 149
gwappa 19:50663f8815b8 150 trialtime_t zero = (flag.reset)? starting : cuestarting;
gwappa 3:991c6d5ce19d 151 IO::write(";whisk");
gwappa 26:b4421d1ee57a 152 whiskIn.writeToSerial(zero);
gwappa 26:b4421d1ee57a 153 IO::write(";gate");
gwappa 26:b4421d1ee57a 154 gateIn.writeToSerial(zero);
gwappa 3:991c6d5ce19d 155 IO::write(";lick");
gwappa 26:b4421d1ee57a 156 lickIn.writeToSerial(zero);
gwappa 4:fcf597f82632 157 IO::write(";\r\n");
gwappa 2:0c241937eabd 158 }