L_identification_wrapper.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /**********************************
  2. * 文件名称: L_identification_wrapper.c
  3. * 功能描述: 电感识别模块
  4. * 功能: 使用递归最小二乘(RLS)算法在线识别电机电感值
  5. **********************************/
  6. #if defined(MATLAB_MEX_FILE)
  7. #include "tmwtypes.h"
  8. #include "simstruc_types.h"
  9. #else
  10. #include "rtwtypes.h"
  11. #endif
  12. #include <math.h>
  13. // 全局变量
  14. float l_h; // 采样时间
  15. float l_Pn0; // 前一时刻的协方差矩阵
  16. float l_Pn1; // 当前时刻的协方差矩阵
  17. float l_x1; // 状态变量1(电感估计值)
  18. float l_x2; // 状态变量2(协方差矩阵)
  19. float l_K; // 卡尔曼增益
  20. float l_theta0; // 前一时刻的电感估计值
  21. float l_theta1; // 当前时刻的电感估计值
  22. float l_Ud; // d轴电压输入
  23. // 输入输出维度定义
  24. #define u_width 2 // 输入维度:[采样时间, d轴电压]
  25. #define y_width 1 // 输出维度:[电感估计值]
  26. /**
  27. * @brief 电感识别初始化函数
  28. * @param xD: 状态变量数组
  29. * @note 初始化电感估计值和协方差矩阵
  30. */
  31. void L_identification_Start_wrapper(real_T *xD)
  32. {
  33. // 初始化电感估计值,初始值设为0.01H
  34. l_theta0 = 0.01f;
  35. // 初始化协方差矩阵
  36. l_Pn0 = 0.0008f * 2.0f;
  37. // 初始化状态变量
  38. l_x1 = l_theta0; // 状态1:电感估计值
  39. l_x2 = l_Pn0; // 状态2:协方差矩阵
  40. }
  41. /**
  42. * @brief 电感识别输出函数
  43. * @param u: 输入数组 [采样时间, d轴电压]
  44. * @param y: 输出数组 [电感估计值]
  45. * @param xD: 状态变量数组
  46. * @note 输出当前的电感估计值
  47. */
  48. void L_identification_Outputs_wrapper(const real32_T *u,
  49. real32_T *y,
  50. const real_T *xD)
  51. {
  52. // 获取当前的电感估计值
  53. l_theta1 = l_x1;
  54. // 输出电感估计值
  55. y[0] = l_theta1;
  56. }
  57. /**
  58. * @brief 电感识别更新函数
  59. * @param u: 输入数组 [采样时间, d轴电压]
  60. * @param y: 输出数组 [电感估计值]
  61. * @param xD: 状态变量数组
  62. * @note 使用递归最小二乘(RLS)算法更新电感估计值
  63. */
  64. void L_identification_Update_wrapper(const real32_T *u,
  65. real32_T *y,
  66. real_T *xD)
  67. {
  68. // 获取输入参数
  69. l_h = u[0]; // 采样时间
  70. l_Ud = u[1]; // d轴电压
  71. // 获取前一时刻的状态
  72. l_Pn0 = l_x2; // 前一时刻的协方差矩阵
  73. l_theta0 = l_x1; // 前一时刻的电感估计值
  74. // 计算卡尔曼增益
  75. l_K = l_Pn0 * l_h / (1 + l_h * l_Pn0 * l_h);
  76. // 更新协方差矩阵
  77. l_Pn1 = l_Pn0 - l_K * l_h * l_Pn0;
  78. // 更新电感估计值
  79. // 公式:theta1 = theta0 + K * (Ud - h * 0.99 * theta0)
  80. // 其中0.99是一个调整系数,用于减少噪声对估计的影响
  81. l_theta1 = l_theta0 + l_K * (l_Ud - l_h * 0.99f * l_theta0);
  82. // 更新状态变量
  83. l_x1 = l_theta1; // 更新后的电感估计值
  84. l_x2 = l_Pn1; // 更新后的协方差矩阵
  85. }
  86. /**********************************
  87. * 电感识别算法原理
  88. *
  89. * 1. 基本原理:
  90. * - 使用递归最小二乘(RLS)算法在线识别电机电感值
  91. * - 基于电机d轴电压方程:Ud = R*Id + L*dId/dt
  92. * - 当Id为恒定值时,dId/dt = 0,方程简化为Ud = R*Id
  93. * - 当Id变化时,通过测量Ud和Id的变化来估计L
  94. *
  95. * 2. 数学推导:
  96. * a. 从d轴电压方程出发
  97. * Ud = R*Id + L*dId/dt
  98. * b. 移项得到
  99. * Ud - R*Id = L*dId/dt
  100. * c. 令y = Ud - R*Id,u = dId/dt,则
  101. * y = L*u
  102. * d. 这是一个线性模型,其中L是待估计的参数
  103. * e. 使用递归最小二乘(RLS)算法估计L值
  104. * - 初始化:θ0 = 初始电感估计值,P0 = 初始协方差矩阵
  105. * - 预测:ŷk = θk-1*uk
  106. * - 预测误差:ek = yk - ŷk
  107. * - 计算增益:Kk = Pk-1*uk/(1 + uk*Pk-1*uk)
  108. * - 更新估计:θk = θk-1 + Kk*ek
  109. * - 更新协方差:Pk = Pk-1 - Kk*uk*Pk-1
  110. *
  111. * 3. 算法流程:
  112. * - 初始化电感估计值和协方差矩阵
  113. * - 每周期采样时,获取d轴电压和采样时间,计算卡尔曼增益
  114. * - 使用卡尔曼增益更新电感估计值和协方差矩阵
  115. * - 输出更新后的电感估计值
  116. *
  117. * 4. 优点:
  118. * - 实现实时识别,能够适应电机参数的变化
  119. * - 算法简单,计算量小,适合嵌入式系统使用
  120. * - 不需要专门的测试信号,可以在电机正常运行时进行识别
  121. **********************************/