Refactoring Ironcup 2020
Dependencies: mbed mbed-rtos MotionSensor EthernetInterface
main.cpp
- Committer:
- starling
- Date:
- 2020-09-21
- Revision:
- 0:8f5db5085df7
File content as of revision 0:8f5db5085df7:
#include "FXAS21002.h" #include "FXOS8700Q.h" #include "mbed.h" #include "CarPWM.h" #include "receiver.h" #include "Motor.hpp" #include "rtos.h" #include "LED.hpp" #include "PIDController.hpp" #define PI 3.141593 #define Ts 0.02 // Controller period(Seconds) #define END_THRESH 4 //For magnetometer calibration #define START_THRESH 10 //For magnetometer calibration #define MINIMUM_VELOCITY 15 #define GYRO_PERIOD 15000 //us #define MIN -1.5 #define MAX 1.5 //Control Objetcs PwmOut servo(PTD1); // Servo connected to pin PTD3 Motor *motor = new Motor(PTC3); FXOS8700Q_mag mag(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); FXOS8700Q_acc acc(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); FXAS21002 *gyro = new FXAS21002(PTE25, PTE24); //Leds Objects LED *led = new LED(PTD0, PTC4, PTC12, LED_RED, LED_GREEN, LED_BLUE); DigitalOut main_led(PTB2); //Protocol Objects Receiver rcv; EthernetInterface eth; // PID controller parameters and functions PIDController *pidController = new PIDController(motor, &servo, gyro); // Motor and servo variables float saved_velocity = 0; bool brake = false; // Magnetometer/Gyro variables and functions float max_x = 0, max_y = 0, min_x = 0, min_y = 0, x, y; MotionSensorDataUnits mag_data; MotionSensorDataCounts mag_raw; float processMagAngle(); void magCal(); // Protocol void readProtocol(); int main() { // Initializing sensors main_led = 1; acc.enable(); gyro->gyro_config(MODE_1); // Set initial control configurations motor->setVelocity(0); // Protocol initialization printf("Initializing Ethernet!\r\n"); led->set_leds_color_nxp(LED::RED); led->set_leds_color_main(LED::RED); eth.init(RECEIVER_IFACE_ADDR, RECEIVER_NETMASK_ADDR, RECEIVER_GATEWAY_ADDR); eth.connect(); printf("Protocol initialized! \r\n"); gyro->start_measure(GYRO_PERIOD); led->set_leds_color_nxp(LED::BLUE); led->set_leds_color_main(LED::BLUE); rcv.set_socket(); main_led = 0; pidController->PIDAttach(); //main loop while (1) { readProtocol(); } } void readProtocol() { if (!rcv.receive()) return; char msg = rcv.get_msg(); switch (msg) { case NONE: break; case BRAKE: float intensity, b_wait; rcv.get_brake(&intensity, &b_wait); if (!brake) { led->set_leds_color_nxp(LED::YELLOW); motor->stopJogging(); setServoPWM(0, servo); pidController->PIDDetach(); motor->brakeMotor(intensity, b_wait); pidController->PIDAttach(); saved_velocity = 0; brake = true; } break; case GYRO_ZERO: gyro->stop_measure(); wait(0.05); gyro->start_measure(GYRO_PERIOD); break; case ANG_SET: led->set_leds_color_nxp(LED::PURPLE); //printf("ANG_SET\r\n"); pidController->setGyroReference(gyro->get_angle()); pidController->initializeController(); break; case ANG_RST: //printf("ANG_RST\r\n"); pidController->setGyroReference(0); led->set_leds_color_nxp(LED::PURPLE); pidController->initializeController(); break; case MAG_ANG_REF: led->set_leds_color_nxp(LED::BLUE); pidController->setTargetAngle(rcv.get_mag_ang_ref() - processMagAngle()); break; case ABS_ANG_REF: led->set_leds_color_nxp(LED::GREEN); pidController->setTargetAngle(rcv.get_abs_ang_ref()); break; case REL_ANG_REF: led->set_leds_color_nxp(LED::RED); pidController->setTargetAngle(rcv.get_rel_ang_ref() + gyro->get_angle() * PI / 180); break; case GND_VEL: led->set_leds_color_nxp(LED::AQUA); saved_velocity = rcv.get_gnd_vel(); if (saved_velocity > 0) { motor->setVelocity(saved_velocity); if (abs(saved_velocity) > MINIMUM_VELOCITY) brake = false; } break; case JOG_VEL: led->set_leds_color_nxp(LED::WHITE); float p, r; rcv.get_jog_vel(&p, &r); if (p == 0 || r == 0) motor->stopJogging(); else motor->startJogging(r, p); break; case PID_PARAMS: led->set_leds_color_nxp(LED::WHITE); float arr[4]; rcv.get_pid_params(arr); pidController->setPIDConstants(arr[0], arr[1], arr[2], arr[3]); break; case MAG_CALIB: led->set_leds_color_nxp(LED::BLUE); float mag[4]; rcv.get_mag_calib(mag); max_x = mag[1]; max_y = mag[3]; min_x = mag[0]; min_y = mag[2]; //printf(" max_x = %f, max_y= %f, min_x= %f, min_y= %f\r\n",mag[1],mag[3],mag[0],mag[2]); break; case LED_ON: led->set_leds_color_nxp(LED::WHITE); led->set_leds_color_main(LED::WHITE); main_led = 1; break; case LED_OFF: led->turn_leds_off_nxp(); led->turn_leds_off_main(); main_led = 0; break; default: //ser.printf("unknown command!\r\n"); } } /* Brake function, braking while the gyroscope is still integrating will cause considerably error in the measurement. */ /* Function to normalize the magnetometer reading */ void magCal() { //red_led = 0; printf("Starting Calibration"); mag.enable(); wait(0.01); mag.getAxis(mag_data); float x0 = max_x = min_y = mag_data.x; float y0 = max_y = min_y = mag_data.y; bool began = false; while (!(began && abs(mag_data.x - x0) < END_THRESH && abs(mag_data.y - y0) < END_THRESH)) { mag.getAxis(mag_data); if (mag_data.x > max_x) max_x = mag_data.x; if (mag_data.y > max_y) max_y = mag_data.y; if (mag_data.y < min_y) min_y = mag_data.y; if (mag_data.x < min_x) min_x = mag_data.x; if (abs(mag_data.x - x0) > START_THRESH && abs(mag_data.y - y0) > START_THRESH) began = true; printf("began: %d X-X0: %f , Y-Y0: %f \n\r", began, abs(mag_data.x - x0), abs(mag_data.y - y0)); } printf("Calibration Completed: X_MAX = %f , Y_MAX = %f , X_MIN = %f and Y_MIN = %f \n\r", max_x, max_y, min_x, min_y); } /* Function to transform the magnetometer reading in angle(rad/s).*/ float processMagAngle() { // printf("starting ProcessMagAngle()\n\r"); float mag_lpf = 0; Timer t1; for (int i = 0; i < 20; i++) { //printf("\r\n"); //wait(0.1); t1.start(); __disable_irq(); mag.getAxis(mag_data); __enable_irq(); t1.stop(); x = 2 * (mag_data.x - min_x) / float(max_x - min_x) - 1; y = 2 * (mag_data.y - min_y) / float(max_y - min_y) - 1; mag_lpf = mag_lpf + (-atan2(y, x)); wait(0.015); } // wait(20*0.01); // printf("Finished ProcessMagAngle() %d \n\r",t1.read_us()); return mag_lpf / 20; }