Controller of the linear speed of the arm
Dependencies: QEI X_NUCLEO_IHM04A1
Revision 1:97a0f449f19d, committed 2019-05-03
- Comitter:
- LuCordeschi
- Date:
- Fri May 03 15:07:35 2019 +0000
- Parent:
- 0:839902368a34
- Child:
- 2:fc8d58f9f5ce
- Commit message:
- Speed arm controller;
Changed in this revision
--- a/main.cpp Thu Apr 11 16:15:01 2019 +0000
+++ b/main.cpp Fri May 03 15:07:35 2019 +0000
@@ -1,50 +1,81 @@
#include "mbed.h"
-#include "L6206_def.h"
+#include "L6206.h"
#include "BDCMotor.h"
-#include "QEI.h"
#include <math.h>
+Thread thread;
+
+
+void encoder() {
+ //Read the position by the encoder and save it in pos_encoder
+ wait(0.1);
+}
+void command() {
+ //Read the command (at the moment considered by me a normalized velocity)
+ wait(0.2);
+}
int main (int argc,char **argv) {
- //Prendo il comando -> fisso un punto da raggiungere (IK) (Automatico) -> In tot step voglio tale duty cicle
+ //Prendo il comando -> fisso un punto da raggiungere (Automatico) -> In tot step voglio tale duty cicle
+ //Common variables
+ float k = 0;
+ float v_max = 15; //mm/s
+ float pos_encoder = 0; //Posizione misurata dall'encoder
+ float k1 = 0;
+ float startPos_encoder = 0;
+ float frequency; //sampling frequency of the encoder
+ int Auto = 0;
+
+ //Auto variables
float finalDestination; //posizione da raggiungere RICEVUTA COME PARAMETRO
- float pos_encoder; //Posizione misurata dall'encoder
- float acceleration_range=40; //n° step in accelerazione/decelerazione. Deciso da me
- float track_error=1;
+ float acceleration_range = 15; //n° step in accelerazione/decelerazione. Deciso da me
+ float track_error = 1;
float sens_error; //Error given by the amplitude of a step of the encoder
- float k=0;
- float Contr_reference=0; //Is the starting tracking error, needed to impose the right form of controller
- float k1=0;
- float startPos_encoder=0;
- float PWM_dutyReduct=0; //Variables used in case of triangular control
- float acc_rangeReduct=0;
- int Auto=0;
- //Initialization
-
+ float v_request = 0;
+ float PWM_dutyReduct = 0; //Variables used in case of triangular control
+ float acc_rangeReduct = 0;
+ float Contr_reference = 0; //Is the starting tracking error, needed to impose the right form of controller
+
+ //Manual variables
+ float v_normalized = 0; //Manual command that indicates the direction and the magnitude of the velocity
+ float v_actual = 0; //real velocity of the arm, computed through as incremental ratio
+ float delta_v=0; //Difference of velocities used as input for control
+ float a_max = 7.5; //maximum accelerazion mm/s^2
+ float time = 0;
+ float prev_pos = 0; //Previous potition to compute the velocity as an incremental ratio
+
+ //Initialization: to write the right pins
+ //L6206(PinName EN_flag_A, PinName EN_flag_B, PinName pwm_1A, PinName pwm_2A, PinName pwm_1B, PinName pwm_2B) : BDCMotor(), flag_A_irq(EN_flag_A), flag_B_irq(EN_flag_B), EN_flag_A(EN_flag_A), EN_flag_B(EN_flag_B), pwm_1A(pwm_1A), pwm_2A(pwm_2A), pwm_1B(pwm_1B), pwm_2B(pwm_2B)
+
L6206 *motor;
- switch Auto {
-
- case 1 {/*The rover is in its automatic mode*/
+ /*Take initial pos encoder -> saved in starPos_encoder*/
+
+ pos_encoder = startPos_encoder;
+ switch (Auto) {
- //OTTENGO LA pozisione iniziale dell'encoder startPos_encoder
+ case 1: {/*The rover is in its automatic mode*/
+
+ //OTTENGO LA posizione iniziale dell'encoder startPos_encoder
//Ottengo il comando
- Contr_reference=finalDestination-startPos_encoder;
- track_error=Contr_reference;
+ Contr_reference = finalDestination-startPos_encoder;
+ track_error = Contr_reference;
while (track_error>sens_error) {
if (Contr_reference>2*acceleration_range) { //Controllo trapezoidale
if (track_error>(finalDestination-acceleration_range)) {
- k1=k;
- k=(track_error/(finalDestination-acceleration_range))*90; //V da imporre
+ k1 = k;
+ k = (track_error/(finalDestination-acceleration_range))*100; //V da imporre
motor->set_speed(k1,k);
+
} else if (track_error<acceleration_range) {
- k1=k;
- k=((track_error)/acceleration_range)*90; //PWM_duty=90*(1-k)
+ k1 = k;
+ k = ((track_error)/acceleration_range)*100; //PWM_duty = 90*(1-k)
motor->set_speed(k1,k);
+
} else { //Can it be eliminated? (no command, no velocity variations)
/*v stays constant*/
}
@@ -53,39 +84,77 @@
} else { //Controllo triangolare
/*Si agisce in maniera analoga al caso non saturato ma si impone un duty cicle massimo minore
In particolare la v_max è proporzionale alla dimensione dello spostamento con 90 che corrisponde
- a un intervallo pari a 40 e poi si defininisce il nuovo PWM_dutyReduct=interval*90/40
+ a un intervallo pari a 40 e poi si defininisce il nuovo PWM_dutyReduct = interval*90/40
*/
- PWM_dutyReduct=(Contr_reference/(2*acceleration_range))*90;
+ PWM_dutyReduct = (Contr_reference/(2*acceleration_range))*100;
//A new variable is needed to indicate the range of acceleration (in this case is less than the acceleration_range)
- acc_rangeReduct=Contr_reference/2;
- if (track_error>acceleration_range) {
- k1=k;
- k=(track_error/(finalDestination-acceleration_range)); //costante di proporzionalità
- //PWM_duty=k1*PWM_dutyReduct
- motor->set_speed(k1,k);
+ acc_rangeReduct = Contr_reference/2;
+ if (track_error>acc_rangeReduct) {
+ k1 = k;
+ k = (track_error/(finalDestination-acc_rangeReduct))*PWM_dutyReduct; //costante di proporzionalità
+ //PWM_duty = k1*PWM_dutyReduct
+ motor->set_speed(k1,k);
+
} else {
- k1=k
- k=(track_error/acceleration_range);
- //PWM_duty=PWM_dutyReduct*(1-k)
+ k1 = k;
+ k = (track_error/acc_rangeReduct)*PWM_dutyReduct;
+ //PWM_duty = PWM_dutyReduct*(1-k)
motor->set_speed(k1,k);
+
}
//Leggo la pos_encoder attuale
}
- track_error=finalDestination-pos_encoder; //It is used as counter
+ track_error = finalDestination-pos_encoder; //It is used as counter
}
}
break;
- case 0 { //Manual control based on a velocity control with a position feedback. The following velocities are gotten through a
-
- }
- break;
-
- default {
- /*Error message*/
- }
- break;
+ default: { //Manual control based on a velocity control with a position feedback. The following velocities are gotten through a [-1,1] command,
+ //normalized velocity
+ while(1) {
+
+ v_request = abs(v_normalized*v_max); //*(100/v_max); //Command is think to be a normalized velocity
+ delta_v = v_request-v_actual;
+ while (delta_v != 0) { //MUST add a condition about the maximum acceleration.
+ /*Choosing a maximum acceleration, preferebly linked to the condition of the syste (motor, structure, Pwm and so on).
+ Imposing an acceleration of 7.5 mm/s^2 to reach the v_max 2 secs are needed.*/
+ //Measure the new position
+ time = time+(1/frequency);
+
+ if (v_normalized > 0){
+ motor->run(1, BDCMotor::FWD);
+ k1 = k;
+ k = k+a_max/frequency*100/v_max;
+ motor->set_speed(k1,k);
+
+ } else if (v_normalized<0){
+ motor->run(1, BDCMotor::BWD);
+ k1 = k;
+ k = k+a_max/frequency*100/v_max;
+ motor->set_speed(k1,k);
+
+ } else{
+ k1 = k;
+ k = k-a_max/frequency*100/v_max;
+ motor->set_speed(k1,k);
+
+ }
+
+ prev_pos = pos_encoder;
+
+ v_actual = (pos_encoder-prev_pos)*frequency;
+ //In this computation is better to consider the velocity in the single period or the overall one?
+
+ delta_v = v_request-v_actual;
+ wait(0.1);
+ }
+
+ }
+ }
+ break;
+
+
+ }
}
-}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Fri May 03 15:07:35 2019 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#c9e63f14085f5751ff5ead79a7c0382d50a813a2
--- a/mbed.bld Thu Apr 11 16:15:01 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file