eeprom_test

Dependencies:   mbed FastPWM

Revision:
62:851cf7b7aa7a
Parent:
61:7572762e3837
Child:
63:a3c7f31742c9
diff -r 7572762e3837 -r 851cf7b7aa7a main.cpp
--- a/main.cpp	Fri Apr 10 02:00:46 2020 +0000
+++ b/main.cpp	Tue May 12 06:23:22 2020 +0000
@@ -64,15 +64,6 @@
 State INIT_Pos;
 State INIT_torq;
 
-float V_out=0.0f;
-float V_rem=0.0f; // for anti-windup
-float V_MAX = 12000.0f; // Maximum Voltage : 12V = 12000mV
-
-float PWM_out=0.0f;
-
-int timer_while = 0;
-int while_index = 0;
-
 extern int CID_RX_CMD;
 extern int CID_RX_REF_POSITION;
 extern int CID_RX_REF_VALVE_POS;
@@ -129,7 +120,7 @@
     MODE_TORQUE_SENSOR_NULLING = 20,                    //20
     MODE_VALVE_NULLING_AND_DEADZONE_SETTING,            //21
     MODE_FIND_HOME,                                     //22
-    MODE_VALVE_GAIN_SETTING,                        //23
+    MODE_VALVE_GAIN_SETTING,                            //23
     MODE_PRESSURE_SENSOR_NULLING,                       //24
     MODE_PRESSURE_SENSOR_CALIB,                         //25
     MODE_ROTARY_FRICTION_TUNING,                        //26
@@ -137,15 +128,22 @@
     MODE_DDV_POS_VS_PWM_ID = 30,                           //30
     MODE_DDV_DEADZONE_AND_CENTER,                       //31
     MODE_DDV_POS_VS_FLOWRATE,                           //32
+    MODE_SYSTEM_ID,                                     //33
 };
 
+void SystemClock_Config(void);
+
 int main()
 {
     /*********************************
     ***     Initialization
     *********************************/
-    //LED = 1;
-    //pc.baud(9600);
+    HAL_Init();
+//    SystemClock_Config();
+    
+    
+//    LED = 1;
+//    pc.baud(9600);
 
     // i2c init
     i2c.frequency(400 * 1000);          // 0.4 mHz
@@ -191,7 +189,7 @@
 
     //Timer priority
     NVIC_SetPriority(TIM3_IRQn, 2);
-//    NVIC_SetPriority(TIM2_IRQn, 3);
+    //NVIC_SetPriority(TIM2_IRQn, 3);
     NVIC_SetPriority(TIM4_IRQn, 3);
 
     //can.reset();
@@ -202,11 +200,13 @@
     make_delay();
 
     //DAC init
-//    dac_1 = PRES_A_VREF / 3.3f;
-//    dac_2 = PRES_B_VREF / 3.3f;
-    dac_1 = TORQUE_VREF / 3.3f;
-    dac_2 = 0.0f;
-    dac_1 = 0.0f;
+    if (SENSING_MODE == 0) {
+        dac_1 = TORQUE_VREF / 3.3f;
+        dac_2 = 0.0f;
+    } else if (SENSING_MODE == 1) {
+        dac_1 = PRES_A_VREF / 3.3f;
+        dac_2 = PRES_B_VREF / 3.3f;
+    }
     make_delay();
 
     for (int i=0; i<50; i++) {
@@ -220,17 +220,19 @@
     ***     Program is operating!
     *************************************/
     while(1) {
-        if(timer_while==1000) {
+        if(timer_while==1000 && OPERATING_MODE==5) {
+//        if(timer_while==1000) {
             //i2c
             read_field(i2c_slave_addr1);
             if(DIR_VALVE_ENC < 0) value = 1023 - value;
-//            if(LED==1) {
-//                LED=0;
-//            } else
-//                LED = 1;
+            //            if(LED==1) {
+            //                LED=0;
+            //            } else
+            //                LED = 1;
             timer_while = 0;
         }
         timer_while ++;
+        //pc.printf("%d\n", value);
     }
 }
 
@@ -243,15 +245,15 @@
         if(REF_JOINT_VEL >= min(JOINT_VEL[i],JOINT_VEL[i+1]) && REF_JOINT_VEL <=  max(JOINT_VEL[i],JOINT_VEL[i+1])) {
             if(i==0) {
                 if(JOINT_VEL[i+1] == JOINT_VEL[i]) {
-                    Ref_Valve_Pos_FF = DDV_CENTER;
+                    Ref_Valve_Pos_FF = (float) VALVE_CENTER;
                 } else {
-                    Ref_Valve_Pos_FF = ((float) 10/(JOINT_VEL[i+1] - JOINT_VEL[i]) * (REF_JOINT_VEL - JOINT_VEL[i])) + DDV_CENTER;
+                    Ref_Valve_Pos_FF = ((float) 10/(JOINT_VEL[i+1] - JOINT_VEL[i]) * (REF_JOINT_VEL - JOINT_VEL[i])) + (float) VALVE_CENTER;
                 }
             } else {
                 if(JOINT_VEL[i+1] == JOINT_VEL[i-1]) {
-                    Ref_Valve_Pos_FF = DDV_CENTER;
+                    Ref_Valve_Pos_FF = (float) VALVE_CENTER;
                 } else {
-                    Ref_Valve_Pos_FF = ((float) 10*(ID_index_array[i+1] - ID_index_array[i-1])/(JOINT_VEL[i+1] - JOINT_VEL[i-1]) * (REF_JOINT_VEL - JOINT_VEL[i-1])) + DDV_CENTER + (float) (10*ID_index_array[i-1]);
+                    Ref_Valve_Pos_FF = ((float) 10*(ID_index_array[i+1] - ID_index_array[i-1])/(JOINT_VEL[i+1] - JOINT_VEL[i-1]) * (REF_JOINT_VEL - JOINT_VEL[i-1])) + (float) VALVE_CENTER + (float) (10*ID_index_array[i-1]);
                 }
             }
             break;
@@ -263,7 +265,7 @@
         Ref_Valve_Pos_FF = (float) VALVE_MIN_POS;
     }
 
-    Ref_Valve_Pos_FF = (float) VELOCITY_COMP_GAIN * 0.01f * (float) (Ref_Valve_Pos_FF - DDV_CENTER);
+    Ref_Valve_Pos_FF = (float) VELOCITY_COMP_GAIN * 0.01f * (float) (Ref_Valve_Pos_FF - (float) VALVE_CENTER);
     return Ref_Valve_Pos_FF;
 
 }
@@ -298,7 +300,7 @@
             break;
         }
     }
-    V_out = VALVE_PWM_RAW_FF + VALVE_PWM_RAW_FB;
+    Vout.ref = VALVE_PWM_RAW_FF + VALVE_PWM_RAW_FB;
 }
 
 #define LT_MAX_IDX  57
@@ -309,12 +311,12 @@
                                  11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f,
                                  25.0f, 30.0f, 35.0f, 40.0f, 50.0f, 60.0f, 80.0f, 100.0f
                                 };  // duty
-float LT_Voltage_Output[LT_MAX_IDX] = {-321.4f, -291.3f, -261.5f, -246.8f, -231.7f, -223.9f, -216.1f, -207.9f, -198.8f,
-                                       -196.9f, -195.0f, -192.5f, -188.8f, -184.5f, -180.2f, -175.9f, -171.5f, -166.3f, -161.0f,
-                                       -156.0f, -149.5f, -139.0f, -126.0f, -107.0f, -87.5f, -64.0f, -38.5f, -9.4f, 0.0f,
-                                       12.0f, 43.5f, 69.0f, 94.0f, 114.0f, 132.0f, 146.0f, 155.5f, 162.3f, 168.2f,
-                                       173.1f, 178.2f, 182.8f, 187.4f, 191.8f, 196.0f, 199.7f, 201.9f, 203.8f, 205.6f,
-                                       214.6f, 222.5f, 230.4f, 238.2f, 253.3f, 268.0f, 297.6f, 327.7f
+float LT_Voltage_Output[LT_MAX_IDX] = {-230.0f, -215.0f, -192.5f, -185.0f, -177.5f, -170.0f, -164.0f, -160.0f, -150.0f,
+                                       -150.0f, -145.0f, -145.0f, -145.0f, -135.0f, -135.0f, -135.0f, -127.5f, -127.5f, -115.0f,
+                                       -115.0f, -115.0F, -100.0f, -100.0f, -100.0f, -60.0f, -60.0f, -10.0f, -5.0f, 0.0f,
+                                       7.5f, 14.0f, 14.0f, 14.0f, 42.5f, 42.5f, 42.5f, 80.0f, 80.0f, 105.0f,
+                                       105.0f, 105.0f, 120.0f, 120.0f, 120.0f, 131.0f, 131.0f, 140.0f, 140.0f, 140.0f,
+                                       155.0f, 160.0f, 170.0f, 174.0f, 182.0f, 191.0f, 212.0f, 230.0f
                                       }; // mV
 
 float PWM_duty_byLT(float Ref_V)
@@ -341,52 +343,82 @@
     return PWM_duty;
 }
 
+
+
+
+
 /*******************************************************************************
                             TIMER INTERRUPT
 *******************************************************************************/
 
 float FREQ_TMR4 = (float)FREQ_20k;
 float DT_TMR4 = (float)DT_20k;
+long  CNT_TMR4 = 0;
+int   TMR4_FREQ_10k = (int)FREQ_10k;
 extern "C" void TIM4_IRQHandler(void)
 {
-
     if (TIM4->SR & TIM_SR_UIF ) {
 
         /*******************************************************
         ***     Sensor Read & Data Handling
         ********************************************************/
 
+        //Encoder
+        if (CNT_TMR4 % (int) ((int) FREQ_TMR4/TMR4_FREQ_10k) == 0) {
+            ENC_UPDATE();
+        }
 
-        //Using LoadCell
-//            ADC1->CR2  |= 0x40000000;                        // adc _ 12bit
-//            //while((ADC1->SR & 0b10));
-//            float alpha_update_torque = 1.0f/(1.0f+(FREQ_TMR4/2.0f)/(2.0f*3.14f*1000.0f));
-//            float torque_new = ((float)ADC1->DR - PRES_A_NULL)  / TORQUE_SENSOR_PULSE_PER_TORQUE + 1.0f;
-//            torq.sen = torq.sen*(1.0f-alpha_update_torque)+torque_new*(alpha_update_torque);
+        ADC1->CR2  |= 0x40000000;
+        if (SENSING_MODE == 0) {
+            // Torque Sensing (0~210)bar =============================================
+            float pres_A_new = (((float) ADC1->DR) - 2047.5f);
+            double alpha_update_ft = 1.0f / (1.0f + FREQ_TMR4 / (2.0f * 3.14f * 100.0f)); // f_cutoff : 200Hz
+            pres_A.sen = (1.0f - alpha_update_ft) * pres_A.sen + alpha_update_ft * pres_A_new;
+            torq.sen = -pres_A.sen / TORQUE_SENSOR_PULSE_PER_TORQUE;
 
 
+//        float alpha_update_pres_A = 1.0f/(1.0f + FREQ_TMR4/(2.0f*3.14f*100.0f));
+////        float pres_A_new = ((float)ADC1->DR - PRES_A_NULL)  / PRES_SENSOR_A_PULSE_PER_BAR;
+//        float pres_A_new = ((float)ADC1->DR);
+//        pres_A.sen = pres_A.sen*(1.0f-alpha_update_pres_A)+pres_A_new*(alpha_update_pres_A);
+//        torq.sen = - (pres_A.sen-2048.0f); //pulse -2047~2047
+
 
-        //Pressure sensor A
-        ADC1->CR2  |= 0x40000000;                        // adc _ 12bit
-        //while((ADC1->SR & 0b10));
-        float alpha_update_pres_A = 1.0f/(1.0f + FREQ_TMR4/(2.0f*3.14f*100.0f));
-//        float pres_A_new = ((float)ADC1->DR - PRES_A_NULL)  / PRES_SENSOR_A_PULSE_PER_BAR;
-        float pres_A_new = ((float)ADC1->DR);
-        pres_A.sen = pres_A.sen*(1.0f-alpha_update_pres_A)+pres_A_new*(alpha_update_pres_A);
-        torq.sen = - (pres_A.sen-2048.0f); //pulse -2047~2047
+        } else if (SENSING_MODE == 1) {
+            // Pressure Sensing (0~210)bar =============================================
+            float pres_A_new = (((float)ADC1->DR) - PRES_A_NULL);
+            float pres_B_new = (((float)ADC2->DR) - PRES_B_NULL);
+            double alpha_update_pres = 1.0f / (1.0f + FREQ_TMR4 / (2.0f * 3.14f * 200.0f)); // f_cutoff : 500Hz
+            pres_A.sen = (1.0f - alpha_update_pres) * pres_A.sen + alpha_update_pres * pres_A_new;
+            pres_B.sen = (1.0f - alpha_update_pres) * pres_B.sen + alpha_update_pres * pres_B_new;
+            CUR_PRES_A_BAR = pres_A.sen / PRES_SENSOR_A_PULSE_PER_BAR;
+            CUR_PRES_B_BAR = pres_B.sen / PRES_SENSOR_B_PULSE_PER_BAR;
 
+            if ((OPERATING_MODE & 0x01) == 0) { // Rotary Actuator
+                torq.sen = (PISTON_AREA_A * CUR_PRES_A_BAR - PISTON_AREA_B * CUR_PRES_B_BAR) * 0.0001f; // mm^3*bar >> Nm
+            } else if ((OPERATING_MODE & 0x01) == 1) { // Linear Actuator
+                torq.sen = (PISTON_AREA_A * CUR_PRES_A_BAR - PISTON_AREA_B * CUR_PRES_B_BAR) * 0.1f; // mm^2*bar >> N
+            }
+        }
 
-        //Pressure sensor 1B
-        //float alpha_update_pres_B = 1.0f/(1.0f+(FREQ_TMR4/2.0f)/(2.0f*3.14f*1000.0f));
-        //float pres_B_new = ((float)ADC2->DR);
-        //pres_B.sen = pres_B.sen*(1.0f-alpha_update_pres_B)+pres_B_new*(alpha_update_pres_B);
-        //torq.sen = pres_A.sen * (float) PISTON_AREA_A - pres_B.sen * (float) PISTON_AREA_B;
-
+//        //Pressure sensor A
+//        ADC1->CR2  |= 0x40000000;                        // adc _ 12bit
+//        //while((ADC1->SR & 0b10));
+//        float alpha_update_pres_A = 1.0f/(1.0f + FREQ_TMR4/(2.0f*3.14f*100.0f));
+//        float pres_A_new = ((float)ADC1->DR);
+//        pres_A.sen = pres_A.sen*(1.0f-alpha_update_pres_A)+pres_A_new*(alpha_update_pres_A);
+//        torq.sen = - (pres_A.sen-2048.0f); //pulse -2047~2047    //SW just changed the sign to correct the direction of loadcell on LIGHT. Correct later.
+//
+//
+//        //Pressure sensor B
+//        float alpha_update_pres_B = 1.0f/(1.0f + FREQ_TMR4/(2.0f*3.14f*100.0f));
+//        float pres_B_new = ((float)ADC2->DR);
+//        pres_B.sen = pres_B.sen*(1.0f-alpha_update_pres_B)+pres_B_new*(alpha_update_pres_B);
+//        //torq.sen = pres_A.sen * (float) PISTON_AREA_A - pres_B.sen * (float) PISTON_AREA_B;
 
 
         //Current
         //ADC3->CR2  |= 0x40000000;                        // adc _ 12bit
-//          a1=ADC2->DR;
         //int raw_cur = ADC3->DR;
         //while((ADC3->SR & 0b10));
         float alpha_update_cur = 1.0f/(1.0f + FREQ_TMR4/(2.0f*3.14f*500.0f)); // f_cutoff : 500Hz
@@ -394,29 +426,34 @@
         cur.sen=cur.sen*(1.0f-alpha_update_cur)+cur_new*(alpha_update_cur);
         //cur.sen = raw_cur;
 
-        /*******************************************************
-        ***     Timer Counting & etc.
-        ********************************************************/
-        //CNT_TMR4++;
+        CNT_TMR4++;
     }
     TIM4->SR = 0x0;  // reset the status register
 }
 
 
 int j =0;
-//unsigned long CNT_TMR3 = 0;
-//float FREQ_TMR3 = (float)FREQ_5k;
 float FREQ_TMR3 = (float)FREQ_5k;
 float DT_TMR3 = (float)DT_5k;
-//float DT_TMR3 = (float)DT_1k;
 int cnt_trans = 0;
 double VALVE_POS_RAW_FORCE_FB_LOGGING = 0.0f;
-int canfreq = CAN_FREQUENCY;
+int can_rest =0;
 
 extern "C" void TIM3_IRQHandler(void)
 {
     if (TIM3->SR & TIM_SR_UIF ) {
-        ENC_UPDATE();
+
+        if (((OPERATING_MODE&0b110)>>1) == 0) {
+            K_v = 0.4f; // Moog (LPM >> mA) , 100bar
+            mV_PER_mA = 500.0f; // 5000mV/10mA
+            mV_PER_pulse = 0.5f; // 5000mV/10000pulse
+            mA_PER_pulse = 0.001f; // 10mA/10000pulse
+        } else if (((OPERATING_MODE&0b110)>>1) == 1) {
+            K_v = 0.5f; // KNR (LPM >> mA) , 100bar
+            mV_PER_mA = 166.6666f; // 5000mV/30mA
+            mV_PER_pulse = 0.5f; // 5000mV/10000pulse
+            mA_PER_pulse = 0.003f; // 30mA/10000pulse
+        }
 
         if(MODE_POS_FT_TRANS == 1) {
             alpha_trans = (float)(1.0f - cos(3.141592f * (float)cnt_trans * DT_TMR3 /3.0f))/2.0f;
@@ -431,400 +468,34 @@
             if((float) cnt_trans * DT_TMR3 > 3.0f )
                 MODE_POS_FT_TRANS = 0;
         } else if(MODE_POS_FT_TRANS == 2) {
-            alpha_trans = 1.0;
+            alpha_trans = 1.0f;
             cnt_trans = 0;
         } else {
-            alpha_trans = 0.0;
+            alpha_trans = 0.0f;
             cnt_trans = 0;
         }
 
 
+        int UTILITY_MODE = 0;
+        int CONTROL_MODE = 0;
+
+        if (CONTROL_UTILITY_MODE >= 20 || CONTROL_UTILITY_MODE == 0) {
+            UTILITY_MODE = CONTROL_UTILITY_MODE;
+            CONTROL_MODE = MODE_NO_ACT;
+        } else {
+            CONTROL_MODE = CONTROL_UTILITY_MODE;
+            UTILITY_MODE = MODE_NO_ACT;
+        }
+
+
 
-        // CONTROL LOOP ------------------------------------------------------------
-
-        switch (CONTROL_MODE) {
-            case MODE_NO_ACT: {
-                V_out = 0.0f;
-                break;
-            }
-
-            case MODE_VALVE_POSITION_CONTROL: {
-                VALVE_POS_CONTROL(valve_pos.ref);
-                break;
-            }
-
-            case MODE_JOINT_CONTROL: {
-
-                float VALVE_POS_RAW_FORCE_FB = 0.0f;
-
-                
-                double torq_ref = 0.0f;
-                //if(TMR3_COUNT_TEST % (int) (50) == 0){
-                pos.err = pos.ref - pos.sen; //[pulse]
-                vel.err = vel.ref - vel.sen; //[pulse/s]
-                torq_ref = torq.ref + (K_SPRING * pos.err * 0.01f - D_DAMPER * vel.sen * 0.0001f) / ENC_PULSE_PER_POSITION; //[N]
-                    //torq_ref_logging = torq_ref
-                //}
-
-                // torque feedback
-                torq.err = torq_ref - torq.sen; //[pulse]
-                torq.err_sum += torq.err/(float) TMR_FREQ_5k; //[pulse]
-//                if (torq.err_sum > 1000) torq.err_sum = 1000;
-//                if (torq.err_sum<-1000) torq.err_sum = -1000;
-
-
-                VALVE_POS_RAW_FORCE_FB = alpha_trans*(((float) P_GAIN_JOINT_TORQUE * torq.err + (float) I_GAIN_JOINT_TORQUE * torq.err_sum) /(float) TORQUE_SENSOR_PULSE_PER_TORQUE * 0.01f
-                                                      + DDV_JOINT_POS_FF(vel.sen))+ (1.0f-alpha_trans) * (P_GAIN_JOINT_POSITION * 0.01f * pos.err /(float) ENC_PULSE_PER_POSITION + DDV_JOINT_POS_FF(vel.ref));
+        // UTILITY MODE ------------------------------------------------------------
 
-                if (VALVE_POS_RAW_FORCE_FB >= 0) {
-                    valve_pos.ref = VALVE_POS_RAW_FORCE_FB + VALVE_DEADZONE_PLUS;
-                } else {
-                    valve_pos.ref = VALVE_POS_RAW_FORCE_FB + VALVE_DEADZONE_MINUS;
-                }
-                
-                if(I_GAIN_JOINT_TORQUE != 0){
-                    double Ka = 1.0f / (double) I_GAIN_JOINT_TORQUE * (float) TORQUE_SENSOR_PULSE_PER_TORQUE * 100.0f;
-                    if(valve_pos.ref>VALVE_MAX_POS){
-                        double valve_pos_rem = valve_pos.ref - VALVE_MAX_POS;
-                        valve_pos_rem = valve_pos_rem * Ka;
-                        valve_pos.ref = VALVE_MAX_POS;
-                        torq.err_sum = torq.err_sum - valve_pos_rem/(float) TMR_FREQ_5k;
-                    }
-                    else if(valve_pos.ref < VALVE_MIN_POS){
-                        double valve_pos_rem = valve_pos.ref - VALVE_MIN_POS;
-                        valve_pos_rem = valve_pos_rem * Ka;
-                        valve_pos.ref = VALVE_MIN_POS;
-                        torq.err_sum = torq.err_sum - valve_pos_rem/(float) TMR_FREQ_5k;
-                    }
-                }    
-            
-                VALVE_POS_CONTROL(valve_pos.ref);
-                
-                //TMR3_COUNT_TEST++;
-                
-                break;
-            }
-            
-
-            case MODE_VALVE_OPEN_LOOP: {
-                V_out = (float) Vout.ref;
-                break;
-            }
-
-            case MODE_JOINT_POSITION_TORQUE_CONTROL_VALVE_POSITION: {
-                float VALVE_POS_RAW_POS_FB = 0.0f; // Valve Position by Position Feedback
-                //float VALVE_POS_RAW_POS_FF = 0.0f; // Valve Position by Position Feedforward
-                float VALVE_POS_RAW_FORCE_FB = 0.0f; // Valve Position by Force Feedback
-                //int DDV_JOINT_CAN = 0;
-                // feedback input for position control
-                pos.err = pos.ref - (float) pos.sen;
-                pos.err_diff = pos.err - pos.err_old;
-                pos.err_old = pos.err;
-                pos.err_sum += pos.err;
-                if (pos.err_sum > 1000) pos.err_sum = 1000;
-                if (pos.err_sum<-1000) pos.err_sum = -1000;
-                VALVE_POS_RAW_POS_FB = (float) P_GAIN_JOINT_POSITION * 0.01f * pos.err/(float) ENC_PULSE_PER_POSITION + (float) I_GAIN_JOINT_POSITION * 0.01f * pos.err_sum/(float) ENC_PULSE_PER_POSITION + (float) D_GAIN_JOINT_POSITION * pos.err_diff/(float) ENC_PULSE_PER_POSITION;
-
-
-                //Ref_Joint_Vel =  Ref_Vel_Test;
-                // feedforward input for position control
-                //            float Ref_Joint_Vel_Act = Ref_Joint_Vel/(float)ENC_PULSE_PER_POSITION; // [pulse/s] >> [deg/s]
-                //            float K_ff = 0.9f;
-                //            if(Ref_Joint_Vel_Act > 0) K_ff = 0.90f; // open
-                //            if(Ref_Joint_Vel_Act > 0) K_ff = 0.75f; // close
-                //            VALVE_POS_RAW_POS_FF = K_ff*Ref_Joint_Vel_Act/0.50f;
-
-                //torque feedback
-                torq.err = - torq.ref + torq.sen;
-                torq.err_diff = torq.err - torq.err_old;
-                torq.err_old = torq.err;
-                torq.err_sum += torq.err;
-                if (torq.err_sum > 1000) torq.err_sum = 1000;
-                if (torq.err_sum<-1000) torq.err_sum = -1000;
-                VALVE_POS_RAW_FORCE_FB = (float) P_GAIN_JOINT_TORQUE * torq.err + (float) I_GAIN_JOINT_TORQUE * torq.err_sum + (float) D_GAIN_JOINT_TORQUE * torq.err_diff;
-                VALVE_POS_RAW_FORCE_FB = VALVE_POS_RAW_FORCE_FB * 0.01f;
-
-//                valve_pos.ref = VALVE_POS_RAW_POS_FB + DDV_JOINT_POS_FF(vel.ref) + VALVE_POS_RAW_FORCE_FB;
-                valve_pos.ref = VALVE_POS_RAW_POS_FB + DDV_JOINT_POS_FF(vel.ref);
-
-                if (valve_pos.ref >= 0) {
-                    valve_pos.ref = valve_pos.ref + VALVE_DEADZONE_PLUS;
-                } else if(valve_pos.ref < 0) {
-                    valve_pos.ref = valve_pos.ref + VALVE_DEADZONE_MINUS;
-                }
-                VALVE_POS_CONTROL(valve_pos.ref);
-
-
+        switch (UTILITY_MODE) {
+            case MODE_NO_ACT: {
                 break;
             }
 
-//            case MODE_VALVE_POSITION_TORQUE_CONTROL_LEARNING: {
-//
-//                break;
-//            }
-
-//            case MODE_JOINT_POSITION_PRES_CONTROL_PWM: {
-//                pos.err = pos.ref - (float) pos.sen;
-//                pos.err_diff = pos.err - pos.err_old;
-//                pos.err_old = pos.err;
-//                pos.err_sum += pos.err;
-//                if (pos.err_sum > 1000) pos.err_sum = 1000;
-//                if (pos.err_sum<-1000) pos.err_sum = -1000;
-//                VALVE_PWM_RAW_POS = ((float) P_GAIN_JOINT_POSITION * pos.err + (float) I_GAIN_JOINT_POSITION * pos.err_sum + (float) D_GAIN_JOINT_POSITION * pos.err_diff)/(float) ENC_PULSE_PER_POSITION;
-//
-//                torq.err = torq.ref - torq.sen;
-//                torq.err_diff = torq.err - torq.err_old;
-//                torq.err_old = torq.err;
-//                torq.err_sum += torq.err;
-//                if (torq.err_sum > 1000) torq.err_sum = 1000;
-//                if (torq.err_sum<-1000) torq.err_sum = -1000;
-//                VALVE_PWM_RAW_TORQ = (float) P_GAIN_JOINT_TORQUE * torq.err + (float) I_GAIN_JOINT_TORQUE * torq.err_sum + (float) D_GAIN_JOINT_TORQUE * torq.err_diff;
-//
-//                VALVE_PWM_RAW_TORQ = VALVE_PWM_RAW_TORQ * 0.01f;
-//
-//                V_out = VALVE_PWM_RAW_POS + (float) COMPLIANCE_GAIN * 0.01f * VALVE_PWM_RAW_TORQ;
-//
-//                CUR_FLOWRATE = (float) CUR_VELOCITY * 0.00009587f;
-//                CUR_FLOWRATE = CUR_FLOWRATE * 0.5757f; // 0.4791=2*pi/65536*5000(pulse/tic to rad/s) 0.5757=0.02525*0.02*0.0095*2*60*1000 (radius * area * 2 * 60(sec --> min) * 1000(m^3 --> L))
-//                if (DIR_VALVE > 0) {
-//                    if (CUR_FLOWRATE >= 0 && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[0]*1.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - 0.0f) / (VALVE_GAIN_LPM_PER_V[0]*1.0f - 0.0f) + 0.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[0]*1.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[2]*2.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[0]*1.0f) / (VALVE_GAIN_LPM_PER_V[2]*2.0f - VALVE_GAIN_LPM_PER_V[0]*1.) + 1.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[2]*2.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[4]*3.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[2]*2.0f) / (VALVE_GAIN_LPM_PER_V[4]*3.0f - VALVE_GAIN_LPM_PER_V[2]*2.) + 2.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[4]*3.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[6]*4.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[4]*3.0f) / (VALVE_GAIN_LPM_PER_V[6]*4.0f - VALVE_GAIN_LPM_PER_V[4]*3.) + 3.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[6]*4.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[8]*5.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[6]*4.0f) / (VALVE_GAIN_LPM_PER_V[8]*5.0f - VALVE_GAIN_LPM_PER_V[6]*4.) + 4.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[8]*5.0f)) VALVE_FF_VOLTAGE = 5.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[1]*(-1.0f)) && CUR_FLOWRATE < 0.0f) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[1]*(-1.0f)) / (0.0f - VALVE_GAIN_LPM_PER_V[1]*(-1.)) - 1.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[3]*(-2.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[1]*(-1.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[3]*(-2.0f)) / ((VALVE_GAIN_LPM_PER_V[1]*(-1.0f)) - VALVE_GAIN_LPM_PER_V[3]*(-2.)) - 2.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[5]*(-3.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[3]*(-2.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[5]*(-3.0f)) / ((VALVE_GAIN_LPM_PER_V[3]*(-2.0f)) - VALVE_GAIN_LPM_PER_V[5]*(-3.)) - 3.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[7]*(-4.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[5]*(-3.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[7]*(-4.0f)) / ((VALVE_GAIN_LPM_PER_V[5]*(-3.0f)) - VALVE_GAIN_LPM_PER_V[7]*(-4.)) - 4.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[9]*(-5.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[7]*(-4.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[9]*(-5.0f)) / ((VALVE_GAIN_LPM_PER_V[7]*(-4.0f)) - VALVE_GAIN_LPM_PER_V[9]*(-5.)) - 5.0f;
-//                    else if (CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[9]*(-5.0f))) VALVE_FF_VOLTAGE = -5;
-//                    else VALVE_FF_VOLTAGE = 0;
-//                } else {
-//                    if (CUR_FLOWRATE >= 0 && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[0]*1.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - 0.0f) / (VALVE_GAIN_LPM_PER_V[0]*1.0f - 0.0f) + 0.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[1]*1.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[2]*2.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[0]*1.0f) / (VALVE_GAIN_LPM_PER_V[2]*2.0f - VALVE_GAIN_LPM_PER_V[0]*1.0f) + 1.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[3]*2.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[4]*3.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[2]*2.0f) / (VALVE_GAIN_LPM_PER_V[4]*3.0f - VALVE_GAIN_LPM_PER_V[2]*2.0f) + 2.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[5]*3.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[6]*4.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[4]*3.0f) / (VALVE_GAIN_LPM_PER_V[6]*4.0f - VALVE_GAIN_LPM_PER_V[4]*3.0f) + 3.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[7]*4.0f) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[8]*5.0f)) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[6]*4.0f) / (VALVE_GAIN_LPM_PER_V[8]*5.0f - VALVE_GAIN_LPM_PER_V[6]*4.0f) + 4.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[9]*5.0f)) VALVE_FF_VOLTAGE = 5.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[0]*(-1.0f)) && CUR_FLOWRATE < 0.0f) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[1]*(-1.0f)) / (0.0f - VALVE_GAIN_LPM_PER_V[1]*(-1.0f)) - 1.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[2]*(-2.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[1]*(-1.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[3]*(-2.0f)) / ((VALVE_GAIN_LPM_PER_V[1]*(-1.0f)) - VALVE_GAIN_LPM_PER_V[3]*(-2.0f)) - 2.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[4]*(-3.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[3]*(-2.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[5]*(-3.0f)) / ((VALVE_GAIN_LPM_PER_V[3]*(-2.0f)) - VALVE_GAIN_LPM_PER_V[5]*(-3.0f)) - 3.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[6]*(-4.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[5]*(-3.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[7]*(-4.0f)) / ((VALVE_GAIN_LPM_PER_V[5]*(-3.0f)) - VALVE_GAIN_LPM_PER_V[7]*(-4.0f)) - 4.0f;
-//                    else if (CUR_FLOWRATE >= (VALVE_GAIN_LPM_PER_V[8]*(-5.0f)) && CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[7]*(-4.0f))) VALVE_FF_VOLTAGE = (CUR_FLOWRATE - VALVE_GAIN_LPM_PER_V[9]*(-5.0f)) / ((VALVE_GAIN_LPM_PER_V[7]*(-4.0f)) - VALVE_GAIN_LPM_PER_V[9]*(-5.0f)) - 5.0f;
-//                    else if (CUR_FLOWRATE < (VALVE_GAIN_LPM_PER_V[8]*(-5.0f))) VALVE_FF_VOLTAGE = -5;
-//                    else VALVE_FF_VOLTAGE = 0;
-//                }
-//                //            VALVE_FF_VOLTAGE = CUR_FLOWRATE * 0.5f;
-//
-//                if (CUR_FLOWRATE >= 0) VALVE_FF_VOLTAGE = (float) VELOCITY_COMP_GAIN * 0.001f * VALVE_FF_VOLTAGE * sqrt((float) PRES_SUPPLY - CUR_PRES_A_BAR) * 0.0707f; // 0.0707 = 1/sqrt(200.))
-//                else if (CUR_FLOWRATE < 0) VALVE_FF_VOLTAGE = (float) VELOCITY_COMP_GAIN * 0.001f * VALVE_FF_VOLTAGE * sqrt((float) PRES_SUPPLY - CUR_PRES_B_BAR) * 0.0707f;
-//
-//                V_out = V_out + VALVE_FF_VOLTAGE;
-//                break;
-//            }
-
-//            case MODE_JOINT_POSITION_PRES_CONTROL_VALVE_POSITION: {
-//
-//                pos.err = pos.ref - (float) pos.sen;
-//                pos.err_diff = pos.err - pos.err_old;
-//                pos.err_old = pos.err;
-//                pos.err_sum += pos.err;
-//                if (pos.err_sum > 1000) pos.err_sum = 1000;
-//                if (pos.err_sum<-1000) pos.err_sum = -1000;
-//                VALVE_PWM_RAW_POS = ((float) P_GAIN_JOINT_POSITION * pos.err + (float) I_GAIN_JOINT_POSITION * pos.err_sum + (float) D_GAIN_JOINT_POSITION * pos.err_diff) * 0.01f;
-//
-//                torq.err = torq.ref - torq.sen;
-//                torq.err_diff = torq.err - torq.err_old;
-//                torq.err_old = torq.err;
-//                torq.err_sum += torq.err;
-//                if (torq.err_sum > 1000) torq.err_sum = 1000;
-//                if (torq.err_sum<-1000) torq.err_sum = -1000;
-//                VALVE_PWM_RAW_TORQ = (float) P_GAIN_JOINT_TORQUE * torq.err + (float) I_GAIN_JOINT_TORQUE * torq.err_sum + (float) D_GAIN_JOINT_TORQUE * torq.err_diff;
-//
-//                valve_pos.ref = VALVE_PWM_RAW_POS + VALVE_PWM_RAW_TORQ;
-//                VALVE_POS_CONTROL(valve_pos.ref);
-//
-//                break;
-//            }
-
-//            case MODE_VALVE_POSITION_PRES_CONTROL_LEARNING: {
-//
-//                break;
-//            }
-
-
-//            case MODE_TEST_CURRENT_CONTROL: {
-//                if (TMR3_COUNT_IREF == TMR_FREQ_5k) {
-//                    TMR3_COUNT_IREF = 0;
-//                }
-//                TMR3_COUNT_IREF++;
-//
-//                // Set Current Reference
-//                float TMR3_CNT_MAX = (float)TMR_FREQ_5k/2.0f;
-//                float I_REF_MID = 0.0f;
-//                if (TMR3_COUNT_IREF < TMR3_CNT_MAX) {
-//                    I_REF = I_REF_MID + 1.0f;
-//                } else {
-//                    I_REF = I_REF_MID - 1.0f;
-//                }
-////              float T = 1.0; // wave period
-////              I_REF = (5. * sin(2. * 3.1415 * (float) TMR3_COUNT_IREF / (float)TMR_FREQ_5k/ T));
-////              I_REF = (2.0 * sin(2. * 2. * 3.14 * (float) TMR3_COUNT_IREF / 5000.)+(2.0 * sin(2. * 1. * 3.14 * (float)TMR3_COUNT_IREF/ 5000.))+(2.0 * sin(2. * 5. * 3.14 * (float)TMR3_COUNT_IREF/ 5000.))+(2.0 * sin(2. * 10. * 3.14 * (float)TMR3_COUNT_IREF/ 5000.)));
-//
-//                if (TMR3_COUNT_IREF % (int) (TMR_FREQ_5k / CAN_FREQ) == 0) {
-//                    //CAN_TX_PRES((int16_t)(I_REF*1000.0), (int16_t) (CUR_CURRENT*1000.0)); // to check the datas
-//                }
-//                break;
-//            }
-
-//            case MODE_TEST_PWM_CONTROL: {
-//                if (TMR3_COUNT_IREF == TMR_FREQ_5k) {
-//                    TMR3_COUNT_IREF = 0;
-//                }
-//                TMR3_COUNT_IREF++;
-//
-//                // Set PWM reference
-//                float TMR3_CNT_MAX = (float)TMR_FREQ_5k/2.0f;
-//                //float I_REF_MID = 0.0f;
-//                if (TMR3_COUNT_IREF < TMR3_CNT_MAX) {
-//                    CUR_PWM = 1000;
-//                } else {
-//                    CUR_PWM = -1000;
-//                }
-//
-//                if (TMR3_COUNT_IREF % (int) (TMR_FREQ_5k / CAN_FREQ) == 0) {
-//                    //CAN_TX_PRES((int16_t)(u_CUR[0]*1000.0f), (int16_t) (CUR_CURRENT*1000.0f)); // to check the datas
-//                }
-//                break;
-//            }
-
-
-//            case MODE_CURRENT_CONTROL: {
-//
-//                cur.ref = cur.ref; // Unit : mA
-//                CurrentControl();
-//                break;
-//            }
-
-//            case MODE_JOINT_POSITION_TORQUE_CONTROL_CURRENT: {
-//                float I_REF_POS_FB = 0.0f; // I_REF by Position Feedback
-//                float I_REF_POS_FF = 0.0f; // I_REF by Position Feedforward
-//                float I_REF_FORCE_FB = 0.0f; // I_REF by Force Feedback
-//                float I_REF_FORCE_FF = 0.0f; // I_REF by Force Feedforward
-//
-//                // feedback input for position control
-//                pos.err = pos.ref - pos.sen;
-//                float alpha_update_vel = 1.0f/(1.0f+(float)FREQ_TMR4/(2.0f*3.1415f*50.0f)); // f_cutoff : 50Hz
-//                float err_diff = (pos.err - pos.err_old)*(float)FREQ_5k;
-//                pos.err_diff = (1.0f-alpha_update_vel)*pos.err_diff + alpha_update_vel*err_diff;
-//                pos.err_old = pos.err;
-//                I_REF_POS_FB = 0.001f*((float)P_GAIN_JOINT_POSITION * pos.err + (float)D_GAIN_JOINT_POSITION * pos.err_diff * 0.1f);
-//
-//                // feedforward input for position control
-//                float Vel_Act_Ref = vel.ref; // [pulse/s] >> [deg/s]
-//                float K_ff = 1.3f;
-//                float K_v = 0.0f;
-//                if(Vel_Act_Ref > 0) K_v = 1.0f/100.0f; // open, tuning. (deg/s >> mA)
-//                if(Vel_Act_Ref < 0) K_v = 1.0f/100.0f; // close, tuning. (deg/s >> mA)
-//                I_REF_POS_FF = K_ff*K_v*Vel_Act_Ref;
-//
-//                // feedback input for position control
-//                I_REF_FORCE_FB = 0.0f;
-//
-//                // feedforward input for position control
-//                I_REF_FORCE_FF = 0.0f;
-//
-//                cur.ref = I_REF_POS_FF + I_REF_POS_FB + I_REF_FORCE_FB + I_REF_FORCE_FF;
-//
-//                CurrentControl();
-//
-//                break;
-//            }
-
-//            case MODE_JOINT_POSITION_PRES_CONTROL_CURRENT: {
-//                //float T_REF = 0.0; // Torque Reference
-//                float I_REF_FORCE_FB = 0.; // I_REF by Force Feedback
-//                float I_REF_VC = 0.; // I_REF for velocity compensation
-//
-//                // feedback input for position control
-//                //float Joint_Pos_Err = 34.0f-(float) pos.sen/(float)ENC_PULSE_PER_POSITION; // [pulse/s] >> [deg/s]
-//                //float Joint_Vel_Err = 0.0f-(float) vel.sen/(float)ENC_PULSE_PER_POSITION; // [pulse/s] >> [deg/s]
-//                //float K_spring = 0.7f;
-//                //float D_damper = 0.02f;
-////              T_REF = K_spring * pos.err + D_damper * Joint_Vel_Err; // unit : Nm
-//
-//                // torque feedback
-//                torq.err = torq.ref - torq.sen;
-//                //            torq.err_diff = torq.err - torq.err_old;
-//                //            torq.err_old = torq.err;
-//                torq.err_sum = torq.err_sum + torq.err/(float)TMR_FREQ_5k;
-//                I_REF_FORCE_FB = 0.001f*((float)P_GAIN_JOINT_TORQUE * torq.err + (float)I_GAIN_JOINT_TORQUE * torq.err_sum);
-//
-//                // velocity compensation for torque control
-//                float Joint_Vel_Act = vel.sen/(float)ENC_PULSE_PER_POSITION; // [pulse/s] >> [deg/s]
-//                float K_vc = 1.5f; // Velocity comp. gain
-//                float K_v = 0.0f; // Valve gain
-//                if(Joint_Vel_Act > 0) K_v = 1.0f/100.0f; // open, tuning
-//                if(Joint_Vel_Act < 0) K_v = 1.0f/100.0f; // close, tuning
-//                I_REF_VC = K_vc*K_v*Joint_Vel_Act;
-//
-//                cur.ref = I_REF_VC + I_REF_FORCE_FB;
-//                //            cur.ref = I_REF_FORCE_FB;
-//
-//                float I_MAX = 10.0f; // Maximum Current : 10mV
-//                float Ka = 1.0f/I_GAIN_JOINT_TORQUE;
-//                if(cur.ref > I_MAX) {
-//                    float I_rem = cur.ref-I_MAX;
-//                    I_rem = Ka*I_rem;
-//                    cur.ref = I_MAX;
-//                    torq.err_sum = torq.err_sum - I_rem/(float)TMR_FREQ_5k;
-//                } else if(cur.ref < -I_MAX) {
-//                    float I_rem = cur.ref-(-I_MAX);
-//                    I_rem = Ka*I_rem;
-//                    cur.ref = -I_MAX;
-//                    torq.err_sum = torq.err_sum - I_rem/(float)TMR_FREQ_5k;
-//                }
-//
-//                CurrentControl();
-//
-//
-//                /*
-//                float I_REF_POS_FB = 0.0f; // I_REF by Position Feedback
-//                float I_REF_POS_FF = 0.0f; // I_REF by Position Feedforward
-//                float I_REF_FORCE_FB = 0.0f; // I_REF by Force Feedback
-//                float I_REF_FORCE_FF = 0.0f; // I_REF by Force Feedforward
-//
-//                // feedback input for position control
-//                pos.err = pos.ref - pos.sen;
-//                float alpha_update_vel = 1.0f/(1.0f+(float)FREQ_TMR4/(2.0f*3.1415f*50.0f)); // f_cutoff : 50Hz
-//                float err_diff = (pos.err - pos.err_old)*(float)FREQ_5k;
-//                pos.err_diff = (1.0f-alpha_update_vel)*pos.err_diff + alpha_update_vel*err_diff;
-//                pos.err_old = pos.err;
-//                I_REF_POS_FB = 0.001f*((float)P_GAIN_JOINT_POSITION * pos.err + (float)D_GAIN_JOINT_POSITION * pos.err_diff * 0.1f);
-//
-//                // feedforward input for position control
-//                float Vel_Act_Ref = vel.ref; // [pulse/s] >> [deg/s]
-//                float K_ff = 1.3f;
-//                float K_v = 0.0f;
-//                if(Vel_Act_Ref > 0) K_v = 1.0f/100.0f; // open, tuning. (deg/s >> mA)
-//                if(Vel_Act_Ref < 0) K_v = 1.0f/100.0f; // close, tuning. (deg/s >> mA)
-//                I_REF_POS_FF = K_ff*K_v*Vel_Act_Ref;
-//
-//                // feedback input for position control
-//                I_REF_FORCE_FB = 0.0f;
-//
-//                // feedforward input for position control
-//                I_REF_FORCE_FF = 0.0f;
-//
-//                cur.ref = I_REF_POS_FF + I_REF_POS_FB + I_REF_FORCE_FB + I_REF_FORCE_FF;
-//
-//                CurrentControl();
-//                */
-//
-//                break;
-//            }
-
             case MODE_TORQUE_SENSOR_NULLING: {
                 // DAC Voltage reference set
                 if (TMR3_COUNT_TORQUE_NULL < TMR_FREQ_5k * 2) {
@@ -834,77 +505,27 @@
                         CUR_TORQUE_mean = CUR_TORQUE_sum / 10.0f;
                         CUR_TORQUE_sum = 0;
 
-                        TORQUE_VREF += 0.0003 * (0.0f - CUR_TORQUE_mean);
+                        TORQUE_VREF += 0.0003f * (0.0f - CUR_TORQUE_mean);
 
                         if (TORQUE_VREF > 3.3f) TORQUE_VREF = 3.3f;
-                        if (TORQUE_VREF < 0) TORQUE_VREF = 0;
+                        if (TORQUE_VREF < 0.0f) TORQUE_VREF = 0.0f;
 
                         //spi_eeprom_write(RID_TORQUE_SENSOR_VREF, (int16_t) (TORQUE_VREF * 1000.0));
                         dac_1 = TORQUE_VREF / 3.3f;
                     }
                 } else {
-                    CONTROL_MODE = MODE_NO_ACT;
+                    CONTROL_UTILITY_MODE = MODE_NO_ACT;
                     TMR3_COUNT_TORQUE_NULL = 0;
                     CUR_TORQUE_sum = 0;
                     CUR_TORQUE_mean = 0;
 
                     ROM_RESET_DATA();
 
-                    //spi_eeprom_write(RID_TORQUE_SENSOR_VREF, (int16_t) (TORQUE_VREF * 1000.0));
-
-                    //pc.printf("%f\n", TORQUE_VREF);
                     dac_1 = TORQUE_VREF / 3.3f;
 
                 }
                 TMR3_COUNT_TORQUE_NULL++;
                 break;
-
-
-
-                //           // DAC Voltage reference set
-//                if (TMR3_COUNT_PRES_NULL < TMR_FREQ_5k * 2) {
-//                    CUR_PRES_A_sum += pres_A.sen;
-//                    CUR_PRES_B_sum += pres_B.sen;
-//
-//                    if (TMR3_COUNT_PRES_NULL % 10 == 0) {
-//                        CUR_PRES_A_mean = CUR_PRES_A_sum / 10.0f;
-//                        CUR_PRES_B_mean = CUR_PRES_B_sum / 10.0f;
-//                        CUR_PRES_A_sum = 0;
-//                        CUR_PRES_B_sum = 0;
-//
-//                        float VREF_NullingGain = 0.0003f;
-//                        PRES_A_VREF = PRES_A_VREF - VREF_NullingGain * (PRES_A_NULL - CUR_PRES_A_mean);
-//                        PRES_B_VREF = PRES_B_VREF - VREF_NullingGain * (PRES_B_NULL - CUR_PRES_B_mean);
-//
-//                        if (PRES_A_VREF > 3.3f) PRES_A_VREF = 3.3f;
-//                        if (PRES_A_VREF < 0.0f) PRES_A_VREF = 0.0f;
-//                        if (PRES_B_VREF > 3.3f) PRES_B_VREF = 3.3f;
-//                        if (PRES_B_VREF < 0.0f) PRES_B_VREF = 0.0f;
-//
-//                        dac_1 = PRES_A_VREF / 3.3f;
-//                        dac_2 = PRES_B_VREF / 3.3f;
-//                    }
-//                } else {
-//                    CONTROL_MODE = MODE_NO_ACT;
-//                    TMR3_COUNT_PRES_NULL = 0;
-//                    CUR_PRES_A_sum = 0;
-//                    CUR_PRES_B_sum = 0;
-//                    CUR_PRES_A_mean = 0;
-//                    CUR_PRES_B_mean = 0;
-//
-//                    ROM_RESET_DATA();
-//
-//                    dac_1 = PRES_A_VREF / 3.3f;
-//                    dac_2 = PRES_B_VREF / 3.3f;
-//                    //pc.printf("nulling end");
-//                }
-//                TMR3_COUNT_PRES_NULL++;
-//                break;
-
-
-
-
-
             }
 
 //            case MODE_VALVE_NULLING_AND_DEADZONE_SETTING: {
@@ -989,19 +610,17 @@
                     cnt_findhome = 0;
                     cnt_vel_findhome = 0;
                     //REFERENCE_MODE = MODE_REF_NO_ACT; // Stop taking reference data from PODO
-                    pos.ref_home_pos = pos.sen;
-                    vel.ref_home_pos = 0.0f;
+                    pos.ref = pos.sen;
+                    vel.ref = 0.0f;
                     FINDHOME_STAGE = FINDHOME_GOTOLIMIT;
-                    CAN_TX_PRES((int16_t)(CONTROL_MODE), (int16_t) (3));
                 } else if (FINDHOME_STAGE == FINDHOME_GOTOLIMIT) {
-                    int cnt_check_enc = (TMR_FREQ_5k/500);
+                    int cnt_check_enc = (TMR_FREQ_5k/20);
                     if(cnt_findhome%cnt_check_enc == 0) {
                         FINDHOME_POSITION = pos.sen;
                         FINDHOME_VELOCITY = FINDHOME_POSITION - FINDHOME_POSITION_OLD;
                         FINDHOME_POSITION_OLD = FINDHOME_POSITION;
                     }
                     cnt_findhome++;
-                    //if(cnt_findhome == TMR_FREQ_5k) cnt_findhome = 0;
 
                     if (abs(FINDHOME_VELOCITY) <= 1) {
                         cnt_vel_findhome = cnt_vel_findhome + 1;
@@ -1009,26 +628,24 @@
                         cnt_vel_findhome = 0;
                     }
 
-                    if ((cnt_vel_findhome < 3*TMR_FREQ_5k) &&  cnt_findhome <= 10*TMR_FREQ_5k) { // wait for 3sec
+                    if ((cnt_vel_findhome < 3*TMR_FREQ_5k) &&  cnt_findhome < 10*TMR_FREQ_5k) { // wait for 3sec
                         //REFERENCE_MODE = MODE_REF_NO_ACT;
-                        //if (HOMEPOS_OFFSET > 0) pos.ref_home_pos = pos.ref_home_pos + (float) ENC_PULSE_PER_POSITION / (float) 512.0f;
-                        if (HOMEPOS_OFFSET > 0) pos.ref_home_pos = pos.ref_home_pos + 8.0f;
-//                        else pos.ref_home_pos = pos.ref_home_pos - (float) ENC_PULSE_PER_POSITION / (float) 512.0f;
-                        else pos.ref_home_pos = pos.ref_home_pos - 8.0f;
-                        pos.err = pos.ref_home_pos - pos.sen;
-                        float VALVE_POS_RAW_POS_FB = 0.0f;
-                        VALVE_POS_RAW_POS_FB = (float) P_GAIN_JOINT_POSITION * pos.err/(float) ENC_PULSE_PER_POSITION * 0.01f;
-                        valve_pos.ref = VALVE_POS_RAW_POS_FB + DDV_CENTER;
-                        VALVE_POS_CONTROL(valve_pos.ref);
+                        if (HOMEPOS_OFFSET > 0) pos.ref = pos.ref + 12.0f;
+                        else pos.ref = pos.ref - 12.0f;
 
-                        //float wn_Pos = 2.0f*PI*5.0f; // f_cut : 10Hz Position Control
-                        //I_REF = 0.04f*wn_Pos*((float)joint_pos_err/ENC_PULSE_PER_POSITION);
-                        ////       L velocity >> mA convert
-                        //if(I_REF>5.0f) I_REF = 5.0f;
-                        //if(I_REF<-5.0f) I_REF = -5.0f;
-                        //FLAG_CURRNET_CONTROL = true;
+//                        pos.err = pos.ref_home_pos - pos.sen;
+//                        float VALVE_POS_RAW_POS_FB = 0.0f;
+//                        VALVE_POS_RAW_POS_FB = (float) P_GAIN_JOINT_POSITION * pos.err/(float) ENC_PULSE_PER_POSITION * 0.01f;
+//                        valve_pos.ref = VALVE_POS_RAW_POS_FB + (float) VALVE_CENTER;
+//                        VALVE_POS_CONTROL(valve_pos.ref);
+
+                        CONTROL_MODE = MODE_JOINT_CONTROL;
+                        alpha_trans = 0.0f;
+
+
                     } else {
                         ENC_SET(HOMEPOS_OFFSET);
+//                        ENC_SET_ZERO();
                         INIT_REF_POS = HOMEPOS_OFFSET;
                         REF_POSITION = 0;
                         REF_VELOCITY = 0;
@@ -1038,18 +655,82 @@
                         cnt_findhome = 0;
                         cnt_vel_findhome = 0;
                         FINDHOME_STAGE = FINDHOME_ZEROPOSE;
+
+
+                        cnt_findhome = 0;
+                        pos.ref = 0.0f;
+                        vel.ref = 0.0f;
+                        pos.ref_home_pos = 0.0f;
+                        vel.ref_home_pos = 0.0f;
+                        //FINDHOME_STAGE = FINDHOME_INIT;
+                        //CONTROL_UTILITY_MODE = MODE_JOINT_CONTROL;
+                        
+                        
                     }
                 } else if (FINDHOME_STAGE == FINDHOME_ZEROPOSE) {
                     int T_move = 2*TMR_FREQ_5k;
-                    pos.ref_home_pos = (0.0f - (float)INIT_REF_POS)*0.5f*(1.0f - cos(3.14159f * (float)cnt_findhome / (float)T_move)) + (float)INIT_REF_POS;
-                    vel.ref_home_pos = 0.0f;
-
+                    pos.ref = (0.0f - (float)INIT_REF_POS)*0.5f*(1.0f - cos(3.14159f * (float)cnt_findhome / (float)T_move)) + (float)INIT_REF_POS;
+                    //pos.ref = 0.0f;
+                    vel.ref = 0.0f;
+                    
                     // input for position control
-                    pos.err = pos.ref_home_pos - (float)pos.sen;
-                    float VALVE_POS_RAW_POS_FB = 0.0f;
-                    VALVE_POS_RAW_POS_FB = (float) P_GAIN_JOINT_POSITION * 0.01f * pos.err/(float) ENC_PULSE_PER_POSITION;
-                    valve_pos.ref = VALVE_POS_RAW_POS_FB + DDV_CENTER;
-                    VALVE_POS_CONTROL(valve_pos.ref);
+                
+//                    CONTROL_MODE = MODE_JOINT_CONTROL;
+                    alpha_trans = 0.0f;
+
+                    double torq_ref = 0.0f;
+                    pos.err = (pos.ref - pos.sen)/(float)(ENC_PULSE_PER_POSITION); //[mm]
+                    vel.err = (0.0f - vel.sen)/(float)(ENC_PULSE_PER_POSITION); //[mm/s]
+                    pos.err_sum += pos.err/(float) TMR_FREQ_5k; //[mm]
+
+                    if (((OPERATING_MODE&0b110)>>1) == 0 || ((OPERATING_MODE&0b110)>>1) == 1) {
+
+                        double I_REF_POS = 0.0f;
+                        double I_REF_FORCE_FB = 0.0f; // I_REF by Force Feedback
+                        double I_REF_VC = 0.0f; // I_REF for velocity compensation
+
+                        double temp_vel_pos = 0.0f;
+                        double temp_vel_torq = 0.0f;
+                        double wn_Pos = 2.0f * PI * 5.0f; // f_cut : 5Hz Position Control
+
+                        if ((OPERATING_MODE && 0x01) == 0) { // Rotary Mode
+                            temp_vel_pos = (0.01f * (double) P_GAIN_JOINT_POSITION * wn_Pos * pos.err + 0.01f * (double) I_GAIN_JOINT_POSITION * wn_Pos * pos.err_sum + 0.01f * (double) VELOCITY_COMP_GAIN * vel.ref / ENC_PULSE_PER_POSITION) * 3.14159f / 180.0f; // rad/s
+                            //                            L when P-gain = 100, f_cut = 10Hz                                 L feedforward velocity
+                        } else if ((OPERATING_MODE && 0x01) == 1) {
+                            temp_vel_pos = (0.01f * (double) P_GAIN_JOINT_POSITION * wn_Pos * pos.err + 0.01f * (double) I_GAIN_JOINT_POSITION * wn_Pos * pos.err_sum + 0.01f * (double) VELOCITY_COMP_GAIN * vel.ref / ENC_PULSE_PER_POSITION); // mm/s
+                            //                            L when P-gain = 100, f_cut = 10Hz                                 L feedforward velocity
+                        }
+                        if (temp_vel_pos > 0.0f) I_REF_POS = temp_vel_pos * ((double) PISTON_AREA_A * 0.00006f / (K_v * sqrt(2.0f * alpha3 / (alpha3 + 1.0f))));
+                        else I_REF_POS = temp_vel_pos * ((double) PISTON_AREA_B * 0.00006f / (K_v * sqrt(2.0f / (alpha3 + 1.0f))));
+
+                        I_REF = I_REF_POS;
+
+
+
+                    } else {
+                        float VALVE_POS_RAW_FORCE_FB = 0.0f;
+                        VALVE_POS_RAW_FORCE_FB = DDV_JOINT_POS_FF(vel.sen) + (P_GAIN_JOINT_POSITION * 0.01f * pos.err + DDV_JOINT_POS_FF(vel.ref));
+
+                        if (VALVE_POS_RAW_FORCE_FB >= 0) {
+                            valve_pos.ref = VALVE_POS_RAW_FORCE_FB + VALVE_DEADZONE_PLUS;
+                        } else {
+                            valve_pos.ref = VALVE_POS_RAW_FORCE_FB + VALVE_DEADZONE_MINUS;
+                        }
+
+                        VALVE_POS_CONTROL(valve_pos.ref);
+
+                        V_out = (float) Vout.ref;
+
+                    }
+
+
+                    
+                    
+//                    pos.err = pos.ref - (float)pos.sen;
+//                    float VALVE_POS_RAW_POS_FB = 0.0f;
+//                    VALVE_POS_RAW_POS_FB = (float) P_GAIN_JOINT_POSITION * 0.01f * pos.err/(float) ENC_PULSE_PER_POSITION;
+//                    valve_pos.ref = VALVE_POS_RAW_POS_FB + (float) VALVE_CENTER;
+//                    VALVE_POS_CONTROL(valve_pos.ref);
 
                     cnt_findhome++;
                     if (cnt_findhome >= T_move) {
@@ -1060,7 +741,7 @@
                         pos.ref_home_pos = 0.0f;
                         vel.ref_home_pos = 0.0f;
                         FINDHOME_STAGE = FINDHOME_INIT;
-                        CONTROL_MODE = MODE_JOINT_CONTROL;
+                        CONTROL_UTILITY_MODE = MODE_JOINT_CONTROL;
                     }
                 }
 
@@ -1138,7 +819,6 @@
 //                }
 //
 //            }
-
             case MODE_PRESSURE_SENSOR_NULLING: {
                 // DAC Voltage reference set
                 if (TMR3_COUNT_PRES_NULL < TMR_FREQ_5k * 2) {
@@ -1152,8 +832,8 @@
                         CUR_PRES_B_sum = 0;
 
                         float VREF_NullingGain = 0.0003f;
-                        PRES_A_VREF = PRES_A_VREF - VREF_NullingGain * (PRES_A_NULL - CUR_PRES_A_mean);
-                        PRES_B_VREF = PRES_B_VREF - VREF_NullingGain * (PRES_B_NULL - CUR_PRES_B_mean);
+                        PRES_A_VREF = PRES_A_VREF + VREF_NullingGain * CUR_PRES_A_mean;
+                        PRES_B_VREF = PRES_B_VREF + VREF_NullingGain * CUR_PRES_B_mean;
 
                         if (PRES_A_VREF > 3.3f) PRES_A_VREF = 3.3f;
                         if (PRES_A_VREF < 0.0f) PRES_A_VREF = 0.0f;
@@ -1164,7 +844,7 @@
                         dac_2 = PRES_B_VREF / 3.3f;
                     }
                 } else {
-                    CONTROL_MODE = MODE_NO_ACT;
+                    CONTROL_UTILITY_MODE = MODE_NO_ACT;
                     TMR3_COUNT_PRES_NULL = 0;
                     CUR_PRES_A_sum = 0;
                     CUR_PRES_B_sum = 0;
@@ -1229,12 +909,13 @@
 //            }
 
             case MODE_DDV_POS_VS_PWM_ID: {
+                CONTROL_MODE = MODE_VALVE_OPEN_LOOP;
                 VALVE_ID_timer = VALVE_ID_timer + 1;
 
                 if(VALVE_ID_timer < TMR_FREQ_5k*1) {
-                    V_out = 3000.0f * sin(2*3.14f*VALVE_ID_timer/TMR_FREQ_5k * 100.0f);
+                    Vout.ref = 3000.0f * sin(2.0f*3.14f*VALVE_ID_timer/TMR_FREQ_5k * 100.0f);
                 } else if(VALVE_ID_timer < TMR_FREQ_5k*2) {
-                    V_out = 1000.0f*(ID_index_array[ID_index]);
+                    Vout.ref = 1000.0f*(ID_index_array[ID_index]);
                 } else if(VALVE_ID_timer == TMR_FREQ_5k*2) {
                     VALVE_POS_TMP = 0;
                     data_num = 0;
@@ -1242,6 +923,8 @@
                     data_num = data_num + 1;
                     VALVE_POS_TMP = VALVE_POS_TMP + value;
                 } else if(VALVE_ID_timer == TMR_FREQ_5k*3) {
+                    Vout.ref = 0.0f;
+                } else {
                     VALVE_POS_AVG[ID_index] = VALVE_POS_TMP / data_num;
                     VALVE_ID_timer = 0;
                     ID_index= ID_index +1;
@@ -1260,9 +943,9 @@
                             VALVE_POS_AVG_OLD = VALVE_MIN_POS;
                         }
                     }
-                    //ROM_RESET_DATA();
+                    ROM_RESET_DATA();
                     ID_index = 0;
-                    CONTROL_MODE = MODE_NO_ACT;
+                    CONTROL_UTILITY_MODE = MODE_NO_ACT;
                 }
 
 
@@ -1270,27 +953,27 @@
             }
 
             case MODE_DDV_DEADZONE_AND_CENTER: {
-
+                CONTROL_MODE = MODE_VALVE_OPEN_LOOP;
                 VALVE_DZ_timer = VALVE_DZ_timer + 1;
                 if(first_check == 0) {
                     if(VALVE_DZ_timer < (int) (1.0f * (float) TMR_FREQ_5k)) {
-                        V_out = VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = VALVE_VOLTAGE_LIMIT * 1000.0f;
                     } else if(VALVE_DZ_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
-                        V_out = VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = VALVE_VOLTAGE_LIMIT * 1000.0f;
                         pos_plus_end = pos.sen;
                     } else if(VALVE_DZ_timer < (int) (2.0f * (float) TMR_FREQ_5k)) {
-                        V_out = -VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = -VALVE_VOLTAGE_LIMIT * 1000.0f;
                     } else if(VALVE_DZ_timer == (int) (2.0f * (float) TMR_FREQ_5k)) {
-                        V_out = -VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = -VALVE_VOLTAGE_LIMIT * 1000.0f;
                         pos_minus_end = pos.sen;
                     } else if(VALVE_DZ_timer < (int) (3.0f * (float) TMR_FREQ_5k)) {
-                        V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                        Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
                     } else if(VALVE_DZ_timer < (int) (4.0f * (float) TMR_FREQ_5k)) {
-                        V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                        Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
                         data_num = data_num + 1;
                         VALVE_POS_TMP = VALVE_POS_TMP + value;
                     } else if(VALVE_DZ_timer == (int) (4.0f * (float) TMR_FREQ_5k)) {
-                        V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                        Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
                         DDV_POS_AVG = VALVE_POS_TMP / data_num;
                         START_POS = pos.sen;
                         VALVE_POS_TMP = 0;
@@ -1303,18 +986,15 @@
                     } else if(VALVE_DZ_timer < (int) (6.0f * (float) TMR_FREQ_5k)) {
                         valve_pos.ref = DDV_POS_AVG;
                         VALVE_POS_CONTROL(valve_pos.ref);
-                        if(CUR_VELOCITY >= 0)
-                            VEL_POINT = VEL_POINT + 1;
-                        else
-                            VEL_POINT = VEL_POINT - 1;
+
                     } else if(VALVE_DZ_timer == (int) (6.0f * (float) TMR_FREQ_5k)) {
                         valve_pos.ref = DDV_POS_AVG;
                         VALVE_POS_CONTROL(valve_pos.ref);
                         FINAL_POS = pos.sen;
 
-                        if((FINAL_POS - START_POS)>100) {
+                        if((FINAL_POS - START_POS)>200) {
                             DZ_case = 1;
-                        } else if((FINAL_POS - START_POS)<-100) {
+                        } else if((FINAL_POS - START_POS)<-200) {
                             DZ_case = -1;
                         } else {
                             DZ_case = 0;
@@ -1322,7 +1002,6 @@
 
                         CAN_TX_PRES((int16_t) (DZ_case), (int16_t) (6));
 
-                        VEL_POINT = 0;
                         first_check = 1;
                         DZ_DIRECTION = 1;
                         VALVE_DZ_timer = 0;
@@ -1334,7 +1013,9 @@
                 } else {
                     if((DZ_case == -1 && DZ_NUM == 1) | (DZ_case == 1 && DZ_NUM == 1)) {
                         if(VALVE_DZ_timer < (int) (1.0 * (float) TMR_FREQ_5k)) {
-                            V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            //pos.ref = 0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end;
+                            //CONTROL_MODE = MODE_JOINT_CONTROL;
                         } else if(VALVE_DZ_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
                             START_POS = pos.sen;
                         } else if(VALVE_DZ_timer < (int) (2.0f * (float) TMR_FREQ_5k)) {
@@ -1345,10 +1026,7 @@
                                 valve_pos.ref = VALVE_MAX_POS;
                             }
                             VALVE_POS_CONTROL(valve_pos.ref);
-                            if(CUR_VELOCITY >= 0)
-                                VEL_POINT = VEL_POINT + 1;
-                            else
-                                VEL_POINT = VEL_POINT - 1;
+
                         } else if(VALVE_DZ_timer == (int) (2.0f * (float) TMR_FREQ_5k)) {
                             Ref_Valve_Pos_Old = valve_pos.ref;
                             FINAL_POS = pos.sen;
@@ -1361,8 +1039,6 @@
                                 DZ_DIRECTION = 1 * DZ_case;
                             }
 
-                            VEL_POINT = 0;
-
                             VALVE_DZ_timer = 0;
                             DZ_index= DZ_index *2;
                             if(DZ_index >= 128) {
@@ -1375,54 +1051,54 @@
                         }
                     } else if((DZ_case == -1 && DZ_NUM == 2) | (DZ_case == 1 && DZ_NUM == 2)) {
                         if(VALVE_DZ_timer < (int) (1.0f * (float) TMR_FREQ_5k)) {
-                            V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            //pos.ref = 0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end;
+                            //CONTROL_MODE = MODE_JOINT_CONTROL;
                         } else if(VALVE_DZ_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
                             START_POS = pos.sen;
                         } else if(VALVE_DZ_timer < (int) (2.0f * (float) TMR_FREQ_5k)) {
-                            valve_pos.ref = Ref_Valve_Pos_Old  + DZ_DIRECTION * 64 / DZ_index;
+                            valve_pos.ref = Ref_Valve_Pos_Old  - DZ_case * DZ_DIRECTION * 64 / DZ_index;
                             if(valve_pos.ref <= VALVE_MIN_POS) {
                                 valve_pos.ref = VALVE_MIN_POS;
                             } else if(valve_pos.ref >= VALVE_MAX_POS) {
                                 valve_pos.ref = VALVE_MAX_POS;
                             }
                             VALVE_POS_CONTROL(valve_pos.ref);
-                            if(CUR_VELOCITY >= 0)
-                                VEL_POINT = VEL_POINT + 1;
-                            else
-                                VEL_POINT = VEL_POINT - 1;
+
                         } else if(VALVE_DZ_timer == (int) (2.0f * (float) TMR_FREQ_5k)) {
+                            Vout.ref = 0.0f;
+                        } else if(VALVE_DZ_timer > (int) (2.0f * (float) TMR_FREQ_5k)) {
                             Ref_Valve_Pos_Old = valve_pos.ref;
                             FINAL_POS = pos.sen;
 
                             if((FINAL_POS - START_POS)>100) {
-                                DZ_DIRECTION = -1;
+                                DZ_DIRECTION = 1 * DZ_case;
                             } else if((FINAL_POS - START_POS)<-100) {
-                                DZ_DIRECTION = 1;
+                                DZ_DIRECTION = -1 * DZ_case;
                             } else {
-                                DZ_DIRECTION = 1;
+                                DZ_DIRECTION = -1 * DZ_case;
                             }
 
-                            VEL_POINT = 0;
-
-
                             VALVE_DZ_timer = 0;
-                            DZ_index= DZ_index *2;
+                            DZ_index= DZ_index * 2;
                             if(DZ_index >= 128) {
                                 SECOND_DZ = valve_pos.ref;
-                                DDV_CENTER = 0.5f * (float) (FIRST_DZ) + 0.5f * (float) (SECOND_DZ);
+                                VALVE_CENTER = (int) (0.5f * (float) (FIRST_DZ) + 0.5f * (float) (SECOND_DZ));
                                 first_check = 0;
                                 VALVE_DEADZONE_MINUS = (float) FIRST_DZ;
                                 VALVE_DEADZONE_PLUS = (float) SECOND_DZ;
 
                                 ROM_RESET_DATA();
 
-                                CONTROL_MODE = MODE_NO_ACT;
+                                CONTROL_UTILITY_MODE = MODE_NO_ACT;
                                 DZ_index = 1;
                             }
                         }
                     } else if(DZ_case == 0 && DZ_NUM ==1) {
                         if(VALVE_DZ_timer < (int) (1.0f * (float) TMR_FREQ_5k)) {
-                            V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            //pos.ref = 0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end;
+                            //CONTROL_MODE = MODE_JOINT_CONTROL;
                         } else if(VALVE_DZ_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
                             START_POS = pos.sen;
                         } else if(VALVE_DZ_timer < (int) (2.0f * (float) TMR_FREQ_5k)) {
@@ -1433,10 +1109,7 @@
                                 valve_pos.ref = VALVE_MAX_POS;
                             }
                             VALVE_POS_CONTROL(valve_pos.ref);
-                            if(CUR_VELOCITY >= 0)
-                                VEL_POINT = VEL_POINT + 1;
-                            else
-                                VEL_POINT = VEL_POINT - 1;
+
                         } else if(VALVE_DZ_timer == (int) (2.0f * (float) TMR_FREQ_5k)) {
                             Ref_Valve_Pos_Old = valve_pos.ref;
                             FINAL_POS = pos.sen;
@@ -1448,8 +1121,6 @@
                             } else {
                                 DZ_DIRECTION = 1;
                             }
-
-                            VEL_POINT = 0;
                             VALVE_DZ_timer = 0;
                             DZ_index= DZ_index *2;
                             if(DZ_index >= 128) {
@@ -1462,7 +1133,9 @@
                         }
                     } else {
                         if(VALVE_DZ_timer < (int) (1.0f * (float) TMR_FREQ_5k)) {
-                            V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            Vout.ref = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                            //pos.ref = 0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end;
+                            //CONTROL_MODE = MODE_JOINT_CONTROL;
                         } else if(VALVE_DZ_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
                             START_POS = pos.sen;
                         } else if(VALVE_DZ_timer < (int) (2.0f * (float) TMR_FREQ_5k)) {
@@ -1473,33 +1146,33 @@
                                 valve_pos.ref = VALVE_MAX_POS - 1;
                             }
                             VALVE_POS_CONTROL(valve_pos.ref);
-                            if(CUR_VELOCITY >= 0)
-                                VEL_POINT = VEL_POINT + 1;
-                            else
-                                VEL_POINT = VEL_POINT - 1;
+
                         } else if(VALVE_DZ_timer == (int) (2.0f * (float) TMR_FREQ_5k)) {
+                            Vout.ref = 0.0f;
+                        } else if(VALVE_DZ_timer > (int) (2.0f * (float) TMR_FREQ_5k)) {
                             Ref_Valve_Pos_Old = valve_pos.ref;
                             FINAL_POS = pos.sen;
-                            if(VEL_POINT >= 0)
-                                DZ_DIRECTION = -1;
-                            else
+
+                            if((FINAL_POS - START_POS)>100) {
                                 DZ_DIRECTION = 1;
-                            if(abs(FINAL_POS - START_POS) < 100)
+                            } else if((FINAL_POS - START_POS)<-100) {
+                                DZ_DIRECTION = -1;
+                            } else {
                                 DZ_DIRECTION = 1;
-
-                            VEL_POINT = 0;
-
+                            }
 
                             VALVE_DZ_timer = 0;
                             DZ_index= DZ_index *2;
                             if(DZ_index >= 128) {
                                 SECOND_DZ = valve_pos.ref;
-                                DDV_CENTER = 0.5f * (float) (FIRST_DZ) + 0.5f * (float) (SECOND_DZ);
+                                VALVE_CENTER = (int) (0.5f * (float) (FIRST_DZ) + 0.5f * (float) (SECOND_DZ));
                                 first_check = 0;
                                 VALVE_DEADZONE_MINUS = (float) FIRST_DZ;
                                 VALVE_DEADZONE_PLUS = (float) SECOND_DZ;
 
-                                CONTROL_MODE = MODE_NO_ACT;
+                                ROM_RESET_DATA();
+
+                                CONTROL_UTILITY_MODE = MODE_NO_ACT;
                                 DZ_index = 1;
                             }
                         }
@@ -1509,39 +1182,42 @@
             }
 
             case MODE_DDV_POS_VS_FLOWRATE: {
+                CONTROL_MODE = MODE_VALVE_OPEN_LOOP;
                 VALVE_FR_timer = VALVE_FR_timer + 1;
                 if(first_check == 0) {
                     if(VALVE_FR_timer < (int) (1.0f * (float) TMR_FREQ_5k)) {
-                        V_out = VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = VALVE_VOLTAGE_LIMIT * 1000.0f;
                         //CAN_TX_PRES((int16_t) (VALVE_FR_timer), (int16_t) (6));
                     } else if(VALVE_FR_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
-                        V_out = VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = VALVE_VOLTAGE_LIMIT * 1000.0f;
                         pos_plus_end = pos.sen;
                         //                    CAN_TX_PRES((int16_t) (V_out), (int16_t) (7));
                     } else if(VALVE_FR_timer < (int) (2.0f * (float) TMR_FREQ_5k)) {
-                        V_out = -VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = -VALVE_VOLTAGE_LIMIT * 1000.0f;
                     } else if(VALVE_FR_timer == (int) (2.0f * (float) TMR_FREQ_5k)) {
                         //                    CAN_TX_PRES((int16_t) (V_out), (int16_t) (8));
-                        V_out = -VALVE_VOLTAGE_LIMIT * 1000.0f;
+                        Vout.ref = -VALVE_VOLTAGE_LIMIT * 1000.0f;
                         pos_minus_end = pos.sen;
                         first_check = 1;
                         VALVE_FR_timer = 0;
-                        valve_pos.ref = DDV_CENTER;
+                        valve_pos.ref = (float) VALVE_CENTER;
                         ID_index = 0;
                         max_check = 0;
                         min_check = 0;
                     }
                 } else {
                     if(VALVE_FR_timer < (int) (1.0f * (float) TMR_FREQ_5k)) {
-                        V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                        //V_out = (float) P_GAIN_JOINT_POSITION * (0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen)/(float) ENC_PULSE_PER_POSITION;
+                        pos.ref = 0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end;
+                        CONTROL_MODE = MODE_JOINT_CONTROL;
                     } else if(VALVE_FR_timer == (int) (1.0f * (float) TMR_FREQ_5k)) {
                         data_num = 0;
-                        valve_pos.ref = 10.0f*((float) ID_index_array[ID_index]) + DDV_CENTER;
+                        valve_pos.ref = 10.0f*((float) ID_index_array[ID_index]) + (float) VALVE_CENTER;
 
                         VALVE_POS_CONTROL(valve_pos.ref);
                         START_POS = pos.sen;
                     } else if(VALVE_FR_timer < (int) (5.0f * (float) TMR_FREQ_5k)) {
-                        valve_pos.ref = 10.0f*((float) ID_index_array[ID_index]) + DDV_CENTER;
+                        valve_pos.ref = 10.0f*((float) ID_index_array[ID_index]) + (float) VALVE_CENTER;
                         VALVE_POS_CONTROL(valve_pos.ref);
                         data_num = data_num + 1;
                         if(abs(0.5f * (float) pos_plus_end + 0.5f * (float) pos_minus_end - (float) pos.sen) > 20000.0f) {
@@ -1551,6 +1227,7 @@
                     } else if(VALVE_FR_timer == (int) (5.0f * (float) TMR_FREQ_5k)) {
                         FINAL_POS = pos.sen;
                         one_period_end = 1;
+                        V_out = 0.0f;
                     }
 
                     if(one_period_end == 1) {
@@ -1561,7 +1238,6 @@
                         }
                         JOINT_VEL[ID_index] = (FINAL_POS - START_POS) / data_num * TMR_FREQ_5k;   //  pulse/sec
 
-                        //ROM_RESET_DATA();
                         VALVE_FR_timer = 0;
                         one_period_end = 0;
                         ID_index= ID_index +1;
@@ -1571,50 +1247,269 @@
                     if(max_check == 1 && min_check == 1) {
 
                         VALVE_POS_NUM = ID_index;
-                        //ROM_RESET_DATA();
+                        ROM_RESET_DATA();
                         ID_index = 0;
                         first_check = 0;
                         VALVE_FR_timer = 0;
-                        CONTROL_MODE = MODE_NO_ACT;
+                        CONTROL_UTILITY_MODE = MODE_NO_ACT;
 //                        CAN_TX_PRES((int16_t) (VALVE_FR_timer), (int16_t) (6));
                     }
                 }
                 break;
             }
 
+            case MODE_SYSTEM_ID: {
+                freq_sysid_Iref = (double) cnt_sysid * DT_TMR3 * 3.;
+                valve_pos.ref = 2500.0f * sin(2.0f * 3.14159f * freq_sysid_Iref * (double) cnt_sysid * DT_TMR3);
+                CONTROL_MODE = MODE_VALVE_OPEN_LOOP;
+                cnt_sysid++;
+                if (freq_sysid_Iref >= 300) {
+                    cnt_sysid = 0;
+                    CONTROL_UTILITY_MODE = MODE_NO_ACT;
+                }
+                break;
+            }
+
+
+
+            default:
+                break;
+        }
+
+        // CONTROL MODE ------------------------------------------------------------
+
+        switch (CONTROL_MODE) {
+            case MODE_NO_ACT: {
+                V_out = 0.0f;
+                break;
+            }
+
+            case MODE_VALVE_POSITION_CONTROL: {
+                if (OPERATING_MODE == 5) { //SW Valve
+                    VALVE_POS_CONTROL(valve_pos.ref);
+                    V_out = Vout.ref;
+                } else if (CURRENT_CONTROL_MODE == 0) { //PWM
+                    V_out = valve_pos.ref;
+                } else { 
+                    I_REF = valve_pos.ref * 0.001f;
+                }
+
+                break;
+            }
+
+            case MODE_JOINT_CONTROL: {
+                double torq_ref = 0.0f;
+                pos.err = (pos.ref - pos.sen)/(float)(ENC_PULSE_PER_POSITION); //[mm]
+                vel.err = (0.0f - vel.sen)/(float)(ENC_PULSE_PER_POSITION); //[mm/s]
+                pos.err_sum += pos.err/(float) TMR_FREQ_5k; //[mm]
+                
+                //K & D Low Pass Filter
+                float alpha_K_D = 1.0f/(1.0f + 5000.0f/(2.0f*3.14f*30.0f)); // f_cutoff : 30Hz
+                K_LPF = K_LPF*(1.0f-alpha_K_D)+K_SPRING*(alpha_K_D);
+                D_LPF = D_LPF*(1.0f-alpha_K_D)+D_DAMPER*(alpha_K_D);
+                
+                torq_ref = torq.ref + K_LPF * pos.err - D_LPF * vel.sen / ENC_PULSE_PER_POSITION; //[N]
+
+                // torque feedback
+                torq.err = (torq_ref)/(float)(TORQUE_SENSOR_PULSE_PER_TORQUE)  - torq.sen; //[N]
+                torq.err_sum += torq.err/(float) TMR_FREQ_5k; //[N]
+
+                if (((OPERATING_MODE&0b110)>>1) == 0 || ((OPERATING_MODE&0b110)>>1) == 1) {
+
+                    double I_REF_POS = 0.0f;
+                    double I_REF_FORCE_FB = 0.0f; // I_REF by Force Feedback
+                    double I_REF_VC = 0.0f; // I_REF for velocity compensation
+
+                    double temp_vel_pos = 0.0f;
+                    double temp_vel_torq = 0.0f;
+                    double wn_Pos = 2.0f * PI * 5.0f; // f_cut : 5Hz Position Control
+
+                    if ((OPERATING_MODE && 0x01) == 0) { // Rotary Mode
+                        temp_vel_pos = (0.01f * (double) P_GAIN_JOINT_POSITION * wn_Pos * pos.err + 0.01f * (double) I_GAIN_JOINT_POSITION * wn_Pos * pos.err_sum + 0.01f * (double) VELOCITY_COMP_GAIN * vel.ref / ENC_PULSE_PER_POSITION) * PI / 180.0f; // rad/s
+                        //                            L when P-gain = 100, f_cut = 10Hz                                 L feedforward velocity
+                    } else if ((OPERATING_MODE && 0x01) == 1) {
+                        temp_vel_pos = (0.01f * (double) P_GAIN_JOINT_POSITION * wn_Pos * pos.err + 0.01f * (double) I_GAIN_JOINT_POSITION * wn_Pos * pos.err_sum + 0.01f * (double) VELOCITY_COMP_GAIN * vel.ref / ENC_PULSE_PER_POSITION); // mm/s
+                        //                            L when P-gain = 100, f_cut = 10Hz                                 L feedforward velocity
+                    }
+                    if (temp_vel_pos > 0.0f) I_REF_POS = temp_vel_pos * ((double) PISTON_AREA_A * 0.00006f / (K_v * sqrt(2.0f * alpha3 / (alpha3 + 1.0f))));
+                    else I_REF_POS = temp_vel_pos * ((double) PISTON_AREA_B * 0.00006f / (K_v * sqrt(2.0f / (alpha3 + 1.0f))));
+
+                    // velocity compensation for torque control
+                    if ((OPERATING_MODE && 0x01) == 0) { // Rotary Mode
+                        I_REF_FORCE_FB = 0.001f * ((double) P_GAIN_JOINT_TORQUE * torq.err + (double) I_GAIN_JOINT_TORQUE * torq.err_sum);
+                        //                temp_vel_torq = (0.01 * (double) VELOCITY_COMP_GAIN * (double) CUR_VELOCITY / (double) ENC_PULSE_PER_POSITION) * PI / 180.0; // rad/s
+                        temp_vel_torq = (0.01f * (double) VELOCITY_COMP_GAIN * vel.ref / (double) ENC_PULSE_PER_POSITION) * PI / 180.0f; // rad/s
+                        //                                                          L feedforward velocity
+                    } else if ((OPERATING_MODE && 0x01) == 1) {
+                        I_REF_FORCE_FB = 0.001f * 0.01f*((double) P_GAIN_JOINT_TORQUE * torq.err + (double) I_GAIN_JOINT_TORQUE * torq.err_sum); // Linear Actuators are more sensitive.
+                        //                temp_vel_torq = (0.01 * (double) VELOCITY_COMP_GAIN * (double) CUR_VELOCITY / (double) ENC_PULSE_PER_POSITION); // mm/s
+                        temp_vel_torq = (0.01f * (double) VELOCITY_COMP_GAIN * vel.ref / (double) ENC_PULSE_PER_POSITION); // mm/s
+                        //                                                          L feedforward velocity
+                    }
+                    if (temp_vel_torq > 0.0f) I_REF_VC = temp_vel_torq * ((double) PISTON_AREA_A * 0.00006f / (K_v * sqrt(2.0f * alpha3 / (alpha3 + 1.0f))));
+                    else I_REF_VC = temp_vel_torq * ((double) PISTON_AREA_B * 0.00006f / (K_v * sqrt(2.0f / (alpha3 + 1.0f))));
+                    //                                                  L   velocity(rad/s or mm/s) >> I_ref(mA)
+                    //            Ref_Joint_FT_dot = (Ref_Joint_FT_Nm - Ref_Joint_FT_Nm_old) / TMR_DT_5k;
+                    //            Ref_Joint_FT_Nm_old = Ref_Joint_FT_Nm;
+
+                    I_REF = (1.0f - alpha_trans) * I_REF_POS + alpha_trans * (I_REF_VC + I_REF_FORCE_FB);
+                    
+                    // Anti-windup for FT
+                    if (I_GAIN_JOINT_TORQUE != 0) {
+                        double I_MAX = 10.0f; // Maximum Current : 10mV
+                        double Ka = 2.0f / ((double) I_GAIN_JOINT_TORQUE * 0.001f);
+                        if (I_REF > I_MAX) {
+                            double I_rem = I_REF - I_MAX;
+                            I_rem = Ka*I_rem;
+                            I_REF = I_MAX;
+                            torq.err_sum = torq.err_sum - I_rem /(float) TMR_FREQ_5k;
+                        } else if (I_REF < -I_MAX) {
+                            double I_rem = I_REF - (-I_MAX);
+                            I_rem = Ka*I_rem;
+                            I_REF = -I_MAX;
+                            torq.err_sum = torq.err_sum - I_rem /(float) TMR_FREQ_5k;
+                        }
+                    }
+
+                } else {
+                    float VALVE_POS_RAW_FORCE_FB = 0.0f;
+
+                    VALVE_POS_RAW_FORCE_FB = alpha_trans*(((float) P_GAIN_JOINT_TORQUE * torq.err + (float) I_GAIN_JOINT_TORQUE * torq.err_sum) * 0.01f
+                                                          + DDV_JOINT_POS_FF(vel.sen))+ (1.0f-alpha_trans) * (P_GAIN_JOINT_POSITION * 0.01f * pos.err + DDV_JOINT_POS_FF(vel.ref));
+
+                    if (VALVE_POS_RAW_FORCE_FB >= 0) {
+                        valve_pos.ref = VALVE_POS_RAW_FORCE_FB + VALVE_DEADZONE_PLUS;
+                    } else {
+                        valve_pos.ref = VALVE_POS_RAW_FORCE_FB + VALVE_DEADZONE_MINUS;
+                    }
+
+                    if(I_GAIN_JOINT_TORQUE != 0) {
+                        double Ka = 1.0f / (double) I_GAIN_JOINT_TORQUE * 100.0f;
+                        if(valve_pos.ref>VALVE_MAX_POS) {
+                            double valve_pos_rem = valve_pos.ref - VALVE_MAX_POS;
+                            valve_pos_rem = valve_pos_rem * Ka;
+                            valve_pos.ref = VALVE_MAX_POS;
+                            torq.err_sum = torq.err_sum - valve_pos_rem/(float) TMR_FREQ_5k;
+                        } else if(valve_pos.ref < VALVE_MIN_POS) {
+                            double valve_pos_rem = valve_pos.ref - VALVE_MIN_POS;
+                            valve_pos_rem = valve_pos_rem * Ka;
+                            valve_pos.ref = VALVE_MIN_POS;
+                            torq.err_sum = torq.err_sum - valve_pos_rem/(float) TMR_FREQ_5k;
+                        }
+                    }
+
+                    VALVE_POS_CONTROL(valve_pos.ref);
+
+//                    Vout.ref = (float) P_GAIN_JOINT_POSITION * 0.01f * ((float) pos.err);
+                    V_out = (float) Vout.ref;
+
+                }
+
+                break;
+            }
+
+            case MODE_VALVE_OPEN_LOOP: {
+                V_out = (float) Vout.ref;
+                break;
+            }
+
             default:
                 break;
         }
 
-//        if (FLAG_VALVE_OUTPUT_CALIB) {
-//            // Valve Dead Zone (Mechanical dead-zone canceling)
-//            //    if (CONTROL_MODE != MODE_VALVE_NULLING_AND_DEADZONE_SETTING) {
-//            //        if (V_out > 0.) {
-//            //            VALVE_PWM_VALVE_DZ = (int) V_out + VALVE_DEADZONE_PLUS;
-//            //        } else if (V_out < 0.) {
-//            //            VALVE_PWM_VALVE_DZ = (int) V_out + VALVE_DEADZONE_MINUS;
-//            //        } else VALVE_PWM_VALVE_DZ = (int) V_out + VALVE_CENTER;
-//            //    } else VALVE_PWM_VALVE_DZ = (int) V_out;
-//
-//            if(V_out>0) V_out = V_out + VALVE_DEADZONE_PLUS;
-//            else if(V_out<0) V_out = V_out + VALVE_DEADZONE_MINUS;
-//
-//            VALVE_PWM_VALVE_DZ = V_out + VALVE_CENTER;
-//
-//            // Output Voltage Linearization and Dead Zone Cancellation (Electrical dead-zone)
-//            float CUR_PWM_nonlin = VALVE_PWM_VALVE_DZ/5.0f*1000.0f; // convert PWM duty to mV
-//            float CUR_PWM_DZ = PWM_duty_byLT(CUR_PWM_nonlin);
-//
-//            if (CUR_PWM_DZ > 0) V_out = (int)CUR_PWM_DZ + 143;
-//            else if (CUR_PWM_DZ < 0) V_out = (int)CUR_PWM_DZ - 138;
-//            else V_out = CUR_PWM_DZ;
-//        } else {
-//            V_out = V_out;
-//        }
+
+        if (((OPERATING_MODE&0b110)>>1) == 0 || ((OPERATING_MODE&0b110)>>1) == 1) { //Moog Valve or KNR Valve
+
+            ////////////////////////////////////////////////////////////////////////////
+            ////////////////////////////  CURRENT CONTROL //////////////////////////////
+            ////////////////////////////////////////////////////////////////////////////
+            if (CURRENT_CONTROL_MODE) {
+                double alpha_update_Iref = 1.0f / (1.0f + 5000.0f / (2.0f * 3.14f * 300.0f)); // f_cutoff : 500Hz
+                I_REF_fil = (1.0f - alpha_update_Iref) * I_REF_fil + alpha_update_Iref*I_REF;
+
+                I_ERR = I_REF_fil - cur.sen;
+                I_ERR_INT = I_ERR_INT + (I_ERR) * 0.0002f;
+
+
+                // Moog Valve Current Control Gain
+                double R_model = 500.0f; // ohm
+                double L_model = 1.2f;
+                double w0 = 2.0f * 3.14f * 150.0f;
+                double KP_I = 0.1f * L_model*w0;
+                double KI_I = 0.1f * R_model*w0;
+
+                // KNR Valve Current Control Gain
+                if (((OPERATING_MODE & 0b110)>>1) == 1) { // KNR Valve
+                    R_model = 163.0f; // ohm
+                    L_model = 1.0f;
+                    w0 = 2.0f * 3.14f * 80.0f;
+                    KP_I = 1.0f * L_model*w0;
+                    KI_I = 0.08f * R_model*w0;
+                }
+
+                double FF_gain = 1.0f;
+
+                VALVE_PWM_RAW = KP_I * 2.0f * I_ERR + KI_I * 2.0f* I_ERR_INT;
+                //        VALVE_PWM_RAW = VALVE_PWM_RAW + FF_gain * (R_model*I_REF); // Unit : mV
+                I_REF_fil_diff = I_REF_fil - I_REF_fil_old;
+                I_REF_fil_old = I_REF_fil;
+//                VALVE_PWM_RAW = VALVE_PWM_RAW + FF_gain * (R_model * I_REF_fil + L_model * I_REF_fil_diff * 5000.0f); // Unit : mV
+                VALVE_PWM_RAW = VALVE_PWM_RAW + FF_gain * (R_model * I_REF_fil); // Unit : mV
+                double V_MAX = 12000.0f; // Maximum Voltage : 12V = 12000mV
 
+                double Ka = 3.0f / KP_I;
+                if (VALVE_PWM_RAW > V_MAX) {
+                    V_rem = VALVE_PWM_RAW - V_MAX;
+                    V_rem = Ka*V_rem;
+                    VALVE_PWM_RAW = V_MAX;
+                    I_ERR_INT = I_ERR_INT - V_rem * 0.0002f;
+                } else if (VALVE_PWM_RAW < -V_MAX) {
+                    V_rem = VALVE_PWM_RAW - (-V_MAX);
+                    V_rem = Ka*V_rem;
+                    VALVE_PWM_RAW = -V_MAX;
+                    I_ERR_INT = I_ERR_INT - V_rem * 0.0002f;
+                }
+                Cur_Valve_Open_pulse = cur.sen / mA_PER_pulse;
+            } else {
+                VALVE_PWM_RAW = I_REF * mV_PER_mA;
+                Cur_Valve_Open_pulse = I_REF / mA_PER_pulse;
+            }
+
+            ////////////////////////////////////////////////////////////////////////////
+            /////////////////  Dead Zone Cancellation & Linearization //////////////////
+            ////////////////////////////////////////////////////////////////////////////
+            // Dead Zone Cancellation (Mechanical Valve dead-zone)
+            if (FLAG_VALVE_DEADZONE) {
+                if (VALVE_PWM_RAW > 0) VALVE_PWM_RAW = VALVE_PWM_RAW + VALVE_DEADZONE_PLUS * mV_PER_pulse; // unit: mV
+                else if (VALVE_PWM_RAW < 0) VALVE_PWM_RAW = VALVE_PWM_RAW + VALVE_DEADZONE_MINUS * mV_PER_pulse; // unit: mV
+
+                VALVE_PWM_VALVE_DZ = VALVE_PWM_RAW + (double)VALVE_CENTER * mV_PER_pulse; // unit: mV
+
+            } else {
+                VALVE_PWM_VALVE_DZ = VALVE_PWM_RAW;
+            }
+
+            // Output Voltage Linearization
+            double CUR_PWM_nonlin = VALVE_PWM_VALVE_DZ; // Unit : mV
+            double CUR_PWM_lin = PWM_duty_byLT(CUR_PWM_nonlin);  // -8000~8000
+
+            // Dead Zone Cancellation (Electrical dead-zone)
+            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);
+        }
+        
+//        if(V_out > 0.0f) V_out = (float) (V_out + 169.0f);
+//        else if(V_out < 0.0f) V_out = (float) (V_out - 174.0f);
+//        else V_out = V_out;
+    
         /*******************************************************
         ***     PWM
         ********************************************************/
+        if(DIR_VALVE<0){
+            V_out = -V_out;
+        }
+        
         if (V_out >= VALVE_VOLTAGE_LIMIT*1000.0f) {
             V_out = VALVE_VOLTAGE_LIMIT*1000.0f;
         } else if(V_out<=-VALVE_VOLTAGE_LIMIT*1000.0f) {
@@ -1622,10 +1517,6 @@
         }
         PWM_out= V_out/(SUPPLY_VOLTAGE*1000.0f); // Full duty : 12000.0mV
 
-        // Saturation of output voltage to 5.0V
-//        if(PWM_out > 0.41667) PWM_out=0.41667; //5.0/12.0 = 0.41667
-//        else if (PWM_out < -0.41667) PWM_out=-0.41667;
-
         // Saturation of output voltage to 12.0V
         if(PWM_out > 1.0f) PWM_out=1.0f;
         else if (PWM_out < -1.0f) PWM_out=-1.0f;
@@ -1643,50 +1534,65 @@
         TIM4->CCR1 = (PWM_ARR)*(1.0f-dtc_w);
 
 
+        if (TMR2_COUNT_CAN_TX % (int) ((int) TMR_FREQ_5k/CAN_FREQ) == 0) {
 
-        
-        if (TMR2_COUNT_CAN_TX % (int) ((int) TMR_FREQ_5k/canfreq) == 0) {
-//        if (TMR2_COUNT_CAN_TX % 10 == 0) {
             // Position, Velocity, and Torque (ID:1200)
             if (flag_data_request[0] == HIGH) {
-                if ((OPERATING_MODE & 0x01) == 0) { // Rotary Actuator
+                if ((OPERATING_MODE & 0b01) == 0) { // Rotary Actuator
                     if (SENSING_MODE == 0) {
                         CAN_TX_POSITION_FT((int16_t) (pos.sen), (int16_t) (vel.sen/10.0f), (int16_t) (torq.sen*10.0f));
                     } else if (SENSING_MODE == 1) {
-                        CAN_TX_POSITION_PRESSURE((int16_t) (pos.sen), (int16_t) (vel.sen/10.0f), (int16_t) (pres_A.sen*10.0f), (int16_t) (pres_B.sen*10.0f));
+                        CAN_TX_POSITION_PRESSURE((int16_t) (pos.sen), (int16_t) (vel.sen/10.0f), (int16_t) ((pres_A.sen)*5.0f), (int16_t) ((pres_B.sen)*5.0f));
                     }
-                } else if ((OPERATING_MODE & 0x01) == 1) { // Linear Actuator
+                } else if ((OPERATING_MODE & 0b01) == 1) { // Linear Actuator
                     if (SENSING_MODE == 0) {
-                        CAN_TX_POSITION_FT((int16_t) (pos.sen/10.0f), (int16_t) (vel.sen/256.0f), (int16_t) (torq.sen*10.0f));
+                        CAN_TX_POSITION_FT((int16_t) (pos.sen/10.0f), (int16_t) (vel.sen/256.0f), (int16_t) (torq.sen));
                     } else if (SENSING_MODE == 1) {
-                        CAN_TX_POSITION_PRESSURE((int16_t) (pos.sen/10.0f), (int16_t) (vel.sen/256.0f), (int16_t) (pres_A.sen*10.0f), (int16_t) (pres_B.sen*10.0f));
+                        CAN_TX_POSITION_PRESSURE((int16_t) (pos.sen/10.0f), (int16_t) (vel.sen/256.0f), (int16_t) ((pres_A.sen)*5.0f), (int16_t) ((pres_B.sen)*5.0f));
                     }
                 }
             }
             if (flag_data_request[1] == HIGH) {
                 //valve position
                 double t_value = 0;
-                if(value>=DDV_CENTER) {
-                    t_value = 10000.0f*((double)value-(double)DDV_CENTER)/((double)VALVE_MAX_POS-(double)DDV_CENTER);
+//                if(valve_pos.ref>=(float) VALVE_CENTER) {
+//                    t_value = 10000.0f*((double)valve_pos.ref - (double)VALVE_CENTER)/((double)VALVE_MAX_POS - (double)VALVE_CENTER);
+//                } else {
+//                    t_value = -10000.0f*((double)valve_pos.ref - (double)VALVE_CENTER)/((double)VALVE_MIN_POS - (double)VALVE_CENTER);
+//                }
+                if(OPERATING_MODE==5) {
+                    t_value = (double) value;
+                } else if(CURRENT_CONTROL_MODE==1) {
+                    t_value = cur.sen;
                 } else {
-                    t_value = -10000.0f*((double)value-(double)DDV_CENTER)/((double)VALVE_MIN_POS-(double)DDV_CENTER);
+                    t_value = V_out;
                 }
-                CAN_TX_TORQUE((int16_t) (t_value));
+                CAN_TX_TORQUE((int16_t) (t_value)); //1300
+                //CAN_TX_TORQUE((int16_t) (cur.sen * 1000.0f)); //1300
+                //CAN_TX_TORQUE((int16_t) (I_REF * 1000.0f)); //1300
             }
 
+
             if (flag_data_request[2] == HIGH) {
                 //pressure A and B
-                CAN_TX_PRES((int16_t) (valve_pos.ref), (int16_t) (MODE_POS_FT_TRANS * 100.0f)); // CUR_PRES_X : 0(0bar)~4096(210bar)
+                CAN_TX_PRES((int16_t) (pres_A.sen), (int16_t) (pres_B.sen)); // CUR_PRES_X : 0(0bar)~4096(210bar) //1400
+            }
+
+            //If it doesn't rest, below can can not work.
+            for (can_rest = 0; can_rest < 10000; can_rest++) {
+                ;
             }
 
             if (flag_data_request[3] == HIGH) {
                 //PWM
-                CAN_TX_PWM((int16_t) VALVE_DEADZONE_PLUS);
+                CAN_TX_PWM((int16_t) value); //1500
             }
-
+            //for (i = 0; i < 10000; i++) {
+//                ;
+//            }
             if (flag_data_request[4] == HIGH) {
                 //valve position
-                CAN_TX_VALVE_POSITION((int16_t) (K_SPRING), (int16_t) (D_DAMPER), (int16_t) VALVE_POS_RAW_FORCE_FB_LOGGING);
+                CAN_TX_VALVE_POSITION((int16_t) (CAN_FREQ), (int16_t) (D_DAMPER), (int16_t) OPERATING_MODE); //1600
             }
 
             // Others : Reference position, Reference FT, PWM, Current  (ID:1300)
@@ -1694,122 +1600,59 @@
 //            CAN_TX_SOMETHING((int) (FORCE_VREF), (int16_t) (1), (int16_t) (2), (int16_t) (3));
 //        }
             //if (flag_delay_test == 1){
-                //CAN_TX_PRES((int16_t) (0),(int16_t) torq_ref);
+            //CAN_TX_PRES((int16_t) (0),(int16_t) torq_ref);
             //}
 
             TMR2_COUNT_CAN_TX = 0;
         }
         TMR2_COUNT_CAN_TX++;
 
-
-
     }
     TIM3->SR = 0x0;  // reset the status register
 
 }
 
-
+void SystemClock_Config(void)
+{
+    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
-//unsigned long CNT_TMR5 = 0;
-//float FREQ_TMR5 = (float)FREQ_500;
-//float DT_TMR5 = (float)DT_500;
-//extern "C" void TIM2_IRQHandler(void)
-//{
-//    LED = 1;
-//    if (TIM2->SR & TIM_SR_UIF ) {
-//
-//        //CAN ----------------------------------------------------------------------
-//        if (flag_data_request[0] == HIGH) {
-//            //position+velocity
-//            CAN_TX_POSITION_FT((int16_t) (pos.sen/4.0f), (int16_t) (vel.sen/100.0f), (int16_t) (torq.sen*10.0f));
-//        }
-//
-//        if (flag_data_request[1] == HIGH) {
-//            //valve position
-//            double t_value = 0;
-//            if(value>=DDV_CENTER) {
-//                t_value = 10000.0f*((double)value-(double)DDV_CENTER)/((double)VALVE_MAX_POS-(double)DDV_CENTER);
-//            } else {
-//                t_value = -10000.0f*((double)value-(double)DDV_CENTER)/((double)VALVE_MIN_POS-(double)DDV_CENTER);
-//            }
-//            CAN_TX_TORQUE((int16_t) (t_value));
-//        }
-//
-//        if (flag_data_request[2] == HIGH) {
-//            //pressure A and B
-//            CAN_TX_PRES((int16_t) (valve_pos.ref), (int16_t) (MODE_POS_FT_TRANS * 100.0f)); // CUR_PRES_X : 0(0bar)~4096(210bar)
-//            //CAN_TX_PRES((int16_t) (pres_A.sen), (int16_t) (pres_B.sen)); // CUR_PRES_X : 0(0bar)~4096(210bar)
-//            //                        CAN_TX_PRES((int16_t) (CUR_PRES_A_BAR * 100.), (int16_t) (CUR_PRES_B_BAR * 100.));
-//            //            CAN_TX_PRES((int16_t) ((DEADZONE_MINUS + 1.)*1000.), (int16_t) ((DEADZONE_PLUS + 1.))*1000.);
-//            //            CAN_TX_PRES((int16_t) DZ_dir, (int16_t) ((VALVE_DEADZONE_PLUS + 1.))*1000.);
-//
-//        }
-//
-//        if (flag_data_request[3] == HIGH) {
-//            //PWM
-//            CAN_TX_PWM((int16_t) VALVE_DEADZONE_PLUS);
-//            //            CAN_TX_PWM((int16_t) cnt_vel_findhome);
-//            //            CAN_TX_PWM((int16_t) (VALVE_VOLTAGE * 1000.));
-//            //                        CAN_TX_PWM((int16_t) (VALVE_VOLTAGE_VALVE_DZ * 1000.));
-//
-//        }
-//
-//        if (flag_data_request[4] == HIGH) {
-//            //valve position
-//            CAN_TX_VALVE_POSITION((int16_t) (K_SPRING), (int16_t) (D_DAMPER), (int16_t) VALVE_POS_RAW_FORCE_FB_LOGGING);
-//            //CAN_TX_VALVE_POSITION((int16_t) (DDV_CENTER * 10.0f), (int16_t) valve_pos.ref, (int16_t) V_out);
-//
-//            //CAN_TX_VALVE_POSITION((int16_t) (VALVE_POS_NUM));
-//            //                        CAN_TX_VALVE_POSITIOfxN((int16_t) (VALVE_FF_VOLTAGE / SUPPLY_VOLTAGE));
-//            //            CAN_TX_VALVE_POSITION((int16_t) P_GAIN_JOINT_POSITION);
-//            //            CAN_TX_VALVE_POSITION((int16_t) Ref_Joint_Pos);
-//            //            CAN_TX_VALVE_POSITION((int16_t) flag_flowrate);
-//        }
-//
-//
-//    }
-//    TIM2->SR = 0x0;  // reset the status register
-//}
+    /** Configure the main internal regulator output voltage
+    */
+    __HAL_RCC_PWR_CLK_ENABLE();
+    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+    /** Initializes the CPU, AHB and APB busses clocks
+    */
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+    RCC_OscInitStruct.PLL.PLLM = 8;  //8
+    RCC_OscInitStruct.PLL.PLLN = 180;//180
+    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+    RCC_OscInitStruct.PLL.PLLQ = 2;
+    RCC_OscInitStruct.PLL.PLLR = 2;
+    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
+        //Error_Handler();
+    }
+    /** Activate the Over-Drive mode
+    */
+    if (HAL_PWREx_EnableOverDrive() != HAL_OK) {
+        //Error_Handler();
+    }
+    /** Initializes the CPU, AHB and APB busses clocks
+    */
+    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
 
-
-
-void CurrentControl()
-{
-    cur.err = cur.ref - cur.sen;
-    cur.err_int = cur.err_int + cur.err*DT_TMR4;
-    cur.err_diff = (cur.err - cur.err_old)*FREQ_TMR4;
-    cur.err_old = cur.err;
-
-    float R_model = 150.0f; // ohm
-    float L_model = 0.3f;
-    float w0 = 2.0f*3.14f*90.0f;
-    float KP_I = L_model*w0;
-    float KI_I = R_model*w0;
-    float KD_I = 0.0f;
-
-    float FF_gain = 0.0f;
-    V_out = (int) (KP_I * cur.err + KI_I * cur.err_int + KD_I * cur.err_diff);
-    //          V_out = V_out + FF_gain * (R_model*I_REF); // Unit : mV
-    V_out = V_out + FF_gain * (R_model*cur.ref + L_model*cur.ref_diff); // Unit : mV
-
-    float Ka = 5.0f/KP_I;
-    if(V_out > V_MAX) {
-        V_rem = V_out-V_MAX;
-        V_rem = Ka*V_rem;
-        V_out = V_MAX;
-        cur.err_int = cur.err_int - V_rem*DT_5k;
-    } else if(V_out < -V_MAX) {
-        V_rem = V_out-(-V_MAX);
-        V_rem = Ka*V_rem;
-        V_out = -V_MAX;
-        cur.err_int = cur.err_int - V_rem*DT_5k;
+    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
+        //Error_Handler();
     }
-}
-
-
-
-
-
-
-
-
+    HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);
+    HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_2);
+}
\ No newline at end of file