Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 5:e4e96d1b446f
- Parent:
- 4:ab834eebd496
- Child:
- 6:12ff056ab2c1
diff -r ab834eebd496 -r e4e96d1b446f main.cpp
--- a/main.cpp Wed Nov 17 15:13:38 2021 +0000
+++ b/main.cpp Thu Nov 18 20:34:22 2021 +0000
@@ -27,9 +27,9 @@
}
/*---------------------- Ethernet setup ----------------------*/
-const int SERVER_PORT = 2;
+const int SERVER_PORT = 11223;
const char* SERVER_ADDRESS = "192.168.1.2"; // Adress of the other Mbed (Mbed B)
-const int LOCAL_PORT = 1;
+const int LOCAL_PORT = 11223;
const char* ip = "192.168.1.1"; // Mbed A = 1; Mbed B = 2
const char* mask = "255.255.255.0";
const char* gateway = "192.168.1.10";
@@ -42,6 +42,10 @@
// buffer length is 6*6 + 11*8 + 14 = 138
char send_buf[138];
+// timer to include dt in messages
+Timer msg_timer;
+
+
/*---------------------- IMU setup ----------------------*/
// TODO: add this eventually
@@ -69,7 +73,7 @@
ltc_spi adc_data;
int16_t ati_data[6];
float ati_filt[6];
-float FILT_COEF = 0.05f;
+float FILT_COEF = 0.10f;
// calibration matrix for ATI sensor
float Fxc[6] = {-0.1971322934773, -0.04349257334311, 2.298051028435, -80.35044049387, 1.362983909976, 78.23673392118};
@@ -324,7 +328,7 @@
void read_bmp_data(){
// read data from sensors
- bmp3_get_sensor_data(sensor_comp, &sn_data1, &s1); // todo: combine into a read_data function
+ bmp3_get_sensor_data(sensor_comp, &sn_data1, &s1);
bmp3_get_sensor_data(sensor_comp, &sn_data2, &s2);
bmp3_get_sensor_data(sensor_comp, &sn_data3, &s3);
bmp3_get_sensor_data(sensor_comp, &sn_data4, &s4);
@@ -335,6 +339,126 @@
}
+/*---------------------- Neural Network Evaluation ----------------------*/
+
+// TODO: add this to test fingertip sensor
+/*
+// sensor data
+uint16_t sense_data_raw[8];
+float sense_data_decode[5];
+
+// internal layers to be evaluated on-line
+float l1[12];
+float l2[25];
+
+// weights and biases for NN (constant)...add more digits here to improve prediction accuracy?
+const float b1[12] = {};
+const float b2[25] = {};
+const float b3[5] = {};
+const float w1[8][12] = { { }, { }, { }, { }, { }, { }, { }, { } };
+const float w2[12][25] = {{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { } };
+const float w3[25][5] = { { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { } };
+
+// values for scaling sensor readings and NN outputs
+const float minims[] = { -79.14952894807573f, -59.34503867427718f, -190.91288f, -0.7863755477785648f, -0.7863755477785648f, -831.0f, -997.0f, -974.0f, -986.0f, -998.0f, -964.0f, -136.0f, -881.0f};
+const float maxims[] = { 145.75214841512442f, 147.80758667427716f, 194.5331016f, 1.5781267096532723f, 1.5765908199115173f, 4079.0f, 3156.0f, 3734.0f, 4001.0f, 3463.0f, 3463.0f, 2621.0f, 3370.0f};
+const float maxS = 4079.0;
+float in_vec[8];
+float out_vec[5];
+int out_vec_pr[5];
+uint16_t offsets[8];
+
+// sensor workflow from before
+//// get sensor data
+//readSensor(sense_data_raw);
+//
+//// scale sensor data
+//for (int i=0; i<8; i++){
+// in_vec[i] = 0.0f;
+// in_vec[i] = (((float)(sense_data_raw[i]-offsets[i])) + abs(minims[i+5])) / maxS;
+//}
+//
+//// evaluate NN
+//decodeSensor(in_vec,sense_data_decode);
+//
+//// post-process, re-scale decoded data
+//for (int i=0; i<5; i++) {
+// out_vec[i] = 0.0f;
+// out_vec[i] = (sense_data_decode[i]*maxims[i]) - abs(minims[i]);
+// out_vec_pr[i] = (int)(out_vec[i]*100.0f);
+//}
+
+
+void calibrateSensor(uint16_t* offsets){ // not sure if this is still necessary?
+ // calculate sensor offsets
+ float temp_offsets[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+ int samps = 10;
+ for (int i=0; i<samps; i++){
+ for (int j=0; j<8; j++){
+ temp_offsets[j] += (float)spi3.binary(j);
+ }
+ wait_ms(1);
+ }
+ for (int i=0; i<8; i++){
+ temp_offsets[i] = temp_offsets[i]/((float)samps); // get overall offset
+ offsets[i] = (uint16_t)temp_offsets[i]; // convert to int
+ }
+}
+
+void decodeSensor(float input[8], float* output) {
+ // decode sensor data here....521*4 operations (multiply,add,activation,add)
+
+ // TODO: do normalization here? would need to change input[8] to raw sensor data for function input
+
+
+ // reset values
+ for (int i = 0; i<12; i++){
+ l1[i] = 0.0f;
+ }
+ for (int i = 0; i<25; i++){
+ l2[i] = 0.0f;
+ }
+ for (int i = 0; i<5; i++){
+ output[i] = 0.0f;
+ }
+
+ // layer 1
+ for(int i = 0; i<12; i++){ // for each node in the next layer
+ for(int j = 0; j<8; j++){ // add contribution of node in prev. layer
+ l1[i] += (w1[j][i]*input[j]);
+ }
+ l1[i] += b1[i]; // add bias
+ l1[i] = fmaxf(0.0f, l1[i]); // relu activation
+ }
+
+ // layer 2
+ for(int i = 0; i<25; i++){ // for each node in the next layer
+ for(int j = 0; j<12; j++){ // add contribution of node in prev. layer
+ l2[i] += (w2[j][i]*l1[j]);
+ }
+ l2[i] += b2[i]; // add bias
+ if (l2[i]<0.0f) { // elu activation
+ l2[i] = exp(l2[i]) - 1.0f; // alpha implicitly set to 1.0 here
+ }
+ }
+
+ // layer 3
+ for(int i = 0; i<5; i++){ // for each node in the next layer
+ for(int j = 0; j<25; j++){ // add contribution of node in prev. layer
+ output[i] += w3[j][i]*l2[j];
+
+ }
+ output[i] += b3[i];// add bias
+ output[i] = 1.0f/(1.0f + exp(-output[i])); // sigmoid activation
+ }
+
+ // TODO: undo normalization here
+
+ }
+*/
+
+
/*---------------------- Main function ----------------------*/
int main()
@@ -345,6 +469,7 @@
// Set up serial port
pc.baud(115200);
+ pc.printf("Initializing.\n\r");
// Set up LTC chip
LTC_chip.format(8, 0);
@@ -403,19 +528,22 @@
}
pc.printf("ATI sensor is calibrated with biases of: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f \n\r", bias[0],bias[1],bias[2],bias[3],bias[4],bias[5]);
+ // TODO: Add calibration for force sensor? Only necessary if the force sensor neural network is being evaluated online
+ //calibrateSensor(offsets);
+
+
// Attach sampling and sending interrupts
-// datalog.attach_us(&log_data,50000); // 1000us = 1ms (10000 = 10 ms = 100 Hz)
- LTC_log.attach_us(&log_LTC_data,5000); // 200Hz
- eth_send.attach(&send_eth_data,0.1); // 10Hz
-
+ pc.printf("Beginning to sample.\n\r");
+ LTC_log.attach_us(&log_LTC_data,1000); // 1kHz // 1000us = 1ms (10000 = 10 ms = 100 Hz)
+ eth_send.attach_us(&send_eth_data,10000); // 100Hz
+ msg_timer.start();
while (true) {
if(LTC_ticker_activated == true) {
// Clear flag
LTC_ticker_activated = false;
- // Sample from LTC chip
- // TODO: sample LTC chip at a much higher frequency (10kHz?)
+ // Sample from LTC chip, filter data
read_LTC_data();
filter_LTC_data();
}
@@ -424,11 +552,11 @@
// Clear flag
eth_ticker_activated = false;
- convert_LTC_data(); // TODO: remove this eventually, since we'll convert the data after sending over ethernet
+ convert_LTC_data(); // TODO: maybe remove this eventually, if we convert the data after sending over ethernet
// Print received data
//pc.printf("%6d,%6d,%6d,%6d,%6d,%6d\n\r", ati_data[0],ati_data[1],ati_data[2],ati_data[3],ati_data[4],ati_data[5]);
// Print converted LTC data
- pc.printf("%.2f,%.2f,%.2f,%.2f,%.2f,%.2f, ", ft_data[0],ft_data[1],ft_data[2],ft_data[3],ft_data[4],ft_data[5]);
+// pc.printf("%.2f,%.2f,%.2f,%.2f,%.2f,%.2f, ", ft_data[0],ft_data[1],ft_data[2],ft_data[3],ft_data[4],ft_data[5]);
// Sample from force sensor
read_bmp_data();
@@ -442,10 +570,11 @@
pr_data[6] = int(sn_data7.pressure)-100000;
pr_data[7] = int(sn_data8.pressure)-100000;
// Print received data
- pc.printf("%d,%d,%d,%d,%d,%d,%d,%d\n\r", pr_data[0],pr_data[1],pr_data[2],pr_data[3],pr_data[4],pr_data[5],pr_data[6],pr_data[7]);
+// pc.printf("%d,%d,%d,%d,%d,%d,%d,%d\n\r", pr_data[0],pr_data[1],pr_data[2],pr_data[3],pr_data[4],pr_data[5],pr_data[6],pr_data[7]);
// Pack and send the ethernet message
- sprintf(send_buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", ati_data[0],ati_data[1],ati_data[2],ati_data[3],ati_data[4],ati_data[5], pr_data[0],pr_data[1],pr_data[2],pr_data[3],pr_data[4],pr_data[5],pr_data[6],pr_data[7]);
+ sprintf(send_buf, "%f,%f,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d\n", msg_timer.read(),ft_data[0],ft_data[1],ft_data[2], pr_data[0],pr_data[1],pr_data[2],pr_data[3],pr_data[4],pr_data[5],pr_data[6],pr_data[7]);
+// sprintf(send_buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", ati_data[0],ati_data[1],ati_data[2],ati_data[3],ati_data[4],ati_data[5], pr_data[0],pr_data[1],pr_data[2],pr_data[3],pr_data[4],pr_data[5],pr_data[6],pr_data[7]);
server.sendto(client, send_buf, sizeof(send_buf)); // send message, look for '\n' character when decoding the string
}
