Balance robot PID understanding
hello all,
i have been struggling part of pid code below. having hard time understandung how "out" part of pid drives motors setpoint. in code below the" out " mentioned once in code. (being new arduino) have expected see "out = drive(0,0);" to drive motors setpoint. said "out" mentioned once(except return). maybe missing has been starring me in face whole time.
my goal use pid other fun things , learn. understand there other pid examples, , tutorials out there learn from, dead set understand one
so if wanted make code measured how hot 1 of sensers(reading) is, , cool down. , temp wanted (target).
and if used fan (out) cool down. part of pid below used drive motor of fan target temp?
for of easy explaination, , appreciate can move forword.
i have been struggling part of pid code below. having hard time understandung how "out" part of pid drives motors setpoint. in code below the" out " mentioned once in code. (being new arduino) have expected see "out = drive(0,0);" to drive motors setpoint. said "out" mentioned once(except return). maybe missing has been starring me in face whole time.
my goal use pid other fun things , learn. understand there other pid examples, , tutorials out there learn from, dead set understand one
so if wanted make code measured how hot 1 of sensers(reading) is, , cool down. , temp wanted (target).
and if used fan (out) cool down. part of pid below used drive motor of fan target temp?
for of easy explaination, , appreciate can move forword.
code: [select]
#include "i2cdev.h"
#include "mpu6050_6axis_motionapps20.h"
//#include "mpu6050.h" // not necessary if using motionapps include file
// arduino wire library required if i2cdev i2cdev_arduino_wire implementation
// used in i2cdev.h
#if i2cdev_implementation == i2cdev_arduino_wire
#include "wire.h"
#endif
mpu6050 mpu;
// mpu control/status vars
bool dmpready = false; // set true if dmp init successful
uint8_t mpuintstatus; // holds actual interrupt status byte mpu
uint8_t devstatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetsize; // expected dmp packet size (default 42 bytes)
uint16_t fifocount; // count of bytes in fifo
uint8_t fifobuffer[64]; // fifo storage buffer
// orientation/motion vars
quaternion q; // [w, x, y, z] quaternion container
vectorint16 aa; // [x, y, z] accel sensor measurements
vectorint16 aareal; // [x, y, z] gravity-free accel sensor measurements
vectorint16 aaworld; // [x, y, z] world-frame accel sensor measurements
vectorfloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi] euler angle container
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container , gravity vector
volatile bool mpuinterrupt = false; // indicates whether mpu interrupt pin has gone high
void dmpdataready() {
mpuinterrupt = true;
}
/* variables pid controller */
float kp = 58.30f;
float kd = 0.00039f;
float ki = 0.0024f; //0.0020 seems work good
float reading = 0.0f;
float target = -1.79f;// add negative give more pwm rear // rear uno side
float errorcurrent = 0.0f;
float errorlast = 0.0f;
float errorsum = 0.0f;
float errordelta = 0.0f;
unsigned long timelast = 0;
int correction = 0;
/* variables motor control*/
const int motorleftpin1 = 8;
const int motorleftpin2 = 9;
const int motorleftpinen = 10; //pwm enabled side mega on
const int motorrightpin1 = 12;
const int motorrightpin2 = 13;
const int motorrightpinen = 11; //pwm enabled oposit side of mega
const int minspeed = 90; // defines useful pwm range of motors [minspeed, 255]
// ================================================================
// === initial setup ===
// ================================================================
void setup() {
// join i2c bus (i2cdev library doesn't automatically)
#if i2cdev_implementation == i2cdev_arduino_wire
wire.begin();
twbr = 24; // 400khz i2c clock (200khz if cpu 8mhz)
#elif i2cdev_implementation == i2cdev_builtin_fastwire
fastwire::setup(400, true);
#endif
mpu.initialize();
devstatus = mpu.dmpinitialize();
if (devstatus == 0) {
mpu.setdmpenabled(true);
attachinterrupt(0, dmpdataready, rising);
mpuintstatus = mpu.getintstatus();
dmpready = true;
packetsize = mpu.dmpgetfifopacketsize();
} else {
}
pinmode(motorleftpin1, output);
pinmode(motorleftpin2, output);
pinmode(motorleftpinen, output);
pinmode(motorrightpin1, output);
pinmode(motorrightpin2, output);
pinmode(motorrightpinen, output);
#define microseconds_per_timer0_overflow (clockcyclestomicroseconds(64 * 256))
to:
#define microseconds_per_timer0_overflow (clockcyclestomicroseconds(1 * 510))
void loop() {
// if programming failed, don't try anything
if (!dmpready) return;
// wait mpu interrupt or packet(s) available
while (!mpuinterrupt && fifocount < packetsize) {
// drive(255, 255);
// delay(5000);
// drive(0,0);
// delay(5000);
}
mpuinterrupt = false;
mpuintstatus = mpu.getintstatus();
// current fifo count
fifocount = mpu.getfifocount();
if ((mpuintstatus & 0x10) || fifocount == 1024) {
// reset can continue cleanly
mpu.resetfifo();
//serial.println(f("fifo overflow!"));
// otherwise, check dmp data ready interrupt (this should happen frequently)
} else if (mpuintstatus & 0x02) {
// wait correct available data length, should short wait
while (fifocount < packetsize) fifocount = mpu.getfifocount();
mpu.getfifobytes(fifobuffer, packetsize);
fifocount -= packetsize;
#ifdef output_readable_quaternion
// display quaternion values in easy matrix form: w x y z
mpu.dmpgetquaternion(&q, fifobuffer);
//
#endif
#ifdef output_readable_euler
// display euler angles in degrees
mpu.dmpgetquaternion(&q, fifobuffer);
mpu.dmpgeteuler(euler, &q);
#endif
#ifdef output_readable_yawpitchroll
// display euler angles in degrees
mpu.dmpgetquaternion(&q, fifobuffer);
mpu.dmpgetgravity(&gravity, &q);
mpu.dmpgetyawpitchroll(ypr, &q, &gravity);
if (millis()>=15000) {
reading = ypr[2] * 180/m_pi;
// stop motors , pid controller if bot tilted more 30 degrees
if ((int)reading >=-30 && reading <= 30) {
correction = pid();
drive(correction, correction);
}
else {
drive(0,0);
}
}
#endif
}
void drive(int leftmotorspeed, int rightmotorspeed) {
int left = constrain(leftmotorspeed, -255, 255);
int right = constrain(rightmotorspeed, -255, 255);
if (left < 0) {
if (left >= -40) {left = 0;}
else if (left >= -100) {left = -100;}
digitalwrite(motorleftpin1, low);
digitalwrite(motorleftpin2, high);
analogwrite(motorleftpinen, -left);
}
else if (left == 0) {
digitalwrite(motorleftpin1, low);
digitalwrite(motorleftpin2, low);
digitalwrite(motorleftpinen, low);
}
else {
if (left <= 40) {left = 0;}
else if (left <= 100) {left = 100;}
digitalwrite(motorleftpin1, high);
digitalwrite(motorleftpin2, low);
analogwrite(motorleftpinen, left);
}
if (right < 0) {
if (right >= -40) {right = 0;}
else if (right >=-100) {right = -100;}
digitalwrite(motorrightpin1, low);
digitalwrite(motorrightpin2, high);
analogwrite(motorrightpinen, -right);
}
else if (right == 0) {
digitalwrite(motorrightpin1, low);
digitalwrite(motorrightpin2, low);
digitalwrite(motorrightpinen, low);
}
else {
if (right <= 45) {right = 0;}
else if (right <= 90) {right = 90;};
digitalwrite(motorrightpin1, high);
digitalwrite(motorrightpin2, low);
analogwrite(motorrightpinen, right);
}
}
int pid() {
// calculate elapsed time since last run
unsigned long = millis();
float timedelta = (float)(now - timelast);
// initialize timedelta float next calculations
// compute error data
errorcurrent = target - reading;
errorsum = errorsum + (errorcurrent * timedelta);
errordelta = (errorcurrent - errorlast) / timedelta;
// constrain output acceptable range motor pwm signal
float pterm = kp * errorcurrent;
float iterm = ki * errorsum;
float dterm = kd * errorsum;
// constrain integral term [-255; 255]
float limit = 255.0f;
if (iterm > limit) {iterm = limit;}
else if (iterm < -limit) {iterm = -limit;}
// calculate pid output
float pid = pterm + iterm + dterm;
// constrain pid output [-255; 255]
if (pid > limit) {pid = limit;}
else if (pid < -limit) {pid = -limit;}
// store data next run
errorlast = errorcurrent;
timelast = now;
int out = (int)pid * (-1); // not worried correct rounding here
return out;
}
quote
i have been struggling part of pid code below.
fyi,
there no code "below".
quote
this pid
what pid ?
Arduino Forum > Using Arduino > Programming Questions > Balance robot PID understanding
arduino
Comments
Post a Comment