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.
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

Popular posts from this blog

Connecting Raspberry Pi 2 to P10(1R)-V706 LED Dot Matrix - Raspberry Pi Forums

TypeError: <unknown> is not a numpy array - Raspberry Pi Forums

datso and removing imagetitle - Joomla! Forum - community, help and support