Browse Source

add tool_scheduler for task schedule.

yuchuli 4 years ago
parent
commit
6814dca237

+ 73 - 0
src/tool/tool_scheduler/.gitignore

@@ -0,0 +1,73 @@
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+.directory
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+

+ 153 - 0
src/tool/tool_scheduler/gnss_coordinate_convert.cpp

@@ -0,0 +1,153 @@
+#include <gnss_coordinate_convert.h>
+
+void gps2xy(double J4, double K4, double *x, double *y)
+{
+    int L4 = (int)((K4 - 1.5) / 3) + 1;
+    double M4 = K4 - (L4 * 3);
+    double N4 = sin(J4 * 3.1415926536 / 180);
+    double O4 = cos(J4 * 3.1415926536 / 180);
+    double P4 = tan(J4 * 3.1415926536 / 180);
+    double Q4 = 111134.8611 * J4 - N4 * O4 * (32005.7799 + 133.9238 * N4 * N4 + 0.6973 * N4 * N4 * N4 * N4 + 0.0039 * N4 * N4 * N4 * N4 * N4 * N4);
+    double R4 = sqrt(0.006738525414683) * O4;
+    double S4 = sqrt(1 + R4 * R4);
+    double T4 = 6399698.901783 / S4;
+    double U4 = (T4 / S4) / S4;
+    double V4 = O4 * M4 * 3.1415926536 / 180;
+    double W4 = 0.5 + (5 - P4 * P4 + 9 * R4 * R4 + 4 * R4 * R4 * R4 * R4) * V4 * V4 / 24;
+    double X4 = V4 * V4 * V4 * V4 / 720 * (61 + (P4 * P4 - 58) * P4 * P4);
+    double Y4 = 1 + V4 * V4 * (1 - P4 * P4 + R4 * R4) / 6;
+    double Z4 = V4 * V4 * V4 * V4 * (5 - 18 * P4 * P4 * P4 * P4 * P4 * P4 + 14 * R4 * R4 - 58 * R4 * R4 * P4 * P4) / 120;
+
+    *y = Q4 + T4 * P4 * V4 * V4 * (W4 + X4);
+    *x = 500000 + T4 * V4 * (Y4 + Z4);
+}
+
+//高斯投影由经纬度(Unit:DD)反算大地坐标(含带号,Unit:Metres)
+void GaussProjCal(double longitude, double latitude, double *X, double *Y)
+{
+    int ProjNo = 0; int ZoneWide; ////带宽
+    double longitude1, latitude1, longitude0, latitude0, X0, Y0, xval, yval;
+    double a, f, e2, ee, NN, T, C, A, M, iPI;
+    iPI = 0.0174532925199433; ////3.1415926535898/180.0;
+    ZoneWide = 6; ////6度带宽
+    a = 6378245.0; f = 1.0 / 298.3; //54年北京坐标系参数
+                                    ////a=6378140.0; f=1/298.257; //80年西安坐标系参数
+    ProjNo = (int)(longitude / ZoneWide);
+    longitude0 = ProjNo * ZoneWide + ZoneWide / 2;
+    longitude0 = longitude0 * iPI;
+    latitude0 = 0;
+    longitude1 = longitude * iPI; //经度转换为弧度
+    latitude1 = latitude * iPI; //纬度转换为弧度
+    e2 = 2 * f - f * f;
+    ee = e2 * (1.0 - e2);
+    NN = a / sqrt(1.0 - e2 * sin(latitude1)*sin(latitude1));
+    T = tan(latitude1)*tan(latitude1);
+    C = ee * cos(latitude1)*cos(latitude1);
+    A = (longitude1 - longitude0)*cos(latitude1);
+    M = a * ((1 - e2 / 4 - 3 * e2*e2 / 64 - 5 * e2*e2*e2 / 256)*latitude1 - (3 * e2 / 8 + 3 * e2*e2 / 32 + 45 * e2*e2
+        *e2 / 1024)*sin(2 * latitude1)
+        + (15 * e2*e2 / 256 + 45 * e2*e2*e2 / 1024)*sin(4 * latitude1) - (35 * e2*e2*e2 / 3072)*sin(6 * latitude1));
+    xval = NN * (A + (1 - T + C)*A*A*A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * ee)*A*A*A*A*A / 120);
+    yval = M + NN * tan(latitude1)*(A*A / 2 + (5 - T + 9 * C + 4 * C*C)*A*A*A*A / 24
+        + (61 - 58 * T + T * T + 600 * C - 330 * ee)*A*A*A*A*A*A / 720);
+    X0 = 1000000L * (ProjNo + 1) + 500000L;
+    Y0 = 0;
+    xval = xval + X0; yval = yval + Y0;
+    *X = xval;
+    *Y = yval;
+}
+
+
+
+//=======================zhaobo0904
+#define PI  3.14159265358979
+//void GaussProjCal(double lon, double lat, double *X, double *Y)
+//{
+//    // 1975 年国际椭球体长半轴 a, 第一离心率 e2, 第二离心率 ep2
+//    double a = 6378140.0;
+//    double e2 = 0.006694384999588;
+//    double ep2 = e2/(1-e2);
+
+//    // 原点所在经度
+//    double lon_origin = 6.0*int(lon/6) + 3.0;
+//    lon_origin *= PI / 180.0;
+
+//    double k0 = 0.9996;
+
+//    // 角度转弧度
+//    double lat1 = lat * PI / 180.0;
+//    double lon1 = lon * PI / 180.0;
+
+
+//    // 经线在该点处的曲率半径,
+//    double N = a / sqrt(1 - e2*sin(lat1)*sin(lat1));
+
+
+//    // 赤道到该点的经线长度近似值 M, 使用泰勒展开逐项积分然后取前四项.
+//    // 这个近似值是将 N 作为纬度 \phi 的函数展开为泰勒计数, 然后在区间 [0, lat1] 上积分得到的.
+//    // 首先计算前四项的系数 a1~a4.
+//    double a1 = 1 - e2/4 - (3*e2*e2)/64 - (5*e2*e2*e2)/256;
+//    double a2 = (3*e2)/8 + (3*e2*e2)/32 + (45*e2*e2*e2)/1024;
+//    double a3 = (15*e2*e2)/256 + (45*e2*e2*e2)/1024;
+//    double a4 = (35*e2*e2*e2)/3072;
+//    double M = a * (a1*lat1 - a2*sin(2*lat1) + a3*sin(4*lat1) - a4*sin(6*lat1));
+
+//    // 辅助量
+//    double T = tan(lat1)*tan(lat1);
+//    double C = ep2*cos(lat1)*cos(lat1);
+//    double A = (lon1 - lon_origin)*cos(lat1);
+
+//    *X = 500000.0 + k0 * N * (A + (1 - T + C)*(A*A*A)/6 + (5 - 18*T + T*T + 72*C - 58*ep2)*(A*A*A*A*A)/120);
+//    *Y = M + N * tan(lat1) * ((A*A)/2 +
+//                              (5 - T + 9*C + 4*C*C)*(A*A*A*A)/24 +
+//                              (61 - 58*T + T*T + 600*C - 330*ep2)*(A*A*A*A*A*A)/720);
+
+
+//    *Y *= k0;
+//    return;
+//}
+//==========================================================
+
+
+
+
+
+//高斯投影由大地坐标(Unit:Metres)反算经纬度(Unit:DD)
+void GaussProjInvCal(double X, double Y, double *longitude, double *latitude)
+{
+    int ProjNo; int ZoneWide; ////带宽
+    double longitude1, latitude1, longitude0, latitude0, X0, Y0, xval, yval;
+    double e1, e2, f, a, ee, NN, T, C, M, D, R, u, fai, iPI;
+    iPI = 0.0174532925199433; ////3.1415926535898/180.0;
+    a = 6378245.0; f = 1.0 / 298.3; //54年北京坐标系参数
+    ////a=6378140.0; f=1/298.257; //80年西安坐标系参数
+    ZoneWide = 6; ////6度带宽
+    ProjNo = (int)(X / 1000000L); //查找带号
+    longitude0 = (ProjNo - 1) * ZoneWide + ZoneWide / 2;
+    longitude0 = longitude0 * iPI; //中央经线
+    X0 = ProjNo * 1000000L + 500000L;
+    Y0 = 0;
+    xval = X - X0; yval = Y - Y0; //带内大地坐标
+    e2 = 2 * f - f * f;
+    e1 = (1.0 - sqrt(1 - e2)) / (1.0 + sqrt(1 - e2));
+    ee = e2 / (1 - e2);
+    M = yval;
+    u = M / (a*(1 - e2 / 4 - 3 * e2*e2 / 64 - 5 * e2*e2*e2 / 256));
+    fai = u + (3 * e1 / 2 - 27 * e1*e1*e1 / 32)*sin(2 * u) + (21 * e1*e1 / 16 - 55 * e1*e1*e1*e1 / 32)*sin(
+                4 * u)
+            + (151 * e1*e1*e1 / 96)*sin(6 * u) + (1097 * e1*e1*e1*e1 / 512)*sin(8 * u);
+    C = ee * cos(fai)*cos(fai);
+    T = tan(fai)*tan(fai);
+    NN = a / sqrt(1.0 - e2 * sin(fai)*sin(fai));
+    R = a * (1 - e2) / sqrt((1 - e2 * sin(fai)*sin(fai))*(1 - e2 * sin(fai)*sin(fai))*(1 - e2 * sin
+                                                                                       (fai)*sin(fai)));
+    D = xval / NN;
+    //计算经度(Longitude) 纬度(Latitude)
+    longitude1 = longitude0 + (D - (1 + 2 * T + C)*D*D*D / 6 + (5 - 2 * C + 28 * T - 3 * C*C + 8 * ee + 24 * T*T)*D
+                               *D*D*D*D / 120) / cos(fai);
+    latitude1 = fai - (NN*tan(fai) / R)*(D*D / 2 - (5 + 3 * T + 10 * C - 4 * C*C - 9 * ee)*D*D*D*D / 24
+                                         + (61 + 90 * T + 298 * C + 45 * T*T - 256 * ee - 3 * C*C)*D*D*D*D*D*D / 720);
+    //转换为度 DD
+    *longitude = longitude1 / iPI;
+    *latitude = latitude1 / iPI;
+}

+ 26 - 0
src/tool/tool_scheduler/gnss_coordinate_convert.h

@@ -0,0 +1,26 @@
+#pragma once
+#ifndef _IV_PERCEPTION_GNSS_CONVERT_
+#define _IV_PERCEPTION_GNSS_CONVERT_
+
+#include <math.h>
+//double nmeaConvert2Lat(string lat)
+//{
+//	Console.WriteLine(lat);
+//	double nmea_d = double.Parse(lat.Substring(0, 2));
+//	double nmea_m = double.Parse(lat.Substring(2, 6));
+//	return nmea_d + nmea_m / 60;
+//}
+//
+//double nmeaConvert2Lon(string lon)
+//{
+//	Console.WriteLine(lon);
+//	double nmea_d = double.Parse(lon.Substring(0, 3));
+//	double nmea_m = double.Parse(lon.Substring(3, 7));
+//	return nmea_d + nmea_m / 60;
+//}
+
+void gps2xy(double , double , double *, double *);
+void GaussProjCal(double longitude, double latitude, double *X, double *Y);
+void GaussProjInvCal(double X, double Y, double *longitude, double *latitude);
+
+#endif // !_IV_PERCEPTION_GNSS_CONVERT_

+ 224 - 0
src/tool/tool_scheduler/ivscheduler.cpp

@@ -0,0 +1,224 @@
+#include "ivscheduler.h"
+
+#include <iostream>
+
+static QMutex gMutexGPSIMU;
+
+static iv::gps::gpsimu ggpsimu;
+static bool gbUpdate = false;
+
+class xodrobj
+{
+public:
+    double flatsrc;
+    double flonsrc;
+    double fhgdsrc;
+    double flat;
+    double flon;
+    int lane;
+};
+
+
+void Listengpsimu(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+//        ggpsimu->UpdateGPSIMU(strdata,nSize);
+
+    iv::gps::gpsimu xgpsimu;
+    if(!xgpsimu.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"ListenRaw Parse error."<<std::endl;
+        return;
+    }
+    (void)&index;
+    (void)dt;
+    (void)strmemname;
+
+    gMutexGPSIMU.lock();
+    ggpsimu.CopyFrom(xgpsimu);
+    gbUpdate = true;
+    gMutexGPSIMU.unlock();
+}
+
+ivscheduler::ivscheduler(std::string strmemname)
+{
+    mstrmemname = strmemname;
+    iv::modulecomm::RegisterRecv(mstrmemname.data(),Listengpsimu);
+    mpadst = iv::modulecomm::RegisterSend("xodrreq",1000,1);
+}
+
+void ivscheduler::run()
+{
+    iv::gps::gpsimu xgpsimu;
+    while(!QThread::isInterruptionRequested())
+    {
+        if(gbUpdate)
+        {
+            gMutexGPSIMU.lock();
+            xgpsimu.CopyFrom(ggpsimu);
+            gbUpdate = false;
+            gMutexGPSIMU.unlock();
+            emit updategps(xgpsimu.lon(),xgpsimu.lat(),xgpsimu.heading());
+            if(mpscheduler == 0)continue;
+            mMutex.lock();
+            if(mncycle<mncyclecount)
+            {
+                if(mnprocess<mpscheduler->mscheduler_unit_size())
+                {
+                    switch (mnstep) {
+                    case 0:
+                    {
+                        mfLatInit = xgpsimu.lat();
+                        mfLonInit = xgpsimu.lon();
+                        mfHeadingInit = xgpsimu.heading();
+                        mnTimeInit = QDateTime::currentMSecsSinceEpoch();
+
+                        //Sending Obj;
+                        iv::scheduler_unit * pscheduler_unit = mpscheduler->mutable_mscheduler_unit(mnprocess);
+                        mfLatObj = pscheduler_unit->mflat();
+                        mfLonObj = pscheduler_unit->mflon();
+                        mfHeadingObj = pscheduler_unit->mfheading();
+                        mnLastSendObj = QDateTime::currentMSecsSinceEpoch();
+                        SendObj(mfLonObj,mfLatObj);
+                        mnstep = 1;
+                    }
+                        break;
+                    case 1:
+                        if(IsVehicleMoving(&xgpsimu))
+                        {
+                            mnstep = 2;
+                        }
+                        else
+                        {
+                            if((QDateTime::currentMSecsSinceEpoch() - mnLastSendObj) > 3000)
+                            {
+                                //Send Obj
+                                SendObj(mfLonObj,mfLatObj);
+                                mnLastSendObj = QDateTime::currentMSecsSinceEpoch();
+                            }
+                        }
+                        if(IsVehcileArrivingStation(&xgpsimu))
+                        {
+                            mnArrivingTime = QDateTime::currentMSecsSinceEpoch();
+                            mnstep = 3;
+                        }
+                        //Decide Vechicle Running.
+                        break;
+                    case 2:
+                        if(IsVehcileArrivingStation(&xgpsimu))
+                        {
+                            mnArrivingTime = QDateTime::currentMSecsSinceEpoch();
+                            mnstep = 3;
+                        }
+                        //Decide Vehiclde Arrive End Point;
+                        break;
+                    case 3:
+                    {
+                        iv::scheduler_unit * pscheduler_unit = mpscheduler->mutable_mscheduler_unit(mnprocess);
+                        if((QDateTime::currentMSecsSinceEpoch() - mnArrivingTime)>= (pscheduler_unit->mstopsecond()*1000) )
+                        {
+                            mnstep = 4;
+                        }
+                    }
+                        //Count Stop Time;
+                        break;
+                    case 4:
+                        mnstep = 0;
+                        mnprocess++;
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                else
+                {
+                    mncycle++;
+                    mnprocess = 0;
+                }
+            }
+            emit updatestate(mncycle,mncyclecount,mnprocess,mpscheduler->mscheduler_unit_size());
+            mMutex.unlock();
+
+
+        }
+        else
+        {
+            msleep(10);
+        }
+    }
+}
+
+void ivscheduler::setscheduler(iv::scheduler *pscheduler, int ncyclecount)
+{
+    mMutex.lock();
+    mpscheduler = pscheduler;
+    mncyclecount = ncyclecount;
+    mncycle = 0;
+    mnprocess = 0;
+    mnstep = 0;
+    mMutex.unlock();
+
+}
+
+void ivscheduler::GetProcess(int &nProc, int &nProcTotal)
+{
+    if(mpscheduler == 0)
+    {
+        nProc = 0;
+        nProcTotal = 0;
+        return;
+    }
+
+    mMutex.lock();
+    nProcTotal = mpscheduler->mscheduler_unit_size();
+    nProc = mnprocess;
+    mMutex.unlock();
+}
+
+void ivscheduler::GetCycle(int &ncycle, int &ncyclecount)
+{
+    ncycle = mncycle;
+    ncyclecount = mncyclecount;
+
+}
+
+bool ivscheduler::IsVehicleMoving(iv::gps::gpsimu * pgpsimu)
+{
+    double dis;
+    double x1,y1;
+    double x2,y2;
+    GaussProjCal(mfLonInit,mfLatInit,&x1,&y1);
+    GaussProjCal(pgpsimu->lon(),pgpsimu->lat(),&x2,&y2);
+    dis = sqrt(pow(x1-x2,2)+pow(y1-y2,2));
+    if(dis > 10.0)return true;
+
+    return false;
+}
+
+bool ivscheduler::IsVehcileArrivingStation(iv::gps::gpsimu *pgpsimu)
+{
+    double dis;
+    double x1,y1;
+    double x2,y2;
+    GaussProjCal(mfLonObj,mfLatObj,&x1,&y1);
+    GaussProjCal(pgpsimu->lon(),pgpsimu->lat(),&x2,&y2);
+    dis = sqrt(pow(x1-x2,2)+pow(y1-y2,2));
+    if(dis < 10.0)
+    {
+        double fheaddiff = pgpsimu->heading() - mfHeadingObj;
+        if(fheaddiff< 0)fheaddiff = fheaddiff + 360.0;
+        if((fheaddiff>300)||(fheaddiff<60))
+            return true;
+    }
+
+    return false;
+}
+
+void ivscheduler::SendObj(double flon, double flat)
+{
+    xodrobj xo;
+    xo.flon = flon;
+    xo.flat = flat;
+    xo.lane = 3;
+
+    iv::modulecomm::ModuleSendMsg(mpadst,(char *)&xo,sizeof(xodrobj));
+}

+ 65 - 0
src/tool/tool_scheduler/ivscheduler.h

@@ -0,0 +1,65 @@
+#ifndef IVSCHEDULER_H
+#define IVSCHEDULER_H
+
+#include <QThread>
+#include <QMutex>
+#include <QDateTime>
+
+#include "scheduler.pb.h"
+#include "gpsimu.pb.h"
+#include "gnss_coordinate_convert.h"
+#include "modulecomm.h"
+
+
+class ivscheduler : public QThread
+{
+        Q_OBJECT
+public:
+    ivscheduler(std::string strmemname);
+
+
+public:
+    void setscheduler(iv::scheduler * pscheduler,int ncyclecount = 1);
+    void run();
+
+    void GetProcess(int & nProc, int & nProcTotal);
+    void GetCycle(int & ncycle, int & ncyclecount);
+
+signals:
+    void updategps(double flon,double flat,double fheading);
+    void updatestate(int ncycle,int ncyclecount,int nprocess,int nprocesscount);
+
+
+private:
+    iv::scheduler * mpscheduler = 0;
+    int mnprocess = 0;
+    int mncycle = 0;
+
+    int mncyclecount = 1;
+    int mnstep = 0;
+    double mfLatInit;
+    double mfLonInit;
+    double mfHeadingInit;
+
+    double mfLatObj;
+    double mfLonObj;
+    double mfHeadingObj;
+
+    qint64 mnTimeInit;
+    qint64 mnLastSendObj;
+    qint64 mnArrivingTime;
+
+
+    QMutex mMutex;
+
+    std::string mstrmemname;
+    void * mpadst;
+
+private:
+    bool IsVehicleMoving(iv::gps::gpsimu * pgpsimu);
+    bool IsVehcileArrivingStation(iv::gps::gpsimu * pgpsimu);
+
+    void SendObj(double flon,double flat);
+};
+
+#endif // IVSCHEDULER_H

+ 11 - 0
src/tool/tool_scheduler/main.cpp

@@ -0,0 +1,11 @@
+#include "mainwindow.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    MainWindow w;
+    w.show();
+    return a.exec();
+}

+ 145 - 0
src/tool/tool_scheduler/mainwindow.cpp

@@ -0,0 +1,145 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#include <QFileDialog>
+#include <QMessageBox>
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+    , ui(new Ui::MainWindow)
+{
+    ui->setupUi(this);
+
+    mpivsch = new ivscheduler("hcp2_gpsimu");
+    mpivsch->start();
+
+    connect(mpivsch,SIGNAL(updategps(double,double,double)),this,SLOT(onUpdatePos(double,double,double)));
+    connect(mpivsch,SIGNAL(updatestate(int,int,int,int)),this,SLOT(onUpdateState(int,int,int,int)));
+}
+
+MainWindow::~MainWindow()
+{
+    delete ui;
+}
+
+
+void MainWindow::on_pushButton_Start_clicked()
+{
+    if(mpscheduler == 0)
+    {
+        QMessageBox::warning(this,"warning","no scheduler select.");
+        return;
+    }
+
+
+    mpivsch->setscheduler(mpscheduler);
+}
+
+void MainWindow::on_pushButton_Load_clicked()
+{
+    QString str = QFileDialog::getOpenFileName(this,"Load Scheduler",".","*.xml");
+    if(str.isEmpty())return;
+
+    ui->lineEdit_FilePath->setText(str);
+
+    QDomDocument doc;
+
+
+    QFile file(str.toLatin1().data());
+    if (!file.open(QIODevice::ReadOnly))
+    {
+        QMessageBox::warning(this,"warning","Load File Fail.");
+        return;
+    }
+
+    if (!doc.setContent(&file)) {
+        QMessageBox::warning(this,"waring","Parse XML Fail.");
+        file.close();
+        return ;
+    }
+    file.close();
+
+    //遍历节点,从配置文件中获取当前有哪些模块,并拼接启动命令和启动参数_tjc
+    QDomElement docElem = doc.documentElement();
+    QDomNode n = docElem.firstChild();
+
+    iv::scheduler * pscheduler = new iv::scheduler;
+
+    while(!n.isNull())
+    {
+        QDomElement e = n.toElement(); // 尝试将节点转换为元素
+        std::string name = e.nodeName().toStdString();
+        if(name == "scheduler_unit")
+        {
+            double flat,flon,fheading,fstoptime;
+            flat = -1000;
+            flon = -1000;
+            fheading = -1000;
+            fstoptime = -1000;
+            QDomNode nodesch = e.firstChild();
+            while(!nodesch.isNull())
+            {
+                QDomElement esch= nodesch.toElement(); // 尝试将节点转换为元素
+                QString strname = nodesch.nodeName();
+                QString strvalue = esch.text();
+                if(strname.toStdString() == "lat")
+                {
+                    flat = atof(strvalue.toStdString().data());
+                }
+                if(strname.toStdString() == "lon")
+                {
+                    flon = atof(strvalue.toStdString().data());
+                }
+                if(strname.toStdString() == "heading")
+                {
+                    fheading = atof(strvalue.toStdString().data());
+                }
+                if(strname.toStdString() == "stoptime")
+                {
+                    fstoptime = atof(strvalue.toStdString().data());
+                }
+                nodesch = nodesch.nextSibling();
+            }
+
+            if((flat == -1000)||(flat == -1000)||(flat == -1000)||(flat == -1000))
+            {
+                qDebug("decode a unit error.");
+            }
+            else
+            {
+                iv::scheduler_unit * pscheduler_unit = pscheduler->add_mscheduler_unit();
+                pscheduler_unit->set_mfheading(fheading);
+                pscheduler_unit->set_mflat(flat);
+                pscheduler_unit->set_mflon(flon);
+                pscheduler_unit->set_mstopsecond(fstoptime);
+            }
+
+
+        }
+        n = n.nextSibling();
+    }
+
+    if(pscheduler->mscheduler_unit_size() < 1)
+    {
+        QMessageBox::warning(this,"waring"," can't load scheduler from xml.");
+        return;
+    }
+
+    mpscheduler = pscheduler;
+}
+
+void MainWindow::onUpdatePos(double flon, double flat, double fheading)
+{
+    ui->lineEdit_Lon->setText(QString::number(flon,'f',7));
+    ui->lineEdit_Lat->setText(QString::number(flat,'f',7));
+    ui->lineEdit_Head->setText(QString::number(fheading,'f',2));
+}
+
+void MainWindow::onUpdateState(int ncycle, int ncyclecount, int nprocess, int nprocesscount)
+{
+    char strout[100];
+    snprintf(strout,100,"%d/%d",ncycle,ncyclecount);
+    ui->lineEdit_CycleProcess->setText(strout);
+    snprintf(strout,100,"%d/%d",nprocess,nprocesscount);
+    ui->lineEdit_Process->setText(strout);
+}

+ 38 - 0
src/tool/tool_scheduler/mainwindow.h

@@ -0,0 +1,38 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QtXml>
+
+#include "scheduler.pb.h"
+
+#include "ivscheduler.h"
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow(QWidget *parent = nullptr);
+    ~MainWindow();
+
+private slots:
+    void on_pushButton_Start_clicked();
+
+    void on_pushButton_Load_clicked();
+
+    void onUpdatePos(double flon,double flat,double fheading);
+    void onUpdateState(int ncycle,int ncyclecount,int nprocess,int nprocesscount);
+
+private:
+    Ui::MainWindow *ui;
+
+    iv::scheduler * mpscheduler = 0;
+
+    ivscheduler * mpivsch;
+};
+#endif // MAINWINDOW_H

+ 206 - 0
src/tool/tool_scheduler/mainwindow.ui

@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QPushButton" name="pushButton_Load">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>40</y>
+      <width>89</width>
+      <height>25</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Load</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_Start">
+    <property name="geometry">
+     <rect>
+      <x>420</x>
+      <y>330</y>
+      <width>89</width>
+      <height>25</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Start</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_Lon">
+    <property name="geometry">
+     <rect>
+      <x>300</x>
+      <y>140</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_Lat">
+    <property name="geometry">
+     <rect>
+      <x>300</x>
+      <y>190</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_Head">
+    <property name="geometry">
+     <rect>
+      <x>300</x>
+      <y>240</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_FilePath">
+    <property name="geometry">
+     <rect>
+      <x>230</x>
+      <y>40</y>
+      <width>541</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_Cycle">
+    <property name="geometry">
+     <rect>
+      <x>240</x>
+      <y>330</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_CycleProcess">
+    <property name="geometry">
+     <rect>
+      <x>240</x>
+      <y>400</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_Process">
+    <property name="geometry">
+     <rect>
+      <x>240</x>
+      <y>453</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label">
+    <property name="geometry">
+     <rect>
+      <x>160</x>
+      <y>140</y>
+      <width>67</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Lon</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_2">
+    <property name="geometry">
+     <rect>
+      <x>160</x>
+      <y>200</y>
+      <width>67</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Lat</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_3">
+    <property name="geometry">
+     <rect>
+      <x>160</x>
+      <y>250</y>
+      <width>67</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Head</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_4">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>330</y>
+      <width>67</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Cycle</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_5">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>410</y>
+      <width>81</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>CycleNum</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_6">
+    <property name="geometry">
+     <rect>
+      <x>110</x>
+      <y>460</y>
+      <width>67</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Process</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>28</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 14 - 0
src/tool/tool_scheduler/scheduler.xml

@@ -0,0 +1,14 @@
+<xml>	
+	<scheduler_unit>
+		<lat>39.1</lat>
+		<lon>117.2</lon>
+		<heading>360</heading>
+		<stoptime>30</stoptime>
+	</scheduler_unit>
+	<scheduler_unit>
+		<lat>39.2</lat>
+		<lon>117.2</lon>
+		<heading>360</heading>
+		<stoptime>10</stoptime>
+	</scheduler_unit>
+</xml>

+ 51 - 0
src/tool/tool_scheduler/tool_scheduler.pro

@@ -0,0 +1,51 @@
+QT       += core gui xml
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    ../../include/msgtype/gps.pb.cc \
+    ../../include/msgtype/gpsimu.pb.cc \
+    ../../include/msgtype/imu.pb.cc \
+    ../../include/msgtype/scheduler.pb.cc \
+    gnss_coordinate_convert.cpp \
+    ivscheduler.cpp \
+    main.cpp \
+    mainwindow.cpp
+
+HEADERS += \
+    ../../include/msgtype/gps.pb.h \
+    ../../include/msgtype/gpsimu.pb.h \
+    ../../include/msgtype/imu.pb.h \
+    ../../include/msgtype/scheduler.pb.h \
+    gnss_coordinate_convert.h \
+    ivscheduler.h \
+    mainwindow.h
+
+FORMS += \
+    mainwindow.ui
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}