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.
Revision 5:0f4204941604, committed 2018-07-13
- Comitter:
- Anaesthetix
- Date:
- Fri Jul 13 14:27:30 2018 +0000
- Parent:
- 4:fab65ad01ab4
- Child:
- 6:033ad7377fee
- Commit message:
- Yaw PID added
Changed in this revision
--- a/Madgwick/MadgwickAHRS.cpp Thu Jul 12 13:53:55 2018 +0000
+++ b/Madgwick/MadgwickAHRS.cpp Fri Jul 13 14:27:30 2018 +0000
@@ -35,7 +35,8 @@
//-------------------------------------------------------------------------------------------
// AHRS algorithm update
-Madgwick::Madgwick() {
+Madgwick::Madgwick()
+{
beta = betaDef;
q0 = 1.0f;
q1 = 0.0f;
@@ -45,7 +46,8 @@
anglesComputed = 0;
}
-void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz) {
+void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz)
+{
float recipNorm;
float s0, s1, s2, s3;
float qDot1, qDot2, qDot3, qDot4;
@@ -105,37 +107,37 @@
q2q2 = q2 * q2;
q2q3 = q2 * q3;
q3q3 = q3 * q3;
-/*
+ /*
+ // Reference direction of Earth's magnetic field
+ hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
+ hy = _2q0mx * q3 + my * q0q0 - _2q0mz * q1 + _2q1mx * q2 - my * q1q1 + my * q2q2 + _2q2 * mz * q3 - my * q3q3;
+ _2bx = sqrtf(hx * hx + hy * hy);
+ _2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
+ _4bx = 2.0f * _2bx;
+ _4bz = 2.0f * _2bz;
+
+ // Gradient decent algorithm corrective step
+ s0 = -_2q2 * (2.0f * q1q3 - _2q0q2 - ax) + _2q1 * (2.0f * q0q1 + _2q2q3 - ay) - _2bz * q2 * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q3 + _2bz * q1) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q2 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
+ s1 = _2q3 * (2.0f * q1q3 - _2q0q2 - ax) + _2q0 * (2.0f * q0q1 + _2q2q3 - ay) - 4.0f * q1 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) + _2bz * q3 * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q2 + _2bz * q0) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q3 - _4bz * q1) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
+ s2 = -_2q0 * (2.0f * q1q3 - _2q0q2 - ax) + _2q3 * (2.0f * q0q1 + _2q2q3 - ay) - 4.0f * q2 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) + (-_4bx * q2 - _2bz * q0) * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q1 + _2bz * q3) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q0 - _4bz * q2) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
+ s3 = _2q1 * (2.0f * q1q3 - _2q0q2 - ax) + _2q2 * (2.0f * q0q1 + _2q2q3 - ay) + (-_4bx * q3 + _2bz * q1) * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q0 + _2bz * q2) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q1 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
+ */
// Reference direction of Earth's magnetic field
hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
hy = _2q0mx * q3 + my * q0q0 - _2q0mz * q1 + _2q1mx * q2 - my * q1q1 + my * q2q2 + _2q2 * mz * q3 - my * q3q3;
- _2bx = sqrtf(hx * hx + hy * hy);
+ _2bx = sqrt(hx * hx + hy * hy);
_2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
_4bx = 2.0f * _2bx;
_4bz = 2.0f * _2bz;
+ _8bx = 2.0f * _4bx;
+ _8bz = 2.0f * _4bz;
// Gradient decent algorithm corrective step
- s0 = -_2q2 * (2.0f * q1q3 - _2q0q2 - ax) + _2q1 * (2.0f * q0q1 + _2q2q3 - ay) - _2bz * q2 * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q3 + _2bz * q1) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q2 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
- s1 = _2q3 * (2.0f * q1q3 - _2q0q2 - ax) + _2q0 * (2.0f * q0q1 + _2q2q3 - ay) - 4.0f * q1 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) + _2bz * q3 * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q2 + _2bz * q0) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q3 - _4bz * q1) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
- s2 = -_2q0 * (2.0f * q1q3 - _2q0q2 - ax) + _2q3 * (2.0f * q0q1 + _2q2q3 - ay) - 4.0f * q2 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) + (-_4bx * q2 - _2bz * q0) * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q1 + _2bz * q3) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q0 - _4bz * q2) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
- s3 = _2q1 * (2.0f * q1q3 - _2q0q2 - ax) + _2q2 * (2.0f * q0q1 + _2q2q3 - ay) + (-_4bx * q3 + _2bz * q1) * (_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q0 + _2bz * q2) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q1 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
- */
- // Reference direction of Earth's magnetic field
- hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
- hy = _2q0mx * q3 + my * q0q0 - _2q0mz * q1 + _2q1mx * q2 - my * q1q1 + my * q2q2 + _2q2 * mz * q3 - my * q3q3;
- _2bx = sqrt(hx * hx + hy * hy);
- _2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
- _4bx = 2.0f * _2bx;
- _4bz = 2.0f * _2bz;
- _8bx = 2.0f * _4bx;
- _8bz = 2.0f * _4bz;
-
- // Gradient decent algorithm corrective step
- s0= -_2q2*(2.0f*(q1q3 - q0q2) - ax) + _2q1*(2.0f*(q0q1 + q2q3) - ay) + -_4bz*q2*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx) + (-_4bx*q3+_4bz*q1)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my) + _4bx*q2*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
- s1= _2q3*(2.0f*(q1q3 - q0q2) - ax) + _2q0*(2.0f*(q0q1 + q2q3) - ay) + -4.0f*q1*(2.0f*(0.5 - q1q1 - q2q2) - az) + _4bz*q3*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx) + (_4bx*q2+_4bz*q0)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my) + (_4bx*q3-_8bz*q1)*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
- s2= -_2q0*(2.0f*(q1q3 - q0q2) - ax) + _2q3*(2.0f*(q0q1 + q2q3) - ay) + (-4.0f*q2)*(2.0f*(0.5 - q1q1 - q2q2) - az) + (-_8bx*q2-_4bz*q0)*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx)+(_4bx*q1+_4bz*q3)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my)+(_4bx*q0-_8bz*q2)*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
- s3= _2q1*(2.0f*(q1q3 - q0q2) - ax) + _2q2*(2.0f*(q0q1 + q2q3) - ay)+(-_8bx*q3+_4bz*q1)*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx)+(-_4bx*q0+_4bz*q2)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my)+(_4bx*q1)*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
- recipNorm = invSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); // normalise step magnitude
+ s0= -_2q2*(2.0f*(q1q3 - q0q2) - ax) + _2q1*(2.0f*(q0q1 + q2q3) - ay) + -_4bz*q2*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx) + (-_4bx*q3+_4bz*q1)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my) + _4bx*q2*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
+ s1= _2q3*(2.0f*(q1q3 - q0q2) - ax) + _2q0*(2.0f*(q0q1 + q2q3) - ay) + -4.0f*q1*(2.0f*(0.5 - q1q1 - q2q2) - az) + _4bz*q3*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx) + (_4bx*q2+_4bz*q0)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my) + (_4bx*q3-_8bz*q1)*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
+ s2= -_2q0*(2.0f*(q1q3 - q0q2) - ax) + _2q3*(2.0f*(q0q1 + q2q3) - ay) + (-4.0f*q2)*(2.0f*(0.5 - q1q1 - q2q2) - az) + (-_8bx*q2-_4bz*q0)*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx)+(_4bx*q1+_4bz*q3)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my)+(_4bx*q0-_8bz*q2)*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
+ s3= _2q1*(2.0f*(q1q3 - q0q2) - ax) + _2q2*(2.0f*(q0q1 + q2q3) - ay)+(-_8bx*q3+_4bz*q1)*(_4bx*(0.5 - q2q2 - q3q3) + _4bz*(q1q3 - q0q2) - mx)+(-_4bx*q0+_4bz*q2)*(_4bx*(q1q2 - q0q3) + _4bz*(q0q1 + q2q3) - my)+(_4bx*q1)*(_4bx*(q0q2 + q1q3) + _4bz*(0.5 - q1q1 - q2q2) - mz);
+ recipNorm = invSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); // normalise step magnitude
s0 *= recipNorm;
s1 *= recipNorm;
s2 *= recipNorm;
@@ -166,7 +168,8 @@
//-------------------------------------------------------------------------------------------
// IMU algorithm update
-void Madgwick::updateIMU(float gx, float gy, float gz, float ax, float ay, float az) {
+void Madgwick::updateIMU(float gx, float gy, float gz, float ax, float ay, float az)
+{
float recipNorm;
float s0, s1, s2, s3;
float qDot1, qDot2, qDot3, qDot4;
@@ -253,7 +256,7 @@
y = y * (1.5f - (halfx * y * y));
y = y * (1.5f - (halfx * y * y));
return y;
-}
+}
float Madgwick::invSqrt(float x){
unsigned int i = 0x5F1F1412 - (*(unsigned int*)&x >> 1);
@@ -261,9 +264,10 @@
return tmp * (1.69000231f - 0.714158168f * x * tmp * tmp);
}
*/
-float Madgwick::invSqrt(float x) {
- float tmp = 1/(sqrt(x));
- return tmp;
+float Madgwick::invSqrt(float x)
+{
+ float tmp = 1/(sqrt(x));
+ return tmp;
}
//-------------------------------------------------------------------------------------------
--- a/calccomp.h Thu Jul 12 13:53:55 2018 +0000
+++ b/calccomp.h Fri Jul 13 14:27:30 2018 +0000
@@ -1,10 +1,12 @@
-// Coded by Erik van de Coevering
+// Coded by: Erik van de Coevering
+
+// Axis are mixed up, will fix soon.
#include "mbed.h"
DigitalOut led1(LED1); // for stick arming (leds are active low)
+extern float Kp, Ki, Kd;
-extern float Kp, Ki, Kd;
void calccomp(int* ctrl, float* angles, int* motor) //ctrl: 0-rud 1-elev 2-throttle 3-aileron angles: 0-ax 1-ay 2-az 3-gx 4-gy 5-gz
{
@@ -28,7 +30,9 @@
static bool armed = false;
float xcntrl = 0;
float ycntrl = 0;
- float KPx, KPy, KIx, KIy, KDx, KDy;
+ float KPx, KPy, KIx, KIy, KDx, KDy, KPz, KIz, KDz;
+ float error_z = 0;
+ float error_z1 = 0;
//Scale rx channels
rud = (((float)(ctrl[0] - ruddercenter))/2.5);
@@ -45,7 +49,7 @@
m3 = throttle;
m4 = throttle;
- // Current values used on a 250 size mini racer (still needs tuning): P: 1.45, I: 1.5, D: 0.34
+ // Current values used on a 250 size mini racer (still needs tuning): P: 1.9, I: 2.4, D: 0.45
// Calc PID values and prevent integral windup on KIx
KPx = (angles[0] - xcntrl) * Kp;
KIx = KIx + ((angles[0] - xcntrl) * Ki * 0.001);
@@ -64,12 +68,12 @@
m4 = m4 - xcomp2;
// Calc PID values and prevent integral windup on KIy
- KPy = (angles[1] + ycntrl) * Kp;
- KIy = KIy + ((angles[1] + ycntrl) * Ki * 0.001);
+ KPy = (angles[1] + ycntrl) * Kp * 0.8f;
+ KIy = KIy + ((angles[1] + ycntrl) * Ki * 0.8f * 0.001);
if(KIy > 50) KIy = 50;
if(KIy < -50) KIy = -50;
- KDy = (angles[4] + (angles[1] + ycntrl)) * Kd;
+ KDy = (angles[4] + (angles[1] + ycntrl)) * Kd * 0.8f;
ycomp = KPy + KIy + KDy;
ycomp = ycomp*-1;
@@ -81,10 +85,19 @@
m4 = m4 - ycomp;
- //Calc rudder compensation and mix
- ruddercomp = (rud + (angles[5]*1.0f)); //has drift
- zcomp = ruddercomp*-1;
- //zcomp = 0;
+ //Yaw PID gains hardcoded for now
+ error_z = angles[5] + rud;
+
+ KPz = error_z * 1.5f;
+ KIz = KIz + (error_z * 0.001f);
+
+ if(KIz > 50) KIz = 50;
+ if(KIz < -50) KIz = -50;
+
+ KDz = (error_z - error_z1) * 0.3f;
+ error_z1 = error_z;
+
+ zcomp = (KPz + KIz + KDz) * -1.0f;
//Mix rudder
m1 = m1 - zcomp;
--- a/main.cpp Thu Jul 12 13:53:55 2018 +0000
+++ b/main.cpp Fri Jul 13 14:27:30 2018 +0000
@@ -1,4 +1,4 @@
-// Coded by Erik van de Coevering
+// Coded by Erik van de Coevering
#include "mbed.h"
#include "MadgwickAHRS.h"
@@ -57,291 +57,295 @@
char mcommand;
-void rx0() {
- trx0.start();
+void rx0()
+{
+ trx0.start();
}
-void rx1() {
- trx1.start();
- trx0.stop();
- if(trx0.read_us() > 900 && trx0.read_us() < 2200) rx_data[0] = trx0.read_us();
- trx0.reset();
+void rx1()
+{
+ trx1.start();
+ trx0.stop();
+ if(trx0.read_us() > 900 && trx0.read_us() < 2200) rx_data[0] = trx0.read_us();
+ trx0.reset();
}
-void rx2() {
- trx2.start();
- trx1.stop();
- if(trx1.read_us() > 900 && trx1.read_us() < 2200) rx_data[1] = trx1.read_us();
- trx1.reset();
+void rx2()
+{
+ trx2.start();
+ trx1.stop();
+ if(trx1.read_us() > 900 && trx1.read_us() < 2200) rx_data[1] = trx1.read_us();
+ trx1.reset();
}
-void rx3() {
- trx3.start();
- trx2.stop();
- if(trx2.read_us() > 900 && trx2.read_us() < 2200) rx_data[2] = trx2.read_us();
- trx2.reset();
+void rx3()
+{
+ trx3.start();
+ trx2.stop();
+ if(trx2.read_us() > 900 && trx2.read_us() < 2200) rx_data[2] = trx2.read_us();
+ trx2.reset();
}
-void rx4() {
- trx4.start();
- trx3.stop();
- if(trx3.read_us() > 900 && trx3.read_us() < 2200) rx_data[3] = trx3.read_us();
- trx3.reset();
+void rx4()
+{
+ trx4.start();
+ trx3.stop();
+ if(trx3.read_us() > 900 && trx3.read_us() < 2200) rx_data[3] = trx3.read_us();
+ trx3.reset();
}
-void rx5() {
- trx5.start();
- trx4.stop();
- if(trx4.read_us() > 900 && trx4.read_us() < 2200) rx_data[4] = trx4.read_us();
- trx4.reset();
+void rx5()
+{
+ trx5.start();
+ trx4.stop();
+ if(trx4.read_us() > 900 && trx4.read_us() < 2200) rx_data[4] = trx4.read_us();
+ trx4.reset();
}
-void rx6() {
- trx5.stop();
- if(trx5.read_us() > 900 && trx5.read_us() < 2200) rx_data[5] = trx5.read_us();
- trx5.reset();
- rxd = true;
+void rx6()
+{
+ trx5.stop();
+ if(trx5.read_us() > 900 && trx5.read_us() < 2200) rx_data[5] = trx5.read_us();
+ trx5.reset();
+ rxd = true;
}
int main()
{
- ch_sw = 1;
- led1 = 1;
- led2 = 0;
- pc1->baud(230400);
- pc1->setTimeout(1);
- pc.baud(230400);
- spi.frequency(4000000);
-
-
- //IAP variables
- char* addr = sector_start_adress[TARGET_SECTOR];
- char mem[ MEM_SIZE ]; // memory, it should be aligned to word boundary
- char PIDsetup = 0;
- int r;
- int tempval;
-
- //IMU variables
- float angles[6] = {0};
- float time = 0;
- float samplef = 0;
- float gyrodata[3] = {0};
- float acceldata[3] = {0};
- float angles_temp[2] = {0};
- float roll, pitch;
- float tempcomp[6] = {0};
- float temp = 0;
- float temp2 = 0;
- float temp3 = 0;
- bool exit = true;
- float noise = 0;
- int count = 0;
-
- //Rx variables
- int motor[4] = {0};
-
- // Init pwm
- motor1.period_ms(10);
- motor1.pulsewidth_us(1000);
- motor2.pulsewidth_us(1000);
- motor3.pulsewidth_us(1000);
- motor4.pulsewidth_us(1000);
-
- filter.begin(1500);
-
- pc.putc('c');
- PIDsetup = pc1->getc();
- if(PIDsetup == 'c') {
- while(1) {
- PIDsetup = pc1->getc();
- if(PIDsetup == 'R') {
- for(int i=0; i<6; i++) {
- pc1->putc(addr[i]);
- wait_ms(1);
+ ch_sw = 1;
+ led1 = 1;
+ led2 = 0;
+ pc1->baud(230400);
+ pc1->setTimeout(1);
+ pc.baud(230400);
+ spi.frequency(4000000);
+
+
+ //IAP variables
+ char* addr = sector_start_adress[TARGET_SECTOR];
+ char mem[ MEM_SIZE ]; // memory, it should be aligned to word boundary
+ char PIDsetup = 0;
+ int r;
+ int tempval;
+
+ //IMU variables
+ float angles[6] = {0};
+ float time = 0;
+ float samplef = 0;
+ float gyrodata[3] = {0};
+ float acceldata[3] = {0};
+ float angles_temp[2] = {0};
+ float roll, pitch;
+ float tempcomp[6] = {0};
+ float temp = 0;
+ float temp2 = 0;
+ float temp3 = 0;
+ bool exit = true;
+ float noise = 0;
+ int count = 0;
+
+ //Rx variables
+ int motor[4] = {0};
+
+ // Init pwm
+ motor1.period_ms(10);
+ motor1.pulsewidth_us(1000);
+ motor2.pulsewidth_us(1000);
+ motor3.pulsewidth_us(1000);
+ motor4.pulsewidth_us(1000);
+
+ filter.begin(1500);
+
+ pc.putc('c');
+ PIDsetup = pc1->getc();
+ if(PIDsetup == 'c') {
+ while(1) {
+ PIDsetup = pc1->getc();
+ if(PIDsetup == 'R') {
+ for(int i=0; i<6; i++) {
+ pc1->putc(addr[i]);
+ wait_ms(1);
+ }
+ }
+
+ if(PIDsetup == 'W') {
+ for(int i=0; i<6; i++) {
+ mem[i] = pc1->getc();
+ }
+ iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
+ r = iap.erase( TARGET_SECTOR, TARGET_SECTOR );
+ iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
+ r = iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
+ }
+ }
+ }
+
+
+ if(PIDsetup == 'W') {
+ mpu9250.init2(1,BITS_DLPF_CFG_188HZ);
+ pc1->setTimeout(0.01);
+
+ rx_rud.rise(&rx0);
+ rx_elev.rise(&rx1);
+ rx_thr.rise(&rx2);
+ rx_ail.rise(&rx3);
+ rx_p1.rise(&rx4);
+ rx_p2.rise(&rx5);
+ rx_p2.fall(&rx6);
+ mcommand = 'a';
+
+ while(exit) {
+ wait_ms(1);
+ if(mcommand == '5') {
+ motor1.pulsewidth_us(rx_data[2] - 20);
+ motor2.pulsewidth_us(1000);
+ motor3.pulsewidth_us(1000);
+ motor4.pulsewidth_us(1000);
+ } else if(mcommand == '6') {
+ motor1.pulsewidth_us(1000);
+ motor2.pulsewidth_us(rx_data[2] - 20);
+ motor3.pulsewidth_us(1000);
+ motor4.pulsewidth_us(1000);
+ } else if(mcommand == '3') {
+ motor1.pulsewidth_us(1000);
+ motor2.pulsewidth_us(1000);
+ motor3.pulsewidth_us(rx_data[2] - 20);
+ motor4.pulsewidth_us(1000);
+ } else if(mcommand == '4') {
+ motor1.pulsewidth_us(1000);
+ motor2.pulsewidth_us(1000);
+ motor3.pulsewidth_us(1000);
+ motor4.pulsewidth_us(rx_data[2] - 20);
+ }
+ if(mcommand == 'E') exit = 0;
+
+ if(rxd) {
+ led2 = !led2;
+ rxd = false;
}
+
+ mpu9250.read_all();
+ if(mpu9250.accelerometer_data[0] >= 0) noise = noise*0.99 + 0.01*mpu9250.accelerometer_data[0];
+
+ if(count>100) {
+ count = 0;
+ pc.printf("%.2f\n", noise);
+ mcommand = pc1->getc();
+ }
+ count++;
+ }
+ }
+
+ tempval = addr[0];
+ tempval = tempval + (addr[1] << 8);
+ Kp = ((float)tempval) / 100;
+ tempval = addr[2];
+ tempval = tempval + (addr[3] << 8);
+ Ki = ((float)tempval) / 100;
+ tempval = addr[4];
+ tempval = tempval + (addr[5] << 8);
+ Kd = ((float)tempval) / 100;
+
+ mpu9250.init(1,BITS_DLPF_CFG_188HZ);
+
+ pc.printf("%.2f %.2f %.2f\r\n", Kp, Ki, Kd);
+
+ rx_rud.rise(&rx0);
+ rx_elev.rise(&rx1);
+ rx_thr.rise(&rx2);
+ rx_ail.rise(&rx3);
+ rx_p1.rise(&rx4);
+ rx_p2.rise(&rx5);
+ rx_p2.fall(&rx6);
+
+ t.start();
+
+ while(1) {
+ print.start();
+ t.stop();
+ time = (float)t.read();
+ t.reset();
+ t.start();
+ filter.invSampleFreq = time;
+ samplef = 1/time;
+
+ mpu9250.read_all();
+ if(mpu9250.Temperature < 6.0f) temp = 6.0f;
+ else if(mpu9250.Temperature > 60.0f) temp = 60.0f;
+ else temp = mpu9250.Temperature;
+ temp2 = temp*temp;
+ temp3 = temp2*temp;
+
+ // Temperature compensation
+ // Derived from datalogging gyro data over a wide temperature range and using the fitting tool in Matlab's plotter
+ tempcomp[0] = -1.77e-6*temp2 + 0.000233*temp + 0.02179;
+ tempcomp[1] = 0.0005727*temp - 0.01488;
+ tempcomp[2] = -2.181e-7*temp3 + 1.754e-5*temp2 - 0.0004955*temp;
+ tempcomp[3] = -0.0002814*temp2 + 0.005545*temp - 3.018;
+ tempcomp[4] = -3.011e-5*temp3 + 0.002823*temp2 - 0.1073*temp + 3.618;
+ tempcomp[5] = 9.364e-5*temp2 + 0.009138*temp - 0.8939;
+
+ // Low pass filters on accelerometer data (calculated with the help of Matlab's FDAtool)
+ acceldata[0] = lp1.run(mpu9250.accelerometer_data[0] - tempcomp[0]);
+ acceldata[1] = lp2.run(mpu9250.accelerometer_data[1] - tempcomp[1]);
+ acceldata[2] = lp3.run((mpu9250.accelerometer_data[2] - tempcomp[2])*-1);
+
+ // 10-term moving average to remove some noise
+ gyrodata[0] = maGX.run((mpu9250.gyroscope_data[0] - tempcomp[3])*-1);
+ gyrodata[1] = maGY.run((mpu9250.gyroscope_data[1] - tempcomp[4])*-1);
+ gyrodata[2] = maGZ.run((mpu9250.gyroscope_data[2] - tempcomp[5])*-1);
+
+ // Madgwick's quaternion algorithm
+ filter.updateIMU(gyrodata[0], gyrodata[1], gyrodata[2], acceldata[0],
+ acceldata[1], acceldata[2]);
+
+ roll = filter.getRoll();
+ pitch = filter.getPitch();
+
+ angles[3] = gyrodata[1];
+ angles[4] = gyrodata[0];
+ angles[5] = gyrodata[2];
+
+ //Simple first order complementary filter -> TODO: CHECK STEP RESPONSE
+ angles[0] = 0.99f*(angles[0] + (gyrodata[1]*time)) + 0.01f*pitch;
+ angles[1] = 0.99f*(angles[1] + (gyrodata[0]*time)) + 0.01f*roll;
+
+ // If [VAR] is NaN use previous value
+ if(angles[0] != angles[0]) angles[0] = angles_temp[0];
+ if(angles[1] != angles[1]) angles[1] = angles_temp[1];
+ if(angles[0] == angles[0]) angles_temp[0] = angles[0];
+ if(angles[1] == angles[1]) angles_temp[1] = angles[1];
+
+ tijd.stop();
+ tijd.reset();
+ tijd.start();
+
+ /*
+ if(print.read_ms() > 100) {
+ print.stop();
+ print.reset();
+ print.start();
+ //led2 = !led2;
+ // pc.printf("X: %.2f Y: %.2f %.0f\r\n", angles[0], angles[1], samplef);
+ pc.printf("%.2f %.0f\r\n", angles[1], samplef);
+ }
+ */
+ pc.printf("%.2f %.0f\r\n", angles[0], samplef);
+ if(rxd) {
+ led2 = !led2;
+ rxd = false;
+ // pc.printf("%d %d %d %d\r\n", motor[0], motor[1], motor[2], motor[3]);
}
- if(PIDsetup == 'W') {
- for(int i=0; i<6; i++) {
- mem[i] = pc1->getc();
- }
- iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
- r = iap.erase( TARGET_SECTOR, TARGET_SECTOR );
- iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
- r = iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
- }
- }
- }
-
-
- if(PIDsetup == 'W') {
- mpu9250.init2(1,BITS_DLPF_CFG_188HZ);
- pc1->setTimeout(0.01);
-
- rx_rud.rise(&rx0);
- rx_elev.rise(&rx1);
- rx_thr.rise(&rx2);
- rx_ail.rise(&rx3);
- rx_p1.rise(&rx4);
- rx_p2.rise(&rx5);
- rx_p2.fall(&rx6);
- mcommand = 'a';
-
- while(exit) {
- wait_ms(1);
- if(mcommand == '5') {
- motor1.pulsewidth_us(rx_data[2] - 20);
- motor2.pulsewidth_us(1000);
- motor3.pulsewidth_us(1000);
- motor4.pulsewidth_us(1000);
- }
- else if(mcommand == '6') {
- motor1.pulsewidth_us(1000);
- motor2.pulsewidth_us(rx_data[2] - 20);
- motor3.pulsewidth_us(1000);
- motor4.pulsewidth_us(1000);
- }
- else if(mcommand == '3') {
- motor1.pulsewidth_us(1000);
- motor2.pulsewidth_us(1000);
- motor3.pulsewidth_us(rx_data[2] - 20);
- motor4.pulsewidth_us(1000);
- }
- else if(mcommand == '4') {
- motor1.pulsewidth_us(1000);
- motor2.pulsewidth_us(1000);
- motor3.pulsewidth_us(1000);
- motor4.pulsewidth_us(rx_data[2] - 20);
- }
- if(mcommand == 'E') exit = 0;
-
- if(rxd) {
- led2 = !led2;
- rxd = false;
- }
-
- mpu9250.read_all();
- if(mpu9250.accelerometer_data[0] >= 0) noise = noise*0.99 + 0.01*mpu9250.accelerometer_data[0];
-
- if(count>100) {
- count = 0;
- pc.printf("%.2f\n", noise);
- mcommand = pc1->getc();
- }
- count++;
- }
- }
-
- tempval = addr[0];
- tempval = tempval + (addr[1] << 8);
- Kp = ((float)tempval) / 100;
- tempval = addr[2];
- tempval = tempval + (addr[3] << 8);
- Ki = ((float)tempval) / 100;
- tempval = addr[4];
- tempval = tempval + (addr[5] << 8);
- Kd = ((float)tempval) / 100;
-
- mpu9250.init(1,BITS_DLPF_CFG_188HZ);
-
- pc.printf("%.2f %.2f %.2f\r\n", Kp, Ki, Kd);
-
- rx_rud.rise(&rx0);
- rx_elev.rise(&rx1);
- rx_thr.rise(&rx2);
- rx_ail.rise(&rx3);
- rx_p1.rise(&rx4);
- rx_p2.rise(&rx5);
- rx_p2.fall(&rx6);
-
- t.start();
-
- while(1) {
- print.start();
- t.stop();
- time = (float)t.read();
- t.reset();
- t.start();
- filter.invSampleFreq = time;
- samplef = 1/time;
-
- mpu9250.read_all();
- if(mpu9250.Temperature < 6.0f) temp = 6.0f;
- else if(mpu9250.Temperature > 60.0f) temp = 60.0f;
- else temp = mpu9250.Temperature;
- temp2 = temp*temp;
- temp3 = temp2*temp;
-
- // Temperature compensation
- // Derived from datalogging gyro data over a wide temperature range and using the fitting tool in Matlab's plotter
- tempcomp[0] = -1.77e-6*temp2 + 0.000233*temp + 0.02179;
- tempcomp[1] = 0.0005727*temp - 0.01488;
- tempcomp[2] = -2.181e-7*temp3 + 1.754e-5*temp2 - 0.0004955*temp;
- tempcomp[3] = -0.0002814*temp2 + 0.005545*temp - 3.018;
- tempcomp[4] = -3.011e-5*temp3 + 0.002823*temp2 - 0.1073*temp + 3.618;
- tempcomp[5] = 9.364e-5*temp2 + 0.009138*temp - 0.8939;
-
- // Low pass filters on accelerometer data (calculated with the help of Matlab's FDAtool)
- acceldata[0] = lp1.run(mpu9250.accelerometer_data[0] - tempcomp[0]);
- acceldata[1] = lp2.run(mpu9250.accelerometer_data[1] - tempcomp[1]);
- acceldata[2] = lp3.run((mpu9250.accelerometer_data[2] - tempcomp[2])*-1);
-
- // 10-term moving average to remove some noise
- gyrodata[0] = maGX.run((mpu9250.gyroscope_data[0] - tempcomp[3])*-1);
- gyrodata[1] = maGY.run((mpu9250.gyroscope_data[1] - tempcomp[4])*-1);
- gyrodata[2] = maGZ.run((mpu9250.gyroscope_data[2] - tempcomp[5])*-1);
-
- // Madgwick's quaternion algorithm
- filter.updateIMU(gyrodata[0], gyrodata[1], gyrodata[2], acceldata[0],
- acceldata[1], acceldata[2]);
-
- roll = filter.getRoll();
- pitch = filter.getPitch();
-
- angles[3] = gyrodata[1];
- angles[4] = gyrodata[0];
- angles[5] = gyrodata[2];
-
- //Simple first order complementary filter -> TODO: CHECK STEP RESPONSE
- angles[0] = 0.99f*(angles[0] + (gyrodata[1]*time)) + 0.01f*pitch;
- angles[1] = 0.99f*(angles[1] + (gyrodata[0]*time)) + 0.01f*roll;
+ if(rx_data[5] > 1650) ch_sw = 0;
+ else ch_sw = 1;
+
+ calccomp(rx_data, angles, motor);
- // If [VAR] is NaN use previous value
- if(angles[0] != angles[0]) angles[0] = angles_temp[0];
- if(angles[1] != angles[1]) angles[1] = angles_temp[1];
- if(angles[0] == angles[0]) angles_temp[0] = angles[0];
- if(angles[1] == angles[1]) angles_temp[1] = angles[1];
-
- tijd.stop();
- tijd.reset();
- tijd.start();
-
- /*
- if(print.read_ms() > 100) {
- print.stop();
- print.reset();
- print.start();
- //led2 = !led2;
- // pc.printf("X: %.2f Y: %.2f %.0f\r\n", angles[0], angles[1], samplef);
- pc.printf("%.2f %.0f\r\n", angles[1], samplef);
- }
- */
- pc.printf("%.2f %.0f\r\n", angles[0], samplef);
- if(rxd) {
- led2 = !led2;
- rxd = false;
- // pc.printf("%d %d %d %d\r\n", motor[0], motor[1], motor[2], motor[3]);
- }
-
- if(rx_data[5] > 1650) ch_sw = 0;
- else ch_sw = 1;
-
- calccomp(rx_data, angles, motor);
-
- motor1.pulsewidth_us(motor[0]);
- motor2.pulsewidth_us(motor[1]);
- motor3.pulsewidth_us(motor[2]);
- motor4.pulsewidth_us(motor[3]);
+ motor1.pulsewidth_us(motor[0]);
+ motor2.pulsewidth_us(motor[1]);
+ motor3.pulsewidth_us(motor[2]);
+ motor4.pulsewidth_us(motor[3]);
}
}