Il sito per chi ama smanettare con Arduino, Raspberry Pi & Co.
Condividi:
Notifiche
Cancella tutti

PID Controllo con 2 motori

   RSS

0

Buongiorno sto cercando di programmare un controllo pid per due motori che hanno dei target diversi per ognuno di essi, ho un problema che quando uno dei due target viene raggiunto da uno dei due motori, l'altro motore inizia a rallentare prima di raggiungere la posizione desiderata finche non la raggiunge. In teoria dovrebbe avere velocità quasi sempre costante e solo in prossimità del target iniziare a rallentare. Sembra un problema di sincronizzazione delle velocità, ho provato a fare di tutto ma non riesco a risolvere. Grazie in anticipo se qualcuno sa come risolvere.

Questo è lo sketch:

#include link rimosso ;
#include
const unsigned int IN1 = 7;
const unsigned int IN2 = 8;
const unsigned int EN = 9;

const unsigned int IN3 = 11;
const unsigned int IN4 = 6;
const unsigned int ENB = 10;

// pin encoder with interrupt
#define encoder0PinA 4
#define encoder0PinB 3
volatile int pinAstateCurrent = LOW; // Current state of Pin A
volatile int pinAStateLast = pinAstateCurrent; // Last read value of Pin A

#define encoder1PinA 5
#define encoder1PinB 2
volatile int pinBstateCurrent = LOW; // Current state of Pin B
volatile int pinBStateLast = pinBstateCurrent; // Last read value of Pin B

int pos=0;
int posB = 0;
//for control with pid
long prevT =0;
float eprev=0;
float eintegral = 0;

long prevT_b =0;
float eprev_b=0;
float eintegral_b = 0;

//L298N motorA(EN, IN1, IN2);
//L298N motorB(ENB, IN3, IN4);
L298NX2 motors(EN, IN1, IN2, ENB, IN3, IN4);
void setup() {
Serial.begin(9600);
//start controller

pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
pinMode(encoder1PinA, INPUT);
pinMode(encoder1PinB, INPUT);

attachInterrupt(digitalPinToInterrupt(encoder0PinB),readEncoderA,CHANGE);
attachInterrupt(digitalPinToInterrupt(encoder1PinB),readEncoderB,CHANGE);

}

void loop() {

Motor1();
motor2();

}

void readEncoderA(){
pinAstateCurrent = digitalRead(encoder0PinA); // Read the current state of Pin A

// If there is a minimal movement of 1 step
if ((pinAStateLast == LOW) && (pinAstateCurrent == HIGH)) {

if (digitalRead(encoder0PinB) == HIGH) { // If Pin B is HIGH
pos++;
} else {
pos--;
}

}

pinAStateLast = pinAstateCurrent;
}

void readEncoderB(){
pinBstateCurrent = digitalRead(encoder1PinA); // Read the current state of Pin A

// If there is a minimal movement of 1 step
if ((pinBStateLast == LOW) && (pinBstateCurrent == HIGH)) {

if (digitalRead(encoder1PinB) == HIGH) { // If Pin B is HIGH
posB++;
} else {
posB--;
}

}

pinBStateLast = pinBstateCurrent;
}

void Motor1(){
int targetA=-500*sin(prevT/1e6);//valore dell'encoder come posizione finale;

// val prof kp = 5 , ki = 1 , kd = 0.01;
//PID constants
float kp = 1; //costante proportional
float kd = 0.025; //costante derivate
float ki = 0;//costante integral

/* val predefiniti
float kp = 1; //costante proportional
float kd = 0; //costante derivate
float ki = 0;//costante integral
*/

//time difference
long currT = micros();

float deltaT = ((float)(currT-prevT)) link rimosso ;
prevT = currT;




//error
int e = pos-targetA;




//derivate
float dedt = (e-eprev)/(deltaT);

//integral
eintegral = eintegral + e*deltaT;

//control signal
float u = kp*e + kd*dedt + ki*eintegral;

//motor power
float pwr = fabs(u);

link rimosso ("PWR : ");
link rimosso ln(pwr);

if(pwr>255){ //controllo velocità forse 400
pwr = 255;

}
if(pwr<30){ //controllo velocità forse 400
//pwr = 30;

}

//motor direction
int dir = 1;
if(u<0){
dir = -1;
}




//signal the motor speed
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){

link rimosso (pwr);
link rimosso (pwr_b);

if(dir==1){
link rimosso ();
digitalWrite(7, LOW); // Impostazione della direzione “avanti” del motore collegato al canale A
digitalWrite(8, HIGH); // Disattivazione del brake del motore per il canale A
analogWrite(9,pwr);
// Serial.println("AVANTI_A");
}
if(dir==-1){
link rimosso ();
digitalWrite(7, HIGH); // Impostazione della direzione “avanti” del motore collegato al canale A
digitalWrite(8, LOW); // Disattivazione del brake del motore per il canale A
analogWrite(9,pwr);
link rimosso ln("INDIETRO_A");
}
if(pwr == 0){
link rimosso ();
digitalWrite(7, LOW); // Impostazione della direzione “avanti” del motore collegato al canale A
digitalWrite(8, LOW);
link rimosso ln("STOP_A");
}

}

// store previous error
eprev = e;




Serial.print(targetA);
Serial.print(" ");
Serial.print(pos);
Serial.println();

}

void motor2(){

int targetB=750*sin(prevT/1e6); //valore dell'encoder come posizione finale;
// val prof kp = 5 , ki = 1 , kd = 0.01;
//PID constant
float kp_b = 1; //costante proportional
float kd_b = 0.025; //costante derivate
float ki_b = 0;//costante integral
/* val predefiniti
float kp = 1; //costante proportional
float kd = 0; //costante derivate
float ki = 0;//costante integral
*/

//time difference

long currT_b = micros();




float deltaT_b = ((float)(currT_b-prevT_b)) link rimosso ;
prevT_b = currT_b;

//error

int e_b = posB-targetB;

//derivate

float dedt_b = (e_b-eprev_b)/(deltaT_b);

//integral

eintegral_b = eintegral_b + e_b*deltaT_b;

//control signal

float u_b = kp_b*e_b + kd_b*dedt_b + ki_b*eintegral_b;

//motor power

float pwr_b = fabs(u_b);
link rimosso ("PWR : ");
link rimosso ln(pwr);

if(pwr_b>255){ //controllo velocità forse 400
pwr_b = 255;

}
if(pwr_b<30){ //controllo velocità forse 400
pwr_b = 30;

}




int dir_b = 1;
if(u_b<0){
dir_b = -1;
}

//signal the motor speed
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){

link rimosso (pwr);
link rimosso (pwr_b);

if(dir_b==1){
link rimosso ();
digitalWrite(11, LOW); // Impostazione della direzione “avanti” del motore collegato al canale A
digitalWrite(6, HIGH); // Disattivazione del brake del motore per il canale A
analogWrite(10, pwr_b); //motoreB
link rimosso ln("AVANTI_B");
}
if(dir_b==-1){
link rimosso ();
digitalWrite(11, HIGH); // Impostazione della direzione “avanti” del motore collegato al canale A
digitalWrite(6, LOW); // Disattivazione del brake del motore per il canale A
analogWrite(10, pwr_b); //motoreB
link rimosso ln("INDIETRO_B");
}
if(pwr_b == 0){
link rimosso ();
digitalWrite(11, LOW); // Impostazione della direzione “avanti” del motore collegato al canale A
digitalWrite(6, LOW); // Disattivazione del brake del motore per il canale A
analogWrite(10, pwr_b); //motoreB
link rimosso ln("STOP_B");
}
}

// store previous error

eprev_b = e_b;




Serial.print(targetB);
Serial.print(" ");
Serial.print(posB);
Serial.print(" ");
Serial.println();

}














Questa argomento è stata modificata 5 mesi fa da admin
Tag argomenti
Condividi:

Entra nel forum

Hai un nuovo progetto in mente ma hai dei dubbi su come realizzarlo? Vuoi condividere la tua conoscenza da maker con gli altri? Registrati nella nostra community e potrai chiedere fare la tua domanda o rispondere e condividere la tua conoscenza in internet.