test
Dependencies: FXOS8700_3 FXAS21002 mbed-rtos kalman MotionSensor EthernetInterface
main.cpp
- Committer:
- fitzpatrick
- Date:
- 2021-03-28
- Revision:
- 2:e429f00a3493
- Parent:
- 1:588b597b1c1b
File content as of revision 2:e429f00a3493:
#include "mbed.h" #include "FXOS8700.h" #include "FXAS21002.h" #include "kalman.c" #include "EthernetInterface.h" #define ROLL_SERVO_CENTER 1570 #define ROLL_SERVO_MAX 2000 #define ROLL_SERVO_MIN 1000 #define PITCH_SERVO_CENTER 1570 #define PITCH_SERVO_MAX 2000 #define PITCH_SERVO_MIN 1000 #define PI 3.14159265 #define Rad2Degree 57.2957795 const int PORT = 7; //arbitrary port static const char* SERVER_IP = "192.168.1.101"; //IP of server board static const char* MASK = "255.255.255.0"; //mask static const char* GATEWAY = "192.168.1.1"; //gateway Serial pc(USBTX, USBRX); // Serial Port 115200 // Sensor GPIO Definitions, I2C FXOS8700 accel(D14,D15); FXOS8700 mag(D14,D15); FXAS21002 gyro(D14,D15); EthernetInterface eth; //create ethernet UDPSocket server; //creat server Endpoint client; //create endpoint //Timer used in Kalman filter Timer ProgramTimer; // Servo GPIO Definitions PwmOut Pitch_M(D11); PwmOut Roll_M(D10); //Define Kalman filter Parameters kalman filter_pitch; kalman filter_roll; float R; float Roll_P_C = 1.0f, Roll_I_C = 0.01f, Roll_D_C = 0.01f; //Roll PID coefficient Values float Roll_P = 0, Roll_I = 0, Roll_D =0, Roll_Correct = 0, Roll_Error = 0; //Roll PID Control Values float Pitch_P_C = 1.0f, Pitch_I_C = 0.01f, Pitch_D_C = 0.01f; //Pitch PID coefficient Values float Pitch_P = 0, Pitch_I = 0, Pitch_D = 0, Pitch_Correct = 0, Pitch_Error = 0; //Pitch PID control Values int Roll_Servo_Val, Pitch_Servo_Val; // Servo pulse widths double angle[3]; // Kalman Pitch and Roll angles unsigned long timer; // absolute time stamp int val, Loop_Count; // Loop_Count used to settel kalman filter int n; //size of received message char counter[1] = {0}; //sample receive/send buffer int main() { pc.baud(115200); // Serial Port 115200 // Configure Accelerometer FXOS8700, Magnetometer FXOS8700 & Gyroscope FXAS21002 accel.accel_config(); mag.mag_config(); gyro.gyro_config(); eth.init(SERVER_IP, MASK, GATEWAY); //set up IP eth.connect(); //connect ethernet printf("\nSERVER - Server IP Address is %s\r\n", eth.getIPAddress()); //get server IP address; server.bind(PORT); //bind server // Initialize Kalman Filter kalman_init(&filter_pitch, R_matrix, Q_Gyro_matrix, Q_Accel_matrix); kalman_init(&filter_roll, R_matrix, Q_Gyro_matrix, Q_Accel_matrix); // Accelerometer, Magnomometer and Gyro Variables float adata[3]; //Accelerometer x, y, x values float mag_data[3]; //Magnomometer x, y, x values float gyro_data[3]; //Gyro pitch, roll, yaw values // Roll Servo Setup int Roll_pulse = ROLL_SERVO_CENTER; Roll_M.period_us(20000); // servo requires a 20ms period Roll_M.pulsewidth_us(Roll_pulse); // servo position determined by a pulsewidth between 1-2ms // Pitch Servo Setup int Pitch_pulse = PITCH_SERVO_CENTER; Pitch_M.period_us(20000); // servo requires a 20ms period Pitch_M.pulsewidth_us(Pitch_pulse); // servo position determined by a pulsewidth between 1-2ms wait(1); // Allow servos to settel //Absolute Time Needed to Calculate Delta Time ProgramTimer.start(); timer = ProgramTimer.read_us(); Loop_Count = 15; // Allows Kalman filter to sync. while (true) { //scanf("%d", &val); // Used for debug //printf("\r\n Value is %d \r\n", val); // Used for debug // Acquire Accelerometer values accel.acquire_accel_data_g(adata); // Acquire Acceleration Vectors printf("\r\n Accelerometer Values\r\n"); printf(" X:%6.1f,\t Y:%6.1f,\t Z:%6.1f\r\n\r\n", adata[0],adata[1],adata[2]); // Acquire Magnomometer Vectors mag.acquire_mag_data_uT(mag_data); // Acquire Magnomometer Vectors printf("\r\n Magnomometer Values\r\n"); printf(" X:%6.1f,\t Y:%6.1f,\t Z:%6.1f\r\n\r\n", mag_data[0],mag_data[1],mag_data[2]); // Acquire Gyro values gyro.acquire_gyro_data_dps(gyro_data); // Acquire Gyro values printf("\r\n Gyro Values\r\n"); printf(" Pitch: %4.2f,\t Roll: %4.2f,\t Yaw: %4.2f\r\n", gyro_data[0],gyro_data[1],gyro_data[2]); // RMS Value of Accelerometer R = sqrt(std::pow(adata[0], 2) + std::pow(adata[1], 2) + std::pow(adata[2], 2)); // Kalman Filter kalman_predict(&filter_pitch, gyro_data[0], (ProgramTimer.read_us() - timer)); // Predict uses Pitch portion of gyro and delta time kalman_update(&filter_pitch, acos(adata[0]/R)); //Update uses normalized Pitch portion of accelerometer kalman_predict(&filter_roll, gyro_data[1], (ProgramTimer.read_us() - timer)); // Predict uses Roll portion of gyro and delta time kalman_update(&filter_roll, acos(adata[1]/R)); //Update uses normalized Roll portion of accelerometer angle[0] = kalman_get_angle(&filter_pitch); // Kalman Pitch angle[1] = kalman_get_angle(&filter_roll); // Kalman Roll timer = ProgramTimer.read_us(); // Update Timer printf("\r\n Roll Angle X: %.6f Pitch Angle Y: %.6f \r\n", Rad2Degree * angle[1], Rad2Degree * angle[0]); if (Loop_Count > 0) { // Loop Iterations to Initialize Kalman Filter to sync. Loop_Count--; printf("\n\rLoop_Count = %d\n\r", Loop_Count); } else { // Loop Iterations Complete, Apply Results of Kalman Filter // PID Controller (Mostly Proportional) Roll_Error = (Rad2Degree * angle[1]) - 90; // Calculate Roll Error Roll_D = Roll_Error - Roll_P; // Differentiation of Roll Error Roll_I = Roll_I + Roll_Error; // Intigration of Roll Error Roll_P = Roll_Error; // Proportional Roll Error Roll_Correct = Roll_P * Roll_P_C + Roll_I * Roll_I_C + Roll_D * Roll_D_C; // Sum product of PID coefficients and values printf("\n\rRoll_Correct = %f\n\r",Roll_Correct); Roll_pulse = Roll_pulse + Roll_Correct; // Update Roll Servo PWM Value if (Roll_pulse <= ROLL_SERVO_MIN) Roll_pulse = ROLL_SERVO_MIN; if (Roll_pulse >= ROLL_SERVO_MAX) Roll_pulse = ROLL_SERVO_MAX; Roll_M.pulsewidth_us(Roll_pulse); // servo position determined by a pulsewidth between 1-2ms printf("\n\rRoll_pulse = %d\n\r",Roll_pulse); Pitch_Error = (Rad2Degree * angle[0]) - 90; // Calculate Pitch Error Pitch_D = Pitch_Error - Pitch_P; // Differentiation of Pitch Error Pitch_I = Pitch_I + Pitch_Error; // Intigration of Pitch Error Pitch_P = Pitch_Error; // Proportional Pitch Error Pitch_Correct = Pitch_P * Pitch_P_C + Pitch_I * Pitch_I_C + Pitch_D * Pitch_D_C; // Sum product of PID coefficients and values printf("\n\rPitch_Correct = %f\n\r",Pitch_Correct); Pitch_pulse = Pitch_pulse + Pitch_Correct; // Update Roll Servo PWM Value if (Pitch_pulse <= PITCH_SERVO_MIN) Pitch_pulse = PITCH_SERVO_MIN; if (Pitch_pulse >= PITCH_SERVO_MAX) Pitch_pulse = PITCH_SERVO_MAX; Pitch_M.pulsewidth_us(Pitch_pulse); // servo position determined by a pulsewidth between 1-2ms printf("\n\rPitch_pulse = %d\n\r",Pitch_pulse); } wait(0.01); // Loop timer } }