diff --git a/Devices/Arduino/HallSensor/HallSensor.ino b/Devices/Arduino/HallSensor/HallSensor.ino index 9d07247a..36aa8ca5 100644 --- a/Devices/Arduino/HallSensor/HallSensor.ino +++ b/Devices/Arduino/HallSensor/HallSensor.ino @@ -1,101 +1,121 @@ #define ARDUINO_TYPE "HALLSENS" -#define VERSION "1" -#define POSITION 1 +#define VERSION "5.0" #define BAUDRATE 9600 -#include +#define MEASDELAY 1 +#define INPUT_BUFFER_SIZE 3000 +#define MAX_SAMPLE_SIZE 10000 -// Tlv493d Opject -Tlv493d Tlv493dMagnetic3DSensor = Tlv493d(); +#include +// Tlv493d Opject +Tle493d_w2b6 sensor = Tle493d_w2b6(Tle493d::MASTERCONTROLLEDMODE); // Communication -#define INPUT_BUFFER_SIZE 256 char input_buffer[INPUT_BUFFER_SIZE]; unsigned int input_pos = 0; -int getData(char*); -int getPosition(char*); -int getTemp(char*); -int getVersion(char*); -int getCommands(char*); -//int setFoo(char*) +int sample_size = 1000; + +int getDelay(char *); +int getData(char *); +int getPosition(char *); +int getTemp(char *); +int getVersion(char *); +int getCommands(char *); +int setSampleSize(char *); -typedef struct { - const char * id; - int (*handler)(char*); +typedef struct +{ + const char *id; + int (*handler)(char *); } commandHandler_t; commandHandler_t cmdHandler[] = { - {"DATA", getData}, - {"POS", getPosition}, - {"TEMP", getTemp}, - {"VERSION", getVersion}, - {"COMMANDS", getCommands}, - //{"FOO", setFoo} -}; - -int getCommands(char*) { - Serial.println("Valid Commands (without quotes):"); - Serial.println("'!DATA*#' "); - Serial.println("'!POS*#' "); - Serial.println("'!VERSION*#' "); - Serial.println("'!COMMANDS*#' "); + {"DELAY", getDelay}, + {"DATA", getData}, + {"TEMP", getTemp}, + {"VERSION", getVersion}, + {"COMMANDS", getCommands}, + {"SAMPLES", setSampleSize}}; + +int getCommands(char *) +{ + Serial.print("Valid Commands (without quotes):"); + Serial.print("'!DATA*#' "); + Serial.print("'!DELAY*#' "); + Serial.print("'!VERSION*#' "); + Serial.print("'!TEMP*#' "); + Serial.print("'!COMMANDS*#' "); + Serial.print("'!SAMPLESx*# 1>=x>=10000' "); Serial.println("#"); } -bool updateBufferUntilDelim(char delim) { +bool updateBufferUntilDelim(char delim) +{ char nextChar; - while (Serial.available() > 0) { - nextChar = Serial.read(); - if (nextChar == delim) { - input_buffer[input_pos] = '\0'; - input_pos = 0; - return true; - } else if (nextChar != '\n') { - input_buffer[input_pos % (INPUT_BUFFER_SIZE - 1)] = nextChar; // Size - 1 to always leave room for \0 - input_pos++; - } + while (Serial.available() > 0) + { + nextChar = Serial.read(); + if (nextChar == delim) + { + input_buffer[input_pos] = '\0'; + input_pos = 0; + return true; + } + else if (nextChar != '\n') + { + input_buffer[input_pos % (INPUT_BUFFER_SIZE - 1)] = nextChar; // Size - 1 to always leave room for \0 + input_pos++; + } } return false; } -void serialCommand() { - int s=-1; - int e=-1; - char beginDelim='!'; +void serialCommand() +{ + int s = -1; + int e = -1; + char beginDelim = '!'; char *beginCmd; - char endDelim='*'; + char endDelim = '*'; char *endCmd; char *command; bool done = false; bool unknown = false; - + // determin substring - if(Serial.available()>0) { - done = updateBufferUntilDelim('#'); + if (Serial.available() > 0) + { + done = updateBufferUntilDelim('#'); } - if (done) { + if (done) + { s = -1; - if ((beginCmd = strchr(input_buffer, beginDelim)) != NULL) { + if ((beginCmd = strchr(input_buffer, beginDelim)) != NULL) + { s = beginCmd - input_buffer; } e = -1; - if ((endCmd = strchr(input_buffer, endDelim)) != NULL) { + if ((endCmd = strchr(input_buffer, endDelim)) != NULL) + { e = endCmd - input_buffer; - } + } unknown = true; - //check if valid command - if (e!=-1 && s!=-1) { + // check if valid command + if (e != -1 && s != -1) + { command = beginCmd + 1; *endCmd = '\0'; Serial.flush(); - //check for known commands - for (int i = 0; i < sizeof(cmdHandler)/sizeof(*cmdHandler); i++) { - if (strncmp(cmdHandler[i].id, command, strlen(cmdHandler[i].id)) == 0) { + // check for known commands + for (int i = 0; i < sizeof(cmdHandler) / sizeof(*cmdHandler); i++) + { + if (strncmp(cmdHandler[i].id, command, strlen(cmdHandler[i].id)) == 0) + { cmdHandler[i].handler(command); unknown = false; input_buffer[0] = '\0'; // "Empty" input buffer @@ -103,73 +123,142 @@ void serialCommand() { } } } - - if (unknown) { + + if (unknown) + { Serial.println("UNKNOWN"); Serial.println("#"); - Serial.flush(); + Serial.flush(); } - } - } //////////////////////////////////////////////////////////////////////////////// -void setup() { +void setup() +{ Serial.begin(BAUDRATE); - while(!Serial); - - //For the Evalkit "TLV493D-A1B6 MS2GO" uncommend following 3 lines: - pinMode(LED2, OUTPUT); //Sensor-VDD as output - digitalWrite(LED2, HIGH); //Power on the sensor + while (!Serial) + ; + + // If using the MS2Go-Kit: Enable following lines to switch on the sensor + // *** + pinMode(LED2, OUTPUT); + digitalWrite(LED2, HIGH); delay(50); - - Tlv493dMagnetic3DSensor.begin(); - Tlv493dMagnetic3DSensor.setAccessMode(Tlv493dMagnetic3DSensor.MASTERCONTROLLEDMODE); - Tlv493dMagnetic3DSensor.disableTemp(); + // *** + + sensor.begin(); + sensor.disableTemp(); } +int getDelay(char *) +{ + Serial.print(MEASDELAY, 7); + Serial.println("#"); + Serial.flush(); +} + +int getData(char *) +{ + unsigned long start; + int16_t x = 0, y = 0, z = 0; + int16_t x_1 = 0, y_1 = 0, z_1 = 0; + int32_t sumX = 0, sumY = 0, sumZ = 0; + int32_t sumXX = 0, sumYY = 0, sumZZ = 0; + float varX = 0, varY = 0, varZ = 0; + float meanX = 0, meanY = 0, meanZ = 0; -int getData(char*) { - Tlv493dMagnetic3DSensor.updateData(); - unsigned long measDelay = Tlv493dMagnetic3DSensor.getMeasurementDelay(); - unsigned long start = millis(); + // updateData reads values from sensor and reading triggers next measurement + sensor.updateData(); + delay(MEASDELAY); + sensor.updateData(); - // TODO perform measurement + //storing first measurement as approximation of mean value + x_1 = sensor.getRawX(); + y_1 = sensor.getRawY(); + z_1 = sensor.getRawZ(); - Serial.write(Tlv493dMagnetic3DSensor.getRawX()); - Serial.write(Tlv493dMagnetic3DSensor.getRawY()); - Serial.write(Tlv493dMagnetic3DSensor.getRawZ()); - Serial.println("#"); - Serial.flush(); + for (int i = 0; i < sample_size; i += 1) + { + sensor.updateData(); + start = millis(); + + x = sensor.getRawX()-x_1; + y = sensor.getRawY()-y_1; + z = sensor.getRawZ()-z_1; - unsigned long end = millis(); - if (end - start < measDelay) { - delay(end - start); + sumX += x; + sumY += y; + sumZ += z; + + sumXX += x * x; + sumYY += y * y; + sumZZ += z * z; + //waiting until new data is ready in the sensor + while( millis() 0 && value_int <= MAX_SAMPLE_SIZE) + { + sample_size = value_int; + } + Serial.print(sample_size); + Serial.println("#"); + Serial.flush(); +} - -void loop() { +void loop() +{ serialCommand(); } diff --git a/config/CalibCube/Protocols/CalibCubeProtocol.toml b/config/CalibCube/Protocols/CalibCubeProtocol.toml new file mode 100644 index 00000000..44c83dd4 --- /dev/null +++ b/config/CalibCube/Protocols/CalibCubeProtocol.toml @@ -0,0 +1,9 @@ +name = "Du" +type = "TDesignCubeProtocol" +description = "protocol for measuring fields with the cube." +targetScanner = "CalibCube" +sequence = "DummySequence" + +controlTx = false +fgFrames = 1 +bgFrames = 1 \ No newline at end of file diff --git a/config/CalibCube/Scanner.toml b/config/CalibCube/Scanner.toml new file mode 100644 index 00000000..d66d2624 --- /dev/null +++ b/config/CalibCube/Scanner.toml @@ -0,0 +1,839 @@ +[General] +boreSize = "70mm" +facility = "Institute for Biomedical Imaging" +manufacturer = "IBI" +name = "CalibCube" +topology = "FFP" +gradient = "42T/m" +datasetStore = "/home/v/Dokumente/BA/datastore" +defaultSequence = "1DSequence" +defaultProtocol = "MPIMeasurement" +producerThreadID = 2 +consumerThreadID = 3 +protocolThreadID = 4 + +[Devices] +initializationOrder = [ + "ard_pool", + "sensor1", + "sensor2", + "sensor3", + "sensor4", + "sensor5", + "sensor6", + "sensor7", + "sensor8", + "sensor9", + "sensor10", + "sensor11", + "sensor12", + "sensor13", + "sensor14", + "sensor15", + "sensor16", + "sensor17", + "sensor18", + "sensor19", + "sensor20", + "sensor21", + "sensor22", + "sensor23", + "sensor24", + "sensor25", + "sensor26", + "cube", +] + +[Devices.ard_pool] +deviceType = "SerialPortPool" +blacklist = [] + +[Devices.cube] +dependencies = [ + "sensor1", + "sensor2", + "sensor3", + "sensor4", + "sensor5", + "sensor6", + "sensor7", + "sensor8", + "sensor9", + "sensor10", + "sensor11", + "sensor12", + "sensor13", + "sensor14", + "sensor15", + "sensor16", + "sensor17", + "sensor18", + "sensor19", + "sensor20", + "sensor21", + "sensor22", + "sensor23", + "sensor24", + "sensor25", + "sensor26", +] +deviceType = "TDesignCube" +T = 6 +N = 26 +radius = "45.00mm" +sampleSize = 500 + +[Devices.sensor1] +dependencies = ["ard_pool"] +positionID = 1 +position = [-27.7, 4.54, 35.17] +deviceType = "ArduinoGaussMeter" +description = "000591152818" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + 0.016267661649074543, + 0.05983558797138986, + -0.05846225315440825, +] +calibration = [ + 0.1274596772714161, + 0.004583083681582869, + -0.002515841133667178, + 0.004677729944059288, + -0.12717276995766122, + 0.004620833525539426, + 0.0014622628826238583, + 0.004458485814247349, + 0.12447605890744025, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor2] +position = [17.78, 21.72, 35.17] +dependencies = ["ard_pool"] +positionID = 2 +deviceType = "ArduinoGaussMeter" +description = "000591153050" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.06251699474741296, + 0.08473138995432242, + 0.14004803136698254, +] +calibration = [ + 0.12445353735332422, + 0.0040478498508808155, + -0.0025769904588185365, + 0.003572688637932503, + -0.12404959211982101, + 0.003933475380712132, + 0.0013572013971591141, + 0.004478584245655492, + 0.11928058441671796, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor3] +dependencies = ["ard_pool"] +positionID = 3 +position = [9.92, -26.26, 35.17] +deviceType = "ArduinoGaussMeter" +description = "000591152804" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.10360856703701277, + -0.04966559042213319, + 0.1196129626330971, +] +calibration = [ + 0.12145628753860568, + 0.002894788252528038, + -0.0012550766961374217, + 0.006884740470811177, + -0.12183204388417378, + 0.000835873700428676, + -0.0006454471112704357, + 0.0019053631411839011, + 0.12512228201334183, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor4] +dependencies = ["ard_pool"] +positionID = 4 +position = [-18.74, 29.96, 27.85] +deviceType = "ArduinoGaussMeter" +description = "000591153036" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +calibration = [ + 0.1193881221604956, + 0.0038959080794159877, + -0.002405824422574261, + 0.004017260430757977, + -0.11954412242536172, + 0.005007750045816211, + 0.003207682610386789, + 0.003968429113480924, + 0.11861587322331456, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor5] +dependencies = ["ard_pool"] +positionID = 5 +position = [16.58, -31.21, 27.85] +deviceType = "ArduinoGaussMeter" +description = "000591152900" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.11175066548695481, + 0.0006928170744047621, + 0.2556224942119227, +] +calibration = [ + 0.11409187878874064, + 0.004029216479061814, + -0.0023818621736909386, + 0.0040765688865262465, + -0.11430970556171086, + 0.0037508327497473935, + 0.0012294671783964315, + 0.006376335041233221, + 0.11473792920006712, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor6] +dependencies = ["ard_pool"] +positionID = 6 +position = [35.32, 1.25, 27.85] +deviceType = "ArduinoGaussMeter" +description = "000591152773" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.07811756516536089, + 0.06052058566672786, + -0.02254532031918051, +] +calibration = [ + 0.12462818380081012, + 0.0014440760989957709, + -0.0007426855311287432, + 0.001600522847027823, + -0.12463218582629801, + 0.003399491752575622, + 0.0005283740187647149, + 0.004944213131627913, + 0.12194107123430963, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor7] +dependencies = ["ard_pool"] +positionID = 7 +position = [-43.89, 9.8, 1.64] +deviceType = "ArduinoGaussMeter" +description = "000591152905" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.03228670338789678, + 0.16282712751388917, + 0.08755835508613954, +] +calibration = [ + 0.126111275647657, + 0.004107199861945852, + -0.0035815161368010647, + 0.004211010316022731, + -0.12523287516529574, + 0.003937637826459097, + 0.0016586019387210603, + 0.005031549241089919, + 0.12031537280905144, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor8] +dependencies = ["ard_pool"] +positionID = 8 +position = [30.43, 33.11, 1.64] +deviceType = "ArduinoGaussMeter" +description = "000591152786" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.050301288735078956, + 0.007242721671125767, + 0.05134387841903545, +] +calibration = [ + 0.123576730357644, + 0.003988330168575955, + -0.0031380314190677747, + 0.0038521766776687025, + -0.12350115321197448, + 0.00363048271780163, + 0.0009221069107641911, + 0.004869635623593624, + 0.11815824410919311, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor9] +dependencies = ["ard_pool"] +positionID = 9 +position = [13.46, -42.91, 1.64] +deviceType = "ArduinoGaussMeter" +description = "000591106144" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.08063851341355473, + -0.09457656907113253, + 0.08909220361954753, +] + + +calibration = [ + 0.12244391471572519, + 0.0029256498113505525, + -0.00022167416408131835, + 0.003097402097904784, + -0.12244105705036513, + 0.004692789310972198, + -0.00037636118491695715, + 0.005000546026764026, + 0.12202206388737671, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor10] +dependencies = ["ard_pool"] +positionID = 10 +position = [33.78, -25.48, 15.31] +deviceType = "ArduinoGaussMeter" +description = "000591152925" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 + + +calibration = [ + 0.12390559353861216, + 0.004581956020932778, + -0.0031437334736553065, + 0.004087690068975834, + -0.12444335130047646, + 0.004286696244503667, + 0.0022119654788205064, + 0.005275299244033051, + 0.11731632250969505, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor11] +dependencies = ["ard_pool"] +positionID = 11 +position = [5.18, 42.0, 15.31] +deviceType = "ArduinoGaussMeter" +description = "000591152752" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + 0.0076351062938645525, + 0.05254555526380801, + -0.09420822368210524, +] + +calibration = [ + 0.11774821988265959, + 0.0024425729269259436, + -0.0018912320622383315, + 0.0029534267545576723, + -0.11799978886980497, + 0.003950839239519023, + 0.001203904842851989, + 0.003375869444462285, + 0.1182349580911541, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor12] +dependencies = ["ard_pool"] +positionID = 12 +position = [-38.96, -16.51, 15.31] +deviceType = "ArduinoGaussMeter" +description = "000591152836" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + 0.040216124945037623, + 0.010318151687317197, + 0.3902923000930719, +] +calibration = [ + 0.12784639522312896, + 0.005860231879385202, + -0.0024065830570815998, + 0.005832152993380663, + -0.12763591649437453, + 0.004513838599449157, + 0.0003537124562931949, + 0.005421453109422933, + 0.1277597911361169, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor13] +dependencies = ["ard_pool"] +positionID = 13 +position = [0, 0, 45.0] +deviceType = "ArduinoGaussMeter" +description = "000591153208" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + 0.05787168087787163, + 0.007782026420615045, + -0.174936145990533, +] +calibration = [ + 0.12569098195219294, + 0.005233531681438331, + -0.0022562058299639195, + 0.0047181079779809775, + -0.12529562541963896, + 0.004980659585153636, + 0.0018033364559025217, + 0.004001198368571654, + 0.12797773298852042, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor14] +dependencies = ["ard_pool"] +positionID = 14 +position = [0, 0, -45.0] +deviceType = "ArduinoGaussMeter" +description = "000591153053" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.09408679131693455, + 0.09262779647023484, + 0.10250268720363576, +] + +calibration = [ + 0.12390788420587295, + 0.00429244965132327, + -0.0014021136965981487, + 0.004145760929457313, + -0.12397944754199161, + 0.003201866497177015, + -0.00020880295332797763, + 0.0038073858276590575, + 0.12736931384524286, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor15] +dependencies = ["ard_pool"] +positionID = 15 +position = [38.96, -16.51, -15.31] +deviceType = "ArduinoGaussMeter" +description = "000591153000" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + 0.11192198667290201, + 0.05873463612139693, + 0.13051974163192132, +] +calibration = [ + 0.1248272449279698, + 0.004237326334326998, + -0.002162055189338484, + 0.004400230004560484, + -0.12490382439755691, + 0.004786338222452498, + 0.0029200969178976, + 0.0031202007013232513, + 0.12505013960877226, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor16] +dependencies = ["ard_pool"] +positionID = 16 +position = [-5.18, 42.0, -15.31] +deviceType = "ArduinoGaussMeter" +description = "000591153086" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.07173692062403533, + -0.10378175361573969, + 0.097268874404342, +] + +calibration = [ + 0.12353271863668144, + 0.003804023770068385, + -0.0007725229368607597, + 0.00479721810049492, + -0.12389040127121184, + 0.0046117109853350624, + 0.0005371490690878517, + 0.004186216311391714, + 0.12677553101043268, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor17] +dependencies = ["ard_pool"] +positionID = 17 +position = [-33.78, -25.48, -15.31] +deviceType = "ArduinoGaussMeter" +description = "000591152858" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.1266129628874156, + 0.03167140604876576, + -0.13144707745193573, +] +calibration = [ + 0.12270692514840652, + 0.004445179696612989, + -0.0025042201916963217, + 0.004950615953220393, + -0.12226284432233685, + 0.003244271456907889, + 0.0005597997123740271, + 0.0048048138251897896, + 0.11926031137762858, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor18] +dependencies = ["ard_pool"] +positionID = 18 +position = [-13.46, -42.91, -1.64] +deviceType = "ArduinoGaussMeter" +description = "000591152745" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.11094011894524748, + 0.04741175004255708, + 0.1164625238871334, +] +calibration = [ + 0.12041932702569226, + 0.0024481330321771888, + -0.000682491637228647, + 0.0031058747870189862, + -0.12006669578003344, + 0.0042715043163949066, + -0.0006503311957971996, + 0.00523488015666569, + 0.1220312806847921, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor19] +dependencies = ["ard_pool"] +positionID = 19 +position = [-30.43, 33.11, -1.64] +deviceType = "ArduinoGaussMeter" +description = "000591153163" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.0005077088500865267, + 0.007655077618018224, + 0.08752565665751846, +] +calibration = [ + 0.1177684010365977, + 0.0044199856753150855, + -0.0014037463632525064, + 0.0047866493162295135, + -0.11810754084387778, + 0.004763458223521106, + 0.0011860103418805592, + 0.004664678798574635, + 0.11566904970266322, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor20] +dependencies = ["ard_pool"] +positionID = 20 +position = [43.89, 9.8, -1.64] +deviceType = "ArduinoGaussMeter" +description = "000591152865" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.009222994401552144, + 0.1162432436837035, + 0.11483458976344611, +] +calibration = [ + 0.12466952768825788, + 0.004985170608510563, + -0.003663669897485981, + 0.005235246102733066, + -0.12483181193487261, + 0.004323413410213953, + 0.0019777288062626844, + 0.005362389732119592, + 0.11662291695309487, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor21] +dependencies = ["ard_pool"] +positionID = 21 +position = [-35.32, 1.25, -27.85] +deviceType = "ArduinoGaussMeter" +description = "000591152814" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.09623373875156094, + -0.017571198598100926, + 0.10795049731508409, +] +calibration = [ + 0.12804902776435978, + 0.006064737083108405, + -0.003059716433604519, + 0.004404445403647393, + -0.12787317745357418, + 0.004804013689090996, + 0.0015268475325486946, + 0.0053093256307858785, + 0.12712766185830032, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor22] +dependencies = ["ard_pool"] +positionID = 22 +position = [16.58, -31.21, -27.85] +deviceType = "ArduinoGaussMeter" +description = "000591153184" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.016120927805560212, + 0.029415934057913852, + 0.09925101870228746, +] +calibration = [ + 0.12265690001211238, + 0.0018839788599497817, + -0.004233899483951015, + 0.0022116137078271466, + -0.1221229452570502, + 0.00251519728469533, + 0.0019562815646702275, + 0.0035158496326256053, + 0.1237546035502813, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor23] +dependencies = ["ard_pool"] +positionID = 23 +position = [18.74, 29.96, -27.85] +deviceType = "ArduinoGaussMeter" +description = "000591152914" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.11860001687513623, + -0.07604163332416954, + 0.10745277327895555, +] +calibration = [ + 0.12021451682605735, + 0.004982661671389753, + -0.003367054241397645, + 0.005134749924187959, + -0.12069178101028209, + 0.0031151188762121042, + 0.002565004060018465, + 0.004370947811472259, + 0.1158821244292794, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor24] +dependencies = ["ard_pool"] +positionID = 24 +position = [-9.92, -26.26, -35.17] +deviceType = "ArduinoGaussMeter" +description = "000591152820" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.14967982391304302, + -0.020045288539361418, + 0.11583690253273501, +] +calibration = [ + 0.117404061511546, + 0.003162778177148975, + -0.0027539062251364646, + 0.0035986026769903004, + -0.11788251648311379, + 0.003369453596198593, + 0.0011353214325678777, + 0.005356662139827337, + 0.117581616474412, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor25] +dependencies = ["ard_pool"] +positionID = 25 +position = [-17.78, 21.72, -35.17] +deviceType = "ArduinoGaussMeter" +description = "000591152996" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +biasCalibration = [ + -0.03639818354549921, + -0.052990255942443824, + 0.06446197954475656, +] +calibration = [ + 0.1219427952740972, + 0.0031995346119920768, + -0.0009550787108900678, + 0.0031151411386121986, + -0.12176984400544262, + 0.0038424014855834, + 0.0006075012327269654, + 0.004017172755673142, + 0.11906107995918964, +] +rotation = [-1, 0, 0, 0, 0, 1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +[Devices.sensor26] +dependencies = ["ard_pool"] +positionID = 26 +position = [27.7, 4.54, -35.17] +deviceType = "ArduinoGaussMeter" +description = "000591153059" +baudrate = 9600 +timeout_ms = 5000 +sampleSize = 100 +##CALIBRATION IS ONLY BASED ON MEAN OF THE OTHER SENSORS +##SENSOR 26 MUST REMEASURED +biasCalibration = [ + -0.03639818354549921, + -0.052990255942443824, + 0.06446197954475656, +] +calibration = [ + 0.12723618674758644, + 0.003612691174133794, + -0.0021100796862250355, + 0.004152317594997159, + -0.12418959384892034, + 0.0036313583295693886, + 0.0012341975010427154, + 0.004690560170016473, + 0.12520873498746155, +] +rotation = [1, 0, 0, 0, 0, -1, 0, 1, 0] +translation = [0, 0, 0, 0, 0, 0, 0, 0, 0] + +#POS - ID +#1 - 000591152818 +#2 - 000591153050 +#3 - 000591152804 +#4 - 000591153036 +#5 - 000591152900 +#6 - 000591152773 +#7 - 000591152905 +#8 - 000591152786 +#9 - 000591106144 +#10 - 000591152925 +#11 - 000591152752 +#12 - 000591152836 +#13 - 000591153208 +#14 - 000591153053 +#15 - 000591153000 +#16 - 000591153086 +#17 - 000591152858 +#18 - 000591152745 +#19 - 000591153163 +#20 - 000591152865 +#21 - 000591152814 +#22 - 000591153184 +#23 - 000591152914 +#24 - 000591152820 +#25 - 000591152996 +#26 - 000591153059 diff --git a/config/DummyCalibCube/Scanner.toml b/config/DummyCalibCube/Scanner.toml new file mode 100644 index 00000000..be575937 --- /dev/null +++ b/config/DummyCalibCube/Scanner.toml @@ -0,0 +1,244 @@ +[General] +boreSize = "70mm" +facility = "Institute for Biomedical Imaging" +manufacturer = "IBI" +name = "DummyCalibCube" +topology = "FFP" +gradient = "42T/m" +datasetStore = "" +defaultSequence = "1DSequence" +defaultProtocol = "MPIMeasurement" +producerThreadID = 2 +consumerThreadID = 3 +protocolThreadID = 4 + +[Devices] +initializationOrder = [ + "ard_pool", + "sensor1", + "sensor2", + "sensor3", + "sensor4", + "sensor5", + "sensor6", + "sensor7", + "sensor8", + "sensor9", + "sensor10", + "sensor11", + "sensor12", + "sensor13", + "sensor14", + "sensor15", + "sensor16", + "sensor17", + "sensor18", + "sensor19", + "sensor20", + "sensor21", + "sensor22", + "sensor23", + "sensor24", + "sensor25", + "sensor26", + "cube", +] + +[Devices.ard_pool] +deviceType = "SerialPortPool" +blacklist = [] + +[Devices.cube] +dependencies = [ + "sensor1", + "sensor2", + "sensor3", + "sensor4", + "sensor5", + "sensor6", + "sensor7", + "sensor8", + "sensor9", + "sensor10", + "sensor11", + "sensor12", + "sensor13", + "sensor14", + "sensor15", + "sensor16", + "sensor17", + "sensor18", + "sensor19", + "sensor20", + "sensor21", + "sensor22", + "sensor23", + "sensor24", + "sensor25", + "sensor26" +] +deviceType = "TDesignCube" +T = 6 +N = 26 +radius = "45.00mm" +sampleSize = 500 + +[Devices.sensor1] +dependencies = ["ard_pool"] +positionID = 1 +deviceType = "DummyGaussMeter" + +[Devices.sensor2] +dependencies = ["ard_pool"] +positionID = 2 +deviceType = "DummyGaussMeter" + + +[Devices.sensor3] +dependencies = ["ard_pool"] +positionID = 3 +deviceType = "DummyGaussMeter" + +[Devices.sensor4] +dependencies = ["ard_pool"] +positionID = 4 +deviceType = "DummyGaussMeter" + +[Devices.sensor5] +dependencies = ["ard_pool"] +positionID = 5 +deviceType = "DummyGaussMeter" + +[Devices.sensor6] +dependencies = ["ard_pool"] +positionID = 6 +deviceType = "DummyGaussMeter" + +[Devices.sensor7] +dependencies = ["ard_pool"] +positionID = 7 +deviceType = "DummyGaussMeter" + +[Devices.sensor8] +dependencies = ["ard_pool"] +positionID = 8 +deviceType = "DummyGaussMeter" + +[Devices.sensor9] +dependencies = ["ard_pool"] +positionID = 9 +deviceType = "DummyGaussMeter" + +[Devices.sensor10] +dependencies = ["ard_pool"] +positionID = 10 +deviceType = "DummyGaussMeter" + +[Devices.sensor11] +dependencies = ["ard_pool"] +positionID = 11 +deviceType = "DummyGaussMeter" + +[Devices.sensor12] +dependencies = ["ard_pool"] +positionID = 12 +deviceType = "DummyGaussMeter" + +[Devices.sensor13] +dependencies = ["ard_pool"] +positionID = 13 +deviceType = "DummyGaussMeter" + +[Devices.sensor14] +dependencies = ["ard_pool"] +positionID = 14 +deviceType = "DummyGaussMeter" + +[Devices.sensor15] +dependencies = ["ard_pool"] +positionID = 15 +deviceType = "DummyGaussMeter" + +[Devices.sensor16] +dependencies = ["ard_pool"] +positionID = 16 +deviceType = "DummyGaussMeter" + +[Devices.sensor17] +dependencies = ["ard_pool"] +positionID = 17 +deviceType = "DummyGaussMeter" + +[Devices.sensor18] +dependencies = ["ard_pool"] +positionID = 18 +deviceType = "DummyGaussMeter" + +[Devices.sensor19] +dependencies = ["ard_pool"] +positionID = 19 +deviceType = "DummyGaussMeter" + +[Devices.sensor20] +dependencies = ["ard_pool"] +positionID = 20 +deviceType = "DummyGaussMeter" + +[Devices.sensor21] +dependencies = ["ard_pool"] +positionID = 21 +deviceType = "DummyGaussMeter" + +[Devices.sensor22] +dependencies = ["ard_pool"] +positionID = 22 +deviceType = "DummyGaussMeter" + +[Devices.sensor23] +dependencies = ["ard_pool"] +positionID = 23 +deviceType = "DummyGaussMeter" + +[Devices.sensor24] +dependencies = ["ard_pool"] +positionID = 24 +deviceType = "DummyGaussMeter" + +[Devices.sensor25] +dependencies = ["ard_pool"] +positionID = 25 +deviceType = "DummyGaussMeter" + +[Devices.sensor26] +dependencies = ["ard_pool"] +positionID = 26 +deviceType = "DummyGaussMeter" + + +#POS - ID +#1 - 000591152818 +#2 - 000591153050 +#3 - 000591152804 +#4 - 000591153036 +#5 - 000591152900 +#6 - 000591152773 +#7 - 000591152905 +#8 - 000591152786 +#9 - 000591106144 +#10 - 000591152925 +#11 - 000591152752 +#12 - 000591152836 +#13 - 000591153208 +#14 - 000591153053 +#15 - 000591153000 +#16 - 000591153086 +#17 - 000591152858 +#18 - 000591152745 +#19 - 000591153163 +#20 - 000591152865 +#21 - 000591152814 +#22 - 000591153184 +#23 - 000591152914 +#24 - 000591152820 +#25 - 000591152996 +#26 - 000591153059 diff --git a/src/Devices/Control/Temperature/ArduinoTemperatureController.jl b/src/Devices/Control/Temperature/ArduinoTemperatureController.jl index f210b20b..8f67a10e 100644 --- a/src/Devices/Control/Temperature/ArduinoTemperatureController.jl +++ b/src/Devices/Control/Temperature/ArduinoTemperatureController.jl @@ -117,7 +117,7 @@ end function retrieveTemps(controller::ArduinoTemperatureController, query::AbstractString = "GET:ALLTEMPS") TempDelim = "," # TODO Retrieve temp properly - Temps = sendCommand(controller.ard, query) + Temps = queryCommand(controller.ard, query) result = tryparse.(Float64,split(Temps,TempDelim)) result = map(x -> isnothing(x) ? 0.0 : x, result) return result @@ -127,7 +127,7 @@ export setMaximumTemps function setMaximumTemps(controller::ArduinoTemperatureController, maxTemps::Array) if length(maxTemps) == controller.params.numSensors maxTempString= join(maxTemps, ",") - ack = sendCommand(controller.ard, "SET:TMAX:<"*maxTempString*">") + ack = queryCommand(controller.ard, "SET:TMAX:<"*maxTempString*">") if parse(Bool, ack) @info "Set max temp for ArduinoTemperatureController $(deviceID(controller))." return true @@ -160,7 +160,7 @@ export setTargetTemps function setTargetTemps(controller::ArduinoTemperatureController, targetTemps::Vector{Int64}) if length(targetTemps) == controller.params.numSensors targetTempString= join(targetTemps, ",") - ack = sendCommand(controller.ard, "SET:TSET:<"*targetTempString*">") + ack = queryCommand(controller.ard, "SET:TSET:<"*targetTempString*">") if parse(Bool, ack) @info "Set target temp for ArduinoTemperatureController $(deviceID(controller))." return true @@ -193,7 +193,7 @@ function setControlMode(controller::ArduinoTemperatureController, mode::Temperat else throw(ScannerConfigurationError("Temp Controller does not support mode $mode")) end - return sendCommand(controller.ard, cmd) + return queryCommand(controller.ard, cmd) end #function getControlMode(controller::ArduinoTemperatureController) @@ -202,13 +202,13 @@ end export resetOvertemp function resetOvertemp(controller::ArduinoTemperatureController) - return parse(Bool, sendCommand(controller.ard, "RESET:OVERTEMP")) + return parse(Bool, queryCommand(controller.ard, "RESET:OVERTEMP")) end function enableControl(controller::ArduinoTemperatureController) - return sendCommand(controller.ard, "SET:ENABLE_HEATING:<1>") + return queryCommand(controller.ard, "SET:ENABLE_HEATING:<1>") end function disableControl(controller::ArduinoTemperatureController) - return sendCommand(controller.ard, "SET:ENABLE_HEATING:<0>") + return queryCommand(controller.ard, "SET:ENABLE_HEATING:<0>") end \ No newline at end of file diff --git a/src/Devices/GaussMeter/ArduinoGaussMeter.jl b/src/Devices/GaussMeter/ArduinoGaussMeter.jl index adc4a7a1..6a17d2b4 100644 --- a/src/Devices/GaussMeter/ArduinoGaussMeter.jl +++ b/src/Devices/GaussMeter/ArduinoGaussMeter.jl @@ -1,40 +1,57 @@ -export ArduinoGaussMeter, ArduinoGaussMeterParams, ArduinoGaussMeterDirectParams, ArduinoGaussMeterPoolParams, ArduinoGaussMeterDescriptionParams +export ArduinoGaussMeter, ArduinoGaussMeterParams, ArduinoGaussMeterDirectParams, ArduinoGaussMeterPoolParams, ArduinoGaussMeterDescriptionParams, getRawXYZValues, getXYZValues, triggerMeasurment, receive, receiveMeasurment, setSampleSize, getSampleSize, getTemperature,reset + + abstract type ArduinoGaussMeterParams <: DeviceParams end + Base.@kwdef struct ArduinoGaussMeterDirectParams <: ArduinoGaussMeterParams portAddress::String - coordinateTransformation::Matrix{Float64} = Matrix{Float64}(I,(3,3)) - calibration::Vector{Float64} = [0.098, 0.098, 0.098] - + position::Int64 = 1 + calibration::Matrix{Float64} = Matrix{Float64}(I, (3, 3)) * 0.125 + rotation::Matrix{Float64} = Matrix{Float64}(I, (3, 3)) + translation::Matrix{Float64} = Matrix{Float64}(I, (3, 3)) + biasCalibration = Vector{Float64} = [0.0, 0.0, 0.0] + sampleSize::Int @add_serial_device_fields "#" @add_arduino_fields "!" "*" end ArduinoGaussMeterDirectParams(dict::Dict) = params_from_dict(ArduinoGaussMeterDirectParams, dict) -Base.@kwdef struct ArduinoGaussMeterPoolParams <: ArduinoGaussMeterParams - position::Int64 - coordinateTransformation::Matrix{Float64} = Matrix{Float64}(I,(3,3)) - calibration::Vector{Float64} = [0.098, 0.098, 0.098] - - @add_serial_device_fields "#" - @add_arduino_fields "!" "*" -end -ArduinoGaussMeterPoolParams(dict::Dict) = params_from_dict(ArduinoGaussMeterPoolParams, dict) Base.@kwdef struct ArduinoGaussMeterDescriptionParams <: ArduinoGaussMeterParams description::String - coordinateTransformation::Matrix{Float64} = Matrix{Float64}(I,(3,3)) - calibration::Vector{Float64} = [0.098, 0.098, 0.098] + positionID::Int + position::Vector{Float64} = [0.0, 0.0, 0.0] + calibration::Matrix{Float64} = Matrix{Float64}(I, (3, 3)) * 0.125 + rotation::Matrix{Float64} = Matrix{Float64}(I, (3, 3)) + translation::Matrix{Float64} = Matrix{Float64}(I, (3, 3)) + biasCalibration::Vector{Float64} = [0.0, 0.0, 0.0] + sampleSize::Int @add_serial_device_fields "#" @add_arduino_fields "!" "*" end -ArduinoGaussMeterDescriptionParams(dict::Dict) = params_from_dict(ArduinoGaussMeterDescriptionParams, dict) + +function ArduinoGaussMeterDescriptionParams(dict::Dict) + if haskey(dict, "translation") + dict["translation"] = Float64.(reshape(dict["translation"], 3, 3)) + end + if haskey(dict, "rotation") + dict["rotation"] = Float64.(reshape(dict["rotation"], 3, 3)) + end + if haskey(dict, "calibration") + dict["calibration"] = Float64.(reshape(dict["calibration"], 3, 3))' + end + params_from_dict(ArduinoGaussMeterDescriptionParams, dict) +end Base.@kwdef mutable struct ArduinoGaussMeter <: GaussMeter @add_device_fields ArduinoGaussMeterParams - ard::Union{SimpleArduino, Nothing} = nothing + ard::Union{SimpleArduino,Nothing} = nothing + sampleSize::Int = 0 + measdelay = 1 + measurementTriggered::Bool = false end neededDependencies(::ArduinoGaussMeter) = [] @@ -43,9 +60,11 @@ optionalDependencies(::ArduinoGaussMeter) = [SerialPortPool] function _init(gauss::ArduinoGaussMeter) params = gauss.params sd = initSerialDevice(gauss, params) - @info "Connection to ArduinoGaussMeter established." - ard = SimpleArduino(;commandStart = params.commandStart, commandEnd = params.commandEnd, sd = sd) + @info "Connection to ArduinoGaussMeter established." + ard = SimpleArduino(; commandStart=params.commandStart, commandEnd=params.commandEnd, sd=sd) gauss.ard = ard + gauss.measdelay = parse(Int64, queryCommand(ard, "DELAY*")) + setSampleSize(gauss, params.sampleSize) end function initSerialDevice(gauss::ArduinoGaussMeter, params::ArduinoGaussMeterDirectParams) @@ -54,10 +73,6 @@ function initSerialDevice(gauss::ArduinoGaussMeter, params::ArduinoGaussMeterDir return sd end -function initSerialDevice(gauss::ArduinoGaussMeter, params::ArduinoGaussMeterPoolParams) - return initSerialDevice(gauss, "!VERSION*", "HALLSENS:1:$(params.position)") -end - function initSerialDevice(gauss::ArduinoGaussMeter, params::ArduinoGaussMeterDescriptionParams) sd = initSerialDevice(gauss, params.description) checkSerialDevice(gauss, sd) @@ -67,9 +82,10 @@ end function checkSerialDevice(gauss::ArduinoGaussMeter, sd::SerialDevice) try reply = query(sd, "!VERSION*") - if !(startswith(reply, "HALLSENS:1")) - close(sd) - throw(ScannerConfigurationError(string("Connected to wrong Device", reply))) + """todo fix number""" + if !(startswith(reply, "HALLSENS:")) + close(sd) + throw(ScannerConfigurationError(string("Connected to wrong Device", reply))) end return sd catch e @@ -77,11 +93,149 @@ function checkSerialDevice(gauss::ArduinoGaussMeter, sd::SerialDevice) end end -function getXYZValues(gauss::ArduinoGaussMeter) - data = zeros(Int16, 3) - sendCommand(gauss.ard, "DATA", data) - #TODO +""" + getRawXYZValues(gauss::ArduinoGaussMeter)::Array{Float64,1} + + start measurment in sensor 'gauss' and returns raw measurment + + #returns + [x_raw_mean,y_raw_mean,z_raw_mean, x_raw_var,y_raw_var,z_raw_var] +""" +function getRawXYZValues(gauss::ArduinoGaussMeter) + + triggerMeasurment(gauss) + data = receive(gauss) return data end +""" + getXYZValues(gauss::ArduinoGaussMeter)::Array{Float64,1} + start and returns calibrated measurment for 'gauss'-sensor in mT + + #returns + [x_mean,y_mean,z_mean, x_var,y_var,z_var] +""" +function getXYZValues(gauss::ArduinoGaussMeter) + data = getRawXYZValues(gauss) + return applyCalibration(gauss, data) +end + + +""" + triggerMeasurment(gauss::ArduinoGaussMeter) + start measurment in sensor 'gauss' + """ +function triggerMeasurment(gauss::ArduinoGaussMeter) + if gauss.measurementTriggered + throw("measurement already triggered, you have to reset the sensor, use reset()") + end + sendCommand(gauss.ard, "DATA") + gauss.measurementTriggered = true +end + + +""" + receiveRawMeasument(gauss::ArduinoGaussMeter)::Array{Float64,1} + + collecting the measurment data for sensor 'gauss' + triggerMeasurment(gauss::ArduinoGaussMeter) has to be called first. + + #returns + [x_raw_mean,y_raw_mean,z_raw_mean, x_raw_var,y_raw_var,z_raw_var] +""" + +function receiveRaWMeasurment(gauss::ArduinoGaussMeter) + if !gauss.measurementTriggered + throw("triggerMeasurment(gauss::ArduinoGaussMeter) has to be called first") + else + temp = get_timeout(gauss.ard) + timeout_ms = max(1000, floor(Int, gauss.sampleSize * gauss.measdelay * 4) + 1) + (timeout_ms) + set_timeout(gauss.ard, timeout_ms) + try + data_strings = split(receive(gauss.ard), ",") + data = [parse(Float64, str) for str in data_strings] + return data + finally + set_timeout(gauss.ard, temp) + gauss.measurementTriggered = false + end + end +end + +function reset(gauss::ArduinoGaussMeter) + if gauss.measurementTriggered + try + receiveRawMeasurment(gauss) + catch + gauss.measurementTriggered = false + end + end +end +""" +receiveMeasurment(gauss::ArduinoGaussMeter)::Array{Float64,1} + collecting, calibrating and returning measurment for 'gauss'-sensor in mT + triggerMeasurment(gauss::ArduinoGaussMeter) has to be called first. + + + #return + [x_mean,y_mean,z_mean, x_var,y_var,z_var] +""" +receiveMeasurment(gauss::ArduinoGaussMeter) = applyCalibration(gauss, receiveRawMeasurment(gauss)) + +""" +applyCalibration(gauss::ArduinoGaussMeter, data::Vector{Float64})::Array{Float64,1} + +calibrate and rotate raw data to mT + +Varianz can't be calibrated + +#returns +[x_mean_c,y_mean_c,z_mean_c] +""" +function applyCalibration(gauss::ArduinoGaussMeter, data::Vector{Float64}) + means = data[1:3] + # TODO Sanity checks on data, does it have the expected size + calibrated_means = gauss.params.rotation * ((gauss.params.calibration * means) + gauss.params.biasCalibration) .* 1.0u"mT" + return calibrated_means +end + + +""" +setSampleSize(gauss::ArduinoGaussMeter, sampleSize::Int)::Int + +sets sample size for measurment + + #Arguments + -`sampleSize` number of mesurments done by the sensor 1=>sample_size<=1024 + -`gauss` sensor + + #return + -updatedSampleSize +""" +function setSampleSize(gauss::ArduinoGaussMeter, sampleSize::Int) + data_string = queryCommand(gauss.ard, "SAMPLES" * string(sampleSize)) + updatedSampleSize = parse(Int, data_string) + if (updatedSampleSize !== sampleSize) + throw(error("wrong sample size set")) + end + gauss.sampleSize = updatedSampleSize + return updatedSampleSize +end + +function getSampleSize(gauss::ArduinoGaussMeter) + return gauss.sampleSize +end + +""" +getTemperature(gauss::ArduinoGaussMeter)::Float32 + +returns tempreture of the sensor, do not expect a high tempreture resolution +""" +function getTemperature(gauss::ArduinoGaussMeter) + temp_str = queryCommand(gauss.ard, "TEMP") + return parse(Float32, temp_str)u"°C" +end + +getPosition(gauss::ArduinoGaussMeter) = gauss.params.position close(gauss::ArduinoGaussMeter) = close(gauss.ard) \ No newline at end of file diff --git a/src/Devices/GaussMeter/DummyGaussMeter.jl b/src/Devices/GaussMeter/DummyGaussMeter.jl index bb8c03ff..e731a18b 100644 --- a/src/Devices/GaussMeter/DummyGaussMeter.jl +++ b/src/Devices/GaussMeter/DummyGaussMeter.jl @@ -1,7 +1,7 @@ export DummyGaussMeter, DummyGaussMeterParams Base.@kwdef struct DummyGaussMeterParams <: DeviceParams - coordinateTransformation::Matrix{Float64} = Matrix{Float64}(I,(3,3)) + positionID = 0 end DummyGaussMeterParams(dict::Dict) = params_from_dict(DummyGaussMeterParams, dict) @@ -17,10 +17,12 @@ neededDependencies(::DummyGaussMeter) = [] optionalDependencies(::DummyGaussMeter) = [] Base.close(gauss::DummyGaussMeter) = nothing - -getXValue(gauss::DummyGaussMeter) = 1.0u"mT" -getYValue(gauss::DummyGaussMeter) = 2.0u"mT" -getZValue(gauss::DummyGaussMeter) = 3.0u"mT" +function triggerMeasurment(gauss::DummyGaussMeter) + #NOP +end +receiveMeasurment(gauss::DummyGaussMeter) =getXYZValues(gauss) +setSampleSize(gauss::DummyGaussMeter, sampleSize) = sampleSize +getXYZValue(gauss::DummyGaussMeter) = [1.0,u"mT",2.0u"mT",3.0u"mT"] getTemperature(gauss::DummyGaussMeter) = 20.0u"°C" getFrequency(gauss::DummyGaussMeter) = 0.0u"Hz" calculateFieldError(gauss::DummyGaussMeter, magneticField::Vector{<:Unitful.BField}) = 1.0u"mT" \ No newline at end of file diff --git a/src/Devices/GaussMeter/GaussMeter.jl b/src/Devices/GaussMeter/GaussMeter.jl index f8df01fe..78b0c85b 100644 --- a/src/Devices/GaussMeter/GaussMeter.jl +++ b/src/Devices/GaussMeter/GaussMeter.jl @@ -9,14 +9,9 @@ getGaussMeters(scanner::MPIScanner) = getDevices(scanner, GaussMeter) export getGaussMeter getGaussMeter(scanner::MPIScanner) = getDevice(scanner, GaussMeter) -export getXValue -@mustimplement getXValue(gauss::GaussMeter) - -export getYValue -@mustimplement getYValue(gauss::GaussMeter) +export getCube +getCube(scanner::MPIScanner) = getDevice(scanner,TDesignCube) -export getZValue -@mustimplement getZValue(gauss::GaussMeter) export getTemperature @mustimplement getTemperature(gauss::GaussMeter) @@ -28,15 +23,21 @@ export calculateFieldError @mustimplement calculateFieldError(gauss::GaussMeter, magneticField::Vector{<:Unitful.BField}) export getXYZValues -""" -Returns x,y, and z values and applies a coordinate transformation -""" -function getXYZValues(gauss::GaussMeter) - values = [getXValue(gauss), getYValue(gauss), getZValue(gauss)] - return gauss.params.coordinateTransformation*values -end +@mustimplement getXYZValues(gauss::GaussMeter) + + +export getXValue +getXValue(gauss::GaussMeter)=getXYZValues(gauss)[1] + +export getYValue +getYValue(gauss::GaussMeter)=getXYZValues(gauss)[2] + +export getZValue +getZValue(gauss::GaussMeter)=getXYZValues(gauss)[3] + include("DummyGaussMeter.jl") include("SimulatedGaussMeter.jl") include("LakeShore.jl") include("ArduinoGaussMeter.jl") +include("TDesignCube.jl") diff --git a/src/Devices/GaussMeter/LakeShoreF71.jl b/src/Devices/GaussMeter/LakeShoreF71.jl index a81c0ab8..f8cb8665 100644 --- a/src/Devices/GaussMeter/LakeShoreF71.jl +++ b/src/Devices/GaussMeter/LakeShoreF71.jl @@ -90,9 +90,6 @@ function setMeasurementMode(gauss::LakeShoreF71GaussMeter, mode::LakeShoreF71Gau end end -getXValue(gauss::LakeShoreF71GaussMeter) = getXYZValues(gauss)[1] -getYValue(gauss::LakeShoreF71GaussMeter) = getXYZValues(gauss)[2] -getZValue(gauss::LakeShoreF71GaussMeter) = getXYZValues(gauss)[3] function getXYZValues(gauss::LakeShoreF71GaussMeter) if gauss.params.measurementMode == F71_MM_DC diff --git a/src/Devices/GaussMeter/SimulatedGaussMeter.jl b/src/Devices/GaussMeter/SimulatedGaussMeter.jl index 8728cd46..23ba5bf7 100644 --- a/src/Devices/GaussMeter/SimulatedGaussMeter.jl +++ b/src/Devices/GaussMeter/SimulatedGaussMeter.jl @@ -18,9 +18,7 @@ optionalDependencies(::SimulatedGaussMeter) = [] Base.close(gauss::SimulatedGaussMeter) = nothing -getXValue(gauss::SimulatedGaussMeter) = 1.0u"mT" -getYValue(gauss::SimulatedGaussMeter) = 2.0u"mT" -getZValue(gauss::SimulatedGaussMeter) = 3.0u"mT" +getXYZValue(gauss::SimulatedGaussMeter) = [1.0u"mT",2.0u"mT",3.0u"mT"] getTemperature(gauss::SimulatedGaussMeter) = 20.0u"°C" getFrequency(gauss::SimulatedGaussMeter) = 0.0u"Hz" calculateFieldError(gauss::SimulatedGaussMeter, magneticField::Vector{<:Unitful.BField}) = 1.0u"mT" \ No newline at end of file diff --git a/src/Devices/GaussMeter/TDesignCube.jl b/src/Devices/GaussMeter/TDesignCube.jl new file mode 100644 index 00000000..3246fc8b --- /dev/null +++ b/src/Devices/GaussMeter/TDesignCube.jl @@ -0,0 +1,87 @@ +export TDesignCubeParams, TDesignCube, setSampleSize, getSampleSize, getT, getN, getRadius, getPositions, getTemperature, measurment, reset + +Base.@kwdef struct TDesignCubeParams <: DeviceParams + T::Int64 + N::Int64 + radius::typeof(1.0u"mm") = 0.0u"mm" + sampleSize::Int64 = 100 +end +TDesignCubeParams(dict::Dict) = params_from_dict(TDesignCubeParams, dict) + + +Base.@kwdef mutable struct TDesignCube <: Device + @add_device_fields TDesignCubeParams + sensors::Union{Vector{GaussMeter},Nothing} = nothing + sampleSize::Int64 = 100 +end + +neededDependencies(::TDesignCube) = [GaussMeter] +optionalDependencies(::TDesignCube) = [] + +function _init(cube::TDesignCube) + sampleSize = cube.params.sampleSize + sensors = dependencies(cube, GaussMeter) + if length(sensors) != cube.params.N + close.(sensors) # TODO @NH Should not close devices here + throw("missing Sensors") + end + sort!(sensors, by=x -> x.params.positionID) + cube.sensors = sensors + setSampleSize(cube, sampleSize) +end + +export setSampleSize +function setSampleSize(cube::TDesignCube, sampleSize::Int) + for sensor in cube.sensors + returnSampleSize = setSampleSize(sensor, sampleSize) + if returnSampleSize != sampleSize + throw("sensors coud not be updated") + end + end + cube.sampleSize = sampleSize +end + +export getSampleSize +getSampleSize(cube::TDesignCube) = cube.sampleSize + +function getXYZValues(cube::TDesignCube) + measurement = zeros(3, cube.params.N) .* 1.0u"mT" + #triggerMeasurment + triggerMeasurment.(cube.sensors) + #readmeasurement + for (i, sensor) in enumerate(cube.sensors) + measurement[:, i] = receiveMeasurment(sensor) + end + return measurement +end + +getT(cube::TDesignCube) = cube.params.T +getN(cube::TDesignCube) = cube.params.N +getRadius(cube::TDesignCube) = cube.params.radius + +getPositions(cube::TDesignCube) = getPosition.(cube.sensors) +getTemperatures(cube::TDesignCube) = getTemperature.(cube.sensors) + +#starts measument and stores it into a hdf5 file +function measurment(cube, filename, center_position=[0, 0, 0], sampleSize=1000) + setSampleSize(cube, 1000) + data = getXYZValues(cube) + println(data) + h5open(filename, "w") do file + println("hear") + write(file, "/fields", ustrip.(u"T", data))# measured field (size: 3 x #points x #patches) + println("hear2") + println(cube.params.radius) + write(file, "/positions/tDesign/radius", ustrip(u"m", cube.params.radius))# radius of the measured ball + write(file, "/positions/tDesign/N", cube.params.N)# number of points of the t-design + write(file, "/positions/tDesign/t", cube.params.T)# t of the t-design + write(file, "/positions/tDesign/center", center_position)# center of the measured ball + write(file, "/sensor/correctionTranslation", zeros(3, 3)) + end + return measurement +end + +reset(cube::TDesignCube) = reset.(cube.sensors) +function close(cube::TDesignCube) + #NOP +end \ No newline at end of file diff --git a/src/Devices/Robots/BrukerRobot.jl b/src/Devices/Robots/BrukerRobot.jl index 5fb07875..3f99eec3 100644 --- a/src/Devices/Robots/BrukerRobot.jl +++ b/src/Devices/Robots/BrukerRobot.jl @@ -39,7 +39,7 @@ const err = "err?\n" dof(rob::BrukerRobot) = 3 axisRange(rob::BrukerRobot) = rob.params.axisRange defaultVelocity(rob::BrukerRobot) = nothing -_getPosition(rob::BrukerRobot) = sendCommand(rob, BrukerCommand(pos)) +_getPosition(rob::BrukerRobot) = queryCommand(rob, BrukerCommand(pos)) _isReferenced(rob::BrukerRobot) = true _enable(rob::BrukerRobot) = nothing _disable(rob::BrukerRobot) = nothing @@ -50,12 +50,12 @@ _doReferenceDrive(rob::BrukerRobot) = nothing """ Move Bruker Robot to center""" function moveCenter(sd::BrukerRobot) - sendCommand(sd, BrukerCommand(center)) + queryCommand(sd, BrukerCommand(center)) end """ Move Bruker Robot to park""" function movePark(sd::BrukerRobot) - sendCommand(sd, BrukerCommand(park)) + queryCommand(sd, BrukerCommand(park)) end function _moveAbs(rob::BrukerRobot, pos::Vector{<:Unitful.Length}, speed::Union{Vector{<:Unitful.Velocity},Nothing}) @@ -63,7 +63,7 @@ function _moveAbs(rob::BrukerRobot, pos::Vector{<:Unitful.Length}, speed::Union{ @warn "BrukerRobot does not support setting velocities!" end cmd = BrukerCommand("goto $(ustrip(Float64, u"mm", pos[1])),$(ustrip(Float64, u"mm", pos[2])),$(ustrip(Float64, u"mm", pos[3]))\n") - res = sendCommand(rob, cmd) + res = queryCommand(rob, cmd) end """ Not Implemented """ @@ -73,7 +73,7 @@ end """ Send Command `sendCommand(sd::BrukerRobot, brukercmd::BrukerCommand)`""" -function sendCommand(sd::BrukerRobot, brukercmd::BrukerCommand) +function queryCommand(sd::BrukerRobot, brukercmd::BrukerCommand) (result, startmovetime, endmovetime) = _sendCommand(sd, brukercmd) diff --git a/src/Devices/Sensors/Temperature/ArduinoTemperatureSensor.jl b/src/Devices/Sensors/Temperature/ArduinoTemperatureSensor.jl index db346565..beb96bed 100644 --- a/src/Devices/Sensors/Temperature/ArduinoTemperatureSensor.jl +++ b/src/Devices/Sensors/Temperature/ArduinoTemperatureSensor.jl @@ -112,7 +112,7 @@ end function retrieveTemps(sensor::ArduinoTemperatureSensor) TempDelim = "," - Temps = sendCommand(sensor.ard, "GET:ALLTEMPS") + Temps = queryCommand(sensor.ard, "GET:ALLTEMPS") Temps = Temps[7:end] #filter out "TEMPS:" at beginning of answer result = tryparse.(Float64,split(Temps,TempDelim)) @@ -123,7 +123,7 @@ end function setMaximumTemps(sensor::ArduinoTemperatureSensor, maxTemps::Array) if length(maxTemps) == sensor.params.numSensors maxTempString= join(maxTemps, ",") - ack = sendCommand(sensor.ard, "SET:MAXTEMPS:<"*maxTempString*">") + ack = queryCommand(sensor.ard, "SET:MAXTEMPS:<"*maxTempString*">") # TODO check ack? @info "acknowledge of MaxTemps from TempUnit." else @@ -132,7 +132,7 @@ function setMaximumTemps(sensor::ArduinoTemperatureSensor, maxTemps::Array) end function getMaximumTemps(sensor::ArduinoTemperatureSensor) - println(sendCommand(sensor.ard, "GET:MAXTEMPS")) + println(queryCommand(sensor.ard, "GET:MAXTEMPS")) end close(sensor::ArduinoTemperatureSensor) = close(sensor.ard) diff --git a/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnit.jl b/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnit.jl index 60dfbbc5..2b6e7c36 100644 --- a/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnit.jl +++ b/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnit.jl @@ -28,94 +28,94 @@ function parseBool(ard::ArduinoSurveillanceUnit, s::Char) end function arEnableWatchDog(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "ENABLE:WD") + ACQ = queryCommand(Arduino, "ENABLE:WD") checkACQ(Arduino, ACQ) end function arDisableWatchDog(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "DISABLE:WD") + ACQ = queryCommand(Arduino, "DISABLE:WD") checkACQ(Arduino, ACQ) end function getDigital(Arduino::ArduinoSurveillanceUnit, DIO::Int) - DIO = sendCommand(Arduino, "GET:DIGITAL:" * string(DIO)) + DIO = queryCommand(Arduino, "GET:DIGITAL:" * string(DIO)) return DIO; end function getAnalog(Arduino::ArduinoSurveillanceUnit, ADC::Int) - ADC = sendCommand(Arduino, "GET:ANALOG:A" * string(ADC)) + ADC = queryCommand(Arduino, "GET:ANALOG:A" * string(ADC)) return ADC; end function getErrorStatus(Arduino::ArduinoSurveillanceUnit) - Errorcode = sendCommand(Arduino, "GET:STATUS"); + Errorcode = queryCommand(Arduino, "GET:STATUS"); ErrorcodeBool = [parseBool(Arduino, x) for x in Errorcode] return ErrorcodeBool end function resetWatchDog(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "RESET:WD") + ACQ = queryCommand(Arduino, "RESET:WD") checkACQ(Arduino, ACQ) end function enableWatchDog(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "ENABLE:WD") + ACQ = queryCommand(Arduino, "ENABLE:WD") checkACQ(Arduino, ACQ) end function disableWatchDog(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "DISABLE:WD") + ACQ = queryCommand(Arduino, "DISABLE:WD") checkACQ(Arduino, ACQ) end function resetFail(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "RESET:FAIL") + ACQ = queryCommand(Arduino, "RESET:FAIL") checkACQ(Arduino, ACQ) end function disableSurveillance(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "DISABLE:SURVEILLANCE") + ACQ = queryCommand(Arduino, "DISABLE:SURVEILLANCE") checkACQ(Arduino, ACQ) end function enableSurveillance(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "ENABLE:SURVEILLANCE") + ACQ = queryCommand(Arduino, "ENABLE:SURVEILLANCE") checkACQ(Arduino, ACQ) end function getCycletime(Arduino::ArduinoSurveillanceUnit) - tcycle = sendCommand(Arduino, "GET:CYCLETIME") + tcycle = queryCommand(Arduino, "GET:CYCLETIME") return tcycle; end function resetArduino(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "RESET:ARDUINO") + ACQ = queryCommand(Arduino, "RESET:ARDUINO") checkACQ(Arduino, ACQ) end function enableACPower(Arduino::ArduinoSurveillanceUnit) - reply = sendCommand(Arduino, "ENABLE:AC"); + reply = queryCommand(Arduino, "ENABLE:AC"); if !parse(Bool, reply) error("AC could not be enabled. Check SU fail") end end function disableACPower(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "DISABLE:AC"); + ACQ = queryCommand(Arduino, "DISABLE:AC"); checkACQ(Arduino, ACQ) end function enableHeating(ard::ArduinoSurveillanceUnit) - ACQ = sendCommand(ard, "ENABLE:HEATING"); + ACQ = queryCommand(ard, "ENABLE:HEATING"); checkACQ(Arduino, ACQ) end function disableHeating(ard::ArduinoSurveillanceUnit) - ACQ = sendCommand(ard, "DISABLE:HEATING"); + ACQ = queryCommand(ard, "DISABLE:HEATING"); checkACQ(Arduino, ACQ) end # TODO this does not seem to be implemented in external client, check server code function NOTAUS(Arduino::ArduinoSurveillanceUnit) - ACQ = sendCommand(Arduino, "NOTAUS"); + ACQ = queryCommand(Arduino, "NOTAUS"); checkACQ(Arduino, ACQ) end diff --git a/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitExternalTemp.jl b/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitExternalTemp.jl index 5b16dcbd..fb9ccb4c 100644 --- a/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitExternalTemp.jl +++ b/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitExternalTemp.jl @@ -26,7 +26,7 @@ end Base.close(su::ArduinoSurveillanceUnitExternalTemp) = close(su.ard) -sendCommand(su::ArduinoSurveillanceUnitExternalTemp, cmdString::String) = sendCommand(su.ard, cmdString) +queryCommand(su::ArduinoSurveillanceUnitExternalTemp, cmdString::String) = queryCommand(su.ard, cmdString) neededDependencies(::ArduinoSurveillanceUnitExternalTemp) = [ArduinoTemperatureSensor] # could in theory be generic temp sensor optionalDependencies(::ArduinoSurveillanceUnitExternalTemp) = [SerialPortPool] @@ -73,12 +73,12 @@ function getTemperatures(su::ArduinoSurveillanceUnitExternalTemp; names::Bool=fa end function getStatus(su::ArduinoSurveillanceUnitExternalTemp) - status = sendCommand(su,"GET:STATS") + status = queryCommand(su,"GET:STATS") return status end function resetDAQ(su::ArduinoSurveillanceUnitExternalTemp) - ACQ = sendCommand(su,"RESET:RP") + ACQ = queryCommand(su,"RESET:RP") checkACQ(su, ACQ) end diff --git a/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitInternalTemp.jl b/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitInternalTemp.jl index fe00fd30..166c57b7 100644 --- a/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitInternalTemp.jl +++ b/src/Devices/SurveillanceUnit/ArduinoSurveillanceUnitInternalTemp.jl @@ -55,10 +55,10 @@ function _init(su::ArduinoSurveillanceUnitInternalTemp) #end end -sendCommand(su::ArduinoSurveillanceUnitInternalTemp, cmdString::String) = sendCommand(su.ard, cmdString) +queryCommand(su::ArduinoSurveillanceUnitInternalTemp, cmdString::String) = queryCommand(su.ard, cmdString) function getTemperatures(Arduino::ArduinoSurveillanceUnitInternalTemp) # toDo: deprecated - Temps = sendCommand(Arduino, "GET:TEMP") + Temps = queryCommand(Arduino, "GET:TEMP") TempDelim = "T" temp = tryparse.(Float64, split(Temps, TempDelim)) diff --git a/src/Devices/Utils/Arduino.jl b/src/Devices/Utils/Arduino.jl index 331f7a78..35c661f8 100644 --- a/src/Devices/Utils/Arduino.jl +++ b/src/Devices/Utils/Arduino.jl @@ -1,4 +1,4 @@ -export Arduino, sendCommand +export Arduino, queryCommand abstract type Arduino <: Device end @@ -7,16 +7,37 @@ abstract type Arduino <: Device end @mustimplement cmdEnd(ard::Arduino) @mustimplement serialDevice(ard::Arduino) -function sendCommand(ard::Arduino, cmdString::String) +function sendCommand(ard::Arduino,cmdString::String) cmd = cmdStart(ard) * cmdString * cmdEnd(ard) - return query(serialDevice(ard), cmd) + sd = serialDevice(ard) + send(sd, cmd) + return nothing end -function sendCommand(ard::Arduino, cmdString::String, data::AbstractArray) +function receive(ard::Arduino) + sd = serialDevice(ard) + return receive(sd) +end + +function queryCommand(ard::Arduino, cmdString::String) + cmd = cmdStart(ard) * cmdString * cmdEnd(ard) + sd = serialDevice(ard) + return query(sd, cmd) +end + +function queryCommand(ard::Arduino, cmdString::String, data::AbstractArray) cmd = cmdStart(ard) * cmdString * cmdEnd(ard) return query!(serialDevice(ard), cmd, data, delimited = true) end +function set_timeout(ard::Arduino,timeout_ms::Int) + set_timeout_ms(ard.sd,timeout_ms) +end + +function get_timeout(ard::Arduino) + return get_timeout_ms(ard.sd) +end + Base.@kwdef struct SimpleArduino <: Arduino commandStart::String = "!" commandEnd::String = "*" diff --git a/src/Devices/Utils/SerialDevices/SerialDevice.jl b/src/Devices/Utils/SerialDevices/SerialDevice.jl index aa903fe3..df54f500 100644 --- a/src/Devices/Utils/SerialDevices/SerialDevice.jl +++ b/src/Devices/Utils/SerialDevices/SerialDevice.jl @@ -67,6 +67,10 @@ function set_timeout_ms(sd::SerialDevice,timeout_ms::Int) return nothing end +function get_timeout_ms(sd::SerialDevice) + return sd.timeout_ms +end + """ Set character which terminates query. """ @@ -149,8 +153,10 @@ function receiveDelimited(sd::SerialDevice, array::AbstractArray) done = false while bytesavailable(sd.sp) > 0 || !done c = read(sd.sp, 1) + # TODO Implement delim check for multi-character delims if c[1] == UInt8(sd.delim_read[1]) + done = true break end @@ -176,6 +182,7 @@ function query(sd::SerialDevice,cmd) sp_flush(sd.sp, SP_BUF_INPUT) return out finally + sp_flush(sd.sp, SP_BUF_INPUT) unlock(sd.sdLock) end end diff --git a/src/Protocols/Protocol.jl b/src/Protocols/Protocol.jl index 5b4a17af..cf73462a 100644 --- a/src/Protocols/Protocol.jl +++ b/src/Protocols/Protocol.jl @@ -312,4 +312,5 @@ include("MPIForceProtocol.jl") include("RobotMPIMeasurementProtocol.jl") include("RobotBasedProtocol.jl") include("ContinousMeasurementProtocol.jl") -#include("TransferFunctionProtocol.jl") \ No newline at end of file +#include("TransferFunctionProtocol.jl") +#include("TDesignCubeProtocol.jl") \ No newline at end of file diff --git a/src/Protocols/TDesignCubeProtocol.jl b/src/Protocols/TDesignCubeProtocol.jl new file mode 100644 index 00000000..dddb2cba --- /dev/null +++ b/src/Protocols/TDesignCubeProtocol.jl @@ -0,0 +1,178 @@ + +export TDesignCubeProtocolParams, TDesignCubeProtocol + +Base.@kwdef mutable struct TDesignCubeProtocolParams <: ProtocolParams + sequence::Union{Sequence,Nothing} = nothing + center::ScannerCoords = ScannerCoords([[0.0u"mm", 0.0u"mm", 0.0u"mm"]]) + samplesSize::Union{Nothing,Int64} = nothing # Optional overwrite +end +function TDesignCubeProtocolParams(dict::Dict, scanner::MPIScanner) + sequence = nothing + if haskey(dict, "sequence") + sequence = Sequence(scanner, dict["sequence"]) + dict["sequence"] = sequence + delete!(dict, "sequence") + end + + params = params_from_dict(TDesignCubeProtocolParams, dict) + params.sequence = sequence + return params + +end + +Base.@kwdef mutable struct TDesignCubeProtocol <: Protocol + @add_protocol_fields TDesignCubeProtocolParams + finishAcknowledged::Bool = false + measurement::Union{Matrix{Float64},Nothing} = nothing + tDesign::Union{SphericalTDesign,Nothing} = nothing +end + +requiredDevices(protocol::TDesignCubeProtocol) = [TDesignCube, AbstractDAQ] + +function _init(protocol::TDesignCubeProtocol) + if isnothing(protocol.params.sequence) + throw(IllegalStateException("Protocol requires a sequence")) + end + cube = getDevice(protocol.scanner, TDesignCube) + # TODO get T, N, radius from TDesignCube + N = getN(cube) + T = getT(cube) + radius = getRadius(cube) + protocol.tDesign = loadTDesign(T, N, radius, protocol.params.center.data) + protocol.measurement = zeros(Float64, 3, length(protocol.tDesign)) +end + + +function enterExecute(protocol::TDesignCubeProtocol) + protocol.finishAcknowledged = false +end + +function _execute(protocol::TDesignCubeProtocol) + @debug "TDesignCube protocol started" + + performMeasurement(protocol) + + put!(protocol.biChannel, FinishedNotificationEvent()) + + debugCount = 0 + + while !(protocol.finishAcknowledged) + handleEvents(protocol) + protocol.cancelled && throw(CancelException()) + end + + @info "Protocol finished." + close(protocol.biChannel) + @debug "Protocol channel closed after execution." +end + +function performMeasurement(protocol::TDesignCubeProtocol) + cube = getDevice(scanner(protocol), TDesignCube) + producer = @tspawnat protocol.scanner.generalParams.producerThreadID measurement(protocol) + while !istaskdone(producer) + handleEvents(protocol) + # Dont want to throw cancel here + sleep(0.05) + end + + if Base.istaskfailed(producer) + currExceptions = current_exceptions(producer) + @error "Measurement failed" exception = (currExceptions[end][:exception], stacktrace(currExceptions[end][:backtrace])) + for i in 1:length(currExceptions)-1 + stack = currExceptions[i] + @error stack[:exception] trace = stacktrace(stack[:backtrace]) + end + ex = currExceptions[1][:exception] + throw(ex) + end +end + +function startMeasurement(protocol::TDesignCubeProtocol) + daq = getDAQ(protocol.scanner) + su = getSurveillanceUnit(protocol.scanner) + tempControl = getTemperatureController(protocol.scanner) + amps = getDevices(protocol.scanner, Amplifier) + if !isempty(amps) + # Only enable amps that amplify a channel of the current sequence + channelIdx = id.(vcat(acyclicElectricalTxChannels(protocol.params.sequence), periodicElectricalTxChannels(protocol.params.sequence))) + amps = filter(amp -> in(channelId(amp), channelIdx), amps) + end + if !isnothing(su) + enableACPower(su) + end + if !isnothing(tempControl) + disableControl(tempControl) + end + @sync for amp in amps + @async turnOn(amp) + end + startTx(daq) + current = 0 + # Wait for measurement proper frame to start + while current < timing.start + current = currentWP(daq.rpc) + sleep(0.01) + end +end + +function stopMeasurement(protocol::TDesignCubeProtocol) + daq = getDAQ(protocol.scanner) + su = getSurveillanceUnit(protocol.scanner) + tempControl = getTemperatureController(protocol.scanner) + amps = getDevices(protocol.scanner, Amplifier) + if !isempty(amps) + # Only disable amps that amplify a channel of the current sequence + channelIdx = id.(vcat(acyclicElectricalTxChannels(protocol.params.sequence), periodicElectricalTxChannels(protocol.params.sequence))) + amps = filter(amp -> in(channelId(amp), channelIdx), amps) + end + timing = getTiming(daq) + @show timing + endSequence(daq, timing.finish) + @sync for amp in amps + @async turnOff(amp) + end + if !isnothing(tempControl) + enableControl(tempControl) + end + if !isnothing(su) + disableACPower(su) + end +end + +function measurement(protocol::TDesignCubeProtocol) + daq = getDAQ(protocol.scanner) + startMeasurement(protocol) + cube = getDevice(scanner(protocol), TDesignCube) + if sample_size + setSampleSize(cube) + end + field = getXYZValues(protocol, cube) + timing = getTiming(daq) + current = currentWP(daq.rpc) + if current > timing.down + @warn current + @warn "Magnetic field was measured too late" + end + stopMeasurement(protocol) + protocol.measurement = ustrip.(u"T", field) +end + +handleEvent(protocol::TDesignCubeProtocol, event::FinishedAckEvent) = protocol.finishAcknowledged = true + +function handleEvent(protocol::TDesignCubeProtocol, event::FileStorageRequestEvent) + filename = event.filename + h5open(filename, "w") do file + write(file, "/fields", protocol.measurement) # measured field (size: 3 x #points x #patches) + # TODO get T, N, radius from TDesignCube + write(file, "/positions/tDesign/radius", ustrip(u"m", radius))# radius of the measured ball + write(file, "/positions/tDesign/N", N)# number of points of the t-design + write(file, "/positions/tDesign/t", T)# t of the t-design + write(file, "/positions/tDesign/center", ustrip.(u"m", protocol.params.center.data))# center of the measured ball + #write(file, "/sensor/correctionTranslation", getGaussMeter(protocol.scanner).params.sensorCorrectionTranslation) # TODO Write 3x3xN rotated translations + end + put!(protocol.biChannel, StorageSuccessEvent(filename)) +end + +function cleanup(protocol::TDesignCubeProtocol) + # NOP +end diff --git a/src/Scanner.jl b/src/Scanner.jl index d0404d21..f0ac9eb2 100644 --- a/src/Scanner.jl +++ b/src/Scanner.jl @@ -48,7 +48,7 @@ device configuration struct. """ function initiateDevices(configDir::AbstractString, devicesParams::Dict{String, Any}; robust = false) devices = Dict{String, Device}() - + println(DeviceParams) # Get implementations for all devices in the specified order for deviceID in devicesParams["initializationOrder"] params = nothing @@ -108,6 +108,11 @@ function initiateDevices(configDir::AbstractString, devicesParams::Dict{String, end catch e if !robust + for (deviceId, device) in devices + if device.present + close(device) + end + end rethrow() else @warn e @@ -239,7 +244,7 @@ Close the devices when closing the scanner. """ function Base.close(scanner::MPIScanner) for device in getDevices(scanner, Device) - close(device) + close(device) end end