Browse Source

add mpc program from fanya

zhangjia 3 years ago
parent
commit
c206cdb9e9

+ 70 - 0
src/decition/mpc-linear/ADC_project_config.xml

@@ -0,0 +1,70 @@
+<xml>
+	<group name="pathConfig">
+		<module name="straight_x" value="2.0" />
+	<module name="straight_y" value="2.0" />
+	<module name="straight_vel" value="0" />
+	<module name="straight_phi" value="100" />
+	<module name="straight_a" value="0.2" />
+	             <module name="straight_delta" value="260" />
+	<module name="curve_large_x" value="3.35" />
+	<module name="curve_large_y" value="3.35" />
+	<module name="curve_large_vel" value="0" />
+	<module name="curve_large_phi" value="35" />
+	<module name="curve_large_a" value="0.2" />
+                <module name="curve_large_delta" value="100" />
+	<module name="curve_small_x" value="2.9" />
+	<module name="curve_small_y" value="2.9" />
+	<module name="curve_small_vel" value="0" />
+	<module name="curve_small_phi" value="35" />
+	<module name="curve_small_a" value="0.2" />
+                  <module name="curve_small_delta" value="110" />
+	<module name="Reversing_x" value="20" />
+	<module name="Reversing_y" value="20" />
+	<module name="Reversing_vel" value="0" />
+	<module name="Reversing_phi" value="70" />
+	<module name="Reversing_a" value="0.2" />
+	<module name="Reversing_delta" value="95" />
+	<module name="lowspeed_straight_x" value="15" />
+	<module name="lowspeed_straight_y" value="15" />
+	<module name="lowspeed_straight_vel" value="0" />
+	<module name="lowspeed_straight_phi" value="100" />
+	<module name="lowspeed_straight_a"  value="0.2" />
+	             <module name="lowspeed_straight_delta" value="140" />
+	<module name="lowspeed_curve_x" value="20" />
+	<module name="lowspeed_curve_y" value="20" />
+	<module name="lowspeed_curve_vel" value="0" />
+	<module name="lowspeed_curve_phi" value="70" />
+	<module name="lowspeed_curve_a" value="0.2" />
+                <module name="lowspeed_curve_delta" value="95" />
+	<module name="wheel_base" value="2.65" />			
+	</group>	
+	
+	<group name="libs">
+	<module name="modulecomm.pro" value="src/common/modulecomm" />
+	<module name="xmlparam.pro" value="src/common/xmlparam" />
+	</group>
+	
+	<group name="driver">
+	<module name="driver_lidar_rs16.pro" value="src/driver/driver_lidar_rs16" />
+	<module name="driver_can_kvaser" value="src/driver/driver_can_kvaser" />
+	<module name="driver_can_vci" value="src/dirver/driver_can_vic"/>
+	</group>
+
+	<group name="controller" >
+
+	</group>
+
+	<group name="decision" >
+
+	</group>
+
+	<group name="detection" >
+
+	</group>
+
+	<group name="tools" >
+
+	</group>
+
+
+</xml>

+ 391 - 0
src/decition/mpc-linear/dcs.cpp

@@ -0,0 +1,391 @@
+#include "dcs/inc/dcs.h"
+#include "bus/inc/bus_manager.h"
+#include "cmp/inc/cmp.h"
+#include "windows.h"
+#include "dcs/inc/dcs_angle_mpc.h"
+#include <QApplication>
+#include <QSettings>
+#include "dcs/inc/mpc.h"
+#include <QDomDocument>
+#include <vector>
+
+
+
+Dcs::Dcs(QObject *parent):QObject(parent)
+{
+    m_thread=new QThread;//创建线程
+
+    moveToThread(m_thread);
+
+    m_thread->start();//线程开启
+}
+
+Dcs::~Dcs()
+{
+    //进程退出
+    m_thread->quit();
+    m_thread->wait();
+    delete m_thread;
+}
+
+void Dcs::Init(Manager* manager,Cmp *cmp)
+{
+    //指针初始化
+    m_cmp = cmp;
+    m_manager = manager;
+    m_datapool = manager->GetDataPool();
+    m_robotBasic = manager->GetRobotBasic();
+    read_xml();
+}
+
+void Dcs::ThreadStart()
+{    
+
+
+
+    if(!m_callFunctionTimer) m_callFunctionTimer = new QTimer(this);
+    if(!m_GetDataForPoolTimer) m_GetDataForPoolTimer = new QTimer(this);
+
+    if(m_callFunctionTimer->isActive())
+    {
+        disconnect(m_callFunctionTimer,SIGNAL(timeout()),this,SLOT(CallFunction()));//定时器调用控制方法
+        m_callFunctionTimer->stop();
+    }
+    if(m_GetDataForPoolTimer->isActive())
+    {
+        disconnect(m_GetDataForPoolTimer,SIGNAL(timeout()),this,SLOT(GetDataForPool()));
+        m_GetDataForPoolTimer->stop();
+    }
+
+    m_callFunctionTimer->setInterval(20) ;
+    QObject::connect(m_callFunctionTimer,SIGNAL(timeout()),this,SLOT(CallFunction()));//定时器调用控制方法
+    m_callFunctionTimer->start();
+
+
+
+
+    connect(m_thread,&QThread::finished,m_callFunctionTimer,&QTimer::deleteLater);
+    connect(m_thread,&QThread::finished,m_GetDataForPoolTimer,&QTimer::deleteLater);
+    connect(m_thread,&QThread::finished,m_angControl,&QThread::deleteLater);
+
+
+
+
+
+}
+
+
+
+
+void Dcs::read_xml()
+{
+    QString proConf_file_path ="D:/3-User/mfj/ZQY0305/ZQY04220312/build-SteerTest_PRO-Desktop_Qt_5_6_2_MinGW_32bit-Debug/ADC_project_config.xml";//./SteerTest_PRO/conf_dcs/ADC_project_config.xml";
+
+    GetConfigParam(&mvtask_param_list, proConf_file_path);
+
+    for(int i=0;i<mvtask_param_list.size();i++)
+    {   //直路参数
+        if(mvtask_param_list[i].mmodule_name=="straight_x")
+        {
+            QString para_straight_x=mvtask_param_list[i].mmodule_dir;
+            mpc_para[0]=atof(para_straight_x.toLatin1().data());
+            qDebug()<<"straight_cte"<<mpc_para[0];
+        }else if(mvtask_param_list[i].mmodule_name=="straight_y")
+        {
+            QString para_straight_y=mvtask_param_list[i].mmodule_dir;
+            mpc_para[1]=atof(para_straight_y.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="straight_vel")
+        {
+            QString para_straight_vel=mvtask_param_list[i].mmodule_dir;
+            mpc_para[2]=atof(para_straight_vel.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="straight_phi")
+        {
+            QString para_straight_phi=mvtask_param_list[i].mmodule_dir;
+            mpc_para[3]=atof(para_straight_phi.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="straight_a")
+        {
+            QString para_straight_a=mvtask_param_list[i].mmodule_dir;
+            mpc_para[4]=atof(para_straight_a.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="straight_delta")
+        {
+            QString para_straight_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[5]=atof(para_straight_delta.toLatin1().data());
+        }//急弯参数
+        else if(mvtask_param_list[i].mmodule_name=="curve_large_x")
+        {
+            QString para_curve_large_x=mvtask_param_list[i].mmodule_dir;
+            mpc_para[6]=atof(para_curve_large_x.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_large_y")
+        {
+            QString para_curve_large_y=mvtask_param_list[i].mmodule_dir;
+            mpc_para[7]=atof(para_curve_large_y.toLatin1().data());
+            qDebug()<<"curve_cte"<<mpc_para[7];
+        }else if(mvtask_param_list[i].mmodule_name=="curve_large_vel")
+        {
+            QString para_curve_large_vel=mvtask_param_list[i].mmodule_dir;
+            mpc_para[8]=atof(para_curve_large_vel.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_large_phi")
+        {
+            QString para_curve_large_phi=mvtask_param_list[i].mmodule_dir;
+            mpc_para[9]=atof(para_curve_large_phi.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_large_a")
+        {
+            QString para_curve_large_a=mvtask_param_list[i].mmodule_dir;
+            mpc_para[10]=atof(para_curve_large_a.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_large_delta")
+        {
+            QString para_curve_large_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[11]=atof(para_curve_large_delta.toLatin1().data());
+        }//平弯参数
+        else if(mvtask_param_list[i].mmodule_name=="curve_small_x")
+        {
+            QString para_curve_small_x=mvtask_param_list[i].mmodule_dir;
+            mpc_para[12]=atof(para_curve_small_x.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_small_y")
+        {
+            QString para_curve_small_y=mvtask_param_list[i].mmodule_dir;
+            mpc_para[13]=atof(para_curve_small_y.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_small_vel")
+        {
+            QString para_curve_small_vel=mvtask_param_list[i].mmodule_dir;
+            mpc_para[14]=atof(para_curve_small_vel.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_small_phi")
+        {
+            QString para_curve_small_phi=mvtask_param_list[i].mmodule_dir;
+            mpc_para[15]=atof(para_curve_small_phi.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_small_a")
+        {
+            QString para_curve_small_a=mvtask_param_list[i].mmodule_dir;
+            mpc_para[16]=atof(para_curve_small_a.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="curve_small_delta")
+        {
+            QString para_curve_small_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[17]=atof(para_curve_small_delta.toLatin1().data());
+        }//倒车参数
+        else if(mvtask_param_list[i].mmodule_name=="Reversing_x")
+        {
+            QString para_Reversing_x=mvtask_param_list[i].mmodule_dir;
+            mpc_para[18]=atof(para_Reversing_x.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="Reversing_y")
+        {
+            QString para_Reversing_y=mvtask_param_list[i].mmodule_dir;
+            mpc_para[19]=atof(para_Reversing_y.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="Reversing_vel")
+        {
+            QString para_Reversing_vel=mvtask_param_list[i].mmodule_dir;
+            mpc_para[20]=atof(para_Reversing_vel.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="Reversing_phi")
+        {
+            QString para_Reversing_phi=mvtask_param_list[i].mmodule_dir;
+            mpc_para[21]=atof(para_Reversing_phi.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="Reversing_a")
+        {
+            QString para_Reversing_a=mvtask_param_list[i].mmodule_dir;
+            mpc_para[22]=atof(para_Reversing_a.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="Reversing_delta")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[23]=atof(para_Reversing_delta.toLatin1().data());
+        }//低速直路
+        else if(mvtask_param_list[i].mmodule_name=="lowspeed_straight_x")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[24]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_straight_y")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[25]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_straight_vel")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[26]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_straight_phi")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[27]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_straight_a")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[28]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_straight_delta")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[29]=atof(para_Reversing_delta.toLatin1().data());
+        }//低速弯道
+        else if(mvtask_param_list[i].mmodule_name=="lowspeed_curve_x")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[30]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_curve_y")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[31]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_curve_vel")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[32]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_curve_phi")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[33]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_curve_a")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[34]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="lowspeed_curve_delta")
+        {
+            QString para_Reversing_delta=mvtask_param_list[i].mmodule_dir;
+            mpc_para[35]=atof(para_Reversing_delta.toLatin1().data());
+        }else if(mvtask_param_list[i].mmodule_name=="wheel_base")
+        {
+            QString para_wheel_base=mvtask_param_list[i].mmodule_dir;
+            mpc_para[36]=atof(para_wheel_base.toLatin1().data());
+        }
+    }
+
+}
+
+
+
+
+void Dcs::CallFunction()
+{
+    GetDataForPool();//读取数据池数据
+    qDebug()<<"controlway:"<<controlWay;
+
+
+
+    m_datapool->GetValue(VehicleGear,DataPool::VEHSFTPSNG);
+
+
+    if(controlWay==3)
+    {
+
+        vector<double> control_cmd(2);//输出控制量
+        vector<double> cur_states;
+        if(cur_states.size()>0){
+            cur_states.clear();
+        }
+
+        cur_states.push_back( g_rtkData.gLng);//车辆坐标系X
+        cur_states.push_back( g_rtkData.gLat);//车辆坐标系Y
+        cur_states.push_back(angleControlParas.gVm/3.6);//车速,m/s
+        cur_states.push_back( strAng); //车辆坐标系下的航向角
+        vector<vector<double>> ref_track;//参考轨迹
+      // ref_track=ref_traj;
+
+        if(ref_traj.size()==0)
+        {
+            qDebug()<<"参考路径异常";
+            return;
+        }
+
+        for(int i=0;i<ref_traj.size()-1;i++)
+        {
+            qDebug() << ref_traj.size()-1;
+            vector<double> ref_track_line;
+            ref_track_line.push_back(ref_traj.at(i).x);
+            ref_track_line.push_back(ref_traj.at(i).y);
+            ref_track_line.push_back(ref_traj.at(i).yaw);
+            ref_track_line.push_back(qAtan(-mpc_para[36]*ref_traj.at(i).k));
+            ref_track.push_back(ref_track_line);
+        }
+        qDebug() << "out";
+        if(ref_track.size()==0)
+        {
+            return;
+        }
+        qDebug() << "reFSize" <<ref_traj.size();
+        int gear_flag=1;
+        if( VehicleGear == 2)
+        {
+            gear_flag=-1;
+        }
+        vector<double> mpc_xy(50);//可去除
+
+        qDebug()<<"参考前轮转角:"<<ref_track[0][3]<<ref_traj.at(0).k;
+
+        mpc_solve(control_cmd,cur_states,ref_track,mpc_xy,gear_flag,mpc_para);
+         CalSteerAngle=15.97*control_cmd[1]/M_PI*180;
+     //   CalSteerAngle=(-0.0011*pow(control_cmd[1]/M_PI*180,3) + 0.0052*pow(control_cmd[1]/M_PI*180,2) + 16.476*control_cmd[1]/M_PI*180 + 1.69);
+        qDebug()<<"中汽研控制方向盘转角__________________________"<<CalSteerAngle;
+    }
+
+
+
+
+
+    if(CalSteerAngle > 500) CalSteerAngle = 500;
+    if(CalSteerAngle <-500) CalSteerAngle =-500;
+
+
+    if(VehicleGear == 2)
+    {
+        CalSteerAngle = CalSteerAngle;
+    }
+
+    m_datapool->SetValue(DataPool::DESIRESTEERANGLE,CalSteerAngle);
+    m_datapool->SetValue(DataPool::DESIRESTEERSPD,400);
+    time2dcs.angle = CalSteerAngle;
+    m_datapool->SetValue(DataPool::MODUEL_RUNTIME,QVariant::fromValue(time2dcs));
+
+    m_robotBasic->OnSteerCtrl(CalSteerAngle,720,0,0);
+
+
+
+}
+
+void Dcs::GetDataForPool()
+{
+    HorizontalDisired target;
+    SpecialCurve curveinfo;
+    StrAngSpeed steerreq;
+    ControlSet Controlpar;
+    unsigned long timeStamp2;
+    Controlpar =  m_datapool->GetValue(DataPool::CONTROLSET).value<ControlSet>();
+    target = m_datapool->GetValue(DataPool::HORIZONTALDISIRED).value<HorizontalDisired>();
+    curveinfo = m_datapool->GetValue(DataPool::SPECIALCURVE).value<SpecialCurve>();
+    QVariant inb = m_datapool->GetValue(DataPool::RTKDATA,0);
+    double rtkgvm = inb.value<RtkData>().gSpd;
+
+
+
+        m_datapool->GetValue(angleControlParas.gVm,DataPool::VEHSPD,&timeStamp2);//车端速度
+
+
+    g_rtkData = m_datapool->GetValue(DataPool::RTKDATA).value<RtkData>();
+    g_keyPoint = m_datapool->GetValue(DataPool::KEYPOINTINFO).value<KeyPointInfo>();
+    g_keyPointref = m_datapool->GetValue(DataPool::KEYPOINTINFOREF).value<KeyPointInfo>();
+    g_globalUTMList = m_datapool->GetValue(DataPool::UTMROUT, 0).value<QList<UTMInfo>>();
+    g_tempRtk = m_datapool->GetValue(DataPool::TEMPRTKDATA).value<TempRTKData>();
+    g_speed=m_datapool->GetValue(DataPool::VEHSPD).value<double>();
+
+    strAng=m_datapool->GetValue(DataPool::VEHSTRANG).value<double>();
+
+
+
+
+
+
+
+    m_datapool->GetValue(controlWay,DataPool::CONTRALWAY);
+
+
+     if(controlWay==3)
+     {
+
+         ref_traj = m_datapool->GetValue(DataPool::REFTRAIL, 0).value<std::vector<UTMInfo>>();
+
+     }
+     int a =0;
+    //MPCcontrolInput();
+}
+
+
+
+
+
+void Dcs::SetValue(int id,const MpcRetPoint &ret)
+{
+    m_datapool->SetValue(id,QVariant::fromValue(ret));
+}

+ 131 - 0
src/decition/mpc-linear/dcs.h

@@ -0,0 +1,131 @@
+#ifndef DCS_H
+#define DCS_H
+
+#include <QObject>
+#include <QThread>
+#include <QTimer>
+#include <QTime>
+#include <QList>
+#include <sys/time.h>
+#include <QVector>
+
+#include "dcs/inc/dcs_angle_control.h"
+#include "dcs/inc/dcs_speed_control.h"
+#include "include/robotbasic_api.h"
+#include "cmp/inc/cmp_PCANBasic.h"
+#include "cmp/inc/cmp_canwrite.h"
+#include <bus/inc/bus_globaldef.h>
+#include "include/coordtrans_api.h"
+#include "dcs/inc/dcs_mpc_corecontrol.h"
+
+
+
+
+class Manager;
+class DataPool;
+class DcsAngleControl;
+class DcsSpeedControl;
+class Cmp;
+class MpcControl;
+class Dcs:public QObject
+{
+    Q_OBJECT
+public:
+    explicit Dcs(QObject *parent=Q_NULLPTR);
+    ~Dcs();
+    void Init(Manager* manager,Cmp *cmp);
+
+    void read_xml();
+
+    AngleControlPara angleControlParas;     //转向控制参数
+
+    Cmp *m_cmp;
+    std::vector<UTMInfo> ref_traj;
+
+    double CalSteerAngle=0;   //横向控制输出方向盘转角
+
+
+
+
+    RtkData g_rtkData;
+
+    KeyPointInfo g_keyPoint;
+
+    QList<UTMInfo> g_globalUTMList;
+    TempRTKData g_tempRtk;
+    double g_speed;
+    double mpc_para[50];
+
+private:
+    Manager *m_manager;
+    CanProcess *canprocess;
+    DataPool *m_datapool;
+
+    CanProcess* m_canProcess;
+    CanWrite *m_CanWrite;
+    QThread *m_thread;
+
+
+    QTimer *m_callFunctionTimer = nullptr;
+    QTimer *m_GetDataForPoolTimer = nullptr;
+
+
+
+
+    QVector<TaskParam> mvtask_param_list;
+
+private:
+    /******************************************************************************
+    *** Function Name:          ThreadStart()
+    *** Function Description:   线程启动
+    *** Inputs:                 None
+    *** Returns:                None
+    ******************************************************************************/
+    void ThreadStart();
+
+
+
+
+
+
+private:
+
+
+
+signals:
+
+
+
+private slots:
+    /******************************************************************************
+    *** Function Name:          CallFunction()
+    *** Function Description:   运动控制函数调用
+    *** Inputs:                 None
+    *** Returns:                None
+    ******************************************************************************/
+    void CallFunction();
+
+    /******************************************************************************
+    *** Function Name:          GetDataForPool
+    *** Function Description:   数据池数据获取
+    *** Inputs:                 None
+    *** Returns:                None
+    ******************************************************************************/
+    void GetDataForPool();
+
+
+
+public slots:
+
+
+    void SetValue(int id, const MpcRetPoint &ret);
+public:
+
+
+
+
+
+};
+
+
+#endif // DCS_H

+ 192 - 0
src/decition/mpc-linear/dps.h

@@ -0,0 +1,192 @@
+#ifndef DPS_H
+#define DPS_H
+
+#include <QObject>
+#include "bus/inc/bus_stdafx.h"
+#include "bus/inc/bus_datapool.h"
+#include "include/tms_api.h"
+#include "include/coordtrans_api.h"
+#include "bus/inc/bus_qtimer2.h"
+
+#define MINDISTANCE            5    //KeyPoint最小距离限制
+
+typedef struct DistanceInfo
+{
+    double dis;//两点绝对距离
+    double disx;//两点x坐标差
+    double disy;//两点y坐标差
+}DistanceInfo;
+
+
+
+
+class DataPool;
+class Manager;
+class CmsDiagnoticsApi;
+class Dps : public QObject
+{
+
+    Q_OBJECT
+public:
+    explicit Dps(Manager *manager);
+    QTimer *m_routeTimer = nullptr;   //定时循环与获取数据
+    void ThreadStart();
+
+
+    ~Dps();
+
+private:
+
+
+    /******************************************************************************
+    *** Function Name:        GetDataPoolParam
+    *** Function Description: 获取Datapool数据,入口一致
+    *** Inputs:
+    ***                       id   数据池id集合
+    ***                       lasttime 时间
+    *** Returns:              数据池数据集合
+    *** Comments:
+    ******************************************************************************/
+    QList<QVariant> GetDataPoolParam(const QList<int> &id, long lasttime);
+
+
+
+    /******************************************************************************
+    *** Function Name:        SetDataPoolParam
+    *** Function Description: 将数据放入数据池
+    *** Inputs:
+    ***                       id   数据池id
+    ***                       var 输入数据
+    *** Returns:
+    *** Comments:
+    ******************************************************************************/
+    void SetDataPoolParam(DataPool::DATAID id, QVariant var);
+
+
+
+
+
+private slots:
+
+
+private:
+    Manager *m_manager;
+    DataPool *m_datapool;
+    QThread *m_thread;
+    Tms *m_tms;
+
+    Coordtrans m_gpsCoorTrans;
+
+
+
+
+signals:
+
+
+public slots:
+
+
+
+public slots:
+
+private:
+
+
+
+
+
+    /*////////////////////////////////////////////////////////////////////////////////////*/
+private slots:
+
+
+
+private:
+
+
+    /******************************************************************************
+    *** Function Name:        DistanceCalculate
+    *** Function Description: 计算两位置点间的间距
+    *** Inputs:
+    ***                       CurrentLongitude--当前点经度
+    ***                       CurrentLatitude --当前点纬度
+    ***                       TargetLongitude --目标点经度
+    ***                       TargetLatitude  --目标点纬度
+
+    *** Returns:              当前点与目标点间距
+    ******************************************************************************/
+    void DistanceCalculate(double CurrentLongitude,double CurrentLatitude,double TargetLongitude,double TargetLatitude,DistanceInfo &returnDis);
+
+    /******************************************************************************
+    *** Function Name:        GetUsualPointKey
+    *** Function Description: 计算离当前点最近的路径点
+    *** Inputs:
+    ***                       GpsList--路径GPS点
+    ***                       CurrentLongitude --当前点经度
+    ***                       CurrentLatitude  --当前点纬度
+    ***                       CurrentHead      --当前航向角
+    ***                       VehicleSpeed     --车速
+    ***                       KeyPointLast     --上一关键点信息
+
+    *** Returns:              路径点序号,规范路径点ID,路径类型
+    ******************************************************************************/
+    void GetUsualPointKey(const QList<GPSInfo> &GpsList,double CurrentLongitude,double CurrentLatitude,double CurrentHead,double VehicleSpeed,const KeyPointInfo &KeyPointLast,KeyPointInfo &retKeyPoint);
+    /******************************************************************************
+    *** Function Name:        GetHead
+    *** Function Description: 计算两点连线与正北向夹角
+    *** Inputs:
+    ***                       ALongitude --A点经度
+    ***                       ALatitude  --A点纬度
+    ***                       BLongitude --B点经度
+    ***                       BLatitude  --B点纬度
+
+
+    *** Returns:              AB两点连线与正北向夹角
+    ******************************************************************************/
+    double GetHead(double ALongitude,double ALatitude,double BLongitude,double BLatitude);
+
+
+    /******************************************************************************
+    *** Function Name:        LateralPlan();
+    *** Function Description: 输出关键点、横向偏差、航向偏差
+    *** Inputs:
+    ***                       地图和当前位置点
+    *** Outputs:              输出参考轨迹点的x,y和斜率
+    ******************************************************************************/
+    //局部路径实时计算
+    void LateralPlan();
+    /******************************************************************************
+    *** Function Name:        GetPreDistance
+    *** Function Description: 计算预瞄距离
+    *** Inputs:
+    ***                       vehicleSpeed  --当前车速
+    ***                       curve      --最大曲率
+    ***                       type       --类型,1=计算第一预瞄点,2=计算第二预瞄点
+
+
+    *** Returns:              预瞄距离,预瞄点数
+    ******************************************************************************/
+
+
+
+
+
+
+    QList<GPSInfo> dpsGlobalPathList; //全局路径
+    KeyPointInfo dpsKeyPoint;         //关键点
+
+     HorizontalDisired angleExpect; //横向期望
+
+
+signals:
+
+
+
+
+
+};
+
+
+
+
+
+#endif // DPS_H

+ 340 - 0
src/decition/mpc-linear/dps_routeplan.cpp

@@ -0,0 +1,340 @@
+#include "dps/inc/dps.h"
+#include "qmath.h"
+#include "bus/inc/bus_manager.h"
+#include <vector>
+
+
+
+
+
+
+
+void Dps::DistanceCalculate(double currentLongitude, double currentLatitude, double targetLongitude, double targetLatitude,DistanceInfo &returnDis)
+{
+    DistanceInfo distance;
+
+    distance.disx=qAbs(currentLongitude-targetLongitude)*qCos(targetLatitude/180*M_PI)*111700;
+    distance.disy=qAbs(currentLatitude-targetLatitude)*111700;
+    distance.dis=qSqrt(distance.disx*distance.disx+distance.disy*distance.disy);//当前点与临时点坐标差
+    returnDis = distance;
+}
+
+
+
+double Dps::GetHead(double aLongitude,double aLatitude,double bLongitude,double bLatitude)
+{
+    double dx;
+    double dy;
+    double angle;
+    dx = (bLongitude - aLongitude) * 111700 * cos(aLatitude / 180 * M_PI);//当前点与最近点经度距离
+    dy = (bLatitude - aLatitude) * 111700;//当前点与最近点纬度距离
+
+    if(dx>-0.0001&&dx<0.0001)
+    {
+        if(dy>0)
+            angle=0;
+        else
+            angle=180;
+    }
+    else
+    {
+        angle = qAtan((double)dy / dx) / M_PI * 180;//当前点与最近点两点连线与正北的夹角
+        if (dx > 0) angle = 90 - angle;
+        else angle = 270 - angle;
+    }
+    return angle;
+}
+
+void Dps::GetUsualPointKey(const QList<GPSInfo> &gpsList,double currentLongitude,double currentLatitude,double currentHead,double vehicleSpeed,const KeyPointInfo &keyPointLast,KeyPointInfo &retKeyPoint)
+{
+    KeyPointInfo keyPoint;//关键点信息
+    int gpsListsize;//传入路径list大小
+    GPSInfo memoryGps;//临时GPS信息
+    double memoryLongitude;//临时经度
+    double memoryLatitude;//临时纬度
+    double memoryHead;//临时航向角
+    double disHead;//航向差
+    int preNum;//检索路径点个数
+    DistanceInfo dis;//两点间距
+    double currentGear;//当前档位
+    int desiredGear;//期望档位
+    double minDistance = MINDISTANCE;//寻找keyPoint的最小值
+    double rtkSpd;
+    int begine;
+    double preDis;
+    keyPoint = keyPointLast;
+    begine = keyPointLast.num;
+
+    gpsListsize=gpsList.size();
+    DistanceInfo pointdistance;
+
+    DistanceCalculate(gpsList.at(9).iLongitude,gpsList.at(9).iLatitude,gpsList.at(10).iLongitude,gpsList.at(10).iLatitude,pointdistance);
+    pointdistance.dis=qAbs(pointdistance.dis);
+    //qDebug()<<"间距:"<<pointdistance.dis;
+
+    preDis =  vehicleSpeed*2*0.2;
+
+    preNum = qRound(preDis/pointdistance.dis);
+    if(preDis < 6)
+    {
+        preNum = qRound(6/pointdistance.dis);
+    }
+    if(preDis > 14)
+    {
+        preNum = qRound(14/pointdistance.dis);
+    }
+    m_datapool->GetValue(desiredGear,DataPool::DESIRESHIFT);
+    m_datapool->GetValue(currentGear,DataPool::VEHSFTPSNG);
+    QVariant ina;
+    ina = m_datapool->GetValue(DataPool::RTKDATA,0);
+    rtkSpd = ina.value<RtkData>().gSpd;
+
+    if((desiredGear==2&&currentGear==4)||(desiredGear==4&&currentGear==2))
+    {
+        preDis = 20;
+        preNum = qRound(preDis/pointdistance.dis);
+        begine =keyPointLast.num+qRound(6/pointdistance.dis);
+
+    }
+    int jLimit;
+    //qDebug()<<"preNum:"<<preNum;
+    jLimit=qMin(keyPointLast.num+preNum,gpsListsize);
+    bool pointFlag=false;
+    for (int j = begine ; j<jLimit; j++)
+    {
+        memoryGps = gpsList.at(j);
+        memoryLongitude = memoryGps.iLongitude;
+        memoryLatitude = memoryGps.iLatitude;
+
+        DistanceCalculate(currentLongitude,currentLatitude,memoryLongitude,memoryLatitude,dis);
+        if((desiredGear==2&&currentGear==4)||(desiredGear==4&&currentGear==2))
+        {
+            memoryHead=GetHead(currentLongitude,currentLatitude,memoryLongitude,memoryLatitude);//当前点到计算点连线与正北方向夹角
+        }
+        else
+        {
+            memoryHead=memoryGps.iHead;
+        }
+        disHead=qAbs(currentHead-memoryHead);
+        if(disHead>M_PI)
+            disHead=disHead-2*M_PI;
+        if(disHead<-M_PI)
+            disHead=2*M_PI+disHead;
+
+        if((desiredGear==2&&currentGear==4)||(desiredGear==4&&currentGear==2))
+        {
+            if((minDistance > dis.dis)&&((disHead>90)&&(disHead<270)))
+            {
+                minDistance = dis.dis;
+                keyPoint.num=memoryGps.num;
+                keyPoint.id=memoryGps.id;
+                keyPoint.type=memoryGps.type;
+                pointFlag = true;
+                timeCount = 0;
+                historygear=currentGear;
+            }
+        }
+        else
+        {
+            if((minDistance > dis.dis)&&((disHead<90)||(disHead>270)))
+            {
+                minDistance = dis.dis;
+                keyPoint.num=memoryGps.num;
+                keyPoint.id=memoryGps.id;
+                keyPoint.type=memoryGps.type;
+                pointFlag = true;
+                timeCount = 0;
+            }
+        }
+    }
+    if(!pointFlag)
+    {
+        if(timeCount == 0)
+        {
+            newPointtime.restart();
+        }
+        timeCount++;
+        if((vehicleSpeed > 1||rtkSpd >1) && newPointtime.elapsed() > 1000)
+        {
+            GetGlobalPointKey(gpsList,currentLongitude,currentLatitude,currentHead,keyPointLast.num,keyPoint);
+            timeCount = 0;
+        }
+        else
+        {
+            keyPoint = keyPointLast;
+        }
+    }
+    retKeyPoint = keyPoint;
+}
+
+
+
+
+
+
+void Dps::LateralPlan()//横向规划:输出关键点、横向偏差、航向偏差
+{
+    int ij;
+    double tLng;//实时经度
+    double tLat;//实时纬度
+    double tHead;//实时航向角
+    double currentHead;//实时航向角
+    SpecialCurve specialCurve;
+    double mCur;//临时曲率
+    double mLngs;
+    double mLats;
+    PrePoint prePoint;
+    int prepointcount;
+    int prepointcount2;
+    double prepointdis;
+    double prepointdis2;
+    double m_angle = 0;//航向偏差
+    double m_anglex[5];
+    double pointangle;//当前点与预瞄点连线夹角
+    double pointangle2;//当前点与关键点连线夹角
+    double near_angle;
+    double vehicleSpeed;//当前车速
+    double strAng;//当前方向盘转角-0811
+    KeyPointInfo keyPointLast;//上次计算的关键点
+    KeyPointInfo keyPointLastRef;//上次计算的关键点
+    QList<GPSInfo> pGpsList;
+    double curveatKeypoint;   //关键点附近的曲率
+    double curveatPreview;    //预瞄点1附近的曲率
+    double curveatPreview2;   //预瞄点2附近的曲率
+    double pointDisx = 0;  //横向偏差
+
+    QVariant ina;
+    ina = m_datapool->GetValue(DataPool::RTKDATA,0);
+    tLng = ina.value<RtkData>().gLng;
+    tLat = ina.value<RtkData>().gLat;
+    tHead = ina.value<RtkData>().gHead;
+    currentHead = ina.value<RtkData>().gHead;
+
+    QVariant inb;
+    inb = m_datapool->GetValue(DataPool::VEHSPD,0);
+    vehicleSpeed = inb.value<double>();
+
+    QVariant inc;
+    inc = m_datapool->GetValue(DataPool::KEYPOINTINFO,0);
+    keyPointLast = inc.value<KeyPointInfo>();
+
+    auto ind = m_datapool->GetValue(DataPool::TMS_GPS_PATH, 0);
+    auto *gpsinfo = ind.value<void*>();
+    QList<GPSInfo> *normPath = (QList<GPSInfo>*)gpsinfo;
+    if(normPath)
+    {
+        pGpsList=*normPath;
+    }
+
+    QVariant ine;//取方向盘转角值
+    ine = m_datapool->GetValue(DataPool::VEHSTRANG,0);
+    strAng = ine.value<double>();
+
+
+
+
+    GetUsualPointKey( pGpsList,tLng,tLat,tHead,vehicleSpeed,keyPointLast, dpsKeyPoint);//计算车辆位置的关键点
+
+    QVariant outa;
+    outa = QVariant::fromValue(dpsKeyPoint);
+    m_datapool->SetValue(DataPool::KEYPOINTINFO,outa);
+
+
+    pointangle2=GetHead(tLng,tLat, pGpsList.at(dpsKeyPoint.num).iLongitude, pGpsList.at(dpsKeyPoint.num).iLatitude);
+
+
+    /*计算预瞄轨迹*/
+    QList<UTMInfo> globalUTMList = m_datapool->GetValue(DataPool::UTMROUT, 0).value<QList<UTMInfo>>();
+    double cur_X,cur_Y,cur_heading;
+     m_gpsCoorTrans.LatLonToUTMXY(tLat, tLng, 50, cur_X, cur_Y);
+     cur_heading=currentHead/180*M_PI;
+     float path_length = 0.0,dx=0.0,dy=0.0;
+     std::vector<UTMInfo> ref_traj;
+    for (int i =  dpsKeyPoint.num; i < globalUTMList.size()-1; i++) {  //车辆坐标系下参考轨迹
+                UTMInfo traj;
+                double x_t,y_t,heading_t;
+                x_t = globalUTMList.at(i).x - cur_X;
+                y_t = globalUTMList.at(i).y - cur_Y;
+                traj.y= x_t * sin(M_PI*3.0/2.0+cur_heading) + y_t * cos(M_PI*3.0/2.0+cur_heading);
+                traj.x = x_t * cos(M_PI*3.0/2.0+cur_heading) - y_t * sin(M_PI*3.0/2.0+cur_heading);//rtk to rear  para广德的车要减0.9
+                traj.yaw = -(dpsGlobalPathList.at(i).iHead/180*M_PI - cur_heading);
+                if(traj.yaw < -M_PI){
+                    traj.yaw = traj.yaw + 2*M_PI;
+                }
+                if(traj.yaw > M_PI){
+                    traj.yaw = traj.yaw - 2*M_PI;
+                }
+                traj.k=dpsGlobalPathList.at(i).iCurvature;
+
+                ref_traj.push_back(traj);
+
+                if(i > 0){
+                    dx = globalUTMList.at(i).x  - globalUTMList.at(i-1).x ;
+                    dy = globalUTMList.at(i).y  - globalUTMList.at(i-1).y ;
+                    path_length += sqrt(dx*dx+dy*dy);
+                }
+                if((path_length > vehicleSpeed/3.6*2)&&(path_length >5)){
+                    break;
+                }
+    }
+
+    double dist = 0;
+    std::vector<UTMInfo> mpc_ref_traj;
+    if(mpc_ref_traj.size()>0)
+    {
+        mpc_ref_traj.clear();
+    }
+    mpc_ref_traj.push_back(ref_traj.at(0));
+    for(int i = 1;i < ref_traj.size();i++){
+                dx = ref_traj.at(i).x - ref_traj.at(i-1).x;
+                dy = ref_traj.at(i).y - ref_traj.at(i-1).y;
+                dist += sqrt(dx*dx + dy*dy);
+                if(dist > (vehicleSpeed/3.6*0.02)){
+                    mpc_ref_traj.push_back(ref_traj.at(i-1));
+                    dist =  dist - vehicleSpeed/3.6*0.02;
+                }
+                if(mpc_ref_traj.size() > 30){
+                    break;
+                }
+    }
+
+    /*将横向偏差、航向偏差、关键点、预瞄点、关注点曲率信息放入datapool*/
+    angleExpect.biaDistance=pointDisx;
+
+
+    angleExpect.biaHead=m_angle;
+
+    QVariant outb;
+    outb = QVariant::fromValue(angleExpect);
+    m_datapool->SetValue(DataPool::HORIZONTALDISIRED,outb);
+
+    prePoint.prePointCount=prepointcount;
+    prePoint.prePointDistance=prepointdis;
+    QVariant outc;
+    outc = QVariant::fromValue(prePoint);
+    m_datapool->SetValue(DataPool::PREPOINT,outc);
+
+
+
+    QVariant outg;
+    outg = QVariant::fromValue(mpc_ref_traj);
+    m_datapool->SetValue(DataPool::REFTRAIL,outg);
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 561 - 0
src/decition/mpc-linear/mpc.cpp

@@ -0,0 +1,561 @@
+#include "OsqpEigen/OsqpEigen.h"
+#include "dcs/inc/mpc.h"
+#include <Eigen/Dense>
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <string>
+#include <vector>
+#include <fstream>
+#include <cmath>
+#include <QVector>
+#include <qdebug.h>
+#include <iomanip>
+using namespace std;
+
+//==========================================================
+void DynamicModel(Eigen::Matrix<double, nx, nx>& a, Eigen::Matrix<double, nx, nu>& b, double vel, double delta, double phi, double T,double L)
+{
+
+    a <<1., 0., cos(phi) * T, -sin(phi)* T*vel,
+        0., 1., sin(phi)* T,  cos(phi)* T*vel,
+        0., 0., 1., 0,
+        0., 0., (T*tan(delta))/L, 1;
+    b <<0, 0.,
+        0, 0.,
+        T, 0.,
+        0., T*vel/(L*cos(delta)*cos(delta));
+}
+
+void InequalityConstraints(Eigen::Matrix<double, nx, 1>& xMax, Eigen::Matrix<double, nx, 1>& xMin,
+    Eigen::Matrix<double, nu, 1>& uMax, Eigen::Matrix<double, nu, 1>& uMin)
+{
+    double u0 = 0;
+
+    uMin << -5 - u0,
+        -0.2 - u0;
+    uMax << 5- u0,
+        0.2 - u0;
+
+    xMin << -OsqpEigen::INFTY, -OsqpEigen::INFTY, -OsqpEigen::INFTY, -OsqpEigen::INFTY;
+    xMax << OsqpEigen::INFTY, OsqpEigen::INFTY, OsqpEigen::INFTY, OsqpEigen::INFTY;
+}
+
+int Roadmode(vector<vector<double>>&ref_traj,int8_t gear_flag,double speed)
+{   int  roadmode,roadmode_pre;
+    double maxdelta=0;
+    static int last_mode=3;
+    if(gear_flag==-1)
+    {
+      return 4;
+    }
+
+    if(ref_traj.size()>6)
+    {
+                for(int i=0;i<6;i++)
+                {
+                    if((fabs(ref_traj[i][3])*180/PI) > maxdelta)
+                      {maxdelta=fabs(ref_traj[i][3])*180/PI;}
+                }
+    }else
+    {
+                maxdelta=0;
+    }
+
+    if (speed<=18/3.6)
+    {  //低速情形
+        if(maxdelta>0.8)
+          {roadmode=5;}//低速弯道
+        else
+          {roadmode=6;}//低速直道
+    }
+    else{
+        if(maxdelta>4.1)
+               {roadmode=1;}
+        else if((maxdelta<=4.1)&&(maxdelta>0.25))
+               {roadmode=2;}
+        else
+               {roadmode=3;}
+
+    }
+
+    if(roadmode==3)
+    {
+        if((last_mode==1)||(last_mode==2))
+        {
+            maxdelta=0;
+            for(int i=ref_traj.size()-6;i<ref_traj.size();i++)
+            {
+                if((fabs(ref_traj[i][3])*180/PI) > maxdelta)
+                  {maxdelta=fabs(ref_traj[i][3])*180/PI;}
+            }
+            if(maxdelta>4.1)
+                   {roadmode_pre=1;}
+            else if((maxdelta<=4.1)&&(maxdelta>0.25))
+                   {roadmode_pre=2;}
+            else
+                   {roadmode_pre=3;}
+
+            if(roadmode_pre==3)
+                    roadmode=3;
+            else
+                    roadmode=last_mode;
+        }
+    }
+
+    if(roadmode==6)
+    {
+        if(last_mode==5)
+        {
+            maxdelta=0;
+            for(int i=ref_traj.size()-6;i<ref_traj.size();i++)
+            {
+                if((fabs(ref_traj[i][3])*180/PI) > maxdelta)
+                  {maxdelta=fabs(ref_traj[i][3])*180/PI;}
+            }
+            if(maxdelta>0.8)
+              {roadmode_pre=5;}//低速弯道
+            else
+              {roadmode_pre=6;}//低速直道
+
+            if(roadmode_pre==6)
+                    roadmode=6;
+            else
+                    roadmode=last_mode;
+        }
+    }
+
+    last_mode=roadmode;
+    return roadmode;
+
+}
+
+
+void WeightMatrices(Eigen::DiagonalMatrix<double, nx>& Q, Eigen::DiagonalMatrix<double, nu>& R,int roadmode,double *_mpc_param,double speed)
+{
+     double speedswitch;
+     switch(roadmode)
+       {
+      case 1:
+              if (speed>30/3.6)
+              {Q.diagonal() << _mpc_param[6], _mpc_param[7], _mpc_param[8], _mpc_param[9];
+                R.diagonal() << _mpc_param[10], _mpc_param[11]; } //a delta}//x y v psi
+              else
+              {speedswitch=_mpc_param[31]*0.5-(speed*3.6-18)/(30-18)*(_mpc_param[31]*0.5-_mpc_param[7]); //20-(35-28)/12*(20-3.35)
+              Q.diagonal() << speedswitch, speedswitch, _mpc_param[8], _mpc_param[9]; //x y v psi
+              R.diagonal() << _mpc_param[10], _mpc_param[11];  }//a delta
+         break;
+      case 2:
+             if (speed>30/3.6)
+             {Q.diagonal() << _mpc_param[12], _mpc_param[13], _mpc_param[14], _mpc_param[15];
+               R.diagonal() << _mpc_param[16], _mpc_param[17]; } //a delta}//x y v psi
+             else
+             {speedswitch=_mpc_param[31]*0.5-(speed*3.6-18)/(30-18)*(_mpc_param[31]*0.5-_mpc_param[13]); //20-(40-28)/12*(20-2.9)
+             Q.diagonal() << speedswitch, speedswitch, _mpc_param[14], _mpc_param[15]; //x y v psi
+             R.diagonal() << _mpc_param[16], _mpc_param[17];  }//a delta
+        break;
+      case 3:
+             if (speed>30/3.6)
+             {Q.diagonal() << _mpc_param[0], _mpc_param[1], _mpc_param[2], _mpc_param[3];
+               R.diagonal() << _mpc_param[4], _mpc_param[5]; } //a delta}//x y v psi
+             else
+             {speedswitch=_mpc_param[25]-(speed*3.6-18)/(30-18)*(_mpc_param[25]-_mpc_param[1]); //15-(40-28)/12*13
+             Q.diagonal() << speedswitch, speedswitch, _mpc_param[2], _mpc_param[3]; //x y v psi
+             R.diagonal() << _mpc_param[4], _mpc_param[5];  }//a delta
+        break;
+      case 4:
+            Q.diagonal() << _mpc_param[18], _mpc_param[19], _mpc_param[20], _mpc_param[21]; //x y v psi
+            R.diagonal() << _mpc_param[22], _mpc_param[23];  //a delta
+       break;
+     case  5:
+            Q.diagonal() << _mpc_param[30], _mpc_param[31], _mpc_param[32], _mpc_param[33]; //x y v psi
+            R.diagonal() << _mpc_param[34], _mpc_param[35];  //a delta
+       break;
+     case  6:
+            Q.diagonal() << _mpc_param[24], _mpc_param[25], _mpc_param[26], _mpc_param[27]; //x y v psi
+            R.diagonal() << _mpc_param[28], _mpc_param[29];  //a delta
+       break;
+      default:
+             Q.diagonal() << _mpc_param[0], _mpc_param[1],_mpc_param[2], _mpc_param[3]; //x y v psi
+             R.diagonal() << _mpc_param[4], _mpc_param[5];  //a delta
+         break;
+        }
+}
+
+void MPC2QPHessian(const Eigen::DiagonalMatrix<double, nx>& Q, const Eigen::DiagonalMatrix<double, nu>& R,
+    Eigen::SparseMatrix<double>& hessianMatrix)
+{
+    hessianMatrix.resize(nx * (mpcWindow + 1.) + nu * mpcWindow, nx * (mpcWindow + 1.) + nu * mpcWindow);
+
+
+    for (int i = 0; i < nx * (mpcWindow + 1) + nu * mpcWindow; i++) {
+        if (i < nx * (mpcWindow + 1)) {
+            int posQ = i % nx;
+            float value = Q.diagonal()[posQ];
+            if (value != 0)
+                hessianMatrix.insert(i, i) = value;
+        }
+        else {
+            int posR = i % nu;
+            float value = R.diagonal()[posR];
+            if (value != 0)
+                hessianMatrix.insert(i, i) = value;
+        }
+    }
+}
+
+void MPC2QPGradient(const Eigen::DiagonalMatrix<double, nx> &Q, const Eigen::Matrix<double, nx, mpcWindow+1> &xRef, Eigen::VectorXd &gradient)
+{
+    gradient = Eigen::VectorXd::Zero(nx * (mpcWindow + 1) + nu * mpcWindow, 1);
+
+}
+void MPC2QPConstraintMatrix(const Eigen::Matrix<double, nx, nx>& dynamicMatrix, const Eigen::Matrix<double, nx, nu>& controlMatrix,
+    Eigen::SparseMatrix<double>& constraintMatrix)
+{
+    constraintMatrix.resize(nx * (mpcWindow + 1.) + nx * (mpcWindow + 1) + nu * mpcWindow, nx * (mpcWindow + 1.) + nu * mpcWindow);
+
+
+    for (int i = 0; i < nx * (mpcWindow + 1); i++) {
+        constraintMatrix.insert(i, i) = -1;
+    }
+
+    for (int i = 0; i < mpcWindow; i++)
+        for (int j = 0; j < nx; j++)
+            for (int k = 0; k < nx; k++) {
+                float value = dynamicMatrix(j, k);
+                if (value != 0) {
+                    constraintMatrix.insert(nx * (i + 1) + j, nx * i + k) = value;
+                }
+            }
+
+    for (int i = 0; i < mpcWindow; i++)
+        for (int j = 0; j < nx; j++)
+            for (int k = 0; k < nu; k++) {
+                float value = controlMatrix(j, k);
+                if (value != 0) {
+                    constraintMatrix.insert(nx * (i + 1) + j, nu * i + k + nx * (mpcWindow + 1)) = value;
+                }
+            }
+
+    for (int i = 0; i < nx * (mpcWindow + 1) + nu * mpcWindow; i++) {
+        constraintMatrix.insert(i + (mpcWindow + 1) * nx, i) = 1;
+    }
+}
+
+void MPC2QPConstraintVectors(const Eigen::Matrix<double, nx, 1>& xMax, const Eigen::Matrix<double, nx, 1>& xMin,
+    const Eigen::Matrix<double, nu, 1>& uMax, const Eigen::Matrix<double, nu, 1>& uMin,
+    const Eigen::Matrix<double, nx, 1>& x0,
+    Eigen::VectorXd& lowerBound, Eigen::VectorXd& upperBound)
+{
+
+    Eigen::VectorXd lowerInequality = Eigen::MatrixXd::Zero(nx * (mpcWindow + 1.) + nu * mpcWindow, 1);
+    Eigen::VectorXd upperInequality = Eigen::MatrixXd::Zero(nx * (mpcWindow + 1.) + nu * mpcWindow, 1);
+    for (int i = 0; i < mpcWindow + 1; i++) {
+        lowerInequality.block(nx * i, 0, nx, 1) = xMin;
+        upperInequality.block(nx * i, 0, nx, 1) = xMax;
+    }
+    for (int i = 0; i < mpcWindow; i++) {
+        lowerInequality.block(nu * i + nx * (mpcWindow + 1), 0, nu, 1) = uMin;
+        upperInequality.block(nu * i + nx * (mpcWindow + 1), 0, nu, 1) = uMax;
+    }
+
+
+    Eigen::VectorXd lowerEquality = Eigen::MatrixXd::Zero(nx * (mpcWindow + 1), 1);
+    Eigen::VectorXd upperEquality;
+    lowerEquality.block(0, 0, nx, 1) = -x0;
+    upperEquality = lowerEquality;
+    lowerEquality = lowerEquality;
+
+
+    lowerBound = Eigen::MatrixXd::Zero(2 * nx * (mpcWindow + 1) + nu * mpcWindow, 1);
+    lowerBound << lowerEquality,
+        lowerInequality;
+
+    upperBound = Eigen::MatrixXd::Zero(2 * nx * (mpcWindow + 1) + nu * mpcWindow, 1);
+    upperBound << upperEquality,
+        upperInequality;
+}
+
+
+void UpdateConstraintVectors(const Eigen::Matrix<double, nx, 1>& x0,
+    Eigen::VectorXd& lowerBound, Eigen::VectorXd& upperBound)
+{
+    lowerBound.block(0, 0, nx, 1) = -x0;
+    upperBound.block(0, 0, nx, 1) = -x0;
+}
+
+
+double getErrorNorm(const Eigen::Matrix<double, nx, 1>& x,
+    const Eigen::Matrix<double, nx, 1>& xRef)
+{
+
+    Eigen::Matrix<double, nx, 1> error = x - xRef;
+
+
+    return error.norm();
+}
+/***************************************************************************************************
+***Function Name:               mpc_solve
+***Function description:        mpc求解器
+***Inputs:
+***
+***                             vector<double> &states:             输入变量,states为车体坐标系下车的x(单位m),y(单位m),v(单位m/s),phi(单位rad),其中x,y,phi都为0
+***                             vector<vector<double>> &ref_traj:   输入变量,存的为车体坐标系下,参考轨迹每个点的x(ref_traj[i][0],单位m),y(ref_traj[i][1],单位m),phi(ref_traj[i][2],单位rad),delta(参考的前轮转角phi(ref_traj[i][3]),单位rad)
+***                             int8_t gear_flag:                   档位标志,D:1,R:-1
+***                             double *_mpc_param:                 mpc的参数,分别为高速直道参数,高速小曲率弯道参数,高速大曲率弯道参数,倒车参数,低速弯道参数,低速直道参数,轴距。详见WeightMatrices函数
+***Outputs:
+***                             vector<double> &control_cmd:        输出的控制指令,control_cmd[1]为车前轮转角,单位rad
+***                             vector<double> &mpc_xy:             输出的用于显示的预测轨迹,可以不用为其赋值,目的为了观测
+*****************************************************************************************************/
+__attribute__((force_align_arg_pointer)) bool mpc_solve(vector<double> &control_cmd, vector<double> &states, vector<vector<double>> &ref_traj,vector<double> &mpc_xy,int8_t gear_flag,double *_mpc_param){
+    //状态量是x,y,v,phi
+    static int outinit=0;
+    double vel = 0.01;
+    double delta = 0.01;
+    double psi;
+    double T = 0.02;
+    double L = _mpc_param[36];
+
+    Eigen::Matrix<double, nx, nx> a;
+    Eigen::Matrix<double, nx, nu> b;
+
+    Eigen::Matrix<double, nx, 1> xMax;
+    Eigen::Matrix<double, nx, 1> xMin;
+
+    Eigen::Matrix<double, nu, 1> uMax;
+    Eigen::Matrix<double, nu, 1> uMin;
+
+    Eigen::DiagonalMatrix<double, nx> Q;
+    Eigen::DiagonalMatrix<double, nu> R;
+
+
+    Eigen::Matrix<double, nx, 1> x0;
+    Eigen::Matrix<double, nx, mpcWindow+1> xRef;  //构造4列的阵
+    Eigen::SparseMatrix<double> hessian;
+    Eigen::VectorXd gradient;
+    Eigen::SparseMatrix<double> linearMatrix;
+    Eigen::VectorXd lowerBound;
+    Eigen::VectorXd upperBound;
+
+
+    int Roadmodecurrent=Roadmode(ref_traj,gear_flag,states[2]);
+    for (int i = 0; i < mpcWindow+1; i++)
+    {
+        xRef(0,i)=0;
+        xRef(1,i)=0;
+        xRef(2,i)=0;
+        xRef(3,i)=0;
+    }
+    vel=gear_flag*states[2];
+    psi=0;
+    delta=gear_flag*ref_traj[0][3];
+
+    x0 << 0-ref_traj[0][0], 0-ref_traj[0][1], 0, 0-ref_traj[0][2];//这里改过了,states[0/1]是大地坐标系减过初始值的
+
+    DynamicModel(a, b, vel, delta, psi, T,L);
+    InequalityConstraints(xMax, xMin, uMax, uMin);
+    WeightMatrices(Q, R, Roadmodecurrent,_mpc_param,states[2]);//采用参考轨迹的下2个点来决定模式
+
+
+    MPC2QPHessian(Q, R, hessian);
+    MPC2QPGradient(Q, xRef, gradient);
+    MPC2QPConstraintMatrix(a, b, linearMatrix);
+    MPC2QPConstraintVectors(xMax, xMin, uMax, uMin, x0, lowerBound, upperBound);
+
+    OsqpEigen::Solver solver;
+    solver.settings()->setWarmStart(true);
+
+
+    solver.data()->setNumberOfVariables(nx * (mpcWindow + 1) + nu * mpcWindow);
+    solver.data()->setNumberOfConstraints(2 * nx * (mpcWindow + 1) + nu * mpcWindow);
+
+    if (!solver.data()->setGradient(gradient)) return 1;
+    if (!solver.data()->setHessianMatrix(hessian)) return 1;
+    if (!solver.data()->setLinearConstraintsMatrix(linearMatrix)) return 1;
+    if (!solver.data()->setLowerBound(lowerBound)) return 1;
+    if (!solver.data()->setUpperBound(upperBound)) return 1;
+
+
+    if (!solver.initSolver()) return 1;
+
+    Eigen::VectorXd ctr;
+    Eigen::VectorXd QPSolution;
+    Eigen::VectorXd state_osqp;
+    if (!solver.solve()) return 1;
+    QPSolution = solver.getSolution();
+    ctr = QPSolution.block(nx * (mpcWindow + 1), 0, nu*mpcWindow, 1);
+    state_osqp = QPSolution.block(0, 0, nx * (mpcWindow + 1), 1);
+
+   //输出处理方式1,最终输出进行拟合
+    int fitting_num=20;//存储前十次的输出
+    int fitting_numgs=10;//存储前十次的输出
+    int fitting_order=3;//拟合曲线的项数(三阶曲线值是四,二阶是三)
+    static double delta_y[20];//存储前num次的输出值,这里是存计算值还是输出值还有待考虑
+    static double delta_x[20];//x轴值(数字编号)
+    static double delta_ygs[10];//存储前num次的输出值,这里是存计算值还是输出值还有待考虑
+    static double delta_xgs[10];//x轴值(数字编号)
+    double poly_result[10];//返回拟合多项式系数,由低到高,poly_result[0]常数项
+    double fitting_effect[3];//dt[0]返回拟合多项式与各数据点误差的平方和;dt[1]返回拟合多
+                             //项式与各数据点的误差绝对值之和;dt[2]返回拟合多项式与各数据
+                             //点误差绝对值的最大值
+    outinit=outinit+1;
+
+    delta_x[0]=1;                 //给x,y循环赋值
+    for (int i=1; i<fitting_num; ++i)
+        { delta_x[i]=i+1;         //x赋值自然数1,2,3....
+          delta_y[i-1]=delta_y[i];//依次更新之前的y值
+        }
+    delta_y[fitting_num-1]=ctr[1]+gear_flag*ref_traj[0][3];//更新最后的y值(本次的计算值)
+       for (int i=0;i<fitting_numgs;++i)
+          {   delta_xgs[i]=delta_x[i+fitting_num-fitting_numgs] ;
+              delta_ygs[i]=delta_y[i+fitting_num-fitting_numgs] ;
+            }
+    if((Roadmodecurrent==5)||(Roadmodecurrent==6))
+      {
+        PolyFit(delta_x, delta_y, fitting_num, poly_result, fitting_order, fitting_effect);//拟合函数得到结果
+        control_cmd[0] = ctr[1]/PI*180;//显示mpc计算的delta
+        control_cmd[1] = poly_result[0]+poly_result[1]*(20-10.5)
+                +poly_result[2]*(20-10.5)*(20-10.5);
+      }
+    else{
+        PolyFit(delta_xgs,delta_ygs, fitting_numgs, poly_result, fitting_order, fitting_effect);//拟合函数得到结果
+        control_cmd[0] = ctr[1]/PI*180;//显示mpc计算的delta
+        control_cmd[1] = poly_result[0]+poly_result[1]*(10-5.5)
+                          +poly_result[2]*(10-5.5)*(10-5.5);//实际控制量输出(这里是二次多项式,(X-Xavr))
+    }
+    if (outinit<20)
+    {control_cmd[0]=0;
+     control_cmd[1]=0;}
+    else {outinit=50;}
+
+    // 将数据写入文件开始
+            ofstream outfile;
+            outfile.open("ctr0427xiashe.txt", ostream::app);        /*以添加模式打开文件*/
+            outfile<< setprecision(10)<<"MODE"<< ","  <<Roadmodecurrent<< "," << "x=" << "," <<x0[0] << ","<< "y=" << ","<<x0[1] << ","<< "phi="<< ","<< x0[3] << "," << "delta" << "," << delta*180/PI
+                  << "," << "mpc"<< ","<<ctr[0]<<","<<ctr[1]*180/PI<<","<<"拟合"<< ","<<control_cmd[1]
+                  << "," << "方向盘输出"  << "," << 15.97*control_cmd[1]*180/PI
+                  << ","<< "gpsnow"<<","<<states[0]<<","<<states[1]<<","<<states[3]<<','<<"速度"<<','<<states[2]*3.6<<','<<endl;
+            outfile.close();                                 /*关闭文件*/
+    // 将数据写入文件结束
+    return true;
+}
+
+/*****************************************************************************
+***Function Name:               PolyFit
+***Function description:        最小二乘法曲线拟合
+***Inputs:
+***                             double *x:      存放n个数据点的X坐标
+***                             double *y:      存放n个数据点的Y坐标
+***                             int n:          给定数据点个数
+***                             int m:          拟合多项式的项数,即拟合多项式的最高次为m-1。要求m<=n,且m<=20。若m>n或m>20,则本函数自动按m=min{n,20}处理
+***Outputs:
+***                             double *a:      返回m-1次拟合多项式的m个系数
+***                             double *dt:     dt[0]返回拟合多项式与各数据点误差的平方和;dt[1]返回拟合多项式与各数据点的误差绝对值之和;dt[2]返回拟合多项式与各数据点误差绝对值的最大值
+***注意事项:拟合多项式的形式为 y = a0 + a1*(x-Xavr)...
+*****************************************************************************/
+void PolyFit(double* x, double* y, int n, double* a, int m, double* dt)
+{
+    int i, j, k;
+    double z, p, c, g, q, d1, d2, s[20], t[20], b[20];
+    for (i = 0; i <= m - 1; i++)
+    {   a[i] = 0.0;}
+    if (m > n)
+    {   m = n;     }
+    if (m > 20)
+    {   m = 20;    }
+    z = 0.0;
+    for (i = 0; i <= n - 1; i++)
+    {
+        z = z + x[i] / (1.0 * n);
+    }
+    b[0] = 1.0;
+    d1 = 1.0 * n;
+    p = 0.0;
+    c = 0.0;
+    for (i = 0; i <= n - 1; i++)
+    {
+        p = p + (x[i] - z);
+        c = c + y[i];
+    }
+    c = c / d1;
+    p = p / d1;
+    a[0] = c * b[0];
+    if (m > 1)
+    {
+        t[1] = 1.0;
+        t[0] = -p;
+        d2 = 0.0;
+        c = 0.0;
+        g = 0.0;
+        for (i = 0; i <= n - 1; i++)
+        {
+            q = x[i] - z - p;
+            d2 = d2 + q * q;
+            c = c + y[i] * q;
+            g = g + (x[i] - z) * q * q;
+        }
+        c = c / d2;
+        p = g / d2;
+        q = d2 / d1;
+        d1 = d2;
+        a[1] = c * t[1];
+        a[0] = c * t[0] + a[0];
+    }
+    for (j = 2; j <= m - 1; j++)
+    {
+        s[j] = t[j - 1];
+        s[j - 1] = -p * t[j - 1] + t[j - 2];
+        if (j >= 3)
+            for (k = j - 2; k >= 1; k--)
+            {
+                s[k] = -p * t[k] + t[k - 1] - q * b[k];
+            }
+        s[0] = -p * t[0] - q * b[0];
+        d2 = 0.0;
+        c = 0.0;
+        g = 0.0;
+        for (i = 0; i <= n - 1; i++)
+        {
+            q = s[j];
+            for (k = j - 1; k >= 0; k--)
+            {
+                q = q * (x[i] - z) + s[k];
+            }
+            d2 = d2 + q * q;
+            c = c + y[i] * q;
+            g = g + (x[i] - z) * q * q;
+        }
+        c = c / d2;
+        p = g / d2;
+        q = d2 / d1;
+        d1 = d2;
+        a[j] = c * s[j];
+        t[j] = s[j];
+        for (k = j - 1; k >= 0; k--)
+        {
+            a[k] = c * s[k] + a[k];
+            b[k] = t[k];
+            t[k] = s[k];
+        }
+    }
+    dt[0] = 0.0;
+    dt[1] = 0.0;
+    dt[2] = 0.0;
+    for (i = 0; i <= n - 1; i++)
+    {
+        q = a[m - 1];
+        for (k = m - 2; k >= 0; k--)
+        {
+            q = a[k] + q * (x[i] - z);
+        }
+        p = q - y[i];
+        if (fabs(p) > dt[2])
+        {
+            dt[2] = fabs(p);
+        }
+        dt[0] = dt[0] + p * p;
+        dt[1] = dt[1] + fabs(p);
+    }
+    return;
+}
+

+ 65 - 0
src/decition/mpc-linear/mpc.h

@@ -0,0 +1,65 @@
+#ifndef MPC_H
+#define MPC_H
+
+#include <iostream>
+#include "osqp.h"
+#include <math.h>
+#include <Eigen/Dense>
+#include<Eigen/Eigen>
+#include<Eigen/Dense>
+//#include <Eigen>
+#include <sstream>
+#include "OsqpEigen/OsqpEigen.h"
+#include <vector>
+#define nx 4
+#define nu 2
+#define PI  3.14159265358979
+#define mpcWindow  25       //mpc步长
+
+using namespace std;
+
+/***************************************************************************************************
+***Function Name:               mpc_solve
+***Function description:        mpc求解器
+***Inputs:
+***
+***                             vector<double> &states:             输入变量,states为车体坐标系下车的x(单位m),y(单位m),v(单位m/s),phi(单位rad),其中x,y,phi都为0
+***                             vector<vector<double>> &ref_traj:   输入变量,存的为车体坐标系下,参考轨迹每个点的x(ref_traj[i][0],单位m),y(ref_traj[i][1],单位m),phi(ref_traj[i][2],单位rad),delta(参考的前轮转角phi(ref_traj[i][3]),单位rad)
+***                             int8_t gear_flag:                   档位标志,D:1,R:-1
+***                             double *_mpc_param:                 mpc的参数,分别为高速直道参数,高速小曲率弯道参数,高速大曲率弯道参数,倒车参数,低速弯道参数,低速直道参数,轴距。详见WeightMatrices函数
+***Outputs:
+***                             vector<double> &control_cmd:        输出的控制指令,control_cmd[1]为车前轮转角,单位rad
+***                             vector<double> &mpc_xy:             输出的用于显示的预测轨迹,可以不用为其赋值,目的为了观测
+*****************************************************************************************************/
+__attribute__((force_align_arg_pointer)) bool mpc_solve(vector<double> &control_cmd, vector<double> &states, vector<vector<double>> &ref_traj,vector<double> &mpc_xy,int8_t gear_flag,double *_mpc_param);
+
+/***************************************************************************************************
+***Function Name:               Roadmode
+***Function description:        判断道路模式
+***Inputs:
+***
+***                             vector<vector<double>>&ref_traj:    输入变量,参考轨迹点的状态量,此函数用的是其中前轮转角量
+***                             int8_t gear_flag:                   档位标志,D:1,R:-1
+***                             double speed:                       车辆当前的实时速度,单位为m/s。
+***Returns:
+***                             返回道路模式:                         1-6分别为:高速模式大弯道,高速模式小弯道,高速模式直道,倒车模式,低速模式弯道,低速模式直道
+*****************************************************************************************************/
+int Roadmode(vector<vector<double>>&ref_traj,int8_t gear_flag,double speed);
+
+/*****************************************************************************
+***Function Name:               PolyFit
+***Function description:        最小二乘法曲线拟合
+***Inputs:
+***                             double *x:      存放n个数据点的X坐标,参数单位均为国际单位
+***                             double *y:      存放n个数据点的Y坐标
+***                             int n:          给定数据点个数
+***                             int m:          拟合多项式的项数,即拟合多项式的最高次为m-1。要求m<=n,且m<=20。若m>n或m>20,则本函数自动按m=min{n,20}处理
+***Outputs:
+***                             double *a:      返回m-1次拟合多项式的m个系数
+***                             double *dt:     dt[0]返回拟合多项式与各数据点误差的平方和;dt[1]返回拟合多项式与各数据点的误差绝对值之和;dt[2]返回拟合多项式与各数据点误差绝对值的最大值
+***注意事项:拟合多项式的形式为 y = a0 + a1*(x-Xavr)...
+*****************************************************************************/
+void PolyFit(double* x, double* y, int n, double* a, int m, double* dt);
+
+
+#endif // MPC_H

+ 245 - 0
src/decition/mpc-linear/tms.cpp

@@ -0,0 +1,245 @@
+#include "include/tms_api.h"
+#include <QXmlStreamReader>
+#include <QFile>
+#include <QString>
+#include <qDebug>
+#include <QDebug>
+#include "bus/inc/bus_datapool.h"
+#include "bus/inc/bus_globaldef.h"
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <string>
+#include <fstream>
+#include <iomanip>
+#include <stdio.h>
+using namespace std;
+
+#define T0301_ELEMENT        "Path"
+#define T0302_ELEMENT        "PathID"
+#define T0303_ELEMENT        "PathFileName"
+#define T0304_ELEMENT        "PathName"
+#define T0305_ELEMENT        "PathMD5"
+
+#define PI 3.141592653
+Tms::Tms(DataPool*pDataPool)
+{
+    m_pDataPool=pDataPool;
+}
+
+Tms::~Tms()
+{
+}
+
+
+
+
+
+QList<GPSInfo> Tms::GetPath(QString path, QMap<int,int> &modToMod)
+{
+    QList<GPSInfo> pathList;
+    Coordtrans m_gpsCoorTrans;
+    int size;
+    //提取GPS数据并计算相邻两点之间的距离及曲率
+    QString gdata=TextStreamRead(path,modToMod);
+    QStringList gst=gdata.split("\n");
+    size=gst.size();
+
+    if(!CheckPathHead(gst[0].split(" ")))
+    {
+        return pathList;
+    }
+
+    for(int gi=1;gi<(size-2);gi++)
+    {
+        GPSInfo ginfo;
+
+        QStringList gs=(gst.at(gi)).split(" ");
+        QStringList gs_1=(gst.at(gi+1)).split(" ");
+
+        ginfo.id=QString(gs.at(0)).toDouble();
+        ginfo.num=ginfo.id;
+        ginfo.type=0;
+        //航向
+        ginfo.iHead=QString(gs.at(3)).toDouble();
+        //纬度
+        ginfo.iLatitude=QString(gs.at(2)).toDouble();
+        //经度
+        ginfo.iLongitude=QString(gs.at(1)).toDouble();
+        //海拔
+        //ginfo.altitude=QString(gs.at(4)).toDouble();
+
+        //计算距离
+        ginfo.iDistance=TmsGetDistance(QString(gs.at(2)).toDouble(),QString(gs.at(1)).toDouble(),QString(gs_1.at(2)).toDouble(),QString(gs_1.at(1)).toDouble());
+       // 计算拐点和曲率
+       pathList.append(ginfo);
+
+    }
+     qDebug()<<pathList.size();
+     qDebug()<<size;
+     QList<UTMInfo> globalZQYUTMList;
+     UTMInfo tempUTM;
+    for (int i=0;i<pathList.size();i++)
+    {
+        double templon;
+        double templat;
+        double tempyaw;
+        templon= pathList.at(i).iLongitude;
+        templat= pathList.at(i).iLatitude;
+        m_gpsCoorTrans.LatLonToUTMXY(templat,templon, 50, tempUTM.x, tempUTM.y);
+        tempUTM.k=0;
+        tempUTM.yaw=pathList.at(i).iHead;
+        tempUTM.x1=0;
+        tempUTM.x2=0;
+        tempUTM.y1=0;
+        tempUTM.y2=0;
+        globalZQYUTMList.append(tempUTM);
+    }
+
+    double x0=globalZQYUTMList.at(0).x;
+     double y0=globalZQYUTMList.at(0).y;
+    for (int i=0;i<pathList.size();i++)
+    {    globalZQYUTMList[i].x=globalZQYUTMList.at(i).x-x0;
+         globalZQYUTMList[i].y=globalZQYUTMList.at(i).y-y0;
+    }
+    // 计算TD平滑后的x,y,
+        double r=5;
+        double h=0.02;
+        for (int i = 0; i < pathList.size()-1; i++)
+          {
+              double fh1=fh(globalZQYUTMList.at(i).x1-globalZQYUTMList.at(i).x,globalZQYUTMList.at(i).x2,r,h);//求fh1
+              globalZQYUTMList[i+1].x1=globalZQYUTMList.at(i).x1+h*globalZQYUTMList.at(i).x2;//更新x1(k+1)
+              globalZQYUTMList[i+1].x2=globalZQYUTMList.at(i).x2+h*fh1;//更新x2(k+1)
+          }
+
+        for (int i = 0; i <pathList.size()-1; i++)
+          {
+              double fh1=fh(globalZQYUTMList.at(i).y1-globalZQYUTMList.at(i).y,globalZQYUTMList.at(i).y2,r,h);//求fh1
+              globalZQYUTMList[i+1].y1=globalZQYUTMList.at(i).y1+h*globalZQYUTMList.at(i).y2;//更新y1(k+1)
+              globalZQYUTMList[i+1].y2=globalZQYUTMList.at(i).y2+h*fh1;//更新y2(k+1)
+          }
+        // 计算曲率
+         double distance,deltaphi;
+               for (int i = 0; i <pathList.size()-31; i++)
+                 {
+                    deltaphi=((globalZQYUTMList.at(i+31).yaw-globalZQYUTMList.at(i).yaw))/180*PI;
+                      if (deltaphi>PI)
+                         {deltaphi=deltaphi-2*PI; }
+                      if (deltaphi<-PI)
+                         {deltaphi=deltaphi+2*PI;}
+                    distance=sqrt( pow((globalZQYUTMList.at(i+31).x1-globalZQYUTMList.at(i).x1),2)+pow((globalZQYUTMList.at(i+31).y1-globalZQYUTMList.at(i).y1),2));
+                    globalZQYUTMList[i].k=deltaphi/distance;
+
+                 }
+           //  曲率滤波//////////////////////////////////////////////////
+                   int n[100];
+                      double value_buf;
+                      for (int i = 50; i < pathList.size()-50-1; i++)
+                      {   value_buf = 0;
+                          for (int j = 0; j < 100; j++)
+                           { value_buf = value_buf+globalZQYUTMList.at(i-50+j).k;
+                           }
+                         globalZQYUTMList[i].k=value_buf/100;
+
+                       }
+//        for  (int i = 0; i <pathList.size()-1; i++)
+//        {
+//                    // 将数据写入文件开始
+//                            ofstream outfile;
+//                            outfile.open("tdlb0427she.txt", ostream::app);        /*以添加模式打开文件*/
+//                            outfile << i << "," << setprecision(12)<<globalZQYUTMList.at(i).k<<endl;
+//                            outfile.close();                                 /*关闭文件*/
+//                    // 将数据写入文件结束
+//        }
+        for (int i=0;i<pathList.size();i++)
+        {    globalZQYUTMList[i].x1=globalZQYUTMList.at(i).x1+x0;
+             globalZQYUTMList[i].y1=globalZQYUTMList.at(i).y1+y0;
+        }
+
+        double templat1;
+        double templon1;
+        for  (int i = 0; i <pathList.size()-1; i++)
+        {
+           m_gpsCoorTrans.UTMXYToLatLon(globalZQYUTMList.at(i).x1, globalZQYUTMList.at(i).y1, 50, 0,templat1, templon1);
+           pathList[i].iLatitude=templat1;
+           pathList[i].iLongitude=templon1;
+           pathList[i].iCurvature=globalZQYUTMList.at(i).k;
+           pathList[i].iCorner=0;
+
+        }
+qDebug()<<"map is ok";
+    return pathList;
+}
+
+bool Tms::CheckPathHead(QStringList pathHead)
+{
+    QStringList path;
+    path<<"Id"<<"Longtitude"<<"Latitude"<<"Heading"<<"Altitude"<<"LongtitudeAcc"<<"LatitudeAcc"
+       <<"Pitch"<<"YawRate"<<"Allipsoid"<<"RTKState";
+
+    if(pathHead.size()!=path.size())
+    {
+        return false;
+    }
+    for(int i = 0;i<path.size();++i)
+    {
+        if(pathHead[i]!=path[i])
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+QString Tms::TextStreamRead(QString path, QMap<int,int> &modToMod)
+{
+    QString rData;
+    QFile file(path);
+    if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        QByteArray line = file.readAll();
+        rData=line;
+    }
+    else
+    {
+
+    }
+    file.close();
+    return rData;
+}
+
+
+
+
+double TmsGetDistance(double lat1,double lng1,double lat2,double lng2)
+{
+    double disn,_x,_y;
+    _x=qAbs(lng1-lng2)*111700*qCos(lat1/180*M_PI);
+    _y=qAbs(lat1-lat2)*111700;
+    disn=qSqrt(_x*_x+_y*_y);
+    return disn;
+}
+
+
+int sgn(double x){
+    if(x>0)
+    {return 1;}
+    if(x<0)
+    {return -1;}
+    if(x==0)
+    {return 0;}
+}
+double fsg(double x,double d)
+{
+       return (sgn(x+d)-sgn(x-d))/2;
+}
+double fh(double x1,double x2,double r,double h)
+{ double d=r*h*h;
+       double a0=h*x2;
+       double y=x1+a0;
+       double a1=sqrt(d*(d+8*fabs(y)));
+       double a2=a0+sgn(y)*(a1-d)/2;
+       double a=(a0+y)*fsg(y,d)+a2*(1-fsg(y,d));
+       double fh1= -r*(a/d)*fsg(a,d)-r*sgn(a)*(1-fsg(a,d));
+       return fh1;
+}
+

+ 101 - 0
src/decition/mpc-linear/tms_api.h

@@ -0,0 +1,101 @@
+#ifndef TMS_H
+#define TMS_H
+ 
+#include <QXmlStreamReader>
+#include <QAxObject>
+#include <QFile>
+#include <QString>
+#include <QObject>
+#include <QtMath>
+//#include <QDebug>
+#include <QList>
+#include <QMap>
+#include <QMutex>
+#include "bus/inc/bus_globaldef.h"
+#include "cmp/inc/cmp_PCANBasic.h"
+#include "include/coordtrans_api.h"
+
+class DataPool;
+
+class Tms:public QObject,public QXmlStreamReader
+{
+    Q_OBJECT
+ public:
+    Tms(DataPool*pDataPool);
+   ~Tms();
+public slots:
+
+
+    /******************************************************************************
+    *** Function Name        :GetPath
+    *** Function Description :读取Path文件,在地理坐标系下对地图x、y进行TD平滑滤波,计算地图上每个点的曲率并进行均值滤波处理
+    *** Inputs:
+    ***             QString   Path文件路径
+    *** Returns:              path数据集合
+    *** Comments:
+    ******************************************************************************/
+    QList<GPSInfo> GetPath(QString path, QMap<int,int> &modToMod);
+
+
+
+
+private:
+    DataPool *m_pDataPool;
+
+
+
+    /******************************************************************************
+    *** Function Name        :CheckPathHead
+    *** Function Description :检验Path文件的头是否正确
+    *** Inputs:
+    ***         pathHead     :path文件头包含的字段
+    *** Returns:              返回Path文件头是否正确
+    *** Comments:
+    ******************************************************************************/
+    bool CheckPathHead(QStringList pathHead);
+
+    /******************************************************************************
+    *** Function Name        :TextStreamRead
+    *** Function Description :路径文件流解析
+    *** Inputs:
+    ***                QSting :Path文件路径
+    *** Returns:               整个path文件流
+    *** Comments:
+    ******************************************************************************/
+    QString TextStreamRead(QString, QMap<int,int> &modToMod);
+
+
+
+    //
+
+};
+/******************************************************************************
+*** Function Name        :TmsGetDistance
+*** Function Description :计算Path文件中的距离
+*** Inputs:
+***        lat1          :当前纬度
+***        lng1          :当前经度
+***        lat2          :下个点纬度
+***        lng2          :下个点经读
+*** Returns:             两点间距离
+*** Comments:
+***
+******************************************************************************/
+double TmsGetDistance(double lat1,double lng1,double lat2,double lng2);
+
+
+/******************************************************************************
+*** Function Name        :fh
+*** Function Description :计算跟踪微分器中的跟踪系数(最速控制综合函数)
+*** Inputs:
+                         x1: 上一步的差值
+                         x2: 跟踪速度
+                         r:   跟踪加速度
+                         h:   跟踪周期
+*** Returns:             跟踪系数
+******************************************************************************/
+double fh(double x1,double x2,double r,double h);
+
+
+
+#endif