2.131 test rig DAQ for MTB suspension characterization project
Dependencies: EthernetInterface ExperimentServer HX711 QEI_pmw mbed-rtos mbed
Fork of Dolphin by
Diff: main.cpp
- Revision:
- 4:300ced917633
- Parent:
- 3:c8e53b5762bd
- Child:
- 6:b7f6433cc765
--- a/main.cpp Sat Oct 03 19:42:23 2015 +0000 +++ b/main.cpp Wed Nov 25 20:24:31 2015 +0000 @@ -3,134 +3,260 @@ #include "EthernetInterface.h" #include "ExperimentServer.h" #include "QEI.h" +#include "HX711.h" -#define NUM_INPUTS 7 -#define NUM_OUTPUTS 6 +#define NUM_INPUTS 21 +#define NUM_OUTPUTS 17 +#define PULSE_TO_RAD (2.0f*3.14159f / 1200.0f) Serial pc(USBTX, USBRX); // USB Serial Terminal ExperimentServer server; // Object that lets us communicate with MATLAB -PwmOut motorPWM(D7); // Motor PWM output -DigitalOut motorFwd(D5); // Motor forward enable -DigitalOut motorRev(D6); // Motor backward enable Timer t; // Timer to measure elapsed time of experiment -Ticker k; // Time interval -AnalogIn Anal(A5); // AnalogIn port for current sensing -QEI encoder(D3,D4, NC, 1200 , QEI::X4_ENCODING); // Pins D3, D4, no index, 1200 counts/rev, Quadrature encoding -float Volt = 0; -float emf = 0; -float Current =0; -float i = 0; -float P = 0; -float vel=0; -float pot=0; -float i_d=0; + +// Variables for q1 +float current1; +float current_des1; +float angle1; +float angle_des1; +float velocity1; +float velocity_des1; +float duty_factor1; +float angle1_init; +float max_angle1; +float dif_ang1; + +// Variables for q2 +float current2; +float current_des2; +float angle2; +float angle_des2; +float velocity2; +float velocity_des2; +float duty_factor2; +float angle2_init; +float max_angle2; +float dif_ang2; + +// Fixed kinematic parameters +const float l_OA=.010; +const float l_OB=.040; +const float l_AC=.095; +const float l_DE=.095; + +// Timing parameters +float pwm_period_us; +float current_control_period_us; +float impedance_control_period_us; +float exp_period; +float omega; +float phase; + +// Control parameters +float K_1; +float K_2; + +float D_1; +float D_2; + +float current_gain; + +float xDesFoot; +float yDesFoot; + +// Model parameters +float R; +float k_emf; +float nu1, nu2; +float supply_voltage; +float duty_max; + + +DigitalOut motorFwd1(D7); +DigitalOut motorRev1(D6); +AnalogIn currentSense1(A0); +PwmOut pwmOut1(D5); + +DigitalOut motorFwd2(D13); +DigitalOut motorRev2(D12); +AnalogIn currentSense2(A1); +PwmOut pwmOut2(D11); + +QEI encoder1(D3,D4 , NC, 1200 , QEI::X4_ENCODING); // Pins D3, D4, no index, 1200 counts/rev, Quadrature encoding +QEI encoder2(D9,D10, NC, 1200 , QEI::X4_ENCODING); // Pins D3, D4, no index, 1200 counts/rev, Quadrature encoding +//HX711 load_cell(D0,D1,uint8_t 120); +Ticker currentLoop; + +float prev_current_des1 = 0; +float prev_current_des2 = 0; +void CurrentLoop() +{ + motorFwd1 = current_des1 >= 0; + motorRev1 = current_des1 < 0; + + current1 = currentSense1.read()*3.3f / 0.14f; //measure current + if (prev_current_des1 < 0) + current1*=-1; + + duty_factor1=(current_des1*R + current_gain*(current_des1-current1) + k_emf*velocity1)/supply_voltage; + motorRev1 = duty_factor1< 0; + motorFwd1 = duty_factor1>=0; + float absDuty1 = abs(duty_factor1); + if (absDuty1 > duty_max) { + duty_factor1 *= duty_max / absDuty1; + absDuty1= duty_max; + } + pwmOut1.write(absDuty1); + prev_current_des1 = current_des1; + + motorFwd2 = current_des2 >= 0; + motorRev2 = current_des2 < 0; + + current2 = currentSense2.read()*3.3f / 0.14f; //measure current + if (prev_current_des2 < 0) + current2*=-1; + + duty_factor2=(current_des2*R + current_gain*(current_des2-current2) + k_emf*velocity2)/supply_voltage; + + motorRev2 = duty_factor2< 0; + motorFwd2 = duty_factor2>=0; + float absDuty2 = abs(duty_factor2); + if (absDuty2 > duty_max) { + duty_factor2 *= duty_max / absDuty2; + absDuty2= duty_max; + } + pwmOut2.write(absDuty2); + prev_current_des2 = current_des2; +} int main (void) { - // Link the terminal with our server and start it up - server.attachTerminal(pc); - server.init(); + + encoder1.reset(); + encoder2.reset(); + + // Link the terminal with our server and start it up + server.attachTerminal(pc); + server.init(); + + // Continually get input from MATLAB and run experiments + float input_params[NUM_INPUTS]; + while(1) { + if (server.getParams(input_params,NUM_INPUTS)) { + pwm_period_us = input_params[0]; // PWM_Period in mirco seconds + current_control_period_us = input_params[1]; // Current control period in micro seconds + impedance_control_period_us = input_params[2]; // Impedance control period in microseconds seconds + exp_period = input_params[3]; // Experiment time in seconds + + R = input_params[4]; // Terminal resistance (Ohms) + k_emf = input_params[5]; // Back EMF Constant (V / (rad/s)) + nu1 = input_params[6]; // Friction coefficienct 1 (Nm / (rad/s)) + nu2 = input_params[7]; // Friction coefficienct 1 (Nm / (rad/s)) + supply_voltage = input_params[8]; // Power Supply Voltage (V) + + angle1_init = input_params[9]; // Initial angle for q1 (rad) + angle2_init = input_params[10];// Initial angle for q2 (rad) + + current_gain = input_params[11]; // Proportional current gain (V/A) + K_1 = input_params[12]; // Foot stiffness N/m + K_2 = input_params[13]; // Foot stiffness N/m + max_angle1 = input_params[14]; // Foot stiffness N/m - // PWM period should nominally be a multiple of our control loop - motorPWM.period_us(200); - - // Continually get input from MATLAB and run experiments - float input_params[NUM_INPUTS]; - - while(1) { - if (server.getParams(input_params,NUM_INPUTS)) { - float tf = input_params[0]; // Voltage for first second - float i_d = input_params[1]; // Voltage for second second - float Kp = input_params[2]; - float R = input_params[3]; - float Kb = input_params[4]; - float Kth = input_params[5]; - float b = input_params[6]; - //float .0thd = input_params[3]; - Volt = 0.0; - emf = 0.0; - Current =0.0; - i = 0.0; - P = 0.0; - vel=0.0; - pot=0.0; - i_d=0.0; - // Setup experiment - t.reset(); - t.start(); - encoder.reset(); - //float thj = 0; - motorFwd = 1; - motorRev = 0; - motorPWM.write(0); + D_1 = input_params[15]; // Foot damping N/(m/s) + D_2 = input_params[16]; // Foot damping N/(m/s) + max_angle2 = input_params[17]; // Foot damping N/(m/s) + duty_max = input_params[18]; // Maximum duty factor + omega = input_params[19]; // Oscillation freq of the tail + phase = input_params[20]; // phase difference between two motors + + pwmOut1.period_us(pwm_period_us); + pwmOut2.period_us(pwm_period_us); + float m1 =.02 + .210; + float m2 =.0225; + float m3 = .004; + float m4 = .017; + //float I1 = 45.389 * 10^-6; + //float I2 = 22.918 * 10^-6; + //float I3 = 3.2570 * 10^-6; + //float I4 = 22.176 * 10^-6; + float l_OA=.011; + float l_OB=.042; + float l_AC=.096; + float l_DE=.096; + float l_O_m1=0.0364; + float l_B_m2=0.040; + float l_A_m3=1/2 * l_AC; + float l_C_m4=1/2 * (l_DE+ l_OB-l_OA); + float g = 9.81; + + // Attach current loop! + currentLoop.attach_us(CurrentLoop,current_control_period_us); + + // Setup experiment + t.reset(); + t.start(); - // Run experiment - while( t.read() < tf ) { - // Perform control loop logic - //void attime(){ - //motorPWM.write(v1); - - - //k.attach_us(0, 2000); - // This is for position based PID - //thj = thj + (thd - encoder.getPulses()); - //float P= Kp*(thd-encoder.getPulses()); - //float I= Ki*(0-encoder.getVelocity()); - //float D= Kd*thj; - // float Volt = P+I+D; - // float pulse = encoder.getPulses(); - - - //below is for Current Based PID - Current = Anal.read(); - vel=encoder.getVelocity()/1200.0*6.28; - pot=encoder.getPulses()/1200.0*6.28; - i_d=(Kth*pot+b*vel)/Kb; - //i_d = 1.5; - i = 3.3f*Current/0.140f; - if (i_d<0){ - i=i*-1; - } - P = Kp*(i_d-i); - emf = Kb*vel; - Volt = (R*i_d+P+emf)/12.0; - //float Kb=(Volt-R*i_d)/vel; - - //float Volt = 0; - //pc.printf(" %f /n",P); - if (Volt>0){ - motorRev.write(1); - motorFwd.write(0); - motorPWM.write(Volt); - } - else{ - motorFwd.write(1); - motorRev.write(0); - motorPWM.write(-1*Volt); - } - - //if (t.read() < 1) - //motorPWM.write(v1); - //else - // motorPWM.write(v2); - - // Form output to send to MATLAB - float output_data[NUM_OUTPUTS]; - output_data[0] = t.read(); - output_data[1] = encoder.getPulses()/1200.0*6.28; - output_data[2] = vel; - output_data[3] = Volt; - output_data[4] = i; - output_data[5] = i_d; - - // Send data to MATLAB - server.sendData(output_data,NUM_OUTPUTS); - wait(.001); - } - // Cleanup after experiment - server.setExperimentComplete(); - motorPWM.write(0); - } // end if - } // end while + motorFwd1 = 1; + motorRev1 = 0; + pwmOut1.write(0); + + motorFwd2 = 1; + motorRev2 = 0; + pwmOut2.write(0); + + // Run experiment + while( t.read() < exp_period ) { + // Perform control loop logic + + angle1 = encoder1.getPulses() *PULSE_TO_RAD; // calculate actual angle of motor + dif_ang1 = angle1 - max_angle1*sin(omega*t.read()); // calc difference of actual and desired angle + velocity1 = encoder1.getVelocity() * PULSE_TO_RAD; + + angle2 = encoder1.getPulses() *PULSE_TO_RAD; // calculate actual angle of motor + dif_ang2 = angle2 - max_angle2*sin(omega*t.read()+phase); // calc difference of actual and desired angle + velocity2 = encoder2.getVelocity() * PULSE_TO_RAD; -}// end main \ No newline at end of file + // Forward Kinematics + + float tau_des1 = (-K_1*dif_ang1-D_1*velocity1+nu1*velocity1); + float tau_des2 = (-K_1*dif_ang2-D_1*velocity2+nu2*velocity2); + + // Set desired currents + current_des1 = tau_des1/k_emf;//(-K_xx*angle1-D_xx*velocity1+nu1*velocity1)/k_emf; + current_des2 = tau_des2/k_emf; //(-K_yy*angle2-D_yy*velocity2+nu2*velocity2)/k_emf; + + // Form output to send to MATLAB + float output_data[NUM_OUTPUTS]; + output_data[0] = t.read(); + output_data[1] = angle1; + output_data[2] = velocity1; + output_data[3] = current1; + output_data[4] = current_des1; + output_data[5] = duty_factor1; + + output_data[6] = angle2; + output_data[7] = velocity2; + output_data[8] = current2; + output_data[9] = current_des2; + output_data[10]= duty_factor2; + + output_data[11] = tau_des1; + output_data[12] = tau_des2; + output_data[13] = dif_ang1; + output_data[14] = dif_ang2; + //output_data[15] = fx; + //output_data[16] = fy; + + // Send data to MATLAB + server.sendData(output_data,NUM_OUTPUTS); + wait_us(impedance_control_period_us); + } + // Cleanup after experiment + server.setExperimentComplete(); + // control.detach(); + currentLoop.detach(); + pwmOut1.write(0); + pwmOut2.write(0); + + } // end if + } // end while +} // end main \ No newline at end of file