2021-04-13 21:51:43 +02:00
|
|
|
#include <Wire.h>
|
|
|
|
|
2021-04-13 20:17:11 +02:00
|
|
|
//temporary variable to measure main loops
|
|
|
|
int temp_loops;
|
|
|
|
|
2021-04-13 21:44:53 +02:00
|
|
|
//lqr stuff
|
|
|
|
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;
|
2021-04-13 22:09:37 +02:00
|
|
|
|
|
|
|
/** PWM signal applied to the motor's driver 255 is 100% */
|
2021-04-13 21:44:53 +02:00
|
|
|
int32_t speed;
|
2021-04-13 22:09:37 +02:00
|
|
|
int safe_angle;
|
2021-04-13 21:44:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
//gyro stuff
|
2021-04-13 20:17:11 +02:00
|
|
|
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;
|
|
|
|
|
|
|
|
//motor stuff
|
|
|
|
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;
|
|
|
|
|
|
|
|
void setup() {
|
2021-04-13 21:51:43 +02:00
|
|
|
Wire.begin();
|
2021-04-13 20:17:11 +02:00
|
|
|
Serial.begin(115200);
|
|
|
|
while (!Serial)
|
|
|
|
delay(10); // will pause Zero, Leonardo, etc until serial console opens
|
2021-04-13 21:44:53 +02:00
|
|
|
|
|
|
|
gyro_setup();
|
2021-04-13 20:17:11 +02:00
|
|
|
|
|
|
|
//motor
|
|
|
|
pinMode(MotorPinA, OUTPUT);
|
|
|
|
pinMode(MotorSpeedA, OUTPUT);
|
|
|
|
pinMode(MotorBrakeA, OUTPUT);
|
|
|
|
|
|
|
|
pinMode(MotorPinB, OUTPUT);
|
|
|
|
pinMode(MotorSpeedB, OUTPUT);
|
|
|
|
pinMode(MotorBrakeB, OUTPUT);
|
|
|
|
|
|
|
|
attachInterrupt(0, magnet_detectA, RISING);
|
|
|
|
//attachInterrupt(1, magnet_detectB, RISING);
|
|
|
|
half_revolutionsA = 0;
|
|
|
|
rpmA = 0;
|
|
|
|
timeoldA = 0;
|
|
|
|
|
|
|
|
half_revolutionsB = 0;
|
|
|
|
rpmB = 0;
|
|
|
|
timeoldB = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
2021-04-13 21:44:53 +02:00
|
|
|
gyro_loop();
|
2021-04-13 20:17:11 +02:00
|
|
|
|
2021-04-13 22:09:37 +02:00
|
|
|
safe_angle = int(round(angle_pitch_output));
|
|
|
|
|
2021-04-13 20:17:11 +02:00
|
|
|
if(temp_loops>100){
|
|
|
|
Serial.println("");
|
|
|
|
Serial.print(" pitch Angle = "); Serial.println(angle_pitch_output);
|
2021-04-13 22:09:37 +02:00
|
|
|
Serial.print(" pitch Angle abs = "); Serial.println(abs(safe_angle));
|
2021-04-13 20:17:11 +02:00
|
|
|
Serial.print(" pitch Angle measured = "); Serial.println(angle_pitch);
|
|
|
|
temp_loops = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
temp_loops++;
|
|
|
|
}
|
2021-04-13 22:09:37 +02:00
|
|
|
|
2021-04-13 22:29:15 +02:00
|
|
|
if(abs(safe_angle)<50 ){
|
|
|
|
speed = 8*safe_angle;
|
|
|
|
if(speed<0){
|
2021-04-13 20:17:11 +02:00
|
|
|
digitalWrite(MotorPinB, CW);
|
|
|
|
digitalWrite(MotorPinA, CCW);
|
2021-04-13 22:29:15 +02:00
|
|
|
speed -= 30;
|
2021-04-13 20:17:11 +02:00
|
|
|
}
|
2021-04-13 22:29:15 +02:00
|
|
|
else if(speed>0){
|
2021-04-13 20:17:11 +02:00
|
|
|
digitalWrite(MotorPinB, CCW);
|
|
|
|
digitalWrite(MotorPinA, CW);
|
2021-04-13 22:29:15 +02:00
|
|
|
speed += 30;
|
2021-04-13 20:17:11 +02:00
|
|
|
}
|
2021-04-13 22:29:15 +02:00
|
|
|
else {
|
|
|
|
speed = 0;
|
|
|
|
}
|
|
|
|
speed = abs(speed);
|
|
|
|
speed = constrain(speed, 0, 249);
|
2021-04-13 22:09:37 +02:00
|
|
|
analogWrite(MotorSpeedB, speed); //Wheel close to connections
|
|
|
|
analogWrite(MotorSpeedA, speed); //First experiment wheel
|
2021-04-13 20:17:11 +02:00
|
|
|
}
|
|
|
|
else{
|
2021-04-13 22:09:37 +02:00
|
|
|
speed = 0;
|
|
|
|
analogWrite(MotorSpeedB, speed);
|
|
|
|
analogWrite(MotorSpeedA, speed);
|
2021-04-13 20:17:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void magnet_detectA()//This function is called whenever a magnet/interrupt is detected by the arduino
|
|
|
|
{
|
|
|
|
half_revolutionsA++;
|
|
|
|
Serial.println("detect");
|
|
|
|
}
|
|
|
|
void magnet_detectB()//This function is called whenever a magnet/interrupt is detected by the arduino
|
|
|
|
{
|
|
|
|
half_revolutionsB++;
|
|
|
|
//Serial.println("detect");
|
|
|
|
}
|