2.74 Bio-Inspired Robotics robot for LGO group. This is the vertical dolphin tail
Dependencies: EthernetInterface ExperimentServer HX711 QEI_pmw mbed-rtos mbed
Fork of experiment_example by
main.cpp
- Committer:
- laskowsk
- Date:
- 2015-11-30
- Revision:
- 6:b7f6433cc765
- Parent:
- 4:300ced917633
File content as of revision 6:b7f6433cc765:
#include "mbed.h" #include "rtos.h" #include "EthernetInterface.h" #include "ExperimentServer.h" #include "QEI.h" #include "HX711.h" #define NUM_INPUTS 22 #define NUM_OUTPUTS 16 #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 Timer t; // Timer to measure elapsed time of experiment // 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; // 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 calibration_factor; 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 scale(A0,A1); 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) { scale.tare(); // tare scale 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 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 calibration_factor = input_params[21]; // calibration factor for load cell pwmOut1.period_us(pwm_period_us); pwmOut2.period_us(pwm_period_us); scale.setScale(calibration_factor); //Adjust to this calibration factor // Attach current loop! currentLoop.attach_us(CurrentLoop,current_control_period_us); // Setup experiment t.reset(); t.start(); 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 = encoder2.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; // Forward Kinematics float tau_des1 = (-K_1*dif_ang1-D_1*velocity1+nu1*velocity1); float tau_des2 = (-K_2*dif_ang2-D_2*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; // take measurement from load cell float F = scale.getGram(); // value from load cell that uses calibration factor // 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] = F; //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