![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Refactoring Ironcup 2020
Dependencies: mbed mbed-rtos MotionSensor EthernetInterface
Diff: main.cpp
- Revision:
- 0:8f5db5085df7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Sep 21 21:42:07 2020 +0000 @@ -0,0 +1,249 @@ +#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; +}