EENX15/EENX15_LQR/EENX15_LQR.ino

206 lines
5.2 KiB
Arduino
Raw Permalink Normal View History

2021-05-13 11:38:40 +02:00
//EENX15_LQR.ino
2021-04-13 21:51:43 +02:00
#include <Wire.h>
int lastCorrectionTime = 0;
int lastPrintTime = 0;
2021-04-24 11:15:41 +02:00
static int fastTimer = 10; //ms
2021-04-20 13:30:48 +02:00
static int slowTimer = 1000; //ms
2021-05-13 11:38:40 +02:00
//lqr
const uint8_t statesNumber = 4;
/** Low pass filter angular Position*/
float angularPositionLP = 0;
/** Zumo's angular position */
float angularPosition = 0;
/** Corrected angular position */
float correctedAngularPosition = 0;
/** Zumo's angular speed */
float angularSpeed = 0;
/** Motor's angular position */
float motorAngularPosition = 0;
/** Motor's angular speed */
float motorAngularSpeed = 0;
/** PWM signal applied to the motor's driver 255 is 100% */
2021-04-20 13:30:48 +02:00
int speed;
int safe_angle;
2021-05-13 11:38:40 +02:00
//gyro
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int gyro_x, gyro_y, gyro_z;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
boolean set_gyro_angles;
long acc_x, acc_y, acc_z, acc_total_vector;
float angle_roll_acc, angle_pitch_acc;
float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
float angle_pitch_output, angle_roll_output;
long loop_timer;
int temp;
2021-05-13 11:38:40 +02:00
//motor
#define encoderA1 2
#define encoderB1 3
#define encoderA2 4
#define encoderB2 7
volatile int countA = 0;
volatile int countAold = 0;
volatile int countB = 0;
const int MotorPinA = 12;
const int MotorSpeedA = 3;
const int MotorBrakeA = 9;
const int MotorPinB = 13;
const int MotorSpeedB = 11;
const int MotorBrakeB = 8;
const int CCW = HIGH;
const int CW = LOW;
volatile byte half_revolutionsA;
volatile byte half_revolutionsB;
unsigned int rpmA;
unsigned int rpmB;
unsigned long timeoldA;
unsigned long timeoldB;
float rpm = 0;
float rps = 0;
void setup() {
2021-04-13 21:51:43 +02:00
Wire.begin();
Serial.begin(115200);
while (!Serial)
2021-05-13 11:38:40 +02:00
delay(10); // will pause until serial console opens
gyro_setup();
//motor
pinMode(encoderA1, INPUT_PULLUP);
pinMode(encoderB1, INPUT_PULLUP);
pinMode(encoderA2, INPUT_PULLUP);
pinMode(encoderB2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(encoderA1), pulseA, RISING);
pinMode(MotorPinA, OUTPUT);
pinMode(MotorSpeedA, OUTPUT);
pinMode(MotorBrakeA, OUTPUT);
pinMode(MotorPinB, OUTPUT);
pinMode(MotorSpeedB, OUTPUT);
pinMode(MotorBrakeB, OUTPUT);
2021-04-19 17:14:25 +02:00
}
2021-04-14 01:52:34 +02:00
void loop() {
gyro_loop();
safe_angle = int(round(angle_pitch_output));
2021-04-14 01:52:34 +02:00
int m = millis();
2021-05-13 11:38:40 +02:00
if (m - lastCorrectionTime >= fastTimer) { //run this code every [fastTimer]ms
lastCorrectionTime = m;
getSpeed();
setSpeed();
}
2021-05-13 11:38:40 +02:00
if (m - lastPrintTime >= slowTimer) { //run this code every [slowTimer]ms
lastPrintTime = m;
printInfo();
}
}
2021-04-14 02:57:38 +02:00
void getSpeed() {
2021-04-14 02:57:38 +02:00
float alpha = 2.0 / (3.0 + 1.0); //Alpha aka EMA length. 3 length = 3*80ms=0.24s
float rpm_const = 1071.43/fastTimer; //60000ms(1min) / ticks per rotation / fasttimer
float rps_const = 112.23/fastTimer; //1000ms(1s) / ticks per rotation / fasttimer
int ticks = countA-countAold;
float rpm_new = ticks*rpm_const;
float rps_new = ticks*rps_const;
rpm = rpm * (1-alpha) + rpm_new * alpha;
rps = rps * (1-alpha) + rps_new * alpha;
countAold = countA;
}
2021-04-14 02:57:38 +02:00
2021-04-14 01:55:14 +02:00
void printInfo(){
Serial.println("");
Serial.print("pitch Angle = "); Serial.println(angle_pitch_output);
Serial.print("pitch Angle abs = "); Serial.println(abs(safe_angle));
Serial.print("pitch Angle measured = "); Serial.println(angle_pitch);
Serial.print("Position: "); Serial.println(countA);
2021-04-14 17:38:24 +02:00
Serial.print("Position (m): "); Serial.println(countA/174.76); //r*2pi
2021-04-20 13:30:48 +02:00
Serial.print("speed (m/s): "); Serial.println(rps * 0.05); //r*rads
2021-04-14 01:55:14 +02:00
Serial.print("Full Rotations: "); Serial.println(countA/56.0); //ca. 56 tick per rotation
Serial.print("Rads rotated: "); Serial.println(countA/8.91); //ca. 56 tick per rotation, 6.26 rads per rotation
Serial.print("RPM: "); Serial.println(rpm); //ca. 56 tick per rotation
Serial.print("Rads per second: "); Serial.println(rps); //ca. 56 tick per rotation, 6.26 rads per rotation
}
void setSpeed(){
2021-04-13 22:29:15 +02:00
if(abs(safe_angle)<50 ){
2021-04-20 13:30:48 +02:00
float position_m = countA/174.76;
float speed_ms = rps * 0.05;
2021-04-16 15:38:21 +02:00
float angle_r = angle_pitch_output * 0.318;
2021-04-20 13:30:48 +02:00
float angle_speed_rs = rps;
2021-04-24 11:15:41 +02:00
speed = lqr_fullstate(0, 0, angle_r, 0);/// 0.019608; // (0.20*255)
2021-04-13 22:29:15 +02:00
if(speed<0){
digitalWrite(MotorPinB, CW);
digitalWrite(MotorPinA, CCW);
}
2021-04-13 22:29:15 +02:00
else if(speed>0){
digitalWrite(MotorPinB, CCW);
digitalWrite(MotorPinA, CW);
}
2021-04-13 22:29:15 +02:00
else {
speed = 0;
}
2021-04-24 11:15:41 +02:00
if(speed!=0){ speed = constrain(speed, -255, 255);speed = calc_speed(speed); }
2021-04-13 22:29:15 +02:00
speed = abs(speed);
2021-04-20 13:30:48 +02:00
speed = constrain(speed, 0, 255);
2021-05-13 11:38:40 +02:00
analogWrite(MotorSpeedB, speed);
analogWrite(MotorSpeedA, speed);
}
else{
speed = 0;
analogWrite(MotorSpeedB, speed);
analogWrite(MotorSpeedA, speed);
}
2021-04-20 13:30:48 +02:00
Serial.print("Speed to motors: "); Serial.println(speed);
}
int directionA(){
if(digitalRead(encoderA2) == HIGH){
return 1;
}
else{
return -1;
}
}
int directionB(){
if(digitalRead(encoderB2) == HIGH){
return 1;
}
else{
return -1;
}
}
void pulseA(){
countA += directionA();
}
void pulseB(){
countB += directionB();
}