taker KRAI 2018
Dependencies: mbed encoderKRTMI Motornew millis
main.cpp
- Committer:
- SalbiFaza
- Date:
- 2019-02-24
- Revision:
- 0:dddc43348c25
File content as of revision 0:dddc43348c25:
//////////////////////////////////////////////////////////////////////////////// // Robo Taker (Semi-Otomatis) 2018 // // -------------------------------------------------------------------------- // // Gerakan Robot: // // - Arah -> Gerak // // - Silang -> Buka atau Tutup Gripper A // // - Lingkaran -> Buka atau Tutup Gripper B // // - Kotak -> Extend atau Shrink Slider A // // - Segitigas -> Extend atau Shrink Slider B // // - Start -> Ubah Mode // //////////////////////////////////////////////////////////////////////////////// #include "mbed.h" #include "Motor.h" #include "encoderKRTMI.h" #include "JoystickPS3.h" #include "pinList.h" #include "millis.h" //////////////////////////////////////////////////////////////////////////////// // Konstanta Program // //////////////////////////////////////////////////////////////////////////////// #define PI 3.141592653593 #define RAD_TO_DEG 57.2957795131 #define MAX_W_SPEED 15000 //max angular speed of robot #define TOLERANCET 0.8 //theta tolerance #define PULSE_TO_JARAK 0.7416027 //0.7656027 //0.581776 //kll roda / pulses #define L 298.0 //roda to center of robot #define TS 2.0 //time sampling #define LIMITPWM 0.4 //limit pwm motor //Konstanta PID Theta #define KP_W 1.8 #define KI_W 0 #define KD_W 140 #define MOTOR_LIMIT_MAX 1 #define MOTOR_LIMIT_MIN -1 // Set 1 untuk aktifkan fitur pc.print #define DEBUG 1 //////////////////////////////////////////////////////////////////////////////// // Object Program // //////////////////////////////////////////////////////////////////////////////// // Serial Serial pc(USBTX, USBRX, 115200); joysticknucleo stick(PIN_TX, PIN_RX); // Pneumatik DigitalOut pneumatik[5]{PIN_PNEUMATIK_1, PIN_PNEUMATIK_2, PIN_PNEUMATIK_5, PIN_PNEUMATIK_6, PIN_PNEUMATIK_9}; // Encoder encoderKRTMI encoder_A(PIN_A_CHANNEL_A, PIN_A_CHANNEL_B, 540, encoderKRTMI::X4_ENCODING); encoderKRTMI encoder_B(PIN_B_CHANNEL_A, PIN_B_CHANNEL_B, 540, encoderKRTMI::X4_ENCODING); encoderKRTMI encoder_C(PIN_C_CHANNEL_A, PIN_C_CHANNEL_B, 540, encoderKRTMI::X4_ENCODING); // Motor Motor motor1(PIN_PWM_A, PIN_FWD_A, PIN_REV_A); Motor motor2(PIN_PWM_B, PIN_FWD_B, PIN_REV_B); Motor motor3(PIN_PWM_C, PIN_FWD_C, PIN_REV_C); //////////////////////////////////////////////////////////////////////////////// // Deklarasi Prosedure dan Fungsi // //////////////////////////////////////////////////////////////////////////////// void gerakMotor(); void hitungPID(double theta_s); void hitungParameter(); void printPulse(); void case_gerak(); void motor_Stop(); void motor_ForceStop(); void gerak_Pneumatic(); void case_pneumatic(); //////////////////////////////////////////////////////////////////////////////// // Variable-variable // //////////////////////////////////////////////////////////////////////////////// int joystick; int pn = 0; int pn2 = 0; int pn3 = 0; int pn_state = 0; double pulse_A=0, pulse_B=0, pulse_C=0; double Vr = 0, Vr_max = 0; double Vw = 0; double a = 0; double w = 0; double x =0, x_s=0, y=0, y_s=0, x_prev=0, y_prev=0; double theta=0, theta_s=0; double theta_error = 0, theta_prev=0, theta_error_prev=0, sum_theta_error=0; unsigned long last_mt_print,last_mt_print2, last_mt_pid, last_mt_rotasi; unsigned long last_mt_aksel, last_mt_desel,last1; bool modeauto = 1; bool print_pulse = 0; int brake_state=0; double Vmax = 0.4; double Vw_max = 0.3; int force=0; int count = 0; int countX = 0; int countKotak = 0; int countCircle = 0; int countSegitiga=0; //////////////////////////////////////////////////////////////////////////////// // Main Program // //////////////////////////////////////////////////////////////////////////////// int main(){ stick.setup(); stick.idle(); while(1){ if(stick.readable() ) { // Panggil fungsi pembacaan joystik stick.baca_data(); // Panggil fungsi pengolahan data joystik stick.olah_data(); if ( (!stick.atas)&&(!stick.bawah)&&(!stick.kanan)&&(!stick.kiri)&&(!stick.L1)&&(!stick.R1) && (!stick.R2) && (!stick.L2) ){ pc.printf("tidak ada input\n"); } else { pc.printf("ada input\n"); } } }/* while(1){ //doing nothing pulse_A = encoder_C.getPulses(); pc.printf("%.2f \n", pulse_A); if (pulse_A>10000) motor3.speed(0.0); else motor3.speed(-0.9); Thread::wait(2); }*/ } //////////////////////////////////////////////////////////////////////////////// // Prosedure dan Fungsi // //////////////////////////////////////////////////////////////////////////////// void hitungParameter(){ pulse_A = encoder_A.getPulses()*PULSE_TO_JARAK; pulse_B = encoder_B.getPulses()*PULSE_TO_JARAK; pulse_C = encoder_C.getPulses()*PULSE_TO_JARAK; //Compute value x = x_prev + (2*pulse_A - pulse_C - pulse_B)/3*cos(theta_prev) - (-pulse_C+pulse_B)*0.5773*sin(theta_prev); y = y_prev + (2*pulse_A - pulse_C - pulse_B)/3*sin(theta_prev) + (-pulse_C+pulse_B)*0.5773*cos(theta_prev); theta = theta_prev + (pulse_A + pulse_C + pulse_B)/(3.0*L); //Update value x_prev = x; y_prev = y; theta_prev = theta; encoder_A.reset(); encoder_B.reset(); encoder_C.reset(); } void hitungPID(double theta_s){ //menghitung error theta theta_error = theta_s - (theta*RAD_TO_DEG); sum_theta_error += theta_error; //kalkulasi PID Theta w = KP_W*theta_error + KI_W*TS*sum_theta_error + KD_W*(theta_error - theta_error_prev)/TS; Vw += (w*L/MAX_W_SPEED)*LIMITPWM; //update theta_error_prev = theta_error; //Limit Kecepatan Vw (kec rotasi) if (Vw > Vw_max){ Vw = Vw_max; } else if ( Vw < -1*Vw_max){ Vw = -1*Vw_max; } } void gerakMotor(){ // Berhenti jika tidak maju, mundur, kiri, kanan, atau pivot if (brake_state == 1){ motor_ForceStop(); //motor_Stop(); } else { if (count>50){ if ((millis() - last_mt_aksel > 100) && Vr < Vr_max){ if (Vr < 0.39){ Vr = 0.39; } else if ( (Vr >= 0.39)&& (Vr<=0.45)){ Vr+= 0.05; } else if ((Vr>0.45) && (Vr<1.00) ){ Vr+=0.12; } else { Vr = 1.2; } last_mt_aksel = millis(); } } else { Vr=0.42; } // Limit if (Vr > Vr_max && Vr_max >= 0.000){ Vr = Vr_max; } // Control Motor motor1.speed((Vr*cos(a) - Vw)); motor2.speed((Vr*(-0.5*cos(a) - 0.866*sin(a)) - Vw)); motor3.speed((Vr*(-0.5*cos(a) + 0.866*sin(a)) - Vw)); print_pulse = 1; } } void printPulse(){ pc.printf("%d \n", pn); //pc.printf("%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n", pulse_A, pulse_B, pulse_C, x, y); //pc.printf("%.2f\t%.2f\t%.2f\t%.2f\t%d\n",theta*RAD_TO_DEG, x, y, Vmax, modeauto); } void motor_Stop(){ //brake biasa motor1.speed(0); motor2.speed(0); motor2.speed(0); } void motor_ForceStop(){ //FORCEBRAKE motor1.brake(BRAKE_HIGH); motor2.brake(BRAKE_HIGH); motor3.brake(BRAKE_HIGH); } void case_gerak(){ if(stick.SELECT_click){ //reset semua variable pneumatik[0]=1; //gripA pneumatik[1]=1; //gripB pneumatik[2]=1; //sliderA pneumatik[3]=1; //sliderB pn=0; pn2=0; pn3=0; modeauto = 0; theta = 0.0; theta_prev = 0.0; theta_s = 0; theta_error_prev = 0; sum_theta_error = 0; theta_error = 0; } // Rotasi if (!stick.L1 && stick.R1){ // Pivot Kanan //theta = 0.0; //theta_prev = 0.0; theta_s = theta*RAD_TO_DEG; theta_error_prev = 0; sum_theta_error = 0; theta_error = 0; if (Vr_max==0) Vw = 0.25; else Vw = 0.17; } else if (!stick.R1 && stick.L1){ // Pivot Kiri //theta = 0.0; //theta_prev = 0.0; theta_s = theta*RAD_TO_DEG; theta_error_prev = 0; sum_theta_error = 0; theta_error = 0; if (Vr_max==0) Vw = -0.25; else Vw = -0.17; } if (stick.R2){ // Mode Sprint Vmax=1.25; } else Vmax=0.83; if ( (!stick.atas)&&(!stick.bawah)&&(!stick.kanan)&&(!stick.kiri)&&(!stick.L1)&&(!stick.R1) && (!stick.R2) && (!stick.L2) ){ count=0; brake_state=1; theta = 0.0; theta_prev = 0.0; theta_s = 0.0; theta_error_prev = 0; sum_theta_error = 0; theta_error = 0; }else{ if (count<200) count++; else count=500; brake_state=0; } // Linier if ((!stick.atas)&&(!stick.bawah)&&(!stick.kanan)&&(!stick.kiri)&&(stick.L2)){ //L2 : serong kiri bawah + pivot kiri (mundur saat kasih SC a = (-22/RAD_TO_DEG); // mundur saat setelah pengambilan Vr_max = 0.84; Vw=-0.19; } else if ((stick.atas)&&(!stick.bawah)&&(!stick.kanan)&&(!stick.kiri)&&(stick.L2)){ a = (5/RAD_TO_DEG); // L2+atas : mundur saat setelah pengambilan Vr_max = 0.87; Vw=-0.05; } else if ((stick.atas)&&(!stick.bawah)&&(!stick.kanan)&&(!stick.kiri)){ a = (90/RAD_TO_DEG); // Maju Vr_max = Vmax; } else if ((!stick.atas)&&(stick.bawah)&&(!stick.kanan)&&(!stick.kiri)){ a = (-96/RAD_TO_DEG); // Mundur Vr_max = Vmax; } else if ((stick.atas)&&(!stick.bawah)&&(!stick.kiri)&&(stick.kanan)){ a = (135/RAD_TO_DEG); // Serong Atas Kanan Vr_max = Vmax; } else if ((!stick.atas)&&(stick.bawah)&&(!stick.kiri)&&(stick.kanan)){ a = (-135/RAD_TO_DEG); // Serong Bawah Kanan Vr_max = Vmax; } else if ((stick.atas)&&(!stick.bawah)&&(stick.kiri)&&(!stick.kanan)){ a = (45/RAD_TO_DEG); // Serong Atas Kiri Vr_max = Vmax; } else if ((!stick.atas)&&(stick.bawah)&&(stick.kiri)&&(!stick.kanan)){ a = (-45/RAD_TO_DEG); // Serong Bawah Kiri Vr_max = Vmax; } else if ((!stick.atas)&&(!stick.bawah)&&(stick.kanan)&&(!stick.kiri)){ a = (180/RAD_TO_DEG); // Kanan Vr_max = 0.8; } else if ((!stick.atas)&&(!stick.bawah)&&(!stick.kanan)&&(stick.kiri)){ a = (0/RAD_TO_DEG); // Kiri Vr_max = 0.8; } else { Vr_max = 0; } //} } void case_pneumatic(){ // Control Pneumatic /** * pneumatik[0] = Gripper A * pneumatik[1] = Gripper B * pneumatik[3] = Slider A * pneumatik[4] = Slider B **/ if((!stick.silang) && (!stick.kotak) && (!stick.lingkaran) && (!stick.segitiga)) { // reset state pneumatik countX=0; countCircle=0; countSegitiga=0; countKotak=0; } if ((stick.silang && countX<50)) { //SILANG : sekuensial tiap tangan gripper countX++; } if (countX>0 && countX<100) { //state button X, lengan Kiri - lengakn Kanan countX=150; if (pn<4 && pn>=0) pn++; else pn=0; if(pn==0 || pn==22){ pneumatik[0]=1;//gripA pneumatik[1]=1;//gripB pneumatik[2]=1;//sliderA pneumatik[3]=1;//sliderB } else if (pn==1){ pneumatik[2] = 0; } else if (pn==2){ pneumatik[0] = 0; wait_ms(50); pneumatik[2] = 1; } else if (pn==3){ pneumatik[3]=0; } else if (pn==4){ pneumatik[1] = 0; wait_ms(50); pneumatik[3] = 1; } pn2=0; pn3=0; } if ((stick.kotak) && countKotak<50){ //KOTAK : maju 2 glider countKotak++; } if (countKotak>5 && countKotak<100){ //state button KOTAK countKotak=250; pn=0; pn3=0; if (pn2<2 && pn2>=0) pn2++; else pn2=0; if(pn2==0){ pneumatik[0]=1; pneumatik[1]=1; pneumatik[2]=1; pneumatik[3]=1; } else if(pn2==1){ pneumatik[2]=0; pneumatik[3]=0; } else if(pn2==2){ pneumatik[0]=0; pneumatik[1]=0; wait_ms(50); pneumatik[2]=1; pneumatik[3]=1; } } if ((stick.segitiga) && countSegitiga<50) //SEGITIGA : buka tutup kedua gripper countSegitiga++; if (countSegitiga>4 && countSegitiga<100) { //state button SEGITIGA countSegitiga=250; if ( (pneumatik[0]==0 && pneumatik[1]==1) || (pneumatik[0]==1 && pneumatik[1]==0) ){ pneumatik[0]=1; pneumatik[1]=1; pneumatik[2]=1; pneumatik[3]=1; } else { pneumatik[0]=!pneumatik[0]; pneumatik[1]=!pneumatik[1]; pneumatik[2]=1; pneumatik[3]=1; } pn=0; pn2=0; pn3=0; } if ((stick.lingkaran) && countCircle<50){ //KOTAK : maju 2 glider , 2 kali kotak 1 kali lingkaran countCircle++; } if (countCircle>4 && countCircle<100){ //LINGKARAN : lengan kanan - lengan kiri countCircle=250; pn=0; pn2=0; if (pn3<4 && pn3>=0) pn3++; else pn3=0; if(pn3==0 || pn3==22){ pneumatik[0]=1;//gripA pneumatik[1]=1;//gripB pneumatik[2]=1;//sliderA pneumatik[3]=1;//sliderB } else if (pn3==1){ pneumatik[3] = 0; } else if (pn3==2){ pneumatik[1] = 0; wait_ms(50); pneumatik[3] = 1; } else if (pn3==3){ pneumatik[2]=0; } else if (pn3==4){ pneumatik[0] = 0; wait_ms(50); pneumatik[2] = 1; } pn2=0; } }