====== Processing GUI ======
===== Plotting sensors data =====
* Compiled in Processing 2.0b6
* [[http://www.processing.org|Processing.org]]
// Created 4.11.12
// by Maciej Kucia
import processing.serial.*;
Serial myPort; // The serial port
int xPos = 1; // horizontal position of the graph
// 0 - old 1-new 2-max
float [][] values = new float[11][3];
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 = {true,true,true,false,false,false,false,false,false,false,false};
void cleanup()
{
background(255,255,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, Serial.list()[1], 115200);
// ^ UPDATE THIS MANUALLY!
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
cleanup();
}
void keyPressed()
{
switch (key)
{
case '1': offChannel[0] = !offChannel[0]; break;
case '2': offChannel[1] = !offChannel[1]; break;
case '3': offChannel[2] = !offChannel[2]; break;
case '4': offChannel[3] = !offChannel[3]; break;
case '5': offChannel[4] = !offChannel[4]; break;
case '6': offChannel[5] = !offChannel[5]; break;
case '7': offChannel[6] = !offChannel[6]; break;
case '8': offChannel[7] = !offChannel[7]; break;
case '9': offChannel[8] = !offChannel[8]; break;
case '0': offChannel[9] = !offChannel[9]; break;
case '-': offChannel[10] = !offChannel[10]; break;
case 'c': cleanup(); break;
default: println("key not active");
}
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil('\n');
if (inString == null) return;
//println(inString);
if (inString.charAt(0) != '~')
{
println("No data.");
return;
}
// trim off any whitespace:
inString = trim(inString);
String[] inStrings = inString.split(",");
for(int i=0;i<=10;++i)
{
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], -values[i][2], values[i][2], 0, height);
}
// draw the line:
for(int i=0;i<=10;++i)
{
if (!offChannel[i]) continue;
stroke(colors[i]);
line(xPos, values[i][0], xPos+1, values[i][1]);
}
// at the edge of the screen, go back to the beginning:
if (xPos++ >= width)
{
cleanup();
}
}
void draw () {
// everything happens in the serialEvent()
}
===== Kalman =====
// Created 4.11.12
// by Maciej Kucia
import processing.serial.*;
Serial myPort; // The serial port
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),color(0,0,0)};
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(" q r p k x[" + q +":"+ r +":"+ p +":"+ k +":"+ x + "]");
}
}
KalmanFilterC kalman;
// code
void cleanup()
{
background(255, 255, 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;i= width)
cleanup();
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil('\n');
if (inString == null) return;
//println(inString);
if (inString.charAt(0) != '~')
{
println("No data.");
return;
}
// trim off any whitespace:
inString = trim(inString);
String[] inStrings = inString.split(",");
for (int i=0;i<=10;++i)
{
values[i][0] = values[i][1];
values[i][1] = float(inStrings[i+1]);
}
Process();
Plot();
}
void draw () {
// everything happens in the serialEvent()
}
===== Complementary filter =====
// Created 1.12.12
// by Maciej Kucia
import processing.serial.*;
Serial myPort; // The serial port
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)/250.0;
gyroY=(0.04*gY)/250.0;
gyroZ=(0.04*gZ)/250.0;
// range +-4g - 11 bits = 10 bits + sign
// (2^10)-1 = 4g -> 4g = 1023 -> 1g = 255
accX=aX/255.0;
accY=aY/255.0;
accZ=aZ/255.0;
accAngle = (float)Math.toDegrees(Math.atan2(aZ, aX) + Math.PI*0.5 );
// "fuse" two sensor data
Angle = (0.90)*(Angle+gyroY) + (0.10)*accAngle;
}
public void Draw()
{
//DrawAcc();
//DrawGyroAngle();
//DrawAccAngle();
DrawComplAngle();
}
public void DrawAcc()
{
float hh = ((float)height/2.0);
stroke(color(0, 255, 0, 100));
//blue
stroke(color(0, 0, 255, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-accX*90) );
//green
stroke(color(0, 255, 0, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-accY*90) );
//red
stroke(color(255, 0, 0, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-accZ*90) );
}
public void DrawGyro()
{
float hh = ((float)height/2.0);
stroke(color(0, 255, 0, 100));
//blue
stroke(color(0, 0, 255, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-gyroX) );
//green
stroke(color(0, 255, 0, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-gyroY) );
//red
stroke(color(255, 0, 0, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-gyroZ) );
}
public void DrawGyroAngle()
{
float hh = ((float)height/2.0);
stroke(color(0, 255, 0, 100));
//blue
stroke(color(0, 0, 255, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-gyroAngle) );
}
public void DrawAccAngle()
{
float hh = ((float)height/2.0);
stroke(color(0, 255, 0, 100));
//red
stroke(color(255, 0, 0, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-accAngle) );
}
public void DrawComplAngle()
{
float hh = ((float)height/2.0);
stroke(color(0, 255, 0, 100));
//green
stroke(color(0, 255, 0, 100));
line((float)xPos, hh, (float)xPos, (float) (hh-Angle) );
}
}
SensorsC sensors = new SensorsC();
void cleanup()
{
float hh = ((float)height/2.0);
background(255, 255, 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, Serial.list()[1], 115200);
// ^ UPDATE THIS MANUALLY!
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
myPort.clear();
cleanup();
}
void keyPressed()
{
switch (key)
{
case 'c':
cleanup();
break;
default:
println("key not active");
}
}
void serialEvent (Serial myPort) {
String inString = myPort.readStringUntil('\n');
if (inString == null) return;
if (inString.charAt(0) != '~')
{
println("No data.");
return;
}
String[] inStrings = trim(inString).split(",");
sensors.UpdateMeasurements(
float(inStrings[4]), float(inStrings[5]), float(inStrings[6]),
float(inStrings[1]), float(inStrings[2]), float(inStrings[3]));
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 =====