projects:gy-80:processing_gui
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
projects:gy-80:processing_gui [2012/11/24 11:06] – created mkucia | projects:gy-80:processing_gui [2012/12/02 13:09] (current) – mkucia | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Processing GUI ====== | ||
+ | |||
+ | |||
+ | ===== Plotting sensors data ===== | ||
+ | |||
+ | * Compiled in Processing 2.0b6 | ||
+ | * [[http:// | ||
+ | |||
+ | < | ||
+ | // Created 4.11.12 | ||
+ | // by Maciej Kucia | ||
+ | |||
+ | import processing.serial.*; | ||
+ | |||
+ | Serial myPort; | ||
+ | int xPos = 1; // horizontal position of the graph | ||
+ | |||
+ | // 0 - old 1-new 2-max | ||
+ | float [][] values = new float[11][3]; | ||
+ | |||
+ | color[] colors = {color(255, | ||
+ | boolean[] offChannel = {true, | ||
+ | |||
+ | void cleanup() | ||
+ | { | ||
+ | background(255, | ||
+ | stroke(0); | ||
+ | line(0, height/2 , width, height/2); | ||
+ | xPos = 0; | ||
+ | } | ||
+ | |||
+ | void setup () | ||
+ | { | ||
+ | // set the window size: | ||
+ | size(800, 600); | ||
+ | |||
+ | println(Serial.list()); | ||
+ | myPort = new Serial(this, | ||
+ | // ^ UPDATE THIS MANUALLY! | ||
+ | // don't generate a serialEvent() unless you get a newline character: | ||
+ | myPort.bufferUntil(' | ||
+ | cleanup(); | ||
+ | } | ||
+ | |||
+ | void keyPressed() | ||
+ | { | ||
+ | switch (key) | ||
+ | { | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | default: println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void serialEvent (Serial myPort) { | ||
+ | // get the ASCII string: | ||
+ | String inString = myPort.readStringUntil(' | ||
+ | |||
+ | if (inString == null) return; | ||
+ | | ||
+ | // | ||
+ | if (inString.charAt(0) != ' | ||
+ | { | ||
+ | println(" | ||
+ | return; | ||
+ | } | ||
+ | | ||
+ | // trim off any whitespace: | ||
+ | inString = trim(inString); | ||
+ | |||
+ | String[] inStrings = inString.split("," | ||
+ | | ||
+ | for(int i=0; | ||
+ | { | ||
+ | values[i][0] = values[i][1]; | ||
+ | values[i][1] = float(inStrings[i+1]); | ||
+ | | ||
+ | //store max | ||
+ | if (values[i][1] > values[i][2]) | ||
+ | values[i][2] = values[i][1]; | ||
+ | | ||
+ | values[i][1] = map(values[i][1], | ||
+ | } | ||
+ | |||
+ | // draw the line: | ||
+ | for(int i=0; | ||
+ | { | ||
+ | if (!offChannel[i]) continue; | ||
+ | | ||
+ | | ||
+ | } | ||
+ | | ||
+ | // at the edge of the screen, go back to the beginning: | ||
+ | if (xPos++ >= width) | ||
+ | { | ||
+ | cleanup(); | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | |||
+ | |||
+ | void draw () { | ||
+ | // everything happens in the serialEvent() | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Kalman ===== | ||
+ | |||
+ | <code c> | ||
+ | // Created 4.11.12 | ||
+ | // by Maciej Kucia | ||
+ | |||
+ | import processing.serial.*; | ||
+ | |||
+ | Serial myPort; | ||
+ | int xPos = 1; // horizontal position of the graph | ||
+ | |||
+ | // 0 - old | ||
+ | // 1 - new | ||
+ | // 2 - scale | ||
+ | float [][] values = new float[11][3]; | ||
+ | float kalman_old = 0; | ||
+ | |||
+ | // sensor data to be filtered | ||
+ | int kalman_sensor = 5; | ||
+ | |||
+ | color[] colors = { | ||
+ | color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(255, 255, 0), color(0, 255, 255), color(255, 0, 255), color(100, 100, 0), color(100, 0, 100), color(0, 100, 100), color(20, 50, 80), color(80, 50, 20), | ||
+ | |||
+ | boolean[] offChannel = { | ||
+ | false, true, false, false, false, false, false, false, false, false, false}; | ||
+ | |||
+ | boolean enableKalman = true; | ||
+ | boolean enableMeasurement = true; | ||
+ | |||
+ | class KalmanFilterC | ||
+ | { | ||
+ | // kalman variables | ||
+ | public double q; // process noise | ||
+ | public double r; // measurement noise | ||
+ | public double x; // value | ||
+ | public double p; // estimation error covariance | ||
+ | public double k; // kalman gain | ||
+ | | ||
+ | public double scale; | ||
+ | |||
+ | public KalmanFilterC() | ||
+ | { | ||
+ | x = 0; | ||
+ | q = 100; | ||
+ | r = 10000; | ||
+ | p = 10000; | ||
+ | k = 0; | ||
+ | | ||
+ | //for plotting | ||
+ | scale = 0.01; | ||
+ | } | ||
+ | |||
+ | void Update(double x_m) | ||
+ | { | ||
+ | p = p + q; // we have more noise | ||
+ | | ||
+ | k = p / (p+r); | ||
+ | | ||
+ | // update by error* kalman gain | ||
+ | x = x + k * (x_m - x); | ||
+ | p = (1-k)*(1-k)* p + r*k*k; | ||
+ | } | ||
+ | | ||
+ | void Print() | ||
+ | { | ||
+ | println(" | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | |||
+ | KalmanFilterC kalman; | ||
+ | |||
+ | // code | ||
+ | |||
+ | void cleanup() | ||
+ | { | ||
+ | background(255, | ||
+ | stroke(0); | ||
+ | line(0, height/2, width, height/2); | ||
+ | xPos = 0; | ||
+ | } | ||
+ | |||
+ | void setup () | ||
+ | { | ||
+ | // set the window size: | ||
+ | size(800, 600); | ||
+ | |||
+ | kalman = new KalmanFilterC(); | ||
+ | |||
+ | //for(int i=0; | ||
+ | values[kalman_sensor][2] = (float)kalman.scale; | ||
+ | |||
+ | println(Serial.list()); | ||
+ | myPort = new Serial(this, | ||
+ | // ^ UPDATE THIS MANUALLY! | ||
+ | | ||
+ | // don't generate a serialEvent() unless you get a newline character: | ||
+ | myPort.bufferUntil(' | ||
+ | cleanup(); | ||
+ | } | ||
+ | |||
+ | void keyPressed() | ||
+ | { | ||
+ | switch (key) | ||
+ | { | ||
+ | case ' | ||
+ | enableMeasurement = !enableMeasurement; | ||
+ | break; | ||
+ | | ||
+ | case ' | ||
+ | cleanup(); | ||
+ | break; | ||
+ | | ||
+ | case ' | ||
+ | enableKalman = !enableKalman; | ||
+ | break; | ||
+ | | ||
+ | default: | ||
+ | println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void Process() | ||
+ | { | ||
+ | if (enableKalman) | ||
+ | kalman.Update(values[kalman_sensor][1]); | ||
+ | } | ||
+ | |||
+ | void Plot() | ||
+ | { | ||
+ | if (enableMeasurement) | ||
+ | { | ||
+ | stroke(colors[colors.length-1]); | ||
+ | line(xPos, values[kalman_sensor][0]*values[kalman_sensor][2]+(height/ | ||
+ | } | ||
+ | | ||
+ | if(enableKalman) | ||
+ | { | ||
+ | float new_kalman = (float)kalman.x; | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | // | ||
+ | } | ||
+ | |||
+ | // at the edge of the screen, go back to the beginning: | ||
+ | if (xPos++ >= width) | ||
+ | cleanup(); | ||
+ | |||
+ | } | ||
+ | |||
+ | void serialEvent (Serial myPort) { | ||
+ | // get the ASCII string: | ||
+ | String inString = myPort.readStringUntil(' | ||
+ | |||
+ | if (inString == null) return; | ||
+ | |||
+ | // | ||
+ | if (inString.charAt(0) != ' | ||
+ | { | ||
+ | println(" | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // trim off any whitespace: | ||
+ | inString = trim(inString); | ||
+ | |||
+ | String[] inStrings = inString.split("," | ||
+ | |||
+ | for (int i=0; | ||
+ | { | ||
+ | values[i][0] = values[i][1]; | ||
+ | values[i][1] = float(inStrings[i+1]); | ||
+ | } | ||
+ | | ||
+ | Process(); | ||
+ | Plot(); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | void draw () { | ||
+ | // everything happens in the serialEvent() | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Complementary filter ===== | ||
+ | <code c> | ||
+ | // Created 1.12.12 | ||
+ | // by Maciej Kucia | ||
+ | |||
+ | import processing.serial.*; | ||
+ | |||
+ | Serial myPort; | ||
+ | int xPos = 1; // horizontal position of the graph | ||
+ | |||
+ | color[] colors = { | ||
+ | color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(255, 255, 0), color(0, 255, 255), color(255, 0, 255), color(100, 100, 0), color(100, 0, 100), color(0, 100, 100), color(20, 50, 80), color(80, 50, 20), color(0, 0, 0) | ||
+ | }; | ||
+ | |||
+ | // Timestep | ||
+ | float deltaT = (1/50); | ||
+ | |||
+ | class SensorsC | ||
+ | { | ||
+ | public float gyroX=0; | ||
+ | public float gyroY=0; | ||
+ | public float gyroZ=0; | ||
+ | |||
+ | public float accX=0; | ||
+ | public float accY=0; | ||
+ | public float accZ=0; | ||
+ | |||
+ | public float gyroAngle=0; | ||
+ | public float accAngle=0; | ||
+ | |||
+ | public float Angle =0.0; | ||
+ | |||
+ | public void UpdateMeasurements(float gX, float gY, float gZ, float aX, float aY, float aZ) | ||
+ | { | ||
+ | // 250 dps | ||
+ | // 25Hz = 40ms | ||
+ | gyroX=(0.04*gX)/ | ||
+ | gyroY=(0.04*gY)/ | ||
+ | gyroZ=(0.04*gZ)/ | ||
+ | |||
+ | // range +-4g - 11 bits = 10 bits + sign | ||
+ | // (2^10)-1 = 4g -> 4g = 1023 -> 1g = 255 | ||
+ | accX=aX/ | ||
+ | accY=aY/ | ||
+ | accZ=aZ/ | ||
+ | |||
+ | accAngle = (float)Math.toDegrees(Math.atan2(aZ, | ||
+ | |||
+ | // " | ||
+ | Angle = (0.90)*(Angle+gyroY) + (0.10)*accAngle; | ||
+ | } | ||
+ | |||
+ | public void Draw() | ||
+ | { | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | DrawComplAngle(); | ||
+ | } | ||
+ | |||
+ | public void DrawAcc() | ||
+ | { | ||
+ | float hh = ((float)height/ | ||
+ | stroke(color(0, | ||
+ | |||
+ | //blue | ||
+ | stroke(color(0, | ||
+ | line((float)xPos, | ||
+ | |||
+ | //green | ||
+ | stroke(color(0, | ||
+ | line((float)xPos, | ||
+ | |||
+ | //red | ||
+ | stroke(color(255, | ||
+ | line((float)xPos, | ||
+ | } | ||
+ | |||
+ | public void DrawGyro() | ||
+ | { | ||
+ | float hh = ((float)height/ | ||
+ | stroke(color(0, | ||
+ | |||
+ | //blue | ||
+ | stroke(color(0, | ||
+ | line((float)xPos, | ||
+ | |||
+ | //green | ||
+ | stroke(color(0, | ||
+ | line((float)xPos, | ||
+ | |||
+ | //red | ||
+ | stroke(color(255, | ||
+ | line((float)xPos, | ||
+ | } | ||
+ | |||
+ | public void DrawGyroAngle() | ||
+ | { | ||
+ | float hh = ((float)height/ | ||
+ | stroke(color(0, | ||
+ | |||
+ | //blue | ||
+ | stroke(color(0, | ||
+ | line((float)xPos, | ||
+ | } | ||
+ | |||
+ | public void DrawAccAngle() | ||
+ | { | ||
+ | float hh = ((float)height/ | ||
+ | stroke(color(0, | ||
+ | |||
+ | //red | ||
+ | stroke(color(255, | ||
+ | line((float)xPos, | ||
+ | } | ||
+ | |||
+ | |||
+ | public void DrawComplAngle() | ||
+ | { | ||
+ | float hh = ((float)height/ | ||
+ | stroke(color(0, | ||
+ | |||
+ | //green | ||
+ | stroke(color(0, | ||
+ | line((float)xPos, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | SensorsC sensors = new SensorsC(); | ||
+ | |||
+ | void cleanup() | ||
+ | { | ||
+ | float hh = ((float)height/ | ||
+ | background(255, | ||
+ | stroke(0); | ||
+ | line(0, hh, width, hh); | ||
+ | stroke(100, 100, 100); | ||
+ | line(0, hh-90, width, hh-90); | ||
+ | line(0, hh+90, width, hh+90); | ||
+ | |||
+ | xPos = 0; | ||
+ | } | ||
+ | |||
+ | void setup () | ||
+ | { | ||
+ | // set the window size: | ||
+ | size(800, 400); | ||
+ | |||
+ | println(Serial.list()); | ||
+ | myPort = new Serial(this, | ||
+ | // ^ UPDATE THIS MANUALLY! | ||
+ | |||
+ | // don't generate a serialEvent() unless you get a newline character: | ||
+ | myPort.bufferUntil(' | ||
+ | |||
+ | myPort.clear(); | ||
+ | cleanup(); | ||
+ | } | ||
+ | |||
+ | void keyPressed() | ||
+ | { | ||
+ | switch (key) | ||
+ | { | ||
+ | |||
+ | case ' | ||
+ | cleanup(); | ||
+ | break; | ||
+ | |||
+ | default: | ||
+ | println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void serialEvent (Serial myPort) { | ||
+ | |||
+ | String inString = myPort.readStringUntil(' | ||
+ | |||
+ | if (inString == null) return; | ||
+ | if (inString.charAt(0) != ' | ||
+ | { | ||
+ | println(" | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | String[] inStrings = trim(inString).split("," | ||
+ | |||
+ | sensors.UpdateMeasurements( | ||
+ | float(inStrings[4]), | ||
+ | float(inStrings[1]), | ||
+ | |||
+ | sensors.Draw(); | ||
+ | |||
+ | // at the edge of the screen, go back to the beginning: | ||
+ | if (xPos++ >= width) | ||
+ | cleanup(); | ||
+ | } | ||
+ | |||
+ | |||
+ | void draw () { | ||
+ | // everything happens in the serialEvent() | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Kalman 3D ===== | ||
+ | |||
+ | <code c> | ||
+ | |||
+ | </ | ||