mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 06:28:27 -04:00
A simple OO PID library
git-svn-id: https://arducopter.googlecode.com/svn/trunk@742 f9c3cf11-9bcb-44bc-f272-b75c42450872
This commit is contained in:
parent
610609f98d
commit
e7b26da27d
186
libraries/PID/PID.cpp
Normal file
186
libraries/PID/PID.cpp
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
#include "PID.h"
|
||||||
|
|
||||||
|
PID::PID()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
PID::get_pid(long err, long dt, float scaler)
|
||||||
|
{
|
||||||
|
// Positive error produces positive output
|
||||||
|
float output;
|
||||||
|
float error = (float)err;
|
||||||
|
float delta_time = (float)dt/1000.0;
|
||||||
|
|
||||||
|
// Compute proportional component
|
||||||
|
if(_kp != 0){
|
||||||
|
output += (_kp * error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_kd != 0){
|
||||||
|
// Compute derivative component
|
||||||
|
//derivative = (error - previous_error)/dt
|
||||||
|
float derivative = (error - _last_error) / dt;
|
||||||
|
|
||||||
|
//Serial.print("d: ");
|
||||||
|
//Serial.println(derivative,DEC);
|
||||||
|
|
||||||
|
_last_error = error;
|
||||||
|
output += _kd * derivative; // Sum the derivative component
|
||||||
|
}
|
||||||
|
|
||||||
|
output *= scaler;
|
||||||
|
|
||||||
|
// Compute integral component
|
||||||
|
if(_ki != 0){
|
||||||
|
_integrator += (error * _ki) * scaler * dt *.001;
|
||||||
|
_integrator = constrain(_integrator, -_imax, _imax);
|
||||||
|
output += _integrator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::reset_I(void)
|
||||||
|
{
|
||||||
|
_integrator = 0;
|
||||||
|
_last_error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// setters
|
||||||
|
void
|
||||||
|
PID::set_P(float p)
|
||||||
|
{
|
||||||
|
_kp = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::set_I(float i)
|
||||||
|
{
|
||||||
|
_ki = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::set_D(float d)
|
||||||
|
{
|
||||||
|
_kd = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::set_imax(int imax)
|
||||||
|
{
|
||||||
|
_imax = imax;
|
||||||
|
Serial.print("set imax ");
|
||||||
|
Serial.println(_imax, DEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// getters
|
||||||
|
float
|
||||||
|
PID::get_P(void)
|
||||||
|
{
|
||||||
|
return _kp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
PID::get_I(void)
|
||||||
|
{
|
||||||
|
return _ki;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
PID::get_D(void)
|
||||||
|
{
|
||||||
|
return _kd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PID::get_imax(void)
|
||||||
|
{
|
||||||
|
return _imax;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::load_gains(int address)
|
||||||
|
{
|
||||||
|
//Serial.println("load gains ");
|
||||||
|
//Serial.println(address, DEC);
|
||||||
|
_kp = (float)(eeprom_read_word((uint16_t *) address)) / 1000.0;
|
||||||
|
_ki = (float)(eeprom_read_word((uint16_t *) (address + 2))) / 1000.0;
|
||||||
|
_kd = (float)(eeprom_read_word((uint16_t *) (address + 4))) / 1000.0;
|
||||||
|
_imax = eeprom_read_word((uint16_t *) (address + 6)) * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::save_gains(int address)
|
||||||
|
{
|
||||||
|
eeprom_write_word((uint16_t *) address, (int)(_kp * 1000));
|
||||||
|
eeprom_write_word((uint16_t *) (address + 2), (int)(_ki * 1000));
|
||||||
|
eeprom_write_word((uint16_t *) (address + 4), (int)(_kd * 1000));
|
||||||
|
eeprom_write_word((uint16_t *) (address + 6), (int)_imax/100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
float
|
||||||
|
read_EE_compressed_float(int address, byte places)
|
||||||
|
{
|
||||||
|
float scale = places * 10;
|
||||||
|
int temp = eeprom_read_word((uint16_t *) address);
|
||||||
|
return ((float)temp / scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_EE_compressed_float(float value, int address, byte places)
|
||||||
|
{
|
||||||
|
float scale = places * 10;
|
||||||
|
int temp = value * scale;
|
||||||
|
eeprom_write_word((uint16_t *) address, temp);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
PID::test(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
int address = 0x46;
|
||||||
|
Serial.print("imax= ");
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.print(eeprom_read_word((uint16_t *) address));
|
||||||
|
Serial.print(" ");
|
||||||
|
address += 8;
|
||||||
|
Serial.println(eeprom_read_word((uint16_t *) address));
|
||||||
|
*/
|
||||||
|
}
|
37
libraries/PID/PID.h
Normal file
37
libraries/PID/PID.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef PID_h
|
||||||
|
#define PID_h
|
||||||
|
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include "WProgram.h"
|
||||||
|
|
||||||
|
//#define PID_SIZE 8
|
||||||
|
|
||||||
|
class PID {
|
||||||
|
public:
|
||||||
|
PID();
|
||||||
|
long get_pid(long err, long dt, float scaler);
|
||||||
|
void reset_I();
|
||||||
|
void load_gains(int address);
|
||||||
|
void save_gains(int address);
|
||||||
|
void set_P(float p);
|
||||||
|
void set_I(float i);
|
||||||
|
void set_D(float d);
|
||||||
|
void set_imax(int imax);
|
||||||
|
void test(void);
|
||||||
|
|
||||||
|
float get_P(void);
|
||||||
|
float get_I(void);
|
||||||
|
float get_D(void);
|
||||||
|
int get_imax(void);
|
||||||
|
float _imax; // integrator max
|
||||||
|
float _integrator; // integrator value
|
||||||
|
float _last_error; // last error for derivative
|
||||||
|
float _kp;
|
||||||
|
float _ki;
|
||||||
|
float _kd;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
38
libraries/PID/examples/pid/pid.pde
Normal file
38
libraries/PID/examples/pid/pid.pde
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Example of PID library.
|
||||||
|
2010 Code by Jason Short. DIYDrones.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <PID.h> // ArduPilot Mega RC Library
|
||||||
|
#include <APM_RC.h> // ArduPilot RC Library
|
||||||
|
|
||||||
|
PID pid;
|
||||||
|
long radio_in;
|
||||||
|
long radio_trim;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(38400);
|
||||||
|
Serial.println("ArduPilot Mega PID library test");
|
||||||
|
APM_RC.Init(); // APM Radio initialization
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
//rc.trim();
|
||||||
|
radio_trim = APM_RC.InputCh(0);
|
||||||
|
|
||||||
|
pid.set_P(1);
|
||||||
|
pid.set_I(0);
|
||||||
|
pid.set_D(.5);
|
||||||
|
pid.set_imax(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
delay(20);
|
||||||
|
//rc.read_pwm();
|
||||||
|
long error = APM_RC.InputCh(0) - radio_trim;
|
||||||
|
long control = pid.get_pid(error, 20, 1);
|
||||||
|
|
||||||
|
Serial.print("control: ");
|
||||||
|
Serial.println(control,DEC);
|
||||||
|
}
|
8
libraries/PID/keywords.txt
Normal file
8
libraries/PID/keywords.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
APM_RC KEYWORD1
|
||||||
|
begin KEYWORD2
|
||||||
|
InputCh KEYWORD2
|
||||||
|
OutputCh KEYWORD2
|
||||||
|
GetState KEYWORD2
|
||||||
|
Force_Out0_Out1 KEYWORD2
|
||||||
|
Force_Out2_Out3 KEYWORD2
|
||||||
|
Force_Out6_Out7 KEYWORD2
|
Loading…
Reference in New Issue
Block a user