PIM.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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_num_cnt;
  19. static real_T pimn_M_P[4][4];
  20. 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. uint16_T socMax;
  26. uint16_T socMin;
  27. boolean_T pimn_flg_inval;
  28. uint16_T factor;
  29. //重置--------------------
  30. if (pimn_st_workStat_Delay != 1 && ihd_st_workStat == 1)
  31. {
  32. pimd_flg_firstRun = true;
  33. }
  34. //限定记忆长度------------------------
  35. if (pimd_flg_firstRun)
  36. {
  37. for (i = 0; i < pimd_L_rls; i++)
  38. {
  39. pimn_V_volt[i] = sfmv_V_cellU[0]; //和CMD匹配
  40. pimn_I_curr[i] = sfmd_I_curr;
  41. }
  42. }
  43. else
  44. {
  45. for (i = 0; i < pimd_L_rls - 1; i++)
  46. {
  47. pimn_V_volt[i] = pimn_V_volt[i+1];
  48. pimn_I_curr[i] = pimn_I_curr[i+1];
  49. }
  50. pimn_V_volt[i] = sfmv_V_cellU[0];
  51. pimn_I_curr[i] = sfmd_I_curr;
  52. }
  53. //初值-------------------
  54. if (pimd_flg_firstRun)
  55. {
  56. pimn_M_P[0][0] = 10; pimn_M_P[0][1] = 0; pimn_M_P[0][2] = 0; pimn_M_P[0][3] = 0;
  57. pimn_M_P[1][0] = 0; pimn_M_P[1][1] = 10; pimn_M_P[1][2] = 0; pimn_M_P[1][3] = 0;
  58. pimn_M_P[2][0] = 0; pimn_M_P[2][1] = 0; pimn_M_P[2][2] = 10; pimn_M_P[2][3] = 0;
  59. pimn_M_P[3][0] = 0; pimn_M_P[3][1] = 0; pimn_M_P[3][2] = 0; pimn_M_P[3][3] = 10;
  60. pimn_V_ocv = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_V_ocv, 13) * 0.001;
  61. pimn_R_ohm = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_ohm, 13) * 0.001 * 0.001;
  62. pimn_R_polar = 0.001;;
  63. pimn_F_polar = 5;
  64. pimn_num_cnt = 0;
  65. pimn_st_workStat_Delay = 0;
  66. }
  67. //放电使能
  68. if(pimn_st_workStat_Delay == 1 && ihd_st_heatStat == 0)
  69. {
  70. pimn_num_cnt = pimn_num_cnt + 1;
  71. //新增-------------------
  72. A[0] = (real_T)pimn_V_volt[pimd_L_rls - 2] * 0.001;
  73. A[1] = (real_T)pimn_I_curr[pimd_L_rls - 1] * 0.1;
  74. A[2] =-(real_T)pimn_I_curr[pimd_L_rls - 2] * 0.1;
  75. A[3] = 1;
  76. //参数形变
  77. theta[0] = exp(-1/pimn_F_polar);
  78. theta[1] = pimn_R_ohm;
  79. theta[2] = pimn_R_ohm * exp(-1/pimn_F_polar) -pimn_R_polar * (1-exp(-1/pimn_F_polar));
  80. theta[3] = (1 -theta[0]) * pimn_V_ocv;
  81. //增益矩阵
  82. 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] +
  83. (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] +
  84. (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] +
  85. (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];
  86. for(i = 0;i < 4;i++)
  87. {
  88. 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);
  89. }
  90. //参数更新
  91. 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]);
  92. pimn_flg_inval = (temp > 0.03 || temp < -0.03);
  93. for(i = 0;i < 4;i++)
  94. {
  95. theta[i] = theta[i] + K[i] * temp;
  96. }
  97. //协方差更新
  98. for(i = 0;i < 4;i++)
  99. {
  100. for(j = 0;j < 4;j++)
  101. {
  102. 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]);
  103. }
  104. }
  105. //传递下循环
  106. for(i = 0;i < 4;i++)
  107. {
  108. for(j = 0;j < 4;j++)
  109. {
  110. pimn_M_P[i][j] = P[i][j];
  111. }
  112. }
  113. //删去---------------
  114. if(pimn_num_cnt > pimd_L_rls + 1)
  115. {
  116. //输入
  117. A[0] = (real_T)pimn_V_volt[0] * 0.001;
  118. A[1] = (real_T)pimn_I_curr[1] * 0.1;
  119. A[2] =-(real_T)pimn_I_curr[0] * 0.1;
  120. A[3] = 1;
  121. //增益矩阵
  122. 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] +
  123. (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] +
  124. (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] +
  125. (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];
  126. for(i = 0;i <4;i++)
  127. {
  128. 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);
  129. }
  130. //协方差更新
  131. for(i = 0;i < 4;i++)
  132. {
  133. for(j = 0;j < 4;j++)
  134. {
  135. 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]);
  136. }
  137. }
  138. //传递下一循环
  139. for(i = 0;i < 4;i++)
  140. {
  141. for(j = 0;j < 4;j++)
  142. {
  143. pimn_M_P[i][j] = P[i][j];
  144. }
  145. }
  146. }
  147. //参数求解
  148. pimn_V_ocv = theta[3]/(1 - theta[0]);
  149. pimn_R_ohm = theta[1];
  150. pimn_R_polar = (theta[0] * theta[1] -theta[2])/(1 -theta[0]);
  151. pimn_F_polar = -1/log(theta[0]);
  152. //pimn_V_ocv = Saturation_r(pimn_V_ocv,3.2, 4.4);
  153. //pimn_R_ohm = Saturation_r(pimn_V_ocv,0.001, 1);
  154. //pimn_R_polar = Saturation_r(pimn_V_ocv,0.0002, 1);
  155. //pimn_F_polar = Saturation_r(pimn_V_ocv,0, 200);
  156. pimd_V_ocv = (uint16_T)(pimn_V_ocv * 1000);
  157. pimd_R_ohm = (uint16_T)(pimn_R_ohm * 1000 * 1000);
  158. pimd_R_polar = (uint16_T)(pimn_R_polar * 1000 * 1000);
  159. pimd_F_polar = (uint16_T)(pimn_F_polar * 1000);
  160. if(pimd_V_ocv > 4400 || pimd_V_ocv < 1000 || pimd_R_ohm < 1000 || pimd_R_ohm > 10000)
  161. {
  162. pimn_flg_inval = 1;
  163. }
  164. }
  165. else
  166. {
  167. pimd_V_ocv = 0;
  168. pimd_R_ohm = 0;
  169. pimd_R_polar = 0;
  170. pimd_F_polar = 0;
  171. pimn_flg_inval = 1;
  172. }
  173. //全部单体参数---------------------
  174. for(i = 0;i < cmnc_num_cellUNum;i++)
  175. {
  176. pimv_V_cellOcv[i] = pimd_V_ocv + cdmv_V_deltOCV[i];
  177. pimv_R_cellOhm[i] = pimd_R_ohm + cdmv_R_deltOhm[i];
  178. pimv_pct_cellSoc[i] = look1_u16tu16(pimv_V_cellOcv[i], cmnm_V_ocv, cmnm_pct_soc, 13);
  179. if((!pimn_flg_inval && !cdmv_flg_inval[i]))
  180. {
  181. pimv_flg_inval[i] = (pimv_V_cellOcv[i] > 4400 || pimv_V_cellOcv[i] < 1000 || pimv_R_cellOhm[i] < 1000 || pimv_R_cellOhm[i] > 10000);
  182. }
  183. else
  184. {
  185. pimv_flg_inval[i] = 1;
  186. }
  187. }
  188. pimd_flg_inval = 0;
  189. for(i = 0;i < cmnc_num_cellUNum;i++)
  190. {
  191. if(pimv_flg_inval[i] == 1)
  192. {
  193. pimd_flg_inval = 1;
  194. break;
  195. }
  196. }
  197. // 整包SOC
  198. socMin = 1000;
  199. socMax = 0;
  200. for(i = 0;i < cmnc_num_cellUNum;i++)
  201. {
  202. if(!pimv_flg_inval[i] && pimv_pct_cellSoc[i] > socMax)
  203. {
  204. socMax = pimv_pct_cellSoc[i];
  205. }
  206. if(!pimv_flg_inval[i] && pimv_pct_cellSoc[i] < socMin)
  207. {
  208. socMin = pimv_pct_cellSoc[i];
  209. }
  210. }
  211. if (socMax > 800)
  212. {
  213. factor = 100;
  214. }
  215. else if (socMin < 200)
  216. {
  217. factor = 0;
  218. }
  219. else
  220. {
  221. factor = (uint16_T)(((uint16_T)(((uint32_T)(socMin - 200) << 6) / (800 - (socMax - socMin) - 200)) * 25U) >> 4);
  222. }
  223. pimd_pct_battSoc = (uint16_T)(((1 - (real_T)(factor * 0.01)) * (real_T)(socMin * 0.1) + (real_T)(factor * 0.01) * (real_T)(socMax * 0.1)) * 10);
  224. //
  225. pimn_st_workStat_Delay = ihd_st_workStat;
  226. pimd_flg_firstRun = false;
  227. }