PIM.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "PIM.h"
  2. #define pimd_L_rls 51
  3. void PIM_Init(void)
  4. {
  5. pimd_flg_firstRun = true;
  6. }
  7. void PIM(void)
  8. {
  9. static uint8_T pimn_st_workStat_Delay;
  10. uint16_T i;
  11. uint16_T j;
  12. static uint16_T pimn_V_volt[pimd_L_rls];
  13. static int16_T pimn_I_curr[pimd_L_rls];
  14. static real_T pimn_V_ocv;
  15. static real_T pimn_R_ohm;
  16. static real_T pimn_R_polar;
  17. static real_T pimn_F_polar;
  18. static uint16_T pimn_N_ctn;
  19. static real_T pimn_M_P[4][4];
  20. static real_T theta[4];
  21. real_T P[4][4];
  22. real_T A[4];
  23. real_T K[4];
  24. real_T temp;
  25. //重置
  26. if (pimn_st_workStat_Delay != 1 && ihd_st_workStat == 1)
  27. {
  28. pimd_flg_firstRun = true;
  29. }
  30. //初值
  31. if (pimd_flg_firstRun)
  32. {
  33. pimn_M_P[0][0] = 10; pimn_M_P[0][1] = 0; pimn_M_P[0][2] = 0; pimn_M_P[0][3] = 0;
  34. pimn_M_P[1][0] = 0; pimn_M_P[1][1] = 10; pimn_M_P[1][2] = 0; pimn_M_P[1][3] = 0;
  35. pimn_M_P[2][0] = 0; pimn_M_P[2][1] = 0; pimn_M_P[2][2] = 10; pimn_M_P[2][3] = 0;
  36. pimn_M_P[3][0] = 0; pimn_M_P[3][1] = 0; pimn_M_P[3][2] = 0; pimn_M_P[3][3] = 10;
  37. pimn_V_ocv = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_V_ocv, 13) * 0.001;
  38. pimn_R_ohm = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_ohm, 13) * 0.001 * 0.001;
  39. pimn_R_polar = 0.001;
  40. pimn_F_polar = 0;
  41. pimn_N_ctn = 0;
  42. pimn_st_workStat_Delay = 0;
  43. }
  44. //限定记忆长度
  45. if (pimd_flg_firstRun)
  46. {
  47. for (i = 0; i < pimd_L_rls; i++)
  48. {
  49. pimn_V_volt[i] = sfmv_V_cellU[0];
  50. pimn_I_curr[i] = sfmd_I_curr;
  51. }
  52. }
  53. else
  54. {
  55. for (i = 0; i < pimd_L_rls - 1; i++)
  56. {
  57. pimn_V_volt[i] = pimn_V_volt[i+1];
  58. pimn_I_curr[i] = pimn_I_curr[i+1];
  59. }
  60. pimn_V_volt[i] = sfmv_V_cellU[0];
  61. pimn_I_curr[i] = sfmd_I_curr;
  62. }
  63. //
  64. if(pimn_st_workStat_Delay == 1)
  65. {
  66. pimn_N_ctn = pimn_N_ctn + 1;
  67. //输入
  68. A[0] = (real_T)pimn_V_volt[pimd_L_rls - 2] * 0.001;
  69. A[1] = (real_T)pimn_I_curr[pimd_L_rls - 1] * 0.1;
  70. A[2] =-(real_T)pimn_I_curr[pimd_L_rls - 2] * 0.1;
  71. A[3] = 1;
  72. //参数形变
  73. theta[0] = exp(-1/pimn_F_polar);
  74. theta[1] = pimn_R_ohm;
  75. theta[2] = pimn_R_ohm * exp(-1/pimn_F_polar) -pimn_R_polar * (1-exp(-1/pimn_F_polar));
  76. theta[3] = (1 -theta[0]) * pimn_V_ocv;
  77. //增益矩阵
  78. temp = (A[0] * pimn_M_P[0][0] +A[1] * pimn_M_P[1][0] + A[2] * pimn_M_P[2][0] + A[3] * pimn_M_P[3][0]) * A[0] +
  79. (A[0] * pimn_M_P[0][1] +A[1] * pimn_M_P[1][1] + A[2] * pimn_M_P[2][1] + A[3] * pimn_M_P[3][1]) * A[1] +
  80. (A[0] * pimn_M_P[0][2] +A[1] * pimn_M_P[1][2] + A[2] * pimn_M_P[2][2] + A[3] * pimn_M_P[3][2]) * A[2] +
  81. (A[0] * pimn_M_P[0][3] +A[1] * pimn_M_P[1][3] + A[2] * pimn_M_P[2][3] + A[3] * pimn_M_P[3][3]) * A[3];
  82. for(i = 0;i < 4;i++)
  83. {
  84. K[i] = (pimn_M_P[i][0] * A[0] + pimn_M_P[i][1] * A[1] + pimn_M_P[i][2] * A[2] + pimn_M_P[i][3] * A[3])/(1 + temp);
  85. }
  86. //参数更新
  87. temp = (real_T)pimn_V_volt[pimd_L_rls - 1] * 0.001 - (theta[0] * A[0] + theta[1] * A[1] + theta[2] * A[2] + theta[3] * A[3]);
  88. for(i = 0;i < 4;i++)
  89. {
  90. theta[i] = theta[i] + K[i] * temp;
  91. }
  92. //协方差更新
  93. for(i = 0;i < 4;i++)
  94. {
  95. for(j = 0;j < 4;j++)
  96. {
  97. P[i][j] = pimn_M_P[i][j] - K[i] * (A[0] * pimn_M_P[0][j] + A[1] * pimn_M_P[1][j] + A[2] * pimn_M_P[2][j] + A[3] * pimn_M_P[3][j]);
  98. }
  99. }
  100. //传递下循环
  101. for(i = 0;i < 4;i++)
  102. {
  103. for(j = 0;j < 4;j++)
  104. {
  105. pimn_M_P[i][j] = P[i][j];
  106. }
  107. }
  108. //=======================================================================
  109. if(pimn_N_ctn > pimd_L_rls)
  110. {
  111. //输入
  112. A[0] = (real_T)pimn_V_volt[0] * 0.001;
  113. A[1] = (real_T)pimn_I_curr[1] * 0.1;
  114. A[2] =-(real_T)pimn_I_curr[0] * 0.1;
  115. A[3] = 1;
  116. //增益矩阵
  117. temp = (A[0] * pimn_M_P[0][0] +A[1] * pimn_M_P[1][0] + A[2] * pimn_M_P[2][0] + A[3] * pimn_M_P[3][0]) * A[0] +
  118. (A[0] * pimn_M_P[0][1] +A[1] * pimn_M_P[1][1] + A[2] * pimn_M_P[2][1] + A[3] * pimn_M_P[3][1]) * A[1] +
  119. (A[0] * pimn_M_P[0][2] +A[1] * pimn_M_P[1][2] + A[2] * pimn_M_P[2][2] + A[3] * pimn_M_P[3][2]) * A[2] +
  120. (A[0] * pimn_M_P[0][3] +A[1] * pimn_M_P[1][3] + A[2] * pimn_M_P[2][3] + A[3] * pimn_M_P[3][3]) * A[3];
  121. for(i = 0;i <4;i++)
  122. {
  123. K[i] = (pimn_M_P[i][0] * A[0] + pimn_M_P[i][1] * A[1] + pimn_M_P[i][2] * A[2] + pimn_M_P[i][3] * A[3])/(1 + temp);
  124. }
  125. //协方差更新
  126. for(i = 0;i < 4;i++)
  127. {
  128. for(j = 0;j < 4;j++)
  129. {
  130. P[i][j] = pimn_M_P[i][j] + K[i] * (A[0] * pimn_M_P[0][j] + A[1] * pimn_M_P[1][j] + A[2] * pimn_M_P[2][j] + A[3] * pimn_M_P[3][j]);
  131. }
  132. }
  133. //传递下一循环
  134. for(i = 0;i < 4;i++)
  135. {
  136. for(j = 0;j < 4;j++)
  137. {
  138. pimn_M_P[i][j] = P[i][j];
  139. }
  140. }
  141. }
  142. //参数求解
  143. pimn_V_ocv = theta[3]/(1 - theta[0]);
  144. pimn_R_ohm = theta[1];
  145. pimn_R_polar = (theta[0] * theta[1] -theta[2])/(1 -theta[0]);
  146. pimn_F_polar = -1/log(theta[0]);
  147. pimn_V_ocv = Saturation_r(pimn_V_ocv,3.2, 4.4);
  148. pimn_R_ohm = Saturation_r(pimn_V_ocv,0.001, 1);
  149. pimn_R_polar = Saturation_r(pimn_V_ocv,0.0002, 1);
  150. pimn_F_polar = Saturation_r(pimn_V_ocv,0, 200);
  151. pimd_V_ocv = (uint16_T)(pimn_V_ocv * 1000);
  152. pimd_R_ohm = (uint16_T)(pimn_R_ohm * 1000 * 1000);
  153. pimd_R_polar = (uint16_T)(pimn_R_polar * 1000 * 1000);
  154. pimd_F_polar = (uint16_T)(pimn_F_polar * 1000);
  155. }
  156. else
  157. {
  158. pimd_V_ocv = 0;
  159. pimd_R_ohm = 0;
  160. pimd_R_polar = 0;
  161. pimd_F_polar = 0;
  162. }
  163. //
  164. pimn_st_workStat_Delay = ihd_st_workStat;
  165. pimd_flg_firstRun = false;
  166. }