用C语言通过无迹卡尔曼滤波算法编写一套电池SOC计算函数,其中电池的容量使用Peukert常数n=1.357来计算并加上UKF算法的实现部分,算法最终输出电池的内阻和当前的SOC值,不使用Eigen C++库
时间: 2023-11-22 10:53:46 浏览: 185
基于无迹卡尔曼滤波的SOC估算_卡尔曼滤波_锂电池SOC估算模型_SOC估算模型_matlab仿真
5星 · 资源好评率100%
首先,我们需要了解几个概念:
1. 电池容量:电池所能存储的电荷量,单位为安时(Ah)。
2. SOC(State of Charge):电池的充电状态,通常用百分比表示。
3. Peukert常数:描述电池在高放电率下的性能损耗,一般为1.1到1.5之间。
接下来,我们来编写无迹卡尔曼滤波算法和Peukert常数计算的函数:
```c
#define N_STATE 2 // 状态量数量
#define N_MEAS 1 // 测量值数量
/* 无迹卡尔曼滤波算法 */
void ukf_filter(float* x, float* P, float* z, float* Q, float* R, float* y, float* K, float* X, float* W, float alpha, float beta, float kappa)
{
int n = N_STATE;
int m = N_MEAS;
int n_sigma = 2 * n + 1;
float lambda = alpha*alpha*(n + kappa) - n;
float c = n + lambda;
/* 生成Sigma点 */
X[0] = x[0];
X[1] = x[1];
for (int i = 0; i < n; i++) {
X[(i + 1) * n + i] = x[i] + sqrt(c)*P[i];
X[(i + 1 + n) * n + i] = x[i] - sqrt(c)*P[i];
}
/* 计算权重 */
W[0] = lambda / c;
for (int i = 1; i < n_sigma; i++) {
W[i] = 1 / (2 * c);
}
/* 预测状态 */
for (int i = 0; i < n_sigma; i++) {
X[i * n] = X[i * n] + X[i * n + 1];
}
x[0] = 1.0 / (1.0 / X[0] + z[0] / (3600.0 * 1.357));
x[1] = (X[1] + z[0]) / x[0];
/* 预测测量值 */
for (int i = 0; i < n_sigma; i++) {
y[i] = X[i * n + 1];
}
/* 计算协方差矩阵 */
for (int i = 0; i < n_sigma; i++) {
for (int j = 0; j < n_sigma; j++) {
if (i == 0 && j == 0) {
K[0] = W[0] * (y[i] - x[1])*(y[j] - x[1]);
}
else if (i == j) {
K[0] += W[i] * (y[i] - x[1])*(y[j] - x[1]);
}
else {
K[0] += W[i] * (y[i] - x[1])*(y[j] - x[1]);
}
}
}
/* 计算卡尔曼增益 */
K[0] += R[0];
K[0] = 1.0 / K[0];
/* 更新状态 */
x[1] = x[1] + K[0] * (z[0] - x[1]);
P[1] = P[1] - K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0] * K[0];
}
/* 计算电池SOC和内阻 */
void battery_soc(float* soc, float* r, float current, float voltage)
{
float x[2] = { 1.0, 1.0 }; // 初始状态向量
float P[2] = { 0.1, 0.1 }; // 初始协方差矩阵
float Q[2] = { 0.001, 0.001 }; // 状态噪声方差
float R[1] = { 0.01 }; // 测量噪声方差
float z[1] = { current }; // 当前测量值
float y[N_STATE * 2 + 1]; // 测量值预测
float K[1]; // 卡尔曼增益
float X[N_STATE * 2 + 1]; // Sigma点
float W[N_STATE * 2 + 1]; // 权重
/* 无迹卡尔曼滤波 */
ukf_filter(x, P, z, Q, R, y, K, X, W, 1.0, 2.0, 0.0);
/* 计算电池SOC */
*soc = x[0] * 100;
/* 计算电池内阻 */
*r = (voltage - current * x[1]) / current;
}
```
在这个函数中,我们使用了无迹卡尔曼滤波算法来进行电池SOC的估计,并在SOC估计的基础上使用Peukert常数来计算电池容量。函数的输入参数为电池当前的电流和电压,输出参数为电池的SOC和内阻。
需要注意的是,这个函数中有一些需要根据具体应用场景来确定的参数,比如Peukert常数和噪声方差等。在实际应用中,我们需要通过实验或模拟来确定这些参数的值。
另外,这个函数中并没有使用任何第三方库,所有的计算都是基于C语言的基本数据类型实现的。这样做的好处是可以减少代码的复杂度和运行时的开销,但也会增加编写代码的难度。
阅读全文