With this program the buttons on the biorobotics shield can be used to move the arms. both buttons pressed means shoot. Also SW3 can be pressed to adjust controller constants via Serial connection

Dependencies:   HIDScope QEI controlandadjust mbed

main.cpp

Committer:
Gerth
Date:
2015-10-01
Revision:
0:24628832f21d
Child:
1:41a9e3340c96

File content as of revision 0:24628832f21d:

#include "mbed.h"
#include "QEI.h"
#include "HIDScope.h"

//////////////////////////////////////CONSTANTS, I/O, FREQUENCIES AND TICKERS//////////////////////////////////////
//info uit
HIDScope scope(5);

//encoders
QEI encoder1 (D12,D13,NC,32); // first b then a for clockwise +
QEI encoder2 (D10,D11,NC,32);

//ingangen
DigitalIn butR(D2);
DigitalIn butL(D3);

//uitgangen
DigitalOut motor1_direction(D7);// draairichting motor 1 (1 is CW encoder als je daar op kijkt en CW shaft als je daar op kijkt)
PwmOut motor1_speed_control(D6);//aanstuursnelheid motor 1
PwmOut motor2_speed_control(D5);
DigitalOut motor2_direction(D4);
const int CW=1; //clockwise
const int CCW=0; //counterclockwise

//frequencies
const double hidscope_frequency=100;//frequentie waarop data naar HIDScope wordt gestuurd
const double pi_control_frequency=25;//frequentie waarop er een control actie wordt uitgevoerd. kan hoger, voorzichtig bij ruis!
const double read_but_frequency=25;

//tickers
Ticker hidscope_ticker;
Ticker pi_control_ticker;
Ticker read_but_ticker;

//constants
const float cpr=32*131;
const float PI=3.1415;
const float counttorad=((2*PI)/cpr);
const float counttodeg=(360/cpr);
const float mmpersecbut=(30/(read_but_frequency));
const float radpersecbut=(PI/read_but_frequency);
const float armlength=400;//length "upper arm" in mm

///////////////////////////////////////////////////CONTROLLER CONSTANTS////////////////////////////////

//DEZE WAARDES ZIJN ZOMAAR RANDOM WAARDES!!!!


double desiredangle[2]= {0,0};
double desiredposition=0;
double signal_motor[2]= {0,0};
////////////////////////////////////////////GO FLAGS AND ACTIVATION FUNCTIONS//////////////////////////////////
//go flags
volatile bool scopedata_go=false, pi_control_go=false,read_but_go=false;

//acvitator functions

void scopedata_activate()
{
    scopedata_go=true;
}
void pi_control_activate()
{
    pi_control_go=true;
}
void read_but_activate()
{
    read_but_go=true;
}
///////////////////////////////////////////////////////FUNCTIONS//////////////////////////////////////////////////////////////////////////

//scopedata
void scopedata()
{
    scope.set(0,desiredposition);//gewenste hoek van arm
    scope.set(1,counttodeg*encoder1.getPulses());//hoek in rad van outputshaft
    scope.set(2,motor1_speed_control.read());//pwm signaal naar motor toe
    scope.set(3,counttodeg*encoder2.getPulses());//hoek in rad van outputshaft
    scope.set(4,motor2_speed_control.read());//pwm signaal naar motor toe
    scope.send();
}
//////////////////////////////////////////////////////////CONTROLLER///////////////////////////////////////
float pi_kp=0.5;
float pi_ki=0.01;
float Ts=1.0/pi_control_frequency;
double e[2]= {0,0};
double motor_error_int[2]= {0,0};

// Reusable PI controller
void pi_control()
{
    motor_error_int[0] = motor_error_int[0] + Ts * e[0]; // e_int is changed globally because it’s ’by reference’ (&)
    signal_motor[0]=pi_kp*e[0]+pi_ki*motor_error_int[0];

    motor_error_int[1] = motor_error_int[1] + Ts * e[1]; // e_int is changed globally because it’s ’by reference’ (&)
    signal_motor[1]=pi_kp*e[1]+pi_ki*motor_error_int[1];
}

//////////////////////////////////////////////////MAIN///////////////////////////////////
int main()
{
    //set initial shizzle
    motor1_speed_control.write(0);
    motor2_speed_control.write(0);

    //tickers
    hidscope_ticker.attach(&scopedata_activate,1.0/hidscope_frequency);
    pi_control_ticker.attach(&pi_control_activate,1.0/pi_control_frequency);
    read_but_ticker.attach(&read_but_activate,1.0/read_but_frequency);

    while(1) {
        //control motor 1 with a pi controller

        if (read_but_go==true) {
            float buttonR=butR.read(), buttonL=butL.read();
            if (buttonR==0 && buttonL ==1) {
                desiredposition += (radpersecbut);
                read_but_go=false;
            }
            if (buttonR==1 && buttonL==0) {
                desiredposition -= (radpersecbut);
                read_but_go=false;
            } else {
                desiredposition=desiredposition;
            }
            desiredangle[0]=desiredposition;
            desiredangle[1]=desiredposition;
            read_but_go=false;
        }

        if (pi_control_go==true) {
            e[0]=desiredangle[0]-(counttorad*encoder1.getPulses());
            e[1]=desiredangle[1]-(counttorad*encoder2.getPulses());
            pi_control();
            //motor1
            if (signal_motor[0]>=0) {//determine CW or CCW rotation
                motor1_direction.write(CW);
            } else {
                motor1_direction.write(CCW);
            }

            if (fabs(signal_motor[0])>=1) { //check if signal is <1
                signal_motor[0]=1;//if signal >1 make it 1 to not damage motor
            } else {
                signal_motor[0]=fabs(signal_motor[0]);// if signal<1 use signal
            }

            //motor 2
            if (signal_motor[1]>=0) {//determine CW or CCW rotation
                motor2_direction.write(CW);
            } else {
                motor2_direction.write(CCW);
            }

            if (fabs(signal_motor[1])>=1) { //check if signal is <1
                signal_motor[1]=1;//if signal >1 make it 1 to not damage motor
            } else {
                signal_motor[1]=fabs(signal_motor[1]);// if signal<1 use signal
            }



            motor1_speed_control.write(fabs(signal_motor[0]));//write signal to motor
            motor2_speed_control.write(fabs(signal_motor[1]));//write signal to motor

            pi_control_go=false;
        }
        //call scopedata
        if (scopedata_go==true) {
            scopedata();
            scopedata_go=false;
        }
    }
    return 0;
}