Balances a robot on two wheels using a PID controller for fine tuning the motor speed and behavior. It uses an IMU to send input to the PID controller and calibrate the robot's desired angle.
Dependencies: mbed Motor LSM9DS1_Library_cal
main.cpp
- Committer:
- johnedwardlee
- Date:
- 2019-12-06
- Revision:
- 3:8898bbbe00d6
- Parent:
- 0:e8167f37725c
File content as of revision 3:8898bbbe00d6:
/* 4180Balancer Names: John Lee, Nyle Malik, Austin Lowe Date: 12/6/19 Description: Balances a robot on two wheels using a PID controller for fine tuning the motor speed and behavior. It uses an IMU to send input to the PID controller and calibrate the robot's desired angle. */ #include "LSM9DS1.h" #include "Motor.h" #include "mbed.h" #include <time.h> #include <stdlib.h> #define RAD_TO_DEG 57.29578 #define M_PI 3.14159265358979323846 #define FILTER_CONSTANT 0.98 #define DT 0.001 DigitalOut myled(LED1); LSM9DS1 imu(p28, p27, 0xD6, 0x3C); Motor left(p21, p7, p8); Motor right(p22, p11, p12); Ticker PID; Serial pc(USBTX, USBRX); //Globals //Configure these float scalingFactor = 2000; float KP = 100; float KI = 100; float KD = 1000; float aBias = 0; float gBias = 0; float aAngle = 0; float gAngle = 0; float intAngle = 0; float derivAngle = 0; float propAngle = 0; float angle = 0; float speed = 0; void calibrate() { for(int i=0; i<100; i++) { imu.readAccel(); imu.readGyro(); aBias=aBias+(-1)*atan2((double)(imu.ay),(double)(imu.az))*180/3.142-90; gBias=gBias+imu.gx; } aBias=aBias/100; gBias=gBias/100; } void pid() { // Save the previous data derivAngle = propAngle; //Read data from the IMU imu.readAccel(); imu.readGyro(); //Controls and PID calculations aAngle = (-1) * atan2((double)(imu.ay), (double)(imu.az)) * RAD_TO_DEG - 90 - aBias; gAngle = (-1)*(imu.gx - gBias) * DT; propAngle = FILTER_CONSTANT * (propAngle + gAngle) + (1 - FILTER_CONSTANT) * aAngle - angle; derivAngle = propAngle - derivAngle; intAngle += (propAngle * DT); { speed = -((KP * propAngle) + (KI * intAngle) + (KD * derivAngle)) / scalingFactor; if (speed < -1) { speed = -1; }else if (speed > 1) { speed = 1; } // Set the speed of the motors left.speed(speed); right.speed(speed); } int main() { imu.begin(); if (!imu.begin()) { pc.printf("Failed to communicate with LSM9DS1.\n"); exit(0); } // Calibrate the IMU and set the biases calibrate(); // Attach ticker to run every 10ms // This handles the pid calculations for controlling the motors PID.attach(&pid, 0.001); // Program loop while(1) { } }