helloworld

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Fork of Robot-Software by Biorobotics

main.cpp

Committer:
Peppypeppy
Date:
2018-10-29
Revision:
13:3482d315877c
Parent:
10:7339dca7d604

File content as of revision 13:3482d315877c:

#include "mbed.h"
#include "MODSERIAL.h"
#include "QEI.h"
#include "BiQuad.h"

// CHECK
PwmOut pwmpin(D6);
PwmOut pwmpin2(D5);
DigitalOut directionpin2(D4);
DigitalOut directionpin(D7);
//MODSERIAL pc(USBTX, USBRX);
Serial pc(USBTX, USBRX);

QEI wheel1 (D13, D12, NC, 32);
QEI wheel2 (D11, D10, NC, 32);
float u1,u2 = 0;

// for trajectory control:
double T = 1; // time to get to destination
double currentx, currenty;
double currentq1, currentq2;
// end    


float angle_resolution = (360.0/32.0)*(1.0/131.0);  //degrees/counts 
double Kp = 2;
double Ki = 1.02;
double Kd = 10;
extern double samplingfreq = 1000;
 
double L1 = 0.43;
double L2 = 0.43;
double x01 = 0.0;
double y01 = 0.0;

void forwardkinematics_function(double& q1, double& q2) {
    // input are joint angles, output are x and y position of end effector
    
    currentx = x01 + L1*cos(q1)-L2*cos(q2);
    currenty = y01 + L1 * sin(q1) - L2 * sin(q2);    
}
 
vector<double> inversekinematics_function(double& x, double& y, const double& T, double& q1, double& q2, double& des_vx, double& des_vy) {
    // x, y: positions of end effector | T: time to get to position | qref1, qref2: reference thetas | q1, q2: current thetas | vx, vy: desired x, y velocities
    
    // pseudo inverse jacobian to get joint speeds
    // input are desired vx and vy of end effector, output joint angle speeds
 
    double q1_star_des; // desired joint velocity of q1_star
    double q2_star_des; // same as above but then for q2_star
    double qref1, qref2;
 
    // The calculation below assumes that the end effector position is calculated before this function is executed
    // In our case the determinant will not equal zero, hence no problems with singularies I think.
    q1_star_des = 1/(L1*(-x*sin(q1)-(-y+y01)*cos(q1)))*(-1*(-x+L1*cos(q1))*des_vx-x*des_vy);
    q2_star_des = 1/(L1*(-x*sin(q1)-(-y+y01)*cos(q1)))*(-1*(-y+y01+L1*sin(q1))*des_vx+1*(-y+y01)*des_vy); // CHECK THIS ONE!!!
    
    qref1 = q1+T*q1_star_des; // Yet to adapt all these equations
    qref2 = q2+T*(q2_star_des - q1_star_des); 
    
    vector<double> thetas;
    thetas.push_back(qref1);
    thetas.push_back(qref2);
    return thetas;
}


void PID_controller(double error1, double error2, float &u1, float &u2)
{   
    double u_k = Kp * error1;
    double u_k2 = Kp * error2;
    static double error_integral = 0;
    static double error_prev = error1; // initialization with this value only done once!
    static double error_prev2 = error2; // initialization with this value only done once!

    static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
    
    error_integral = error_integral + error1 * 1/samplingfreq;
    double u_i = Ki * error_integral;
    double error_derivative = (error1 - error_prev)*samplingfreq;
    double filtered_error_derivative = LowPassFilter.step(error_derivative);
    double u_d = Kd * filtered_error_derivative;
    error_prev = error1;
    error_prev2 = error2; 
    u1 =  float(u_k/360);//+u_i+u_d;
    u2 = float(u_k2/360);
    
   
   
}

int main()
{   
    pwmpin.period_us(60);
    int pulses1, pulses2 = 0;
    float angle1, angle2;
    int realangle1, realangle2;
    double ref1, error1;
    double ref2, error2;
    bool reached;
    
    double vx, vy;
    
    while (true) {
        pulses1 = wheel1.getPulses();
        angle1 = pulses1*angle_resolution;
        realangle1 = abs(int(angle1)) % 360;
        
        pulses2 = wheel2.getPulses();
        angle2 = pulses2*angle_resolution;
        realangle2 = abs(int(angle2)) % 360;
        
        currentq1 = angle1;
        currentq2 = angle2;
        
        //forwardkinematics_function(currentq1, currentq2);
        T = 2; // 2 seconds seems slow enough :D
        vx = 0.1;
        vy = 0;
    
        vector<double> refangles = inversekinematics_function(currentx, currenty, T, currentq1, currentq2, vx, vy);
        
        ref1 = 0;
        ref2 = 0;
        
        error1 = ref1 - realangle1;
        error2 = ref2 - realangle2;
        
        
        //PID_controller(error1, error2, u1, u2); 
        if(u1 > 1){
            u1 = 1;
        }
        if(u1 < -1){
            u1 = -1;
            }
        if(u2 > 1){
            u2 = 1;
        }
        if(u2 < -1){
            u2 = -1;
            } 

            
        pwmpin = fabs(u1);
        pwmpin2 = fabs(u2);
         
        // 1/true is negative, 0/false is positive 
        directionpin2 = u2 < 0;
        directionpin = u1 < 0;
        pc.printf("angle %f, error: %f, pwm: %f \r \n",realangle1, error1, u1);
        
         
        
    }
}