2011

Dependencies:   mbed FastPWM

Revision:
235:c831718303c9
Parent:
234:bd00f763acb1
Child:
236:fd7961dfa78a
--- a/main.cpp	Mon Jun 07 01:17:25 2021 +0000
+++ b/main.cpp	Mon Jun 14 10:36:29 2021 +0000
@@ -2,7 +2,7 @@
 //distributed by Sungwoo Kim
 //       2020/12/28
 //revised by Buyoun Cho
-//       2021/04/20  
+//       2021/04/20
 
 // 유의사항
 // 소수 적을때 뒤에 f 꼭 붙이기
@@ -95,10 +95,12 @@
 float temp_P_GAIN = 0.0f;
 float temp_I_GAIN = 0.0f;
 int temp_VELOCITY_COMP_GAIN = 0;
+int logging = 0;
 
-inline float tanh_inv(float y) {
-    if(y >= 1.0f - 0.000001f) y = 1.0f - 0.000001f;  
-    if(y <= -1.0f + 0.000001f) y = -1.0f + 0.000001f;  
+inline float tanh_inv(float y)
+{
+    if(y >= 1.0f - 0.000001f) y = 1.0f - 0.000001f;
+    if(y <= -1.0f + 0.000001f) y = -1.0f + 0.000001f;
     return log(sqrt((1.0f+y)/(1.0f-y)));
 }
 
@@ -107,9 +109,9 @@
  *  REFERENCE MODE
  ******************************************************************************/
 enum _REFERENCE_MODE {
-    MODE_REF_NO_ACT = 0,                         
-    MODE_REF_DIRECT, 
-    MODE_REF_FINDHOME                                  
+    MODE_REF_NO_ACT = 0,
+    MODE_REF_DIRECT,
+    MODE_REF_FINDHOME
 };
 
 /*******************************************************************************
@@ -441,7 +443,7 @@
 
         // Current ===================================================
         //ADC3->CR2  |= 0x40000000;                        // adc _ 12bit
-        
+
         cur.UpdateSen(((float)ADC3->DR-2047.5f)/2047.5f*10.0f, FREQ_TMR4, 500.0f); // unit : mA
 
         // Encoder ===================================================
@@ -466,7 +468,7 @@
             pres_B.UpdateSen(pres_B_new,FREQ_TMR4,200.0f);
 
             if ((OPERATING_MODE & 0x01) == 0) { // Rotary Actuator
-                float torq_new = (PISTON_AREA_A * pres_A.sen - PISTON_AREA_B * pres_B.sen) * 0.0001f; // mm^3*bar >> Nm 
+                float torq_new = (PISTON_AREA_A * pres_A.sen - PISTON_AREA_B * pres_B.sen) * 0.0001f; // mm^3*bar >> Nm
                 torq.UpdateSen(torq_new,FREQ_TMR4,1000.0f);  // unit : Nm
             } else if ((OPERATING_MODE & 0x01) == 1) { // Linear Actuator
                 float force_new = (PISTON_AREA_A * pres_A.sen - PISTON_AREA_B * pres_B.sen) * 0.1f; // mm^2*bar >> N
@@ -541,7 +543,7 @@
 
         if (((OPERATING_MODE&0b010)>>1) == 0) {
             K_v = 1.03f; // Q = K_v*sqrt(deltaP)*tanh(C_d*Xv);
-            K_v = 0.16f; 
+            C_d = 0.16f;
             mV_PER_mA = 500.0f; // 5000mV/10mA
             mV_PER_pulse = 0.5f; // 5000mV/10000pulse
             mA_PER_pulse = 0.001f; // 10mA/10000pulse
@@ -551,7 +553,7 @@
             mV_PER_pulse = 0.5f; // 5000mV/10000pulse
             mA_PER_pulse = 0.003f; // 30mA/10000pulse
         }
-        
+
         // =====================================================================
         // CONTROL LOOP --------------------------------------------------------
         // =====================================================================
@@ -571,12 +573,11 @@
                 break;
             }
 
-            case MODE_TORQUE_SENSOR_NULLING: 
-            {
-                static float FORCE_pulse_sum = 0.0; 
-                static float PresA_pulse_sum = 0.0; 
-                static float PresB_pulse_sum = 0.0; 
-                
+            case MODE_TORQUE_SENSOR_NULLING: {
+                static float FORCE_pulse_sum = 0.0;
+                static float PresA_pulse_sum = 0.0;
+                static float PresB_pulse_sum = 0.0;
+
                 // DAC Voltage reference set
                 float VREF_TuningGain = -0.000003f;
                 if (TMR3_COUNT_TORQUE_NULL < TMR_FREQ_5k * 5) {
@@ -592,7 +593,7 @@
                             if (FORCE_VREF < 0.0f) FORCE_VREF = 0.0f;
                             dac_1 = FORCE_VREF / 3.3f;
                         }
-                    } else if (SENSING_MODE == 1) { // Pressure Sensor 
+                    } else if (SENSING_MODE == 1) { // Pressure Sensor
                         PresA_pulse_sum += pres_A.sen*PRES_SENSOR_A_PULSE_PER_BAR;
                         PresB_pulse_sum += pres_B.sen*PRES_SENSOR_B_PULSE_PER_BAR;
                         if (TMR3_COUNT_TORQUE_NULL % 10 == 0) {
@@ -607,7 +608,7 @@
                             dac_1 = PRES_A_VREF / 3.3f;
                             PRES_B_VREF += VREF_TuningGain * (0.0f - PresB_pluse_mean);
                             if (PRES_B_VREF > 3.3f) PRES_B_VREF = 3.3f;
-                            if (PRES_B_VREF < 0.0f) PRES_B_VREF = 0.0f; 
+                            if (PRES_B_VREF < 0.0f) PRES_B_VREF = 0.0f;
                             dac_2 = PRES_B_VREF / 3.3f;
                         }
                     }
@@ -631,14 +632,13 @@
                 break;
             }
 
-            case MODE_FIND_HOME: 
-            {
+            case MODE_FIND_HOME: {
                 static int cnt_findhome = 0;
                 static int cnt_terminate_findhome = 0;
                 static float FINDHOME_POSITION_pulse = 0.0f;
                 static float FINDHOME_POSITION_pulse_OLD = 0.0f;
                 static float FINDHOME_VELOCITY_pulse = 0.0f;
-                static float REF_POSITION_FINDHOME_INIT = 0.0f; 
+                static float REF_POSITION_FINDHOME_INIT = 0.0f;
 
                 if (FINDHOME_STAGE == FINDHOME_INIT) {
                     REFERENCE_MODE = MODE_REF_FINDHOME;
@@ -666,7 +666,7 @@
                     if ((cnt_terminate_findhome < 3*TMR_FREQ_5k) &&  cnt_findhome < 10*TMR_FREQ_5k) { // wait for 3sec
                         double GOTOHOME_SPEED = 10.0f; // 20mm/s or 20deg/s
                         if (HOMEPOS_OFFSET > 0) {
-                            REF_POSITION_FINDHOME = REF_POSITION_FINDHOME + GOTOHOME_SPEED*DT_5k; 
+                            REF_POSITION_FINDHOME = REF_POSITION_FINDHOME + GOTOHOME_SPEED*DT_5k;
                         } else {
                             REF_POSITION_FINDHOME = REF_POSITION_FINDHOME - GOTOHOME_SPEED*DT_5k;
                         }
@@ -678,24 +678,24 @@
                         FINDHOME_POSITION_pulse = 0;
                         FINDHOME_POSITION_pulse_OLD = 0;
                         FINDHOME_VELOCITY_pulse = 0;
-                
+
                         cnt_findhome = 0;
                         cnt_terminate_findhome = 0;
                         pos.ref = 0.0f;
                         FINDHOME_STAGE = FINDHOME_ZEROPOSE;
                     }
                 } else if (FINDHOME_STAGE == FINDHOME_ZEROPOSE) {
-                    
+
 //                    int T_move = 2*TMR_FREQ_5k;
                     int T_move = 10000;
                     REF_POSITION_FINDHOME = ((0.0f - REF_POSITION_FINDHOME_INIT)*0.5f*(1.0f - cos(3.14159f * (float)cnt_findhome / (float)T_move)) + (float)REF_POSITION_FINDHOME_INIT)/ENC_PULSE_PER_POSITION;
-    
+
                     cnt_findhome++;
-                    
+
                     REFERENCE_MODE = MODE_REF_FINDHOME;
                     CONTROL_MODE = MODE_JOINT_CONTROL;
                     alpha_trans = 0.0f;
-                    
+
                     if (cnt_findhome >= T_move) {
                         cnt_findhome = 0;
                         pos.ref = 0.0f;
@@ -722,7 +722,7 @@
                     VALVE_POS_CONTROL(valve_pos.ref);
                     V_out = Vout.ref;
                 } else if (CURRENT_CONTROL_MODE == 0) { //PWM
-                    V_out = valve_pos.ref; 
+                    V_out = valve_pos.ref;
                 } else {
                     I_REF = valve_pos.ref * 0.001f; // Unit : pulse >> mA
                     float I_MAX = 10.0f; // Max : 10mA
@@ -735,56 +735,56 @@
                 break;
             }
 
-            case MODE_JOINT_CONTROL: 
-            {
+            case MODE_JOINT_CONTROL: {
 
                 float temp_vel_pos = 0.0f; // desired velocity for position control
-                float temp_vel_FT = 0.0f; // desired velocity for force/torque control 
-                float temp_vel_ff = 0.0f; // desired velocity for feedforward control 
+                float temp_vel_FT = 0.0f; // desired velocity for force/torque control
+                float temp_vel_ff = 0.0f; // desired velocity for feedforward control
                 float temp_vel = 0.0f;
 
                 float wn_Pos = 2.0f * PI * 5.0f; // f_cut : 5Hz Position Control
-                
+
                 pos.err = pos.ref - pos.sen; // Unit : mm or deg
                 vel.err = vel.ref - vel.sen; // Unit : mm/s or deg/s
-                
+
                 // position control command ===============================================================================================================================================
-                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode 
-                    temp_vel_pos = 0.01f * (P_GAIN_JOINT_POSITION * wn_Pos * pos.err) * PI / 180.0f; // rad/s
-                    //                            L when P-gain = 100, f_cut = 10Hz                           
+                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode
+                    temp_vel_pos = 0.1f * (P_GAIN_JOINT_POSITION * wn_Pos * pos.err) * PI / 180.0f; // rad/s
+                    //                            L when P-gain = 100, f_cut = 10Hz
                 } else {
-                    temp_vel_pos = 0.01f * (P_GAIN_JOINT_POSITION * wn_Pos * pos.err); // mm/s
-                    //                            L when P-gain = 100, f_cut = 10Hz                            
+                    temp_vel_pos = 0.1f * (P_GAIN_JOINT_POSITION * wn_Pos * pos.err); // mm/s
+                    //                            L when P-gain = 100, f_cut = 10Hz
                 }
 
                 // torque control command ===============================================================================================================================================
                 float alpha_SpringDamper = 1.0f/(1.0f+TMR_FREQ_5k/(2.0f*PI*30.0f));
                 K_LPF = alpha_SpringDamper * K_LPF + (1.0f-alpha_SpringDamper) * K_SPRING;
                 D_LPF = alpha_SpringDamper * D_LPF + (1.0f-alpha_SpringDamper) * D_DAMPER;
-                
-                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode 
-                    float torq_ref_act = torq.ref + K_SPRING * pos.err + D_DAMPER * vel.err; // unit : Nm 
+
+                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode
+                    float torq_ref_act = torq.ref + K_SPRING * pos.err + D_DAMPER * vel.err; // unit : Nm
                     torq.err = torq_ref_act - torq.sen;
                     torq.err_int += torq.err/((float)TMR_FREQ_5k);
-                    temp_vel_FT = 0.0001f * (P_GAIN_JOINT_TORQUE * torq.err + I_GAIN_JOINT_TORQUE * torq.err_int); // Nm >> rad/s
+                    temp_vel_FT = 0.001f * (P_GAIN_JOINT_TORQUE * torq.err + I_GAIN_JOINT_TORQUE * torq.err_int); // Nm >> rad/s
                 } else {
-                    float force_ref_act = force.ref + K_SPRING * pos.err + D_DAMPER * vel.err; // unit : N 
+                    float force_ref_act = force.ref + K_SPRING * pos.err + D_DAMPER * vel.err; // unit : N
                     force.err = force_ref_act - force.sen;
                     force.err_int += force.err/((float)TMR_FREQ_5k);
-                    temp_vel_FT = 0.0001f * (P_GAIN_JOINT_TORQUE * force.err + I_GAIN_JOINT_TORQUE * force.err_int); // N >> mm/s
+                    temp_vel_FT = 0.001f * (P_GAIN_JOINT_TORQUE * force.err + I_GAIN_JOINT_TORQUE * force.err_int); // N >> mm/s
                 }
-                
-                // velocity feedforward command ========================================================================================================================================    
-                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode 
+
+
+                // velocity feedforward command ========================================================================================================================================
+                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode
                     temp_vel_ff = 0.01f * (float)VELOCITY_COMP_GAIN * vel.ref * PI / 180.0f; // rad/s
                 } else {
                     temp_vel_ff = 0.01f * (float)VELOCITY_COMP_GAIN * vel.ref; // mm/s
                 }
 
-                // command integration =================================================================================================================================================    
+                // command integration =================================================================================================================================================
                 temp_vel = (1.0f - alpha_trans) * temp_vel_pos  + alpha_trans * temp_vel_FT + temp_vel_ff; // Position Control + Torque Control + Velocity Feedforward
                 
-                float Qact = 0.0f; // required flow rate  
+                float Qact = 0.0f; // required flow rate
                 if( temp_vel > 0.0f ) {
                     Qact = temp_vel * ((float)PISTON_AREA_A * 0.00006f); // mm^3/sec >> LPM
                     I_REF = tanh_inv(Qact/(K_v * sqrt(PRES_SUPPLY * alpha3 / (alpha3 + 1.0f))))/C_d;
@@ -793,23 +793,29 @@
                     I_REF = tanh_inv(Qact/(K_v * sqrt(PRES_SUPPLY / (alpha3 + 1.0f))))/C_d;
                 }
                 
+                float I_MAX = 10.0f; // Maximum Current : 10mA
+                
                 // Anti-windup for FT
-                if (I_GAIN_JOINT_TORQUE != 0.0f) {
-                    float I_MAX = 10.0f; // Maximum Current : 10mA
+//                if (I_GAIN_JOINT_TORQUE != 0.0f) {
+                if (I_GAIN_JOINT_TORQUE > 0.001f) {
                     float Ka = 2.0f;
                     if (I_REF > I_MAX) {
                         float I_rem = I_REF - I_MAX;
                         I_REF = I_MAX;
-                        float temp_vel_rem = K_v * sqrt(PRES_SUPPLY * alpha3 / (alpha3 + 1.0f)) * tanh(C_d*I_rem) / ((double) PISTON_AREA_A * 0.00006f); // Unit : mm/s [linear] / rad/s [rotary]  
-//                        torq.err_int = torq.err_int - Ka * temp_vel_rem * (10000.0f/I_GAIN_JOINT_TORQUE)*(float)TMR_FREQ_5k; // Need to Check!
+                        float temp_vel_rem = K_v * sqrt(PRES_SUPPLY * alpha3 / (alpha3 + 1.0f)) * tanh(C_d*I_rem) / ((double) PISTON_AREA_A * 0.00006f); // Unit : mm/s [linear] / rad/s [rotary]
                         torq.err_int = torq.err_int - Ka * temp_vel_rem * (10000.0f/I_GAIN_JOINT_TORQUE);
                     } else if (I_REF < -I_MAX) {
                         double I_rem = I_REF - (-I_MAX);
                         I_REF = -I_MAX;
-                        float temp_vel_rem = K_v * sqrt(PRES_SUPPLY / (alpha3 + 1.0f)) * tanh(C_d*I_rem) / ((double) PISTON_AREA_B * 0.00006f); // Unit : mm/s [linear] / rad/s [rotary]  
-/*                        torq.err_int = torq.err_int - Ka * temp_vel_rem * (10000.0f/I_GAIN_JOINT_TORQUE)*(float)TMR_FREQ_5k; // Need to Check!*/
+                        float temp_vel_rem = K_v * sqrt(PRES_SUPPLY / (alpha3 + 1.0f)) * tanh(C_d*I_rem) / ((double) PISTON_AREA_B * 0.00006f); // Unit : mm/s [linear] / rad/s [rotary]
                         torq.err_int = torq.err_int - Ka * temp_vel_rem * (10000.0f/I_GAIN_JOINT_TORQUE);
                     }
+                } else {
+                    if(I_REF > I_MAX) {
+                        I_REF = I_MAX;
+                    } else if (I_REF < -I_MAX) {
+                        I_REF = -I_MAX;  
+                    }
                 }
                 break;
             }
@@ -909,7 +915,7 @@
                 if (I_REF_fil > 0.0f) I_REF_fil_DZ = I_REF_fil + (double)VALVE_DEADZONE_PLUS*mA_PER_pulse; // unit: mA
                 else if (I_REF_fil < 0.0f) I_REF_fil_DZ = I_REF_fil + (double)VALVE_DEADZONE_MINUS*mA_PER_pulse; // unit: mA
                 else I_REF_fil_DZ = I_REF_fil + (double)(VALVE_DEADZONE_PLUS+VALVE_DEADZONE_MINUS)/2.0f*mA_PER_pulse; // unit: mA
-                    
+
                 I_ERR = I_REF_fil_DZ - (double)cur.sen;
                 I_ERR_INT = I_ERR_INT + (I_ERR) * 0.0002f;
 
@@ -969,7 +975,7 @@
             if (CUR_PWM_lin > 0) V_out = (float) (CUR_PWM_lin + 169.0f);
             else if (CUR_PWM_lin < 0) V_out = (float) (CUR_PWM_lin - 174.0f);
             else V_out = (float) (CUR_PWM_lin);
-            
+
         } else {            //////////////////////////sw valve
             // Output Voltage Linearization & Dead Zone Cancellation (Electrical dead-zone) by SW
             if (V_out > 0 ) V_out = (V_out + 180.0f)/0.8588f;
@@ -1009,29 +1015,31 @@
 
         ////////////////////////////////////////////////////////////////////////////
         //////////////////////  Data transmission through CAN //////////////////////
-        ////////////////////////////////////////////////////////////////////////////   
-        
+        ////////////////////////////////////////////////////////////////////////////
+
         if (TMR2_COUNT_CAN_TX % (int) ((int) TMR_FREQ_5k/CAN_FREQ) == 0) {
-            
+
             // Position, Velocity, and Torque (ID:1200)
             if (flag_data_request[0] == HIGH) {
                 if ((OPERATING_MODE & 0b01) == 0) { // Rotary Actuator
                     CAN_TX_POSITION_FT((int16_t) (pos.sen*200.0f), (int16_t) (vel.sen*20.0f), (int16_t) (torq.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
-//                    CAN_TX_POSITION_FT((int16_t) (PRES_A_VREF*10.0f*200.0f), (int16_t) (vel.sen*20.0f), (int16_t) (pres_A.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
+//                    CAN_TX_POSITION_FT((int16_t) (PRES_B_VREF*10.0f*200.0f), (int16_t) (vel.sen*20.0f), (int16_t) (pres_B.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
+
                 } else if ((OPERATING_MODE & 0b01) == 1) { // Linear Actuator
                     CAN_TX_POSITION_FT((int16_t) (pos.sen*200.0f), (int16_t) (vel.sen*20.0f), (int16_t) (force.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
 //                    CAN_TX_POSITION_FT((int16_t) (PRES_B_VREF*10.0f*200.0f), (int16_t) (vel.sen*20.0f), (int16_t) (pres_B.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
+//                    CAN_TX_POSITION_FT((int16_t) (logging*200.0f), (int16_t) (vel.sen*20.0f), (int16_t) (force.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
                 }
             }
 
             // Valve Position (ID:1300)
             if (flag_data_request[1] == HIGH) {
-                CAN_TX_PWM((int16_t)(cur.sen/mA_PER_pulse)); 
+                CAN_TX_PWM((int16_t)(cur.sen/mA_PER_pulse));
             }
 
             // Others : Pressure A, B, Supply Pressure, etc. (for Debugging)  (ID:1400)
             if (flag_data_request[2] == HIGH) {
-                CAN_TX_SOMETHING((int16_t)(pres_A.sen*100.0f), (int16_t)(pres_B.sen*100.0f), (int16_t) (PRES_SUPPLY), (int16_t) (PRES_SUPPLY_NOM)); 
+                CAN_TX_SOMETHING((int16_t)(pres_A.sen*100.0f), (int16_t)(pres_B.sen*100.0f), (int16_t) (PRES_SUPPLY), (int16_t) (PRES_SUPPLY_NOM));
             }
 
             TMR2_COUNT_CAN_TX = 0;