roboforum.ru

Технический форум по робототехнике.

Точное позиционирование коллекторного двигателя

Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 17:31

Ребята. Мучаюсь уже месяц. Помогите
Взял за основу гуляющий по инету код ПИД алгоритма и вот не могу добиться точного положения. Либо вообще не позиционируется. Смыкает во все стороны ни как не может попсать в точку. Есть энкодер. По прерыванию снимаем импульсы. Но вот добиться точного положения не могу. Перерыл кучу литературы по ПИД - ужас. Может есть решение проще?
Вот куски кода.



// spinMotor(),
int pinMotor1 = 8;
int pinMotor2 = 9;
int pinMotorSpeed = 10;

// pid ()
float kP = 2.25;
float kI = .5;
float kD = 1;
int iMax = 100;
int iMin = 0;
int error = 0;
int lastError = 0;
int sumError = 0;
int minSpeed = 100;
int maxSpeed = 255;

// loop()
int potVal = 0; // значение потенциометра
int inTimeStep = 0;

// encoder()
int interruptPin = 2;
int buttonDir = 3;
volatile int steping = 0;

void setup() {
Serial.begin(9600);
// motor
pinMode(pinMotor1, OUTPUT);
pinMode(pinMotor2, OUTPUT);
pinMode(pinMotorSpeed, OUTPUT);
// encoder
pinMode(interruptPin, INPUT);
pinMode(buttonDir, INPUT);
digitalWrite(interruptPin, HIGH);
digitalWrite(buttonDir, HIGH);
attachInterrupt(0, encoder, RISING);

}

void loop() {
if (Serial.available()>0) potVal = readPotSerial();
inTimeStep = pid(potVal);
spinMotor (inTimeStep);
}


// speedR - скорость вращения от 0 до 255 (положительное значение вращаем в одну сторону, отрицательное - в другую)
void spinMotor (int speedR) {
if (speedR > 0)
{
digitalWrite(pinMotor1,HIGH);
digitalWrite(pinMotor2,LOW);
}
else if (speedR < 0)
{
digitalWrite(pinMotor1,LOW);
digitalWrite(pinMotor2,HIGH);
speedR = speedR * -1;
}
int motorSpeed = map(speedR, 0, 1024, minSpeed, maxSpeed);

if (steping == potVal ) {
digitalWrite(pinMotor1,LOW);
digitalWrite(pinMotor2,LOW);
}
analogWrite(pinMotorSpeed, motorSpeed);
}

// основной алгоритм подсчета
// расчет скорости и направления движения двигателя (ПИД алгоритм)
int pid(int target) {
int error = steping - target;
int correct = kP * error + kD * (error - lastError) + kI * (sumError);
lastError = error;
sumError += error;

if(sumError > iMax){
sumError = iMax;
}
else if(sumError < iMin){
sumError = iMin;
}
return correct;
}


// читает значение с энкодера через прерывание и инкрементирует или декрементирует значение steping
void encoder() {
if (digitalRead(interruptPin) == digitalRead(buttonDir)) {
steping ++;
}
else {
steping --;
}
}


int minSpeed = 100; взята потому, что на меньших значениях появляется писк и не хватает усилия провернуть мотор
Поделитесь идеями, что не так?

Re: Точное позиционирование коллекторного двигателя

=DeaD= » 30 сен 2011, 17:45

Сколько у вас кликов на оборот? Сколько оборотов в минуту? Какая частота работы ПИД-регулятора? Какую точность позиционирования в кликах хотите получит?

Re: Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 18:02

так. Энкодер 256 имп. на оборот
Что значит частота ПИД- регулятора? Функия выполняется циклически - это видно в коде.
Можно повесить проверку положения на прерывание по таймеру но, что - это даст?

Re: Точное позиционирование коллекторного двигателя

=DeaD= » 30 сен 2011, 18:32

ПИД-регулятор не выполняется циклически сколько угодно раз в секунду, он должен выполняться с какой-то частотой, иначе это у вас не ПИД-регулятор, а неведомая зверушка :).

Re: Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 18:51

Я запостил код. Ткните пальцем.
Повесить функцию pid на таймер?

Re: Точное позиционирование коллекторного двигателя

=DeaD= » 30 сен 2011, 19:50

Можно на таймер, можно банально паузу вставить в loop() в конце, чтобы оно хотя-бы близко к нужной периодичности работало, а не просто "чем чаще, тем лучше", как сейчас.

Re: Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 19:57

Хорошо... Что дальше?
Я так понимаю все дело в коэффициентах?

Добавлено спустя 49 секунд:
loop() Что-то очень не хочется использовать.

Re: Точное позиционирование коллекторного двигателя

boez » 30 сен 2011, 20:07

Все дело и в коэффициентах, и в точном времени цикла! Потому что любое изменение времени цикла эквивалентно пропорциональному изменению сразу двух коэффициентов - интегрального и дифференциального, причем в разные стороны. Естественно это приводит к нестабильной работе.

Re: Точное позиционирование коллекторного двигателя

=DeaD= » 30 сен 2011, 20:14

nefilim писал(а):Я так понимаю все дело в коэффициентах?

Смотря какое дело. Скажем, если у вас энкодер даёт 2 клика на каждый оборот, то стабилизировать скорость 60rpm при изменяющейся каждую секунду нагрузке будет трудно, как ни подбирай коэффициенты :)

Re: Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 20:23

Так. То есть функцию pid однозначно вешаем на таймер?! Так?
Сейчас попробую... Спасибо за наводку.
Извините, но ПИД для меня сложновато. Системы автоматического управления - это вообще целая наука.
Спасибо за подсказки, но думаю - это еще не все... Будут еще танцы с бубном с коэффициентами я так понимаю.

Добавлено спустя 4 минуты 13 секунд:
С какой частотой должен работать ПИД? 100 кГц достаточно?

Re: Точное позиционирование коллекторного двигателя

=DeaD= » 30 сен 2011, 20:46

Я тут статью переводил: [[Перевод статьи "Просто о ПИД-алгоритмах"]]

По частоте - 100кГц нафиг не надо скорее всего, для управления движками 100Гц может хватить, если вы не стабилизируете обороты шпинделя жесткого диска :) в целом нет смысла вызывать ПИД-регулятор чаще срабатываний энкодера.

Re: Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 20:58

Читал вашу статью. Конечно-же. точнее перевод.
Теоретически понятно, вот на практике не получается.
http://pidcontrol.narod.ru/ здесь тоже доходчиво..
В общем погодите.. Пока информации достаточно.
Разберемся для начала с таймером

Re: Точное позиционирование коллекторного двигателя

avr123.nm.ru » 30 сен 2011, 21:31

nefilim писал(а):Может есть решение проще?
Попробуйте код из апноута взять - микрочип AN696 атмел AVR447 AVR-про ПИД AVR49x

Re: Точное позиционирование коллекторного двигателя

nefilim » 30 сен 2011, 21:37

Так повесил все на прерывание. Результат то-же...
Смыкает в разные стороны и ни как не может стабилизироваться.
Что я не так делаю?

Re: Точное позиционирование коллекторного двигателя

avr123.nm.ru » 30 сен 2011, 22:07

А еще готовый проект РАБОЧИЙ "uhu servo" на основе серво Элм Чена и легко найдете его переделанный рус умельцем на мегу8 и работающий на ЧПУ.


Rambler\'s Top100 Mail.ru counter