最小二乘擬合二次曲線在STM32中的實現筆記

2021-09-27 08:12:15 字數 3351 閱讀 4486

感測器使用前要進行標定, 標定時必定需要進行曲線擬合。若用計算機處理很簡單, 但實際中用微控制器中標定時, 只能進行一般的代數運算,無矩陣運算, 處理就顯得非常不方便。最小二乘法推導了二次多項式曲線擬合待定係數的代數計算公式, 應用這些公式來處理資料非常方便。

設有一組實測資料(x i , yi)i =1 , 2 , … , n , 其擬合函式為

假定一種感測器的標準輸入與輸出曲線如圖1(紅色曲線)所示,由於環境以及外部干擾原因導致感測器輸入與輸出曲線發生偏移,如圖1(藍色曲線)。如果要得到感測器正確的資料就需要一條矯正曲線,將輸入帶有誤差的曲線矯正成紅色的標準曲線。首先我們要先確認誤差曲線,如圖2所示。紅色為平滑後的曲線。

matlab矯正過程簡述如下:

將標準曲線匯入matlab

將現場採集到的誤差曲線匯入matlab

取標準曲線和帶有誤差的曲線個7個資料

計算誤差(擬合曲線的輸出)

利用最小二乘法集合誤差曲線

f(標準輸出)  = f(現場輸入)-f(誤差)

擬合後的曲線如圖3所示:

matlab**如下(可直接執行):

%**********====定義標準********************%

a = [310.0 305.9 302.6 300.2 298.1 296.0 294.1 292.4 290.8 288.8 287.4 286.1 284.8 283.7 282.7 281.9 281.0 280.2 279.4 278.8 278.2 277.6 277.0 276.4 275.9 275.5 275.0 274.3 273.8 273.4];

a = a/10.0;

%**********====定義實際輸入********************%

b = [308.7 304.3 301.0 298.4 296.2 294.1 291.9 290.0 288.2 286.6 285.2 283.7 282.5 281.5 280.5 279.5 278.7 277.9 277.2 276.5 275.9 275.2 274.7 274.0 273.5 273.0 272.5 272.0 271.5 271.1];

b = b/10.0;

bb = [b(1),b(5),b(10),b(15),b(20),b(25),b(30)];%需要擬合的資料,取輸入的其中7個資料

%**********===定義標準輸出(為誤差)***************==%

out = [a(1)-b(1),a(5)-b(5),a(10)-b(10),a(15)-b(15),a(20)-b(20),a(25)-b(25),a(30)-b(30)];

%***************==一下為計算引數***************====%

b1 = sum(bb);

b2 = sum(bb.^2);

b3 = sum(bb.^3);

b4 = sum(bb.^4);

c1 = sum(out);

c2 = sum(out.*bb);

c3 = sum(out.*bb.^2);

n=7;%擬合資料長度為 7

k = n*b2*b4 + 2*b1*b2*b3 - n*b3^2 - b1^2*b4 - b2^3;%%計算k

a0 = ((b2*b4-b3^2)*c1 + (b2*b3-b1*b4)*c2 + (b1*b3-b2^2)*c3 )/k;

a1 = ((b2*b3-b1*b4)*c1 + (n*b4-b2^2)*c2 + (b1*b2-n*b3)*c3 )/k;

a2 = ((b1*b3-b2^2)*c1 + (b1*b2-n*b3)*c2 + (n*b2-b1^2)*c3 )/k;

%%擬合函式%%%%%

syms funb x0

funb = a0 + a1*x0 + a2*x0*x0;%%函式

%***************=誤差曲線和平滑後的曲線**********==%

error = a-b;%得出資料誤差

t = 1:1:30;%定義橫座標

error_p = zeros(1,30);%定義空向量

for i=2:30

error_p(i) = error_p(i-1)*0.8 + error(i)*(1-0.8);%一階低通濾波

endplot(t,error);%畫誤差曲線

hold on;

plot(t,error_p);%畫平滑誤差曲線

figure;

ezplot(funb,[27,38]);%畫出擬合曲線

自stm32f4系列推出之後,stm32已經帶有dsp運算單元了,即使需要實時的曲線擬合,stm32也可以完全的勝任了。

計算**如下:

/*

顯示函式

誤差曲線擬合

其中 n 為需要擬合資料長度

其中g_ddata 為待擬合的曲線資料(x)

其中g_dout 為擬合曲線的輸出(y)

*/void disposehmi()

for(i=0;i<7;i++)

for(i=0;i<7;i++)

for(i=0;i<7;i++)

for(i=0;i<7;i++)

for(i=0;i<7;i++)

for(i=0;i<7;i++)

k = n*b2*b4 + 2*b1*b2*b3 - n*b3*b3 - b1*b1*b4 - b2*b2*b2;

//**********====一下為計算係數*************************===//

a0 = ((b2*b4-b3*b3)*c1 + (b2*b3-b1*b4)*c2 + (b1*b3-b2*b2)*c3 )/k;

a1 = ((b2*b3-b1*b4)*c1 + (n*b4-b2*b2)*c2 + (b1*b2-n*b3)*c3 )/k;

a2 = ((b1*b3-b2*b2)*c1 + (b1*b2-n*b3)*c2 + (n*b2-b1*b1)*c3 )/k;

} }}

三、總結

利用本文推導的二次項式曲線擬合待定係數的代數計算公式求待定係數比較方便, 然後, 再進行曲線擬合, 其擬合準確度也很高, 尤其用微控制器進行標定時優點更為顯著。筆者能力有限,如有錯誤望提示更正。

最小二乘法擬合二次曲線 C語言

題目x 21 y 21 利用最小二乘法將上面資料所標示的曲線擬合為二次曲線,使用c語言程式設計求解函式係數 最小二乘法原理 原理不再贅述,主要是解法採用偏微分求出來的係數公式a,b,c 就是這個公式,對應了二次方程的a,b,c include include define n 1e 13 int m...

一元二次曲線擬合的最小二乘python實現

1 首先定義乙個誤差函式,t為需要擬合的引數 def residual t,x y return y t 0 x 2 t 1 x t 2 2 接著設定真實值 x np.linspace 2,2,50 a,b,c 2,3,1 為真實值 y a x 2 b x c np.random.rand len ...

最小二乘曲線擬合matlab實現

對如下圖所示的加雜訊曲線,如何進行曲線擬合呢?我們可以採用 階多項式去逼近它 係數隨機資料的產生如下 function y truth,y observed unknown model1 x y truth 0.001 x.4 x.3 5 x.2 0.5 x 4階的資料 y observed y t...