Werkcollege opgave 23 september BMT K9

Dependencies:   Encoder HIDScope MODSERIAL mbed QEI biquadFilter

Committer:
ThomasBNL
Date:
Mon Oct 19 20:49:18 2015 +0000
Revision:
36:f29a36683b1a
Parent:
32:97cf6cb8d054
Child:
37:6c04c15d9bbe
EMG testing HIGH-NOTCH-LOW left and right bicep + hidscope werkt?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bscheltinga 0:fe3896c6eeb0 1 #include "mbed.h"
bscheltinga 12:0a079e86348e 2 #include "HIDScope.h"
bscheltinga 0:fe3896c6eeb0 3 #include "MODSERIAL.h"
bscheltinga 13:04e10692e239 4 #include "biquadFilter.h" //Filter direct form II
bscheltinga 0:fe3896c6eeb0 5
bscheltinga 26:1090acf98efc 6 // [DEFINE INPUTS] //
ThomasBNL 36:f29a36683b1a 7
bscheltinga 21:594915ba2bf9 8
bscheltinga 26:1090acf98efc 9 // [DEFINE CONSTANTS] //
ThomasBNL 27:85e5d36bb6c5 10 HIDScope scope(3); // Aantal HIDScope kanalen
bscheltinga 18:68067ffd169e 11 MODSERIAL pc(USBTX,USBRX);
bscheltinga 20:d5f5c60adc43 12 Ticker control_tick;
ThomasBNL 27:85e5d36bb6c5 13 Ticker T1;
bscheltinga 15:7870f7912904 14
bscheltinga 26:1090acf98efc 15 // [BIQUAD FILTERS] //
ThomasBNL 27:85e5d36bb6c5 16 int Fs = 512; // sampling frequency
ThomasBNL 36:f29a36683b1a 17 const double low_b0 = 0.05892937945281792;
ThomasBNL 36:f29a36683b1a 18 const double low_b1 = 0.11785875890563584;
ThomasBNL 36:f29a36683b1a 19 const double low_b2 = 0.05892937945281792;
ThomasBNL 36:f29a36683b1a 20 const double low_a1 = -1.205716572226748;
ThomasBNL 36:f29a36683b1a 21 const double low_a2 = 0.44143409003801976; // VIA online biquad calculator Lowpas 520-48-0.7071-6
bscheltinga 15:7870f7912904 22
ThomasBNL 36:f29a36683b1a 23 const double high_b0 = 0.6389437261127494;
ThomasBNL 36:f29a36683b1a 24 const double high_b1 = -1.2778874522254988;
ThomasBNL 36:f29a36683b1a 25 const double high_b2 = 0.6389437261127494;
ThomasBNL 36:f29a36683b1a 26 const double high_a1 = -1.1429772843080923;
ThomasBNL 36:f29a36683b1a 27 const double high_a2 = 0.41279762014290533; // VIA online biquad calculator Highpas 520-52-0.7071-6
bscheltinga 22:14abcfdd1554 28
ThomasBNL 36:f29a36683b1a 29 //Left bicep
ThomasBNL 36:f29a36683b1a 30 biquadFilter highpassfilter_1(high_a1, high_a2, high_b0, high_b1, high_b2);// moeten nog waardes voor gemaakt worden? (>25Hz doorlaten)
ThomasBNL 36:f29a36683b1a 31 biquadFilter notchL1(low_a1, low_a2, low_b0, low_b1, low_b2);// moeten nog waardes voor gemaakt worden (>52Hz doorlaten)
ThomasBNL 36:f29a36683b1a 32 biquadFilter notchL2(low_a1, low_a2, low_b0, low_b1, low_b2);// moeten nog waardes voor gemaakt worden (<48Hz doorlaten)
ThomasBNL 36:f29a36683b1a 33 biquadFilter lowpassfilter_1(low_a1, low_a2, low_b0, low_b1, low_b2);// moeten nog waardes voor gemaakt worden? (<5-10 Hz ???) // (<200 Hz doorlaten) => wat is het verschil wat is bruikbaar
bscheltinga 0:fe3896c6eeb0 34
ThomasBNL 36:f29a36683b1a 35 // Right bicep
ThomasBNL 36:f29a36683b1a 36 biquadFilter highpassfilter_2(high_a1, high_a2, high_b0, high_b1, high_b2);// moeten nog waardes voor gemaakt worden?
ThomasBNL 36:f29a36683b1a 37 biquadFilter notchR1(low_a1, low_a2, low_b0, low_b1, low_b2); // moeten nog waardes voor gemaakt worden
ThomasBNL 36:f29a36683b1a 38 biquadFilter notchR2(low_a1, low_a2, low_b0, low_b1, low_b2); // moeten nog waardes voor gemaakt worden
ThomasBNL 36:f29a36683b1a 39 biquadFilter lowpassfilter_2(low_a1, low_a2, low_b0, low_b1, low_b2);// moeten nog waardes voor gemaakt worden?
bscheltinga 20:d5f5c60adc43 40
ThomasBNL 27:85e5d36bb6c5 41
ThomasBNL 36:f29a36683b1a 42 AnalogIn input1(A0); // EMG: Two AnalogIn EMG inputs
ThomasBNL 36:f29a36683b1a 43 AnalogIn input2(A1); // EMG: Two AnalogIn EMG inputs
ThomasBNL 36:f29a36683b1a 44
ThomasBNL 36:f29a36683b1a 45 // __________________________
ThomasBNL 36:f29a36683b1a 46 // : [EMG variables] :
ThomasBNL 36:f29a36683b1a 47 // :__________________________:
ThomasBNL 36:f29a36683b1a 48 //
ThomasBNL 36:f29a36683b1a 49
ThomasBNL 36:f29a36683b1a 50 volatile bool control_go = false; // EMG:
ThomasBNL 36:f29a36683b1a 51 volatile bool sample = false;
ThomasBNL 36:f29a36683b1a 52 volatile bool sample_error = false;
ThomasBNL 36:f29a36683b1a 53 volatile bool sample_error_strike = false;
ThomasBNL 36:f29a36683b1a 54
ThomasBNL 36:f29a36683b1a 55 double Sample_EMG_L_1, Sample_EMG_L_2, Sample_EMG_L_3, Sample_EMG_L_4, Sample_EMG_L_5, Sample_EMG_L_6, Sample_EMG_L_7, Sample_EMG_L_8, Sample_EMG_L_9, Sample_EMG_L_10, moving_average_left;
ThomasBNL 36:f29a36683b1a 56 double Sample_EMG_R_1, Sample_EMG_R_2, Sample_EMG_R_3, Sample_EMG_R_4, Sample_EMG_R_5, Sample_EMG_R_6, Sample_EMG_R_7, Sample_EMG_R_8, Sample_EMG_R_9, Sample_EMG_R_10, moving_average_right;
ThomasBNL 36:f29a36683b1a 57
ThomasBNL 36:f29a36683b1a 58 double minimum_L; double maximum_L;
ThomasBNL 36:f29a36683b1a 59 double EMG_L_min; double EMG_L_max;
ThomasBNL 36:f29a36683b1a 60 double minimum_R; double maximum_R;
ThomasBNL 36:f29a36683b1a 61 double EMG_R_min; double EMG_R_max;
ThomasBNL 36:f29a36683b1a 62 double EMG_left_Bicep; double EMG_Right_Bicep; // input variables
ThomasBNL 36:f29a36683b1a 63 double EMG_Left_Bicep_filtered_notch_1;double EMG_Right_Bicep_filtered_notch_1;
ThomasBNL 36:f29a36683b1a 64 double EMG_Left_Bicep_filtered_notch_2;double EMG_Right_Bicep_filtered_notch_2;
ThomasBNL 36:f29a36683b1a 65 double EMG_Left_Bicep_filtered; double EMG_Right_Bicep_filtered; // output variables
ThomasBNL 36:f29a36683b1a 66
ThomasBNL 36:f29a36683b1a 67
ThomasBNL 36:f29a36683b1a 68 double n=0; double c=0; double k=0; double p=0; double er=0;
ThomasBNL 36:f29a36683b1a 69
ThomasBNL 36:f29a36683b1a 70 // FUNCTIONS
ThomasBNL 36:f29a36683b1a 71 void ControlGo();
ThomasBNL 36:f29a36683b1a 72 void take_sample();
ThomasBNL 36:f29a36683b1a 73 void Filter();
ThomasBNL 36:f29a36683b1a 74 void sample_filter();
ThomasBNL 36:f29a36683b1a 75 void countdown_from_5();
ThomasBNL 36:f29a36683b1a 76 void calibration();
ThomasBNL 36:f29a36683b1a 77
ThomasBNL 36:f29a36683b1a 78 //==========================//
ThomasBNL 27:85e5d36bb6c5 79 // [MAIN FUNCTION] //
ThomasBNL 36:f29a36683b1a 80 //==========================//
ThomasBNL 27:85e5d36bb6c5 81 int main()
ThomasBNL 27:85e5d36bb6c5 82 {
ThomasBNL 27:85e5d36bb6c5 83 control_tick.attach(&ControlGo, (float)1/Fs);
ThomasBNL 27:85e5d36bb6c5 84 pc.baud(9600);
ThomasBNL 36:f29a36683b1a 85 // calibration(); // calibreer min en max positie
ThomasBNL 27:85e5d36bb6c5 86 while(1)
ThomasBNL 27:85e5d36bb6c5 87 {
ThomasBNL 27:85e5d36bb6c5 88 if(control_go)
ThomasBNL 27:85e5d36bb6c5 89 {
ThomasBNL 27:85e5d36bb6c5 90 sample_filter();
ThomasBNL 36:f29a36683b1a 91 scope.set(0,EMG_left_Bicep); //left bicep unfiltered
ThomasBNL 36:f29a36683b1a 92 scope.set(1,EMG_Left_Bicep_filtered); //Filtered signal
ThomasBNL 36:f29a36683b1a 93 scope.set(2,moving_average_left); //
ThomasBNL 27:85e5d36bb6c5 94 scope.send();
ThomasBNL 27:85e5d36bb6c5 95 control_go = 0;
ThomasBNL 27:85e5d36bb6c5 96 }
ThomasBNL 27:85e5d36bb6c5 97 } // while end
ThomasBNL 27:85e5d36bb6c5 98 } // main end
ThomasBNL 36:f29a36683b1a 99
ThomasBNL 36:f29a36683b1a 100 // --------------------------------------------------------------------------------------------------------
ThomasBNL 36:f29a36683b1a 101 // [FUNCTIONS] //
ThomasBNL 36:f29a36683b1a 102 void ControlGo() //Control flag
ThomasBNL 36:f29a36683b1a 103 {
ThomasBNL 36:f29a36683b1a 104 control_go = true;
ThomasBNL 36:f29a36683b1a 105 }
ThomasBNL 36:f29a36683b1a 106
ThomasBNL 36:f29a36683b1a 107 void sample_filter()
ThomasBNL 36:f29a36683b1a 108 {
ThomasBNL 36:f29a36683b1a 109 Filter();
ThomasBNL 36:f29a36683b1a 110 take_sample();
ThomasBNL 36:f29a36683b1a 111 if(sample)
ThomasBNL 36:f29a36683b1a 112 {
ThomasBNL 36:f29a36683b1a 113 sample=false;
ThomasBNL 36:f29a36683b1a 114 Sample_EMG_L_1 = EMG_Left_Bicep_filtered; Sample_EMG_R_1 = EMG_Right_Bicep_filtered;
ThomasBNL 36:f29a36683b1a 115
ThomasBNL 36:f29a36683b1a 116 Sample_EMG_L_10= Sample_EMG_L_9; Sample_EMG_R_10= Sample_EMG_R_9;
ThomasBNL 36:f29a36683b1a 117 Sample_EMG_L_9 = Sample_EMG_L_8; Sample_EMG_R_9 = Sample_EMG_R_8;
ThomasBNL 36:f29a36683b1a 118 Sample_EMG_L_8 = Sample_EMG_L_7; Sample_EMG_R_8 = Sample_EMG_R_7;
ThomasBNL 36:f29a36683b1a 119 Sample_EMG_L_7 = Sample_EMG_L_6; Sample_EMG_R_7 = Sample_EMG_R_6;
ThomasBNL 36:f29a36683b1a 120 Sample_EMG_L_6 = Sample_EMG_L_5; Sample_EMG_R_6 = Sample_EMG_R_5;
ThomasBNL 36:f29a36683b1a 121 Sample_EMG_L_5 = Sample_EMG_L_4; Sample_EMG_R_5 = Sample_EMG_R_4;
ThomasBNL 36:f29a36683b1a 122 Sample_EMG_L_4 = Sample_EMG_L_3; Sample_EMG_R_4 = Sample_EMG_R_3;
ThomasBNL 36:f29a36683b1a 123 Sample_EMG_L_3 = Sample_EMG_L_2; Sample_EMG_R_3 = Sample_EMG_R_2;
ThomasBNL 36:f29a36683b1a 124 Sample_EMG_L_2 = Sample_EMG_L_1; Sample_EMG_R_2 = Sample_EMG_R_1;
ThomasBNL 36:f29a36683b1a 125 }
ThomasBNL 36:f29a36683b1a 126 moving_average_left=Sample_EMG_L_1*0.1+Sample_EMG_L_2*0.1+Sample_EMG_L_3*0.1+Sample_EMG_L_4*0.1+Sample_EMG_L_5*0.1+Sample_EMG_L_6*0.1+Sample_EMG_L_7*0.1+Sample_EMG_L_8*0.1+Sample_EMG_L_9*0.1+Sample_EMG_L_10*0.1;
ThomasBNL 36:f29a36683b1a 127 moving_average_right=Sample_EMG_R_1*0.1+Sample_EMG_R_2*0.1+Sample_EMG_R_3*0.1+Sample_EMG_R_4*0.1+Sample_EMG_R_5*0.1+Sample_EMG_R_6*0.1+Sample_EMG_R_7*0.1+Sample_EMG_R_8*0.1+Sample_EMG_R_9*0.1+Sample_EMG_R_10*0.1;
ThomasBNL 36:f29a36683b1a 128 n++;
ThomasBNL 36:f29a36683b1a 129 }
ThomasBNL 36:f29a36683b1a 130
ThomasBNL 36:f29a36683b1a 131 void take_sample() // Take a sample every 25th sample
ThomasBNL 36:f29a36683b1a 132 {
ThomasBNL 36:f29a36683b1a 133 if(n==25)
ThomasBNL 36:f29a36683b1a 134 {
ThomasBNL 36:f29a36683b1a 135 sample = true; n=0;
ThomasBNL 36:f29a36683b1a 136 }
ThomasBNL 36:f29a36683b1a 137
ThomasBNL 36:f29a36683b1a 138 if(er==5)
ThomasBNL 36:f29a36683b1a 139 {
ThomasBNL 36:f29a36683b1a 140 sample_error = true; er=0;
ThomasBNL 36:f29a36683b1a 141 }
ThomasBNL 36:f29a36683b1a 142
ThomasBNL 36:f29a36683b1a 143 sample_error_strike = true;
ThomasBNL 36:f29a36683b1a 144 }
ThomasBNL 36:f29a36683b1a 145
ThomasBNL 36:f29a36683b1a 146 // [FILTER FUNCTIONS] //
ThomasBNL 36:f29a36683b1a 147 // [EMG] //
ThomasBNL 36:f29a36683b1a 148
ThomasBNL 36:f29a36683b1a 149 void Filter() // Unfiltered EMG (input) -> highpass filter -> rectify -> lowpass filter -> Filtered EMG (output)
ThomasBNL 36:f29a36683b1a 150 {
ThomasBNL 36:f29a36683b1a 151 EMG_left_Bicep = input1; EMG_Right_Bicep = input2;
ThomasBNL 36:f29a36683b1a 152
ThomasBNL 36:f29a36683b1a 153 EMG_Left_Bicep_filtered = highpassfilter_1.step(EMG_left_Bicep); EMG_Right_Bicep_filtered = highpassfilter_2.step(EMG_Right_Bicep);
ThomasBNL 36:f29a36683b1a 154 EMG_Left_Bicep_filtered = fabs(EMG_Left_Bicep_filtered); EMG_Right_Bicep_filtered = fabs(EMG_Right_Bicep_filtered);
ThomasBNL 36:f29a36683b1a 155
ThomasBNL 36:f29a36683b1a 156 EMG_Left_Bicep_filtered_notch_1 = notchL1.step(EMG_Left_Bicep_filtered); EMG_Right_Bicep_filtered_notch_1 = notchR1.step(EMG_Right_Bicep_filtered);
ThomasBNL 36:f29a36683b1a 157 EMG_Left_Bicep_filtered_notch_2 = notchL2.step(EMG_Left_Bicep_filtered_notch_1); EMG_Right_Bicep_filtered_notch_2 = notchR2.step(EMG_Right_Bicep_filtered_notch_1);
ThomasBNL 36:f29a36683b1a 158
ThomasBNL 36:f29a36683b1a 159 EMG_Left_Bicep_filtered = lowpassfilter_1.step(EMG_Left_Bicep_filtered_notch_2); EMG_Right_Bicep_filtered = lowpassfilter_2.step(EMG_Right_Bicep_filtered_notch_2);
ThomasBNL 36:f29a36683b1a 160 }
ThomasBNL 36:f29a36683b1a 161
ThomasBNL 36:f29a36683b1a 162 void countdown_from_5() // Countdown from 5 till 0 inside Putty (interface)
ThomasBNL 36:f29a36683b1a 163 {
ThomasBNL 36:f29a36683b1a 164 wait(1); pc.printf("5 \n\r"); wait(1); pc.printf("4 \n\r"); wait(1); pc.printf("3 \n\r"); wait(1); pc.printf("2 Ready \n\r");
ThomasBNL 36:f29a36683b1a 165 wait(1); pc.printf("1 Set \n\r"); wait(1); pc.printf("Go \n\r");
ThomasBNL 36:f29a36683b1a 166 }
ThomasBNL 36:f29a36683b1a 167
ThomasBNL 36:f29a36683b1a 168 void calibration()
ThomasBNL 36:f29a36683b1a 169 {
ThomasBNL 36:f29a36683b1a 170
ThomasBNL 36:f29a36683b1a 171
ThomasBNL 36:f29a36683b1a 172 // [MINIMUM VALUE BICEPS CALIBRATION] //
ThomasBNL 36:f29a36683b1a 173
ThomasBNL 36:f29a36683b1a 174 pc.printf("Start minimum calibration in 5 seconds \n\r");
ThomasBNL 36:f29a36683b1a 175 pc.printf("Keep your biceps as relaxed as possible \n\r");
ThomasBNL 36:f29a36683b1a 176
ThomasBNL 36:f29a36683b1a 177 countdown_from_5();
ThomasBNL 36:f29a36683b1a 178 c=0;
ThomasBNL 36:f29a36683b1a 179
ThomasBNL 36:f29a36683b1a 180 while(c<2560) // 512Hz -> 2560 is equal to five seconds
ThomasBNL 36:f29a36683b1a 181 {
ThomasBNL 36:f29a36683b1a 182 Filter(); // Filter EMG signal
ThomasBNL 36:f29a36683b1a 183 minimum_L=EMG_Left_Bicep_filtered+minimum_L; // Take previous sample EMG_Left_Bicep_filtered and add the new value
ThomasBNL 36:f29a36683b1a 184 minimum_R=EMG_Right_Bicep_filtered+minimum_R;
ThomasBNL 36:f29a36683b1a 185 // scope.set(0,EMG_left_Bicep);
ThomasBNL 36:f29a36683b1a 186 // scope.set(1,EMG_Left_Bicep_filtered);
ThomasBNL 36:f29a36683b1a 187 // scope.set(2,minimum_L);
ThomasBNL 36:f29a36683b1a 188 // scope.send();
ThomasBNL 36:f29a36683b1a 189 c++; // Every sample c is increased by one until the statement c<2560 is false
ThomasBNL 36:f29a36683b1a 190 wait(0.001953125); // wait one sample
ThomasBNL 36:f29a36683b1a 191 }
ThomasBNL 36:f29a36683b1a 192
ThomasBNL 36:f29a36683b1a 193 pc.printf("Finished minimum calibration \n\r");
ThomasBNL 36:f29a36683b1a 194
ThomasBNL 36:f29a36683b1a 195 EMG_L_min=minimum_L/2560; // Divide the summation by the number of measurements (2560 measurements) to get a mean value over 5 seconds
ThomasBNL 36:f29a36683b1a 196 EMG_R_min=minimum_R/2560;
ThomasBNL 36:f29a36683b1a 197
ThomasBNL 36:f29a36683b1a 198 pc.printf("EMG_L_min = %f \n\r EMG_R_min = %f \n\r", EMG_L_min, EMG_R_min);
ThomasBNL 36:f29a36683b1a 199
ThomasBNL 36:f29a36683b1a 200 wait (3); //cooldown
ThomasBNL 36:f29a36683b1a 201
ThomasBNL 36:f29a36683b1a 202
ThomasBNL 36:f29a36683b1a 203 // [MAXIMUM VALUE BICEPS CALIBRATION] //
ThomasBNL 36:f29a36683b1a 204
ThomasBNL 36:f29a36683b1a 205
ThomasBNL 36:f29a36683b1a 206 pc.printf("start maximum calibration in 5 seconds (start contraction at 3) \n\r");
ThomasBNL 36:f29a36683b1a 207
ThomasBNL 36:f29a36683b1a 208 countdown_from_5();
ThomasBNL 36:f29a36683b1a 209 c=0;
ThomasBNL 36:f29a36683b1a 210
ThomasBNL 36:f29a36683b1a 211 while(c<2560) // 512Hz -> 2560 is equal to five seconds
ThomasBNL 36:f29a36683b1a 212 {
ThomasBNL 36:f29a36683b1a 213 Filter(); // Filter EMG signal
ThomasBNL 36:f29a36683b1a 214 maximum_L=EMG_Left_Bicep_filtered+maximum_L; // Take previous sample EMG_Left_Bicep_filtered and add the new value
ThomasBNL 36:f29a36683b1a 215 maximum_R=EMG_Right_Bicep_filtered+maximum_R;
ThomasBNL 36:f29a36683b1a 216 c++; // Every sample c is increased by one until the statement c<2560 is false
ThomasBNL 36:f29a36683b1a 217 wait(0.001953125);
ThomasBNL 36:f29a36683b1a 218 }
ThomasBNL 36:f29a36683b1a 219
ThomasBNL 36:f29a36683b1a 220 pc.printf("Finished minimum calibration \n\r");
ThomasBNL 36:f29a36683b1a 221
ThomasBNL 36:f29a36683b1a 222 EMG_L_max=maximum_L/2560; // Divide the summation by the number of measurements (2560 measurements) to get a mean value over 5 seconds
ThomasBNL 36:f29a36683b1a 223 EMG_R_max=maximum_R/2560;
ThomasBNL 36:f29a36683b1a 224
ThomasBNL 36:f29a36683b1a 225 pc.printf("EMG_L_max = %f \n\r EMG_R_max = %f \n\r", EMG_L_max, EMG_R_max);
ThomasBNL 36:f29a36683b1a 226
ThomasBNL 36:f29a36683b1a 227 wait (3); //cooldown
ThomasBNL 36:f29a36683b1a 228
ThomasBNL 36:f29a36683b1a 229
ThomasBNL 36:f29a36683b1a 230 // [MAXIMUM VALUE BICEPS CALIBRATION] //
ThomasBNL 36:f29a36683b1a 231 // Calculate threshold percentages //
ThomasBNL 36:f29a36683b1a 232
ThomasBNL 36:f29a36683b1a 233 const float Threshold_Bicep_Left_1=((EMG_L_max-EMG_L_min)*0.2)+EMG_L_min;; //(waarde waarop het gemeten EMG signaal 20% van max het maximale is); // LEFT
ThomasBNL 36:f29a36683b1a 234 const float Threshold_Bicep_Left_2=((EMG_L_max-EMG_L_min)*0.6)+EMG_L_min; //(waarde waarop het gemeten EMG signaal 60% van max het maximale is);
ThomasBNL 36:f29a36683b1a 235 const float Threshold_Bicep_Right_1=((EMG_R_max-EMG_R_min)*0.2)+EMG_R_min; //(waarde waarop het gemeten EMG signaal 20% van max het maximale is); // RIGHT
ThomasBNL 36:f29a36683b1a 236 const float Threshold_Bicep_Right_2=((EMG_R_max-EMG_R_min)*0.6)+EMG_R_min; //(waarde waarop het gemeten EMG signaal 60% van max het maximale is);
ThomasBNL 36:f29a36683b1a 237
ThomasBNL 36:f29a36683b1a 238 pc.printf("left 1: %f left 2: %f right 1: %f right 2: %f \n\r", Threshold_Bicep_Left_1, Threshold_Bicep_Left_2, Threshold_Bicep_Right_1, Threshold_Bicep_Right_2);
ThomasBNL 36:f29a36683b1a 239
ThomasBNL 36:f29a36683b1a 240 }
ThomasBNL 36:f29a36683b1a 241
ThomasBNL 36:f29a36683b1a 242
ThomasBNL 36:f29a36683b1a 243