RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是線性插值?一維線性插值和雙線性插值在BMS開發(fā)中的應(yīng)用

jf_L18yujSQ ? 來源:小飛哥玩嵌入式 ? 2023-12-24 10:44 ? 次閱讀

Part11、什么是線性插值

線性插值法(linear interpolation),是指使用連接兩個已知量的直線來確定在這兩個已知量之間的一個未知量的值的方法。

有好幾種插值方法,本文僅僅介紹一維線性插值和雙線性插值在BMS開發(fā)中的應(yīng)用。

11.1、 一維線性插值

如下圖:

a5866e84-a145-11ee-8b88-92fbcf53809c.png

已知坐標(biāo) (x0, y0) 與 (x1, y1),要得到 [x0, x1] 區(qū)間內(nèi)某一位置 x 在直線上的值。

從數(shù)學(xué)上來看,3點處于1條直線,斜率是相等的,于是有:

a5936616-a145-11ee-8b88-92fbcf53809c.png

由于 x 值已知,所以可以從公式得到 y 的值:

a59a14ac-a145-11ee-8b88-92fbcf53809c.png

公式太長不好記,可以進(jìn)行簡化方便記憶,方然推導(dǎo)也沒問題....

a5936616-a145-11ee-8b88-92fbcf53809c.png,

令α = (y-y0)/(x-x0),同樣有,α = (y1 - y0)/(x1 - x0),上面的方程式就可以簡化為:

y = y0 + α(y1 ? y0)

這樣已知x的值,就可以輕松計算出y的值,同樣的,已知y的值,可以輕松求出x的值。

21.2、雙線性插值

在數(shù)學(xué)上,雙線性插值是有兩個變量的插值函數(shù)的線性插值擴(kuò)展,其核心思想是在兩個方向分別進(jìn)行一次線性插值。

以下理論搬自網(wǎng)絡(luò)。

a5a9e49a-a145-11ee-8b88-92fbcf53809c.png紅色的數(shù)據(jù)點與待插值得到的綠色點

假如我們想得到未知函數(shù) f 在點 P = (x, y) 的值,假設(shè)我們已知函數(shù) f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四個點的值。

首先在 x 方向進(jìn)行線性插值,得到:

a5b7a29c-a145-11ee-8b88-92fbcf53809c.pnga5c26506-a145-11ee-8b88-92fbcf53809c.png

然后在 y 方向進(jìn)行線性插值,得到:

a5cf4654-a145-11ee-8b88-92fbcf53809c.png

這樣就得到所要的結(jié)果 f(x, y):

a5daa0da-a145-11ee-8b88-92fbcf53809c.pnga5ed1774-a145-11ee-8b88-92fbcf53809c.png

Part22、線性插值在BMS中的應(yīng)用

32.1 一維線性插值在BMS中的應(yīng)用

電芯SOC和開路電壓是有一定關(guān)系的,也就是我們常聽說的OCV,OCV是Open circuit voltage(開路電壓),指的是電池不放電開路時,兩極之間的電位差.

但是因為電池的極化效應(yīng),想要測量準(zhǔn)確的OCV得靜止2小時,假設(shè)我們通過設(shè)置放電電流來控制電池的SOC從100%-0%變化,間隔為1%,那么整個實驗做完至少需要200小時。

來看一組電池數(shù)據(jù),一般電芯廠家提供的都是5%步進(jìn)的SOC對應(yīng)的電壓值,在兩個電壓點之間的SOC可以近似直線,當(dāng)然這樣也是有誤差的。

a5fa59b6-a145-11ee-8b88-92fbcf53809c.pnga612b09c-a145-11ee-8b88-92fbcf53809c.png

那么如何利用一維線性差值計算不同電壓下對應(yīng)的SOC值呢?

例如:計算紅框中的某一電壓對應(yīng)的SOC值

根據(jù)一維線性差值的公式編寫代碼如下:

#include
#include

#defineSOC_FULL(100)
#defineSOC_OCV_STEP(SOC_FULL/20)
#defineCELLVOL_LEN(21)

constuint16_tvoltage[CELLVOL_LEN]={2966,3140,3244,3343,3427,3491,3525,
3576,3633,3687,3730,3772,3813,3858,
3914,3955,4007,4054,4077,4099,4180};

/**
*根據(jù)ocv曲線計算SOC
*/
uint8_tget_soc_by_cellocv(constuint16_t*cell_table,uint16_tcellvol)
{
/**y=y0+(x-x0)*(y1?y0)/(x1-x0)*/
/**計算3343和3427電壓直接的電壓對應(yīng)的SOC值,取3400電壓下的SOC*/

uint16_tsoc;
uint8_ti;

if(cellvol<=?cell_table[0])?//?0%
??{
????return?0;
??}
??else?if?(cellvol?>=cell_table[SOC_FULL/SOC_OCV_STEP])//100%
{
returnSOC_FULL;
}

for(i=0;icell_table[i])
{
i++;
}
else
{
break;
}
}

/**y0=(i-1)*SOC_OCV_STEP*/
/**(x-x0)=(cellvol-cell_table[i-1])*/
/**(y1?y0)=SOC_OCV_STEP,這里由于SOC是5%均勻步進(jìn),所以直接取了步進(jìn)值作為y1-y0*/

soc=(i-1)*SOC_OCV_STEP+SOC_OCV_STEP*(cellvol-cell_table[i-1])/
(cell_table[i]-cell_table[i-1]);

returnsoc;
}

intmain(void)
{
uint16_tsoc_ocv=0;

soc_ocv=get_soc_by_cellocv(voltage,3400);

printf("

----soc_ocv=%d---

",soc_ocv);

return0;
}

vscode環(huán)境下編譯看看結(jié)果,我們要計算的是3400mV時候?qū)?yīng)的SOC為18%,計算結(jié)果是OK的,要注意限幅處理,0%和100%對應(yīng)的點。

a624a7a2-a145-11ee-8b88-92fbcf53809c.pnga6317446-a145-11ee-8b88-92fbcf53809c.png

42.2 雙線性插值在BMS中的應(yīng)用

要計算在負(fù)載情況下的SOC,需要對電壓和電流做建模,獲得比較準(zhǔn)確的SOC,當(dāng)然這個SOC也只是盡可能準(zhǔn)確一些,相比較OCV,電池工作過程中是不能直接使用OCV計算SOC的。

包括電池的充放電MAP,都是需要進(jìn)行二維插值計算的,例如:

a63aceb0-a145-11ee-8b88-92fbcf53809c.png

看一組數(shù)據(jù),橫軸是電流,縱軸是電壓,中間數(shù)據(jù)為SOC值,接下來看看如何利用雙線性插值計算SOC,這里取得都是1%精度,沒有用浮點類型數(shù)據(jù)。

a64cff86-a145-11ee-8b88-92fbcf53809c.png

還是要回歸到第一章節(jié)介紹的公式,雙線性插值實際上是進(jìn)行3次單線性插值,x軸進(jìn)行2次插值計算,y軸進(jìn)行1次插值計算。

就不再針對公式一一分析了,直接上代碼:

#include
#include
#include
#include

#defineSOC_FULL(100)
#defineSOC_OCV_STEP(SOC_FULL/20)
#defineCELLVOL_LEN(21)

#defineCURRENT_LEN7
#defineVOLTAGE_LEN6

constuint16_tvoltage[CELLVOL_LEN]={2966,3140,3244,3343,3427,3491,3525,
3576,3633,3687,3730,3772,3813,3858,
3914,3955,4007,4054,4077,4099,4180};

staticconstint32_tcurrent_map[CURRENT_LEN]={0,50,200,500,
1200,2500,2501};//橫軸
staticconstuint16_tvoltage_map[VOLTAGE_LEN]={0,2500,3200,
3380,3500,3501};//縱軸

staticconstint16_tload_soc_map[CURRENT_LEN][VOLTAGE_LEN]={
{100,100,100,100,100,100},
{0,0,4,15,35,100},
{-2,-2,0,8,22,100},
{-4,-4,-1,4,15,100},
{-6,-6,-3,2,10,100},
{-6,-6,-3,2,10,100},
{-6,-6,-3,2,10,100}};

/**
*根據(jù)ocv曲線計算SOC
*/
uint8_tget_soc_by_cellocv(constuint16_t*cell_table,uint16_tcellvol)
{
/**y=y0+(x-x0)*(y1?y0)/(x1-x0)*/
/**計算3343和3427電壓直接的電壓對應(yīng)的SOC值,取3400電壓下的SOC*/

uint16_tsoc;
uint8_ti;

if(cellvol<=?cell_table[0])?//?0%
??{
????return?0;
??}
??else?if?(cellvol?>=cell_table[SOC_FULL/SOC_OCV_STEP])//100%
{
returnSOC_FULL;
}

for(i=0;icell_table[i])
{
i++;
}
else
{
break;
}
}

/**y0=(i-1)*SOC_OCV_STEP*/
/**(x-x0)=(cellvol-cell_table[i-1])*/
/**(y1?y0)=SOC_OCV_STEP,這里由于SOC是5%均勻步進(jìn),所以直接取了步進(jìn)值作為y1-y0*/

soc=(i-1)*SOC_OCV_STEP+SOC_OCV_STEP*(cellvol-cell_table[i-1])/
(cell_table[i]-cell_table[i-1]);

returnsoc;
}

/*
*負(fù)載SOC查表
*/
staticint16_tget_soc_by_load_map(constint16_t*table,uint16_tvoltage,int32_tcurrent)
{
int16_tresult=0;
int16_tmap_voltage_low=0,map_voltage_high=0,map_current_low=0,
map_current_high=0;

int16_tmap_high=0,map_low=0;
uint8_ti=0;

int16_tvol_step=0;
int16_tvol_diff=0;

int32_tcurrent_step=0;
int32_tcurrent_diff=0;
int16_tsoc_diff=0;
int16_tsoc_step=0;

for(i=0;icurrent_map[CURRENT_LEN-1])||
(voltage>voltage_map[VOLTAGE_LEN-1])))
{
return100;
}
vol_diff=voltage-voltage_map[map_voltage_low];
vol_step=voltage_map[map_voltage_high]-
voltage_map[map_voltage_low];

soc_step=table[(CURRENT_LEN-1-map_current_low)*VOLTAGE_LEN+
map_voltage_high]-
table[(CURRENT_LEN-1-map_current_low)*VOLTAGE_LEN+
map_voltage_low];
map_low=(int16_t)(soc_step*vol_diff/vol_step+
table[(CURRENT_LEN-1-map_current_low)*VOLTAGE_LEN+map_voltage_low]);

vol_diff=voltage-voltage_map[map_voltage_low];
vol_step=(voltage_map[map_voltage_high]-
voltage_map[map_voltage_low]);

soc_step=(table[(CURRENT_LEN-1-map_current_high)*VOLTAGE_LEN+
map_voltage_high]-
table[(CURRENT_LEN-1-map_current_high)*VOLTAGE_LEN+
map_voltage_low]);

map_high=(int16_t)(vol_diff*soc_step/vol_step+
table[(CURRENT_LEN-1-map_current_high)*VOLTAGE_LEN+
map_voltage_low]);
result=
(int16_t)((abs(current)-current_map[map_current_low])*
(map_high-map_low)/(current_map[map_current_high]-current_map[map_current_low])+
map_low);

returnresult;
}

intmain(void)
{
int16_tsoc_ocv=0;
uint16_tcell_vol=3200;
int32_tcurrent=0;

while(1)
{
current+=100;
soc_ocv=get_soc_by_cellocv(voltage,3400);
printf("----soc_ocv=%d----
",soc_ocv);

soc_ocv=get_soc_by_load_map((constint16_t*)load_soc_map,cell_vol,current);
printf("!!!!current=%d,cell_vol=%d,soc_load=%d!!!!

",current,cell_vol,soc_ocv);
if(current>2600)
return0;

Sleep(1000);
}

return0;
}

看下運行結(jié)果,驗證也是OK的,這個代碼寫的略微shi,大家可以自己優(yōu)化優(yōu)化,可以把一維線性函數(shù)抽出來封裝,這樣單線性和雙線性可以復(fù)用函數(shù),代碼更簡潔一些。

a65ed2f6-a145-11ee-8b88-92fbcf53809c.png

Part3經(jīng)驗交流








審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • bms
    bms
    +關(guān)注

    關(guān)注

    107

    文章

    996

    瀏覽量

    65946
  • OCV
    OCV
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    12527
  • 線性插值
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    6675
  • 開路電壓
    +關(guān)注

    關(guān)注

    0

    文章

    36

    瀏覽量

    12608
  • vscode
    +關(guān)注

    關(guān)注

    1

    文章

    155

    瀏覽量

    7696

原文標(biāo)題:線性插值在BMS開發(fā)中的應(yīng)用

文章出處:【微信號:小飛哥玩嵌入式,微信公眾號:小飛哥玩嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    線性插值

    求解線性插值的時候,我先把個數(shù)組分成兩個,再求的時候,有時候出結(jié)果,有時候不出結(jié)果,求指教
    發(fā)表于 11-08 22:04

    雙線性插值法的C語言程序!幫幫忙!拜托各位了!

    DSP6000開發(fā)平臺上用C語言實現(xiàn)雙線性插值法,實現(xiàn)對圖像的縮放效果的改進(jìn)。
    發(fā)表于 04-20 18:52

    基于FPGA的線性插值-上

    1,背景 利用FPGA做數(shù)據(jù)處理、系統(tǒng)控制時,經(jīng)常需要做線性插值。如圖(1)所示,給點A和B的x,y坐標(biāo),需要求A,B中間某點C的坐標(biāo)。限定x取整數(shù)。 圖(1) 示意圖 根據(jù)A,
    發(fā)表于 11-20 23:10

    基于FPGA的線性插值-

    上次分享了基于FPGA的線性插值的背景和方法原理,今天分享 方法原理的驗證。 通常FPGA的開發(fā)分為電路功能設(shè)計、設(shè)計輸入、功能仿真、綜合優(yōu)化、綜合后仿真、實現(xiàn)、布線后仿真、板級仿真以及芯片編程
    發(fā)表于 11-23 23:09

    基于PLC的線性插值模糊控制器的設(shè)計

    通過對噴淋式除塵系統(tǒng)采用的常規(guī)模糊控制器實際應(yīng)用存在的問題進(jìn)行分析,提出種分段線性插值的設(shè)計方法,并將該方法模糊控制器
    發(fā)表于 05-03 17:29 ?60次下載
    基于PLC的<b class='flag-5'>線性插值</b>模糊控制器的設(shè)計

    種改進(jìn)的線性圖像算法

    針對傳統(tǒng)的雙線性插值法在對圖像進(jìn)行后會不可避免的產(chǎn)生邊緣模糊的問題,提出了種改進(jìn)的線性插值法,該算法首先把待
    發(fā)表于 08-20 12:01 ?29次下載

    基于Matlab的雙線性插值算法圖像旋轉(zhuǎn)的應(yīng)用

    MATLAB雙線性插值圖像處理的算法,讀者可以自行參考。
    發(fā)表于 05-04 16:04 ?1次下載

    基于最優(yōu)移位雙線性插值的圖像縮放旋轉(zhuǎn)硬件加速研究

    基于最優(yōu)移位雙線性插值的圖像縮放旋轉(zhuǎn)硬件加速研究_丁家隆
    發(fā)表于 01-08 15:15 ?10次下載

    基于雙線性插值的圖像縮放在GPU上的實現(xiàn)

    基于雙線性插值的圖像縮放在GPU上的實現(xiàn)
    發(fā)表于 01-08 14:47 ?0次下載

    基于AIS線性插值的綜合方法

    實時視景顯示,為了使目標(biāo)的運動軌跡平滑,針對傳統(tǒng)AIS線性插值的弊端,本文提出種綜合考慮目標(biāo)的航速、航向等運行信息的
    發(fā)表于 11-13 17:20 ?13次下載
    基于AIS<b class='flag-5'>線性插值</b>的綜合<b class='flag-5'>插</b><b class='flag-5'>值</b>方法

    種不同于雙線性插值的上采樣方法

    我們可以看到,該網(wǎng)絡(luò)將傳統(tǒng)的非線性插值替換成 DUpsample,同時 feature fuse 方面,不同于之前方法將 Decoder 的特征上采樣與 Encoder 特征融合,本工作將 Encoder
    的頭像 發(fā)表于 04-08 14:47 ?6415次閱讀
    <b class='flag-5'>一</b>種不同于<b class='flag-5'>雙線性插值</b>的上采樣方法

    FPGA上如何實現(xiàn)雙線性插值的計算

    雙線性插值顧名思義是線性插值Pro,為了說明白什么是雙線性插值,首先得先從線性插值說起。那么什么又是線性呢?
    發(fā)表于 08-09 17:33 ?4633次閱讀

    雙線性插值算法的講解

    雙線性插值,我們現(xiàn)在找x0', y0'所在位置旁邊的四個點,再根據(jù)這四個點與(x0',y0')距離的關(guān)系得到權(quán)重,最后計算出目標(biāo)圖像
    的頭像 發(fā)表于 09-19 10:25 ?3239次閱讀

    LInterp之線性插值PROGMEM數(shù)組生成器

    電子發(fā)燒友網(wǎng)站提供《LInterp之線性插值PROGMEM數(shù)組生成器.zip》資料免費下載
    發(fā)表于 10-20 17:32 ?0次下載
    LInterp之<b class='flag-5'>線性插值</b>PROGMEM數(shù)組生成器

    基于FPGA的圖像旋轉(zhuǎn)和雙線性插值算法設(shè)計

    今天開源個FPGA圖像處理相關(guān)的項目:圖像旋轉(zhuǎn)。圖像旋轉(zhuǎn)算法本身非常簡單,但是如果想讓旋轉(zhuǎn)之后的圖像更加完整、平滑,還需要進(jìn)行雙線性插值處理,因此整個算法FPGA實現(xiàn)起來還是有定難度的。
    的頭像 發(fā)表于 09-04 16:52 ?1671次閱讀
    基于FPGA的圖像旋轉(zhuǎn)和<b class='flag-5'>雙線性插值</b>算法設(shè)計
    RM新时代网站-首页