查看: 3108|回复: 3

【征文FSL 算法经验篇】三次曲线拟合

[复制链接]

该用户从未签到

6

主题

34

帖子

0

注册会员

Rank: 2

积分
98
最后登录
2015-6-6
发表于 2015-5-11 23:31:09 | 显示全部楼层 |阅读模式
下面是我的三次曲线拟合的算法,没有使用开方求极大值,经过我一般的试验后,发现在知道上精确度是很高的,误差范围小于1cm.但由于传感器最大值与最小值比标定做的不好,所以诚心将算法拿出来和大家交流,希望能将曲线拟合算法变得跟使用与丰富,也希望大家能将好的传感器最大值与最小值比标定的算法能和我分享510786964@qq.com
//
传感器位置-10-5 5 10,三次多项式矩阵的逆矩阵。系数Q[4]=X_Array[4]*L_value[4];
float X_Array[4][4]={ {-0.0007,0.0013,-0.0013,0.0007},
                                      {0.0067,-0.0067,-0.0067,0.0067},
                                      {0.0167,-0.1333,0.1333,-0.0167},
                                      {-0.1667,0.6667,0.6667,-0.1667}  };
char X[4] = {-10,-5,5,10}; //传感器实际位置
unsigned char L_value[4]={0};  //存储传感器归一化后的值
float AD[4];            //存储ad转换的值
float XX;           //存储最终得到的偏移距离


//曲线拟合函数,目的是求出小车偏离磁导线的偏移距离
void Curve_fitting()
{
        float Q[4]={0};  //存储三次多项式系数
        float Xi=0;
        float Y=0,Ymax=0;//二次函数值
        unsigned char ss=0;
        char Xmax=0; //存储X[4]中最大的值
        float Ys,Xs=0;//存储二次函数的最大值对应的x值;
        float Xtemp=0;//存储磁导线偏移的实际位置
        unsigned char i,j;

        
               
        Get_Lvalue();   //归一化函数,得到归一后的值  可是本人对传感器最大值与最小值标定这一块做的不理想

    //找出对应最大值的传感器位置
        ss=L_value[0];
        Xmax=X[0];
        for(i=0;i<3;i++)
        {
                if(ss<L_value[i+1])
                {
                       ss=L_value[i+1];
                       Xmax=X[i+1];
                }
        }
        
        
    //计算三次多项式系数
        for(i=0;i<4;i++)
                for(j=0;j<4;j++)
                {
                       Q += X_Array[j]*L_value[j];
                }

    //
计算三次多项式求导后,Xmax对应的二次函数的值Ymax,它主要用于后面的比较与搜素极大值使用
        Ymax=3*Q[0]*Xmax*Xmax+2*Q[1]*Xmax+Q[2];
        
        //计算二次函数的中轴线及其对应的函数值,也是用于后面的比较与搜素极大值使用
        Xs=(-Q[1])/(3*Q[0]);      
        Ys=3*Q[0]*Xs*Xs+2*Q[1]*Xs+Q[2];

//**************************************************************************
            if(Q[0]>0&&Ys<0)        //当二次曲线开口向上,必须保证有解,所以Ys<0
                {
                       if(Xmax>=Xs)         //画图后很直观的能明白这样做的目的
                               for(Xi=Xs;;Xi-=0.1)
                               {
                                      Y=3*Q[0]*Xi*Xi+2*Q[1]*Xi+Q[2];
                                       if(Y>=0)
                                       {
                                              Xtemp = Xi;
                                              break;
                                       }
                               }
                       else
                          {
                               if(Ymax>=0)
                                      for(Xi=Xmax;;Xi+=0.1)
                                       {
                                              Y=3*Q[0]*Xi*Xi+2*Q[1]*Xi+Q[2];
                                              if(Y<=0)
                                              {
                                                      Xtemp = Xi-0.1;
                                                      break;
                                              }
                                       }
                               else
                                       for(Xi=Xmax;;Xi-=0.1)
                                       {
                                              Y=3*Q[0]*Xi*Xi+2*Q[1]*Xi+Q[2];
                                              if(Y>=0)
                                              {
                                                      Xtemp = Xi+0.1;
                                                      break;
                                              }
                                       }
                               }
                }
//**************************************************************************
        
//**************************************************************************      
        if(Q[0]<0&&Ys>0)               //当二次曲线开口向下,必须保证有解,所以Ys<0
        {
                if(Xmax<Xs)
                       for(Xi=Xs;;Xi+=0.1)
                       {
                               Y=3*Q[0]*Xi*Xi+2*Q[1]*Xi+Q[2];
                               if(Y<=0)
                               {
                                       Xtemp = Xi-0.1;
                                       break;
                               }
                       }
                else if(Xmax>=Xs)
                   {
                       if(Ymax>=0)
                               for(Xi=Xmax;;Xi+=0.1)
                               {
                                      Y=3*Q[0]*Xi*Xi+2*Q[1]*Xi+Q[2];
                                       if(Y<=0)
                                       {
                                              Xtemp = Xi-0.1;
                                              break;
                                       }
                               }
                       else
                               for(Xi=Xmax;;Xi-=0.1)
                               {
                                      Y=3*Q[0]*Xi*Xi+2*Q[1]*Xi+Q[2];
                                       if(Y>=0)
                                       {
                                              Xtemp = Xi+0.1;
                                              break;
                                       }
                               }
                       }
        }
//**************************************************************************
//若磁导线在最左的电感之左或在最右电感的之右,将偏移值设最大
       if(Q[0]>0&&Ys>0||Q[0]<0&&Ys<0)
                Xtemp = Xmax;         //这样做就是为了测试用,具体针对中情况的算法还没想好


        
     XX =  Xtemp;      //最后得到偏移值
}

回复

使用道具 举报

该用户从未签到

6

主题

34

帖子

0

注册会员

Rank: 2

积分
98
最后登录
2015-6-6
 楼主| 发表于 2015-5-11 23:46:09 | 显示全部楼层
大家觉得咋样呢
回复 支持 反对

使用道具 举报

该用户从未签到

6

主题

34

帖子

0

注册会员

Rank: 2

积分
98
最后登录
2015-6-6
 楼主| 发表于 2015-5-12 00:23:00 | 显示全部楼层
大家觉得如何,自顶
回复 支持 反对

使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6020
    最后登录
    2020-9-28
    发表于 2015-5-13 14:58:08 | 显示全部楼层
    非常感谢你的经验分享!
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-20 12:16 , Processed in 0.089388 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表