Buyoun Cho / Mbed 2 deprecated HydraulicControlBoard_PostLIGHT_210420

Dependencies:   mbed FastPWM

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //Hydraulic Control Board
00002 //distributed by Sungwoo Kim
00003 //       2020/12/28
00004 //revised by Buyoun Cho
00005 //       2021/04/20  
00006 
00007 // 유의사항
00008 // 소수 적을때 뒤에 f 꼭 붙이기
00009 // CAN 선은 ground까지 있는 3상 선으로 써야함.
00010 // 전원은 12~24V 인가.
00011 
00012 #include "mbed.h"
00013 #include "FastPWM.h"
00014 #include "INIT_HW.h"
00015 #include "function_CAN.h"
00016 #include "SPI_EEP_ENC.h"
00017 #include "I2C_AS5510.h"
00018 #include "setting.h"
00019 #include "function_utilities.h"
00020 #include "stm32f4xx_flash.h"
00021 #include "FlashWriter.h"
00022 #include <string>
00023 #include <iostream>
00024 #include <cmath>
00025 
00026 using namespace std;
00027 Timer t;
00028 
00029 // dac & check ///////////////////////////////////////////
00030 DigitalOut check(PC_2);
00031 DigitalOut check_2(PC_3);
00032 AnalogOut dac_1(PA_4); // 0.0f ~ 1.0f
00033 AnalogOut dac_2(PA_5); // 0.0f ~ 1.0f
00034 AnalogIn adc1(PC_4); //pressure_1
00035 AnalogIn adc2(PB_0); //pressure_2
00036 AnalogIn adc3(PC_1); //current
00037 
00038 // PWM ///////////////////////////////////////////
00039 float dtc_v=0.0f;
00040 float dtc_w=0.0f;
00041 
00042 // I2C ///////////////////////////////////////////
00043 I2C i2c(PC_9,PA_8); // SDA, SCL (for K22F)
00044 const int i2c_slave_addr1 =  0x56;  // AS5510 address
00045 unsigned int value; // 10bit output of reading sensor AS5510
00046 
00047 // SPI ///////////////////////////////////////////
00048 SPI eeprom(PB_15, PB_14, PB_13); // EEPROM //(SPI_MOSI, SPI_MISO, SPI_SCK);
00049 DigitalOut eeprom_cs(PB_12);
00050 SPI enc(PC_12,PC_11,PC_10);
00051 DigitalOut enc_cs(PD_2);
00052 DigitalOut LED(PA_15);
00053 
00054 // UART ///////////////////////////////////////////
00055 Serial pc(PA_9,PA_10); //  _ UART
00056 
00057 // CAN ///////////////////////////////////////////
00058 CAN can(PB_8, PB_9, 1000000);
00059 CANMessage msg;
00060 void onMsgReceived()
00061 {
00062     CAN_RX_HANDLER();
00063 }
00064 
00065 // Variables ///////////////////////////////////////////
00066 State pos;
00067 State vel;
00068 State Vout;
00069 State force;
00070 State torq;         // unit : N
00071 State torq_dot;
00072 State pres_A;       // unit : bar
00073 State pres_B;
00074 State cur;          // unit : mA
00075 State valve_pos;
00076 
00077 State INIT_Vout;
00078 State INIT_Valve_Pos;
00079 State INIT_Pos;
00080 State INIT_torq;
00081 
00082 extern int CID_RX_CMD;
00083 extern int CID_RX_REF_POSITION;
00084 extern int CID_RX_REF_OPENLOOP;
00085 extern int CID_RX_REF_PWM;
00086 
00087 extern int CID_TX_INFO;
00088 extern int CID_TX_POS_VEL_TORQ;
00089 extern int CID_TX_PWM;
00090 extern int CID_TX_CURRENT;
00091 extern int CID_TX_VOUT;
00092 extern int CID_TX_VALVE_POSITION;
00093 extern int CID_TX_SOMETHING;
00094 
00095 float temp_P_GAIN = 0.0f;
00096 float temp_I_GAIN = 0.0f;
00097 int temp_VELOCITY_COMP_GAIN = 0;
00098 
00099 inline float tanh_inv(float y) {
00100     if(y >= 1.0f - 0.000001f) y = 1.0f - 0.000001f;  
00101     if(y <= -1.0f + 0.000001f) y = -1.0f + 0.000001f;  
00102     return log(sqrt((1.0f+y)/(1.0f-y)));
00103 }
00104 
00105 
00106 /*******************************************************************************
00107  *  REFERENCE MODE
00108  ******************************************************************************/
00109 enum _REFERENCE_MODE {
00110     MODE_REF_NO_ACT = 0,                         
00111     MODE_REF_DIRECT, 
00112     MODE_REF_FINDHOME                                  
00113 };
00114 
00115 /*******************************************************************************
00116  *  CONTROL MODE
00117  ******************************************************************************/
00118 enum _CONTROL_MODE {
00119     //control mode
00120     MODE_NO_ACT = 0,                                    //0
00121     MODE_VALVE_POSITION_CONTROL,                        //1
00122     MODE_JOINT_CONTROL,                                 //2
00123 
00124     MODE_VALVE_OPEN_LOOP,                               //3
00125     MODE_JOINT_ADAPTIVE_BACKSTEPPING,                   //4
00126     MODE_RL,                                            //5
00127 
00128     MODE_JOINT_POSITION_PRES_CONTROL_PWM,               //6
00129     MODE_JOINT_POSITION_PRES_CONTROL_VALVE_POSITION,    //7
00130     MODE_VALVE_POSITION_PRES_CONTROL_LEARNING,          //8
00131 
00132     MODE_TEST_CURRENT_CONTROL,                          //9
00133     MODE_TEST_PWM_CONTROL,                              //10
00134 
00135     MODE_CURRENT_CONTROL,                               //11
00136     MODE_JOINT_POSITION_TORQUE_CONTROL_CURRENT,         //12
00137     MODE_JOINT_POSITION_PRES_CONTROL_CURRENT,           //13
00138     MODE_VALVE_POSITION_TORQUE_CONTROL_LEARNING,        //14
00139 
00140     //utility
00141     MODE_TORQUE_SENSOR_NULLING = 20,                    //20
00142     MODE_VALVE_NULLING_AND_DEADZONE_SETTING,            //21
00143     MODE_FIND_HOME,                                     //22
00144     MODE_VALVE_GAIN_SETTING,                            //23
00145     MODE_PRESSURE_SENSOR_NULLING,                       //24
00146     MODE_PRESSURE_SENSOR_CALIB,                         //25
00147     MODE_ROTARY_FRICTION_TUNING,                        //26
00148 
00149     MODE_DDV_POS_VS_PWM_ID = 30,                        //30
00150     MODE_DDV_DEADZONE_AND_CENTER,                       //31
00151     MODE_DDV_POS_VS_FLOWRATE,                           //32
00152     MODE_SYSTEM_ID,                                     //33
00153     MODE_FREQ_TEST,                                     //34
00154     MODE_SEND_BUFFER,                                   //35
00155     MODE_SEND_OVER,                                     //36
00156     MODE_STEP_TEST,                                     //37
00157 };
00158 
00159 void SystemClock_Config(void)
00160 {
00161     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
00162     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
00163 
00164     /* Configure the main internal regulator output voltage
00165     */
00166     __HAL_RCC_PWR_CLK_ENABLE();
00167     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
00168     /* Initializes the CPU, AHB and APB busses clocks
00169     */
00170     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
00171     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
00172     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
00173     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
00174     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
00175     RCC_OscInitStruct.PLL.PLLM = 8;//8
00176     RCC_OscInitStruct.PLL.PLLN = 180; //180
00177     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
00178     RCC_OscInitStruct.PLL.PLLQ = 2;
00179     RCC_OscInitStruct.PLL.PLLR = 2;
00180     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
00181         //Error_Handler();
00182     }
00183     /** Activate the Over-Drive mode
00184     */
00185     if (HAL_PWREx_EnableOverDrive() != HAL_OK) {
00186         //Error_Handler();
00187     }
00188     /** Initializes the CPU, AHB and APB busses clocks
00189     */
00190     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
00191                                   |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
00192     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
00193     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
00194     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
00195     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
00196 
00197     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
00198         //Error_Handler();
00199     }
00200 }
00201 
00202 
00203 int main()
00204 {
00205     /*********************************
00206     ***     Initialization
00207     *********************************/
00208 
00209     HAL_Init();
00210     SystemClock_Config();
00211 
00212     LED = 0;
00213     pc.baud(9600);
00214 
00215     // i2c init
00216 //    i2c.frequency(400 * 1000);          // 0.4 mHz
00217 //    wait_ms(2);                         // Power Up wait
00218 //    look_for_hardware_i2c();            // Hardware present
00219 //    init_as5510(i2c_slave_addr1);
00220 //    make_delay();
00221 
00222     // spi init
00223     eeprom_cs = 1;
00224     eeprom.format(8,3);
00225     eeprom.frequency(5000000); //5M
00226     eeprom_cs = 0;
00227     make_delay();
00228 
00229     enc_cs = 1;     //sw add
00230     enc.format(8,0);
00231     enc.frequency(5000000); //10M
00232     enc_cs = 0;     //sw add
00233 
00234     make_delay();
00235 
00236     // spi _ enc
00237     spi_enc_set_init();
00238     make_delay();
00239 
00240     ////// bno rom
00241 //    spi_eeprom_write(RID_BNO, (int16_t)1);
00242 //    make_delay();
00243     ////////
00244 
00245     // rom
00246     ROM_CALL_DATA();
00247     make_delay();
00248 
00249     // ADC init
00250     Init_ADC();
00251     make_delay();
00252 
00253     // Pwm init
00254     Init_PWM();
00255     TIM4->CR1 ^= TIM_CR1_UDIS;
00256     make_delay();
00257 
00258     // CAN
00259     can.attach(&CAN_RX_HANDLER);
00260     CAN_ID_INIT();
00261     make_delay();
00262 
00263     //can.reset();
00264     can.filter(msg.id, 0xFFFFF000, CANStandard);
00265 
00266     // TMR3 init
00267     Init_TMR3();
00268     TIM3->CR1 ^= TIM_CR1_UDIS;
00269     make_delay();
00270 
00271     //Timer priority
00272     NVIC_SetPriority(TIM3_IRQn, 2);
00273     NVIC_SetPriority(TIM4_IRQn, 3);
00274 
00275 
00276     //DAC init
00277     if (SENSING_MODE == 0) {
00278         dac_1 = FORCE_VREF / 3.3f;
00279         dac_2 = 0.0f;
00280     } else if (SENSING_MODE == 1) {
00281         if (DIR_VALVE_ENC > 0) {
00282             dac_1 = PRES_A_VREF / 3.3f;
00283             dac_2 = PRES_B_VREF / 3.3f;
00284         } else {
00285             dac_1 = PRES_B_VREF / 3.3f;
00286             dac_2 = PRES_A_VREF / 3.3f;
00287         }
00288     }
00289     make_delay();
00290 
00291     for (int i=0; i<50; i++) {
00292         if(i%2==0)
00293             ID_index_array[i] = - i * 0.5f;
00294         else
00295             ID_index_array[i] =  (i+1) * 0.5f;
00296     }
00297 
00298     /************************************
00299     ***     Program is operating!
00300     *************************************/
00301     while(1) {
00302 
00303         // UART example
00304 //        if(timer_while==100000) {
00305 //            timer_while = 0;
00306 //            pc.printf("%f\n", value);
00307 //        }
00308 //        timer_while ++;
00309 
00310         //i2c for SW valve
00311         //if(OPERATING_MODE == 5) {
00312 //            read_field(i2c_slave_addr1);
00313 //            if(DIR_VALVE_ENC < 0) value = 1023 - value;
00314 //        }
00315     }
00316 }
00317 
00318 
00319 // Velocity feedforward for SW valve
00320 float DDV_JOINT_POS_FF(float REF_JOINT_VEL)
00321 {
00322     int i = 0;
00323     float Ref_Valve_Pos_FF = 0.0f;
00324     for(i=0; i<VALVE_POS_NUM; i++) {
00325         if(REF_JOINT_VEL >= min(JOINT_VEL[i],JOINT_VEL[i+1]) && REF_JOINT_VEL <=  max(JOINT_VEL[i],JOINT_VEL[i+1])) {
00326             if(i==0) {
00327                 if(JOINT_VEL[i+1] == JOINT_VEL[i]) {
00328                     Ref_Valve_Pos_FF = (float) VALVE_CENTER;
00329                 } else {
00330                     Ref_Valve_Pos_FF = ((float) 10/(JOINT_VEL[i+1] - JOINT_VEL[i]) * (REF_JOINT_VEL - JOINT_VEL[i])) + (float) VALVE_CENTER;
00331                 }
00332             } else {
00333                 if(JOINT_VEL[i+1] == JOINT_VEL[i-1]) {
00334                     Ref_Valve_Pos_FF = (float) VALVE_CENTER;
00335                 } else {
00336                     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]);
00337                 }
00338             }
00339             break;
00340         }
00341     }
00342     if(REF_JOINT_VEL > max(JOINT_VEL[VALVE_POS_NUM-1], JOINT_VEL[VALVE_POS_NUM-2])) {
00343         Ref_Valve_Pos_FF = (float) VALVE_MAX_POS;
00344     } else if(REF_JOINT_VEL < min(JOINT_VEL[VALVE_POS_NUM-1], JOINT_VEL[VALVE_POS_NUM-2])) {
00345         Ref_Valve_Pos_FF = (float) VALVE_MIN_POS;
00346     }
00347 
00348     Ref_Valve_Pos_FF = (float) VELOCITY_COMP_GAIN * 0.01f * (float) (Ref_Valve_Pos_FF - (float) VALVE_CENTER);  //VELOCITY_COMP_GAIN : 0~100
00349     return Ref_Valve_Pos_FF;
00350 }
00351 
00352 // Valve feedforward for SW valve
00353 void VALVE_POS_CONTROL(float REF_VALVE_POS)
00354 {
00355     int i = 0;
00356 
00357     if(REF_VALVE_POS > VALVE_MAX_POS) {
00358         REF_VALVE_POS = VALVE_MAX_POS;
00359     } else if(REF_VALVE_POS < VALVE_MIN_POS) {
00360         REF_VALVE_POS = VALVE_MIN_POS;
00361     }
00362     valve_pos_err = (float) (REF_VALVE_POS - value);
00363     valve_pos_err_diff = valve_pos_err - valve_pos_err_old;
00364     valve_pos_err_old = valve_pos_err;
00365     valve_pos_err_sum += valve_pos_err;
00366     if (valve_pos_err_sum > 1000.0f) valve_pos_err_sum = 1000.0f;
00367     if (valve_pos_err_sum<-1000.0f) valve_pos_err_sum = -1000.0f;
00368 
00369     VALVE_PWM_RAW_FB = P_GAIN_VALVE_POSITION * valve_pos_err + I_GAIN_VALVE_POSITION * valve_pos_err_sum + D_GAIN_VALVE_POSITION * valve_pos_err_diff;
00370 
00371     for(i=0; i<24; i++) {
00372         if(REF_VALVE_POS >= min(VALVE_POS_VS_PWM[i],VALVE_POS_VS_PWM[i+1]) && (float) REF_VALVE_POS <=  max(VALVE_POS_VS_PWM[i],VALVE_POS_VS_PWM[i+1])) {
00373             if(i==0) {
00374                 VALVE_PWM_RAW_FF = (float) 1000.0f / (float) (VALVE_POS_VS_PWM[i+1] - VALVE_POS_VS_PWM[i]) * ((float) REF_VALVE_POS - VALVE_POS_VS_PWM[i]);
00375             } else {
00376                 VALVE_PWM_RAW_FF = (float) 1000.0f* (float) (ID_index_array[i+1] - ID_index_array[i-1])/(VALVE_POS_VS_PWM[i+1] - VALVE_POS_VS_PWM[i-1]) * ((float) REF_VALVE_POS - VALVE_POS_VS_PWM[i-1]) + 1000.0f * (float) ID_index_array[i-1];
00377             }
00378             break;
00379         }
00380     }
00381     Vout.ref = VALVE_PWM_RAW_FF + VALVE_PWM_RAW_FB;
00382 }
00383 
00384 // PWM duty vs. voltage output of L6205 in STM board
00385 #define LT_MAX_IDX  57
00386 float LT_PWM_duty[LT_MAX_IDX] = {-100.0f, -80.0f, -60.0f, -50.0f, -40.0f, -35.0f, -30.0f, -25.0f, -20.0f,
00387                                  -19.0f, -18.0f, -17.0f, -16.0f, -15.0f, -14.0f, -13.0f, -12.0f, -11.0f, -10.0f,
00388                                  -9.0f, -8.0f, -7.0f, -6.0f, -5.0f, -4.0f, -3.0f, -2.0f, -1.0f, 0.0f,
00389                                  1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f,
00390                                  11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f,
00391                                  25.0f, 30.0f, 35.0f, 40.0f, 50.0f, 60.0f, 80.0f, 100.0f
00392                                 };  // duty
00393 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,
00394                                        -150.0f, -145.0f, -145.0f, -145.0f, -135.0f, -135.0f, -135.0f, -127.5f, -127.5f, -115.0f,
00395                                        -115.0f, -115.0F, -100.0f, -100.0f, -100.0f, -60.0f, -60.0f, -10.0f, -5.0f, 0.0f,
00396                                        7.5f, 14.0f, 14.0f, 14.0f, 42.5f, 42.5f, 42.5f, 80.0f, 80.0f, 105.0f,
00397                                        105.0f, 105.0f, 120.0f, 120.0f, 120.0f, 131.0f, 131.0f, 140.0f, 140.0f, 140.0f,
00398                                        155.0f, 160.0f, 170.0f, 174.0f, 182.0f, 191.0f, 212.0f, 230.0f
00399                                       }; // mV
00400 
00401 float PWM_duty_byLT(float Ref_V)
00402 {
00403     float PWM_duty = 0.0f;
00404     if(Ref_V<LT_Voltage_Output[0]) {
00405         PWM_duty = (Ref_V-LT_Voltage_Output[0])/1.5f+LT_PWM_duty[0];
00406     } else if (Ref_V>=LT_Voltage_Output[LT_MAX_IDX-1]) {
00407         PWM_duty = (Ref_V-LT_Voltage_Output[LT_MAX_IDX-1])/1.5f+LT_PWM_duty[LT_MAX_IDX-1];
00408     } else {
00409         int idx = 0;
00410         for(idx=0; idx<LT_MAX_IDX-1; idx++) {
00411             float ini_x = LT_Voltage_Output[idx];
00412             float fin_x = LT_Voltage_Output[idx+1];
00413             float ini_y = LT_PWM_duty[idx];
00414             float fin_y = LT_PWM_duty[idx+1];
00415             if(Ref_V>=ini_x && Ref_V<fin_x) {
00416                 PWM_duty = (fin_y-ini_y)/(fin_x-ini_x)*(Ref_V-ini_x) + ini_y;
00417                 break;
00418             }
00419         }
00420     }
00421 
00422     return PWM_duty;
00423 }
00424 
00425 
00426 
00427 /*******************************************************************************
00428                             TIMER INTERRUPT
00429 *******************************************************************************/
00430 
00431 //------------------------------------------------
00432 //     TMR4 : Sensor Read & Data Handling
00433 //-----------------------------------------------
00434 float FREQ_TMR4 = (float)FREQ_20k;
00435 float DT_TMR4 = (float)DT_20k;
00436 long  CNT_TMR4 = 0;
00437 int   TMR4_FREQ_10k = (int)FREQ_10k;
00438 extern "C" void TIM4_IRQHandler(void)
00439 {
00440     if (TIM4->SR & TIM_SR_UIF ) {
00441 
00442         // Current ===================================================
00443         //ADC3->CR2  |= 0x40000000;                        // adc _ 12bit
00444         
00445         cur.UpdateSen(((float)ADC3->DR-2047.5f)/2047.5f*10.0f, FREQ_TMR4, 500.0f); // unit : mA
00446 
00447         // Encoder ===================================================
00448         if (CNT_TMR4 % (int) ((int) FREQ_TMR4/TMR4_FREQ_10k) == 0) {
00449             ENC_UPDATE();
00450         }
00451 
00452         // Force or Pressure Transducer =============================================
00453         ADC1->CR2  |= 0x40000000;
00454         if (SENSING_MODE == 0) {  // Force sensing
00455             force.UpdateSen((((float)ADC1->DR) - 2047.5f)/TORQUE_SENSOR_PULSE_PER_TORQUE, FREQ_TMR4, 100.0f); // unit : N
00456         } else if (SENSING_MODE == 1) { // Pressure sensing
00457             float pres_A_new, pres_B_new;
00458             if (DIR_VALVE_ENC > 0) {
00459                 pres_A_new = (((float)ADC1->DR) - PRES_A_NULL_pulse)/ PRES_SENSOR_A_PULSE_PER_BAR; // unit : bar
00460                 pres_B_new = (((float)ADC2->DR) - PRES_B_NULL_pulse)/ PRES_SENSOR_A_PULSE_PER_BAR;
00461             } else {
00462                 pres_A_new = (((float)ADC2->DR) - PRES_A_NULL_pulse)/ PRES_SENSOR_A_PULSE_PER_BAR; // unit : bar
00463                 pres_B_new = (((float)ADC1->DR) - PRES_B_NULL_pulse)/ PRES_SENSOR_A_PULSE_PER_BAR;
00464             }
00465             pres_A.UpdateSen(pres_A_new,FREQ_TMR4,200.0f);
00466             pres_B.UpdateSen(pres_B_new,FREQ_TMR4,200.0f);
00467 
00468             if ((OPERATING_MODE & 0x01) == 0) { // Rotary Actuator
00469                 float torq_new = (PISTON_AREA_A * pres_A.sen - PISTON_AREA_B * pres_B.sen) * 0.0001f; // mm^3*bar >> Nm 
00470                 torq.UpdateSen(torq_new,FREQ_TMR4,1000.0);  // unit : Nm
00471             } else if ((OPERATING_MODE & 0x01) == 1) { // Linear Actuator
00472                 float force_new = (PISTON_AREA_A * pres_A.sen - PISTON_AREA_B * pres_B.sen) * 0.1f; // mm^2*bar >> N
00473                 force.UpdateSen(force_new,FREQ_TMR4,1000.0);  // unit : N
00474             }
00475         }
00476 
00477         CNT_TMR4++;
00478     }
00479     TIM4->SR = 0x0;  // reset the status register
00480 }
00481 
00482 
00483 int j =0;
00484 float FREQ_TMR3 = (float)FREQ_5k;
00485 float DT_TMR3 = (float)DT_5k;
00486 int cnt_trans = 0;
00487 double VALVE_POS_RAW_FORCE_FB_LOGGING = 0.0f;
00488 int can_rest =0;
00489 
00490 extern "C" void TIM3_IRQHandler(void)
00491 {
00492     if (TIM3->SR & TIM_SR_UIF ) {
00493 
00494         if(MODE_POS_FT_TRANS == 1) {
00495             if (alpha_trans == 1.0f) MODE_POS_FT_TRANS = 2;
00496             alpha_trans = (float)(1.0f - cos(3.141592f * (float)cnt_trans * DT_TMR3 /3.0f))/2.0f;
00497             cnt_trans++;
00498             torq.err_sum = 0;
00499             if((float)cnt_trans * DT_TMR3 > 3.0f)
00500                 MODE_POS_FT_TRANS = 2;
00501         } else if(MODE_POS_FT_TRANS == 3) {
00502             if (alpha_trans == 0.0f) MODE_POS_FT_TRANS = 0;
00503             alpha_trans = (float)(1.0f + cos(3.141592f * (float)cnt_trans * DT_TMR3 /3.0f))/2.0f;
00504             cnt_trans++;
00505             torq.err_sum = 0;
00506             if((float) cnt_trans * DT_TMR3 > 3.0f )
00507                 MODE_POS_FT_TRANS = 0;
00508         } else if(MODE_POS_FT_TRANS == 2) {
00509             alpha_trans = 1.0f;
00510             cnt_trans = 0;
00511         } else {
00512             alpha_trans = 0.0f;
00513             cnt_trans = 0;
00514         }
00515 
00516 
00517         // Reference Update ==========================================================
00518         switch (REFERENCE_MODE) {
00519             case MODE_REF_NO_ACT: {
00520                 break;
00521             }
00522             case MODE_REF_DIRECT: {
00523                 pos.ref = REF_POSITION;
00524                 vel.ref = REF_VELOCITY;
00525                 torq.ref = REF_TORQUE;
00526                 force.ref = REF_FORCE;
00527                 break;
00528             }
00529             case MODE_REF_FINDHOME: {
00530                 pos.ref = REF_POSITION_FINDHOME;
00531                 vel.ref = 0.0f;
00532                 torq.ref = 0.0f;
00533                 force.ref = 0.0f;
00534                 break;
00535             }
00536             default:
00537                 break;
00538         }
00539 
00540         if (((OPERATING_MODE&0b010)>>1) == 0) {
00541             K_v = 1.03f; // Q = K_v*sqrt(deltaP)*tanh(C_d*Xv);
00542             K_v = 0.16f; 
00543             mV_PER_mA = 500.0f; // 5000mV/10mA
00544             mV_PER_pulse = 0.5f; // 5000mV/10000pulse
00545             mA_PER_pulse = 0.001f; // 10mA/10000pulse
00546         } else if (((OPERATING_MODE&0b010)>>1) == 1) {
00547             K_v = 0.5f; // KNR (LPM >> mA) , 100bar
00548             mV_PER_mA = 166.6666f; // 5000mV/30mA
00549             mV_PER_pulse = 0.5f; // 5000mV/10000pulse
00550             mA_PER_pulse = 0.003f; // 30mA/10000pulse
00551         }
00552         
00553         // =====================================================================
00554         // CONTROL LOOP --------------------------------------------------------
00555         // =====================================================================
00556         int UTILITY_MODE = 0;
00557         int CONTROL_MODE = 0;
00558 
00559         if (CONTROL_UTILITY_MODE >= 20 || CONTROL_UTILITY_MODE == 0) {
00560             UTILITY_MODE = CONTROL_UTILITY_MODE;
00561             CONTROL_MODE = MODE_NO_ACT;
00562         } else {
00563             CONTROL_MODE = CONTROL_UTILITY_MODE;
00564             UTILITY_MODE = MODE_NO_ACT;
00565         }
00566         // UTILITY MODE ------------------------------------------------------------
00567         switch (UTILITY_MODE) {
00568             case MODE_NO_ACT: {
00569                 break;
00570             }
00571 
00572             case MODE_TORQUE_SENSOR_NULLING: 
00573             {
00574                 static float FORCE_pulse_sum = 0.0; 
00575                 static float PresA_pulse_sum = 0.0; 
00576                 static float PresB_pulse_sum = 0.0; 
00577                 
00578                 // DAC Voltage reference set
00579                 float VREF_TuningGain = 0.000003f;
00580                 if (TMR3_COUNT_TORQUE_NULL < TMR_FREQ_5k * 5) {
00581                     LED = 1;
00582                     if(SENSING_MODE == 0) { // Force Sensor (Loadcell)
00583                         FORCE_pulse_sum = FORCE_pulse_sum + force.sen*TORQUE_SENSOR_PULSE_PER_TORQUE;
00584                         if (TMR3_COUNT_TORQUE_NULL % 10 == 0) {
00585                             float FORCE_pluse_mean = FORCE_pulse_sum / 10.0f;
00586                             FORCE_pulse_sum = 0.0f;
00587 
00588                             FORCE_VREF += VREF_TuningGain * (0.0f - FORCE_pluse_mean);
00589                             if (FORCE_VREF > 3.3f) FORCE_VREF = 3.3f;
00590                             if (FORCE_VREF < 0.0f) FORCE_VREF = 0.0f;
00591                             dac_1 = FORCE_VREF / 3.3f;
00592                         }
00593                     } else if (SENSING_MODE == 1) { // Pressure Sensor 
00594                         PresA_pulse_sum += pres_A.sen*PRES_SENSOR_A_PULSE_PER_BAR;
00595                         PresB_pulse_sum += pres_B.sen*PRES_SENSOR_B_PULSE_PER_BAR;
00596                         if (TMR3_COUNT_TORQUE_NULL % 10 == 0) {
00597                             float PresA_pluse_mean = PresA_pulse_sum / 10.0f;
00598                             float PresB_pluse_mean = PresB_pulse_sum / 10.0f;
00599                             PresA_pulse_sum = 0.0f;
00600                             PresB_pulse_sum = 0.0f;
00601 
00602                             PRES_A_VREF += VREF_TuningGain * (0.0f - PresA_pluse_mean);
00603                             if (PRES_A_VREF > 3.3f) PRES_A_VREF = 3.3f;
00604                             if (PRES_A_VREF < 0.0f) PRES_A_VREF = 0.0f;
00605                             dac_1 = PRES_A_VREF / 3.3f;
00606                             PRES_B_VREF += VREF_TuningGain * (0.0f - PresB_pluse_mean);
00607                             if (PRES_B_VREF > 3.3f) PRES_B_VREF = 3.3f;
00608                             if (PRES_B_VREF < 0.0f) PRES_B_VREF = 0.0f; 
00609                             dac_2 = PRES_B_VREF / 3.3f;
00610                         }
00611                     }
00612                     TMR3_COUNT_TORQUE_NULL++;
00613                 } else {
00614                     if(SENSING_MODE == 0 ) { // Force Sensor (Loadcell)
00615                         FORCE_pulse_sum = 0.0f;
00616                         dac_1 = FORCE_VREF / 3.3f;
00617                         spi_eeprom_write(RID_FORCE_SENSOR_VREF, (int16_t)(FORCE_VREF * 1000.0f));
00618                     } else if (SENSING_MODE == 1) {
00619                         PresA_pulse_sum = 0.0f;
00620                         PresB_pulse_sum = 0.0f;
00621                         dac_1 = PRES_A_VREF / 3.3f;
00622                         dac_2 = PRES_B_VREF / 3.3f;
00623                         spi_eeprom_write(RID_PRES_A_SENSOR_VREF, (int16_t)(PRES_A_VREF * 1000.0f));
00624                         spi_eeprom_write(RID_PRES_B_SENSOR_VREF, (int16_t)(PRES_B_VREF * 1000.0f));
00625                     }
00626                     CONTROL_UTILITY_MODE = MODE_NO_ACT;
00627                     TMR3_COUNT_TORQUE_NULL = 0;
00628                 }
00629                 break;
00630             }
00631 
00632             case MODE_FIND_HOME: 
00633             {
00634                 static int cnt_findhome = 0;
00635                 static int cnt_terminate_findhome = 0;
00636                 static float FINDHOME_POSITION_pulse = 0.0f;
00637                 static float FINDHOME_POSITION_pulse_OLD = 0.0f;
00638                 static float FINDHOME_VELOCITY_pulse = 0.0f;
00639                 static float REF_POSITION_FINDHOME_INIT = 0.0f; 
00640 
00641                 if (FINDHOME_STAGE == FINDHOME_INIT) {
00642                     REFERENCE_MODE = MODE_REF_FINDHOME;
00643                     cnt_findhome = 0;
00644                     cnt_terminate_findhome = 0;
00645                     pos.ref = pos.sen;
00646                     vel.ref = 0.0f;
00647                     REF_POSITION_FINDHOME = pos.ref;
00648                     FINDHOME_STAGE = FINDHOME_GOTOLIMIT;
00649                 } else if (FINDHOME_STAGE == FINDHOME_GOTOLIMIT) {
00650                     int cnt_check_enc = (TMR_FREQ_5k/20); // 5000/20 = 250tic = 50msec
00651                     if(cnt_findhome%cnt_check_enc == 0) {
00652                         FINDHOME_POSITION_pulse = pos.sen*ENC_PULSE_PER_POSITION;
00653                         FINDHOME_VELOCITY_pulse = FINDHOME_POSITION_pulse - FINDHOME_POSITION_pulse_OLD;
00654                         FINDHOME_POSITION_pulse_OLD = FINDHOME_POSITION_pulse;
00655                     }
00656                     cnt_findhome++;
00657 
00658                     if (fabs(FINDHOME_VELOCITY_pulse) <= 1) {
00659                         cnt_terminate_findhome = cnt_terminate_findhome + 1;
00660                     } else {
00661                         cnt_terminate_findhome = 0;
00662                     }
00663 
00664                     if ((cnt_terminate_findhome < 3*TMR_FREQ_5k) &&  cnt_findhome < 10*TMR_FREQ_5k) { // wait for 3sec
00665                         double GOTOHOME_SPEED = 10.0f; // 20mm/s or 20deg/s
00666                         if (HOMEPOS_OFFSET > 0) {
00667                             REF_POSITION_FINDHOME = REF_POSITION_FINDHOME + GOTOHOME_SPEED*DT_5k; 
00668                         } else {
00669                             REF_POSITION_FINDHOME = REF_POSITION_FINDHOME - GOTOHOME_SPEED*DT_5k;
00670                         }
00671                         CONTROL_MODE = MODE_JOINT_CONTROL;
00672                         alpha_trans = 0.0f;
00673                     } else {
00674                         ENC_SET((long)((long)HOMEPOS_OFFSET*10));
00675                         REF_POSITION_FINDHOME_INIT = (float)((long)HOMEPOS_OFFSET*10);
00676                         FINDHOME_POSITION_pulse = 0;
00677                         FINDHOME_POSITION_pulse_OLD = 0;
00678                         FINDHOME_VELOCITY_pulse = 0;
00679                 
00680                         cnt_findhome = 0;
00681                         cnt_terminate_findhome = 0;
00682                         pos.ref = 0.0f;
00683                         FINDHOME_STAGE = FINDHOME_ZEROPOSE;
00684                     }
00685                 } else if (FINDHOME_STAGE == FINDHOME_ZEROPOSE) {
00686                     
00687                     int T_move = 2*TMR_FREQ_5k;
00688                     REF_POSITION_FINDHOME = (0.0f - REF_POSITION_FINDHOME_INIT)*0.5f*(1.0f - cos(3.14159f * (float)cnt_findhome / (float)T_move)) + (float)REF_POSITION_FINDHOME_INIT;
00689 
00690                     cnt_findhome++;
00691                     if (cnt_findhome >= T_move) {
00692                         cnt_findhome = 0;
00693                         pos.ref = 0.0f;
00694                         FINDHOME_STAGE = FINDHOME_INIT;
00695                         CONTROL_UTILITY_MODE = MODE_JOINT_CONTROL;
00696                         REFERENCE_MODE = MODE_REF_DIRECT;
00697                     }
00698                 }
00699                 break;
00700             }
00701             default:
00702                 break;
00703         }
00704 
00705         // CONTROL MODE ------------------------------------------------------------
00706         switch (CONTROL_MODE) {
00707             case MODE_NO_ACT: {
00708                 V_out = 0.0f;
00709                 break;
00710             }
00711 
00712             case MODE_VALVE_POSITION_CONTROL: {
00713                 if (OPERATING_MODE == 5) { //SW Valve
00714                     VALVE_POS_CONTROL(valve_pos.ref);
00715                     V_out = Vout.ref;
00716                 } else if (CURRENT_CONTROL_MODE == 0) { //PWM
00717                     V_out = valve_pos.ref; 
00718                 } else {
00719                     I_REF = valve_pos.ref * 0.001f; // Unit : pulse >> mA
00720                     float I_MAX = 10.0f; // Max : 10mA
00721                     if (I_REF > I_MAX) {
00722                         I_REF = I_MAX;
00723                     } else if (I_REF < -I_MAX) {
00724                         I_REF = -I_MAX;
00725                     }
00726                 }
00727                 break;
00728             }
00729 
00730             case MODE_JOINT_CONTROL: 
00731             {
00732 
00733                 float temp_vel_pos = 0.0f; // desired velocity for position control
00734                 float temp_vel_FT = 0.0f; // desired velocity for force/torque control 
00735                 float temp_vel_ff = 0.0f; // desired velocity for feedforward control 
00736                 float temp_vel = 0.0f;
00737 
00738                 float wn_Pos = 2.0f * PI * 5.0f; // f_cut : 5Hz Position Control
00739                 
00740                 pos.err = pos.ref - pos.sen; // Unit : mm or deg
00741                 vel.err = vel.ref - vel.sen; // Unit : mm/s or deg/s
00742                 
00743                 // position control command ===============================================================================================================================================
00744                 if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode 
00745                     temp_vel_pos = 0.01f * (P_GAIN_JOINT_POSITION * wn_Pos * pos.err) * PI / 180.0f; // rad/s
00746                     //                            L when P-gain = 100, f_cut = 10Hz                           
00747                 } else {
00748                     temp_vel_pos = 0.01f * (P_GAIN_JOINT_POSITION * wn_Pos * pos.err); // mm/s
00749                     //                            L when P-gain = 100, f_cut = 10Hz                            
00750                 }
00751 
00752                 // torque control command ===============================================================================================================================================
00753                 float alpha_SpringDamper = 1.0f/(1.0f+TMR_FREQ_5k/(2.0f*PI*30.0f));
00754                 K_LPF = alpha_SpringDamper * K_LPF + (1.0f-alpha_SpringDamper) * K_SPRING;
00755                 D_LPF = alpha_SpringDamper * D_LPF + (1.0f-alpha_SpringDamper) * D_DAMPER;
00756                 
00757                 if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode 
00758                     float torq_ref_act = torq.ref + K_SPRING * pos.err + D_DAMPER * vel.err; // unit : Nm 
00759                     torq.err = torq_ref_act - torq.sen;
00760                     torq.err_int += torq.err/((float)TMR_FREQ_5k);
00761                     temp_vel_FT = 0.0001f * (P_GAIN_JOINT_TORQUE * torq.err + I_GAIN_JOINT_TORQUE * torq.err_int); // Nm >> rad/s
00762                 } else {
00763                     float force_ref_act = force.ref + K_SPRING * pos.err + D_DAMPER * vel.err; // unit : N 
00764                     force.err = force_ref_act - force.sen;
00765                     force.err_int += force.err/((float)TMR_FREQ_5k);
00766                     temp_vel_FT = 0.0001f * (P_GAIN_JOINT_TORQUE * force.err + I_GAIN_JOINT_TORQUE * force.err_int); // N >> mm/s
00767                 }
00768                 
00769                 // velocity feedforward command ========================================================================================================================================    
00770                 if ((OPERATING_MODE & 0x01) == 0) { // Rotary Mode 
00771                     temp_vel_ff = 0.01f * (float)VELOCITY_COMP_GAIN * vel.ref * PI / 180.0f; // rad/s
00772                 } else {
00773                     temp_vel_ff = 0.01f * (float)VELOCITY_COMP_GAIN * vel.ref; // mm/s
00774                 }
00775 
00776                 // command integration =================================================================================================================================================    
00777                 temp_vel = (1.0f - alpha_trans) * temp_vel_pos  + alpha_trans * temp_vel_FT + temp_vel_ff; // Position Control + Torque Control + Velocity Feedforward
00778                 
00779                 float Qact = 0.0f; // required flow rate  
00780                 if( temp_vel > 0.0f ) {
00781                     Qact = temp_vel * ((float)PISTON_AREA_A * 0.00006f); // mm^3/sec >> LPM
00782                     I_REF = tanh_inv(Qact/(K_v * sqrt(PRES_SUPPLY * alpha3 / (alpha3 + 1.0f))))/C_d;
00783                 } else {
00784                     Qact = temp_vel * ((float)PISTON_AREA_B * 0.00006f); // mm^3/sec >> LPM
00785                     I_REF = tanh_inv(Qact/(K_v * sqrt(PRES_SUPPLY / (alpha3 + 1.0f))))/C_d;
00786                 }
00787                 
00788                 // Anti-windup for FT
00789                 if (I_GAIN_JOINT_TORQUE != 0.0f) {
00790                     float I_MAX = 10.0f; // Maximum Current : 10mA
00791                     float Ka = 2.0f;
00792                     if (I_REF > I_MAX) {
00793                         float I_rem = I_REF - I_MAX;
00794                         I_REF = I_MAX;
00795                         float temp_vel_rem = K_v * sqrt(PRES_SUPPLY * alpha3 / (alpha3 + 1.0f)) * tanh(C_d*I_rem) / ((double) PISTON_AREA_A * 0.00006f); // Unit : mm/s [linear] / rad/s [rotary]  
00796                         torq.err_int = torq.err_int - Ka * temp_vel_rem * (10000.0f/I_GAIN_JOINT_TORQUE)*(float)TMR_FREQ_5k; // Need to Check!
00797                     } else if (I_REF < -I_MAX) {
00798                         double I_rem = I_REF - (-I_MAX);
00799                         I_REF = -I_MAX;
00800                         float temp_vel_rem = K_v * sqrt(PRES_SUPPLY / (alpha3 + 1.0f)) * tanh(C_d*I_rem) / ((double) PISTON_AREA_B * 0.00006f); // Unit : mm/s [linear] / rad/s [rotary]  
00801                         torq.err_int = torq.err_int - Ka * temp_vel_rem * (10000.0f/I_GAIN_JOINT_TORQUE)*(float)TMR_FREQ_5k; // Need to Check!
00802                     }
00803                 }
00804                 break;
00805             }
00806 
00807             case MODE_VALVE_OPEN_LOOP: {
00808                 V_out = (float) Vout.ref;
00809                 break;
00810             }
00811 
00812 //            case MODE_JOINT_ADAPTIVE_BACKSTEPPING: {
00813 //
00814 //                float Va = (1256.6f + Amm * pos.sen/(float)(ENC_PULSE_PER_POSITION)) * 0.000000001f; // 4mm pipe * 100mm + (25mm Cylinder 18mm Rod) * x,      unit : m^3
00815 //                float Vb = (1256.6f + Amm  * (79.0f - pos.sen/(float)(ENC_PULSE_PER_POSITION))) * 0.000000001f; // 4mm pipe * 100mm + (25mm Cylinder 18mm Rod) * (79.0mm-x),      unit : m^3
00816 //
00817 //                V_adapt = 1.0f / (1.0f/Va + 1.0f/Vb); //initial 0.0000053f
00818 //
00819 //                //float f3 = -Amm*Amm*beta*0.000001f*0.000001f/V_adapt * vel.sen/(float)(ENC_PULSE_PER_POSITION)*0.001f; // unit : N/s    //xdot=10mm/s일때 -137076
00820 //                float f3_hat = -a_hat * vel.sen/(float)(ENC_PULSE_PER_POSITION)*0.001f; // unit : N/s    //xdot=10mm/s일때 -137076
00821 //
00822 //                float g3_prime = 0.0f;
00823 //                if (torq.sen > Amm*(Ps-Pt)*0.000001f) {
00824 //                    g3_prime = 1.0f;
00825 //                } else if (torq.sen < -Amm*(Ps-Pt)*0.000001f) {
00826 //                    g3_prime = -1.0f;
00827 //                } else {
00828 //                    if ((value-VALVE_CENTER) > 0) {
00829 //                        g3_prime = sqrt(Ps-Pt-torq.sen/Amm*1000000.0f);
00830 ////                        g3_prime = sqrt(Ps-Pt);
00831 //                    } else {
00832 //                        g3_prime = sqrt(Ps-Pt+torq.sen/Amm*1000000.0f);
00833 ////                        g3_prime = sqrt(Ps-Pt);
00834 //                    }
00835 //                }
00836 //                float tau = 0.01f;
00837 //                float K_valve = 0.0004f;
00838 //
00839 //                float x_v = 0.0f;   //x_v : -1~1
00840 //                if(value>=VALVE_CENTER) {
00841 //                    x_v = 1.0f*((double)value - (double)VALVE_CENTER)/((double)VALVE_MAX_POS - (double)VALVE_CENTER);
00842 //                } else {
00843 //                    x_v = -1.0f*((double)value - (double)VALVE_CENTER)/((double)VALVE_MIN_POS - (double)VALVE_CENTER);
00844 //                }
00845 //                float f4 = -x_v/tau;
00846 //                float g4 = K_valve/tau;
00847 //
00848 //                float torq_ref_dot = torq.ref_diff * 500.0f;
00849 //
00850 //                pos.err = (pos.ref - pos.sen)/(float)(ENC_PULSE_PER_POSITION); //[mm]
00851 //                vel.err = (0.0f - vel.sen)/(float)(ENC_PULSE_PER_POSITION); //[mm/s]
00852 //                pos.err_sum += pos.err/(float) TMR_FREQ_5k; //[mm]
00853 //
00854 //                torq.err = torq.ref - torq.sen; //[N]
00855 //                torq.err_sum += torq.err/(float) TMR_FREQ_5k; //[N]
00856 //
00857 //                float k3 = 2000.0f; //2000  //20000
00858 //                float k4 = 10.0f;
00859 //                float rho3 = 3.2f;
00860 //                float rho4 = 10000000.0f;  //25000000.0f;
00861 //                float x_4_des = (-f3_hat + torq_ref_dot - k3*(-torq.err))/(gamma_hat*g3_prime);
00862 //                if (x_4_des > 1) x_4_des = 1;
00863 //                else if (x_4_des < -1) x_4_des = -1;
00864 //
00865 //                if (x_4_des > 0) {
00866 //                    valve_pos.ref = x_4_des * (float)(VALVE_MAX_POS - VALVE_CENTER) + (float) VALVE_CENTER;
00867 //                } else {
00868 //                    valve_pos.ref = x_4_des * (float)(VALVE_CENTER - VALVE_MIN_POS) + (float) VALVE_CENTER;
00869 //                }
00870 //
00871 //                float x_4_des_dot = (x_4_des - x_4_des_old)*(float) TMR_FREQ_5k;
00872 //                x_4_des_old = x_4_des;
00873 //                V_out = (-f4 + x_4_des_dot - k4*(x_v-x_4_des)- rho3/rho4*gamma_hat*g3_prime*(-torq.err))/g4;
00874 //
00875 //                float rho_a = 0.00001f;
00876 //                float a_hat_dot = -rho3/rho_a*vel.sen/(float)(ENC_PULSE_PER_POSITION)*0.001f*(-torq.err);
00877 //                a_hat = a_hat + a_hat_dot / (float) TMR_FREQ_5k;
00878 //
00879 //                if(a_hat > -3000000.0f) a_hat = -3000000.0f;
00880 //                else if(a_hat < -30000000.0f) a_hat = -30000000.0f;
00881 //
00882 //                break;
00883 //            }
00884 
00885             default:
00886                 break;
00887         }
00888 
00889 
00890         if (((OPERATING_MODE&0b110)>>1) == 0 || ((OPERATING_MODE&0b110)>>1) == 1) { //Moog Valve or KNR Valve
00891 
00892             ////////////////////////////////////////////////////////////////////////////
00893             ////////////////////////////  CURRENT CONTROL //////////////////////////////
00894             ////////////////////////////////////////////////////////////////////////////
00895             if (CURRENT_CONTROL_MODE) {
00896                 double alpha_update_Iref = 1.0f / (1.0f + 5000.0f / (2.0f * 3.14f * 300.0f)); // f_cutoff : 500Hz
00897                 I_REF_fil = (1.0f - alpha_update_Iref) * I_REF_fil + alpha_update_Iref*I_REF;
00898 
00899                 if (I_REF_fil > 0.0f) I_REF_fil_DZ = I_REF_fil + (double)VALVE_DEADZONE_PLUS*mA_PER_pulse; // unit: mA
00900                 else if (I_REF_fil < 0.0f) I_REF_fil_DZ = I_REF_fil + (double)VALVE_DEADZONE_MINUS*mA_PER_pulse; // unit: mA
00901                 else I_REF_fil_DZ = I_REF_fil + (double)(VALVE_DEADZONE_PLUS+VALVE_DEADZONE_MINUS)/2.0f*mA_PER_pulse; // unit: mA
00902                     
00903                 I_ERR = I_REF_fil_DZ - (double)cur.sen;
00904                 I_ERR_INT = I_ERR_INT + (I_ERR) * 0.0002f;
00905 
00906 
00907                 // Moog Valve Current Control Gain
00908                 double R_model = 500.0f; // ohm
00909                 double L_model = 1.2f;
00910                 double w0 = 2.0f * 3.14f * 150.0f;
00911                 double KP_I = 0.1f * L_model*w0;
00912                 double KI_I = 0.1f * R_model*w0;
00913 
00914                 // KNR Valve Current Control Gain
00915                 if (((OPERATING_MODE & 0b110)>>1) == 1) { // KNR Valve
00916                     R_model = 163.0f; // ohm
00917                     L_model = 1.0f;
00918                     w0 = 2.0f * 3.14f * 80.0f;
00919                     KP_I = 1.0f * L_model*w0;
00920                     KI_I = 0.08f * R_model*w0;
00921                 }
00922 
00923                 double FF_gain = 1.0f;
00924 
00925                 VALVE_PWM_RAW = KP_I * 2.0f * I_ERR + KI_I * 2.0f* I_ERR_INT;
00926                 I_REF_fil_diff = I_REF_fil_DZ - I_REF_fil_old;
00927                 I_REF_fil_old = I_REF_fil_DZ;
00928 //                VALVE_PWM_RAW = VALVE_PWM_RAW + FF_gain * (R_model * I_REF_fil + L_model * I_REF_fil_diff * 5000.0f); // Unit : mV
00929                 VALVE_PWM_RAW = VALVE_PWM_RAW + FF_gain * (R_model * I_REF_fil_DZ); // Unit : mV
00930                 double V_MAX = 12000.0f; // Maximum Voltage : 12V = 12000mV
00931 
00932                 double Ka = 3.0f / KP_I;
00933                 if (VALVE_PWM_RAW > V_MAX) {
00934                     V_rem = VALVE_PWM_RAW - V_MAX;
00935                     V_rem = Ka*V_rem;
00936                     VALVE_PWM_RAW = V_MAX;
00937                     I_ERR_INT = I_ERR_INT - V_rem * 0.0002f;
00938                 } else if (VALVE_PWM_RAW < -V_MAX) {
00939                     V_rem = VALVE_PWM_RAW - (-V_MAX);
00940                     V_rem = Ka*V_rem;
00941                     VALVE_PWM_RAW = -V_MAX;
00942                     I_ERR_INT = I_ERR_INT - V_rem * 0.0002f;
00943                 }
00944             } else {
00945                 VALVE_PWM_RAW = I_REF * mV_PER_mA;
00946             }
00947 
00948             ////////////////////////////////////////////////////////////////////////////
00949             /////////////////  Dead Zone Cancellation & Linearization //////////////////
00950             ////////////////////////////////////////////////////////////////////////////
00951 
00952             // Output Voltage Linearization
00953             double CUR_PWM_nonlin = (double)VALVE_PWM_RAW; // Unit : mV
00954             double CUR_PWM_lin = PWM_duty_byLT(CUR_PWM_nonlin);  // -8000~8000
00955 
00956             // Dead Zone Cancellation (Electrical dead-zone)
00957             if (CUR_PWM_lin > 0) V_out = (float) (CUR_PWM_lin + 169.0f);
00958             else if (CUR_PWM_lin < 0) V_out = (float) (CUR_PWM_lin - 174.0f);
00959             else V_out = (float) (CUR_PWM_lin);
00960             
00961         } else {            //////////////////////////sw valve
00962             // Output Voltage Linearization & Dead Zone Cancellation (Electrical dead-zone) by SW
00963             if (V_out > 0 ) V_out = (V_out + 180.0f)/0.8588f;
00964             else if (V_out < 0) V_out = (V_out - 200.0f)/0.8651f;
00965             else V_out = 0.0f;
00966         }
00967 
00968         ////////////////////////////////////////////////////////////////////
00969         ///////////////////  PWM Command ///////////////////////////////////
00970         ////////////////////////////////////////////////////////////////////
00971         if(DIR_VALVE<0) {
00972             V_out = -V_out;
00973         }
00974 
00975         if (V_out >= VALVE_VOLTAGE_LIMIT*1000.0f) {
00976             V_out = VALVE_VOLTAGE_LIMIT*1000.0f;
00977         } else if(V_out<=-VALVE_VOLTAGE_LIMIT*1000.0f) {
00978             V_out = -VALVE_VOLTAGE_LIMIT*1000.0f;
00979         }
00980         PWM_out= V_out/(SUPPLY_VOLTAGE*1000.0f);
00981 
00982         // Saturation of output voltage
00983         if(PWM_out > 1.0f) PWM_out=1.0f;
00984         else if (PWM_out < -1.0f) PWM_out=-1.0f;
00985 
00986         if (PWM_out>0.0f) {
00987             dtc_v=0.0f;
00988             dtc_w=PWM_out;
00989         } else {
00990             dtc_v=-PWM_out;
00991             dtc_w=0.0f;
00992         }
00993 
00994         //pwm
00995         TIM4->CCR2 = (PWM_ARR)*(1.0f-dtc_v);
00996         TIM4->CCR1 = (PWM_ARR)*(1.0f-dtc_w);
00997 
00998         ////////////////////////////////////////////////////////////////////////////
00999         //////////////////////  Data transmission through CAN //////////////////////
01000         ////////////////////////////////////////////////////////////////////////////   
01001         
01002         if (TMR2_COUNT_CAN_TX % (int) ((int) TMR_FREQ_5k/CAN_FREQ) == 0) {
01003             
01004             // Position, Velocity, and Torque (ID:1200)
01005             if (flag_data_request[0] == HIGH) {
01006                 if ((OPERATING_MODE & 0b01) == 0) { // Rotary Actuator
01007                     CAN_TX_POSITION_FT((int16_t) (pos.sen*ENC_PULSE_PER_POSITION), (int16_t) (vel.sen*ENC_PULSE_PER_POSITION*0.1f), (int16_t) (torq.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
01008                 } else if ((OPERATING_MODE & 0b01) == 1) { // Linear Actuator
01009                     CAN_TX_POSITION_FT((int16_t) (pos.sen*ENC_PULSE_PER_POSITION*0.25f), (int16_t) (vel.sen*ENC_PULSE_PER_POSITION*0.01f), (int16_t) (force.sen*TORQUE_SENSOR_PULSE_PER_TORQUE*10.0f));
01010                 }
01011             }
01012 
01013             // Valve Position (ID:1300)
01014             if (flag_data_request[1] == HIGH) {
01015                 CAN_TX_PWM((int16_t)(cur.sen/mA_PER_pulse)); 
01016             }
01017 
01018             // Others : Pressure A, B, Supply Pressure, etc. (for Debugging)  (ID:1400)
01019             if (flag_data_request[2] == HIGH) {
01020                 CAN_TX_SOMETHING((int16_t)(pres_A.sen*100.0f), (int16_t)(pres_B.sen*100.0f), (int16_t) (PRES_SUPPLY), (int16_t) (PRES_SUPPLY_NOM)); 
01021             }
01022 
01023             TMR2_COUNT_CAN_TX = 0;
01024         }
01025         TMR2_COUNT_CAN_TX++;
01026 
01027     }
01028     TIM3->SR = 0x0;  // reset the status register
01029 
01030 }