2017年伊豆大島共同打ち上げ実験用電装モジュール搭載GPS測位プログラム

Dependents:   Hybrid_interruptGPS Hybrid_main_FirstEdtion rocket_logger_sinkan2018_v1 HYBRYD2018_IZU_ROCKET ... more

GPS_interrupt.h

Committer:
Sigma884
Date:
2018-11-14
Revision:
17:4b09630703c0
Parent:
16:ded6e8e2850f

File content as of revision 17:4b09630703c0:

/*=============================================================================
*   GPS_interrupt.lib ver 1.6
*   
*   Each palameters are not stable because they can be changed unexpectedly.
*   Therefor, you should use the funtions which have return value.
*   Then, you must not substitute any value for those palameters.
*   なんかコマンドの送信ミスがあるみたいで、確認して次に進めるようにすべきかも
*   PCソフトで設定して、バックアップ電池付けるのが正確っぽい
*=============================================================================*/
/**
 * @file GPS_interrupt.h
 * @brief GPSから送られてくるデータをバックグラウンドで解析し、呼び出せるライブラリ
 * @author 松本岳 and 林拓真
 * @note ver1.6
 */
 
#ifndef GPS_INTERRUPT_H_
#define GPS_INTERRUPT_H_

#include "mbed.h"//要る?
#define  EARTH_EQUATOR_RADIUS       6378136.6//地球の赤道半径[m]
#define  EARTH_POLAR_RADIUS         6356751.9//地球の極半径[m]
#define  EIRTH_AspectRatioInverse   298.257223563//地球の扁平率の逆数、0に近づくにつれ真球になる
#define  GPS_PI                     3.1415926535897932384626433832795
#define  GPS_2PI                    6.283185307179586476925286766559
#define  KNOT_TO_M_S                0.514444444444444444444444444

class GPS_interrupt{
    
    public:
        /**
        *  @bref GPS_interrupt's constructer
        *  @param _gps GPSと通信したいSerialバスのポインタ
        */
        GPS_interrupt(Serial *_gps);
        
        /**
        *  @bref GPSのボーレートを変更
        *  @param _baudrate GPSのボーレート(4800, 9600, 14400, 19200, 38400, 57600, 115200)
        */
        void changeGPSBaud(int _baudrate);
        
        /**
        *  @bref GPSのデータレート(1秒に何回データを送信するか)を変更
        *  @param _frequency GPSのデータレート(1~10)
        *  @retval false 失敗
        *  @retval true 成功
        */
        bool changeGPSFreq(int _frequency);
        
        /**
        *  @bref GPSのデータ内容を変更
        *  @param _GLL GLLの送信頻度(0 or 1)
        *  @param _RMC RMCの送信頻度(1)
        *  @param _VTG VTGの送信頻度(0 or 1)
        *  @param _GGA GGAの送信頻度(1)
        *  @param _GSA GSAの送信頻度(0 or 1)
        *  @param _GSV GSVの送信頻度(0 or 1)
        *  @retval false 失敗
        *  @retval true 成功
        */
        bool changeGPSData(int _GLL, int _RMC, int _VTG, int _GGA, int _GSA, int _GSV);
        
        void debug(bool tf);

    private:
        void initialize();//初期化関数
        void gps_auto_receive();
        bool processGPRMC(char *line);
        bool processGPGGA(char *line);
        void processPMTK(char *line);
        
        unsigned char checkSum(char *str);
        void rmc_initialize();
        void gga_initialize();
        
    private://別にpublicにしても良かったけれど、unexpectedlyに変更されるので使えないようにしてやった
        GPS_interrupt* gps_irq;
        int baudrate;
        int frequency;
        char gps_buffer_A[128];
        char gps_buffer_B[128];
        //static char gps_buffer_C[128];
        bool debugFlag;
        int data_sum; //for ChangeGPSData
        int flag_change_freq; // for ChangeGPSFreq
        int flag_change_data; // for ChangeGPSData
        int wait_change;
        
    public:
        double latitude;
        double longitude;
        int year;
        int month;
        int day;
        int hour;
        int minutes;
        float seconds;
        float knot;
        float degree;
        float height;
        float geoid;
        int number;
        
    public:
        char *gps_read_buffer;
        bool gps_readable;
    private:
        Serial *gps;
    public:
    
        /** 経度を返す関数
         * @brief 経度を取得
         * @return double型 経度
         * @note inline展開したつもり
         */
        inline double Longitude(){
            return longitude;
        }
        
        /** 緯度を返す関数
         * @brief 緯度を取得
         * @return double型 緯度
         * @note inline展開したつもり
         */
        inline double Latitude(){
            return latitude;
        }
        
        /** 年を返す関数
         * @brief 年を取得
         * @return int型 年
         * @note inline展開したつもり
         */
        inline int Year(){
            return year;
        }
        
        /** 月を返す関数
         * @brief 月を取得
         * @return int型 月
         * @note inline展開したつもり
         */
        inline int Month(){
            return month;
        }
        
        /**  日にちを返す関数
         * @brief 日にちを取得
         * @return int型 日にち
         * @note inline展開したつもり
         */
        inline int Day(){
            return day;
        }
        
        /**  時間を返す関数
         * @brief 時間を取得
         * @return int型 時間
         * @note inline展開したつもり
         */
        inline int Hour(){
            return hour;   
        }
        
        /** 分を返す関数
         * @brief 分を取得
         * @return int型 分
         * @note inline展開したつもり
         */
        inline int Minutes(){
            return minutes;
        }
        
        /**  秒を返す関数
         * @brief 秒を取得
         * @return float型 秒
         */
        inline float Seconds(){
            return seconds;   
        }
        
        /** 経度・緯度を取得できる関数
         * @brief 2つの変数に経度、緯度の順に値を代入する
         * @param lon double型 経度 ポインタ
         * @param lat double型 緯度 ポインタ 
         * @return データが有効かどうか 有効ならtrue, 無効ならfalse
         * @note 2つ変数を作って、そのアドレスを引数に与えてください。
         */
        inline bool getPosition(double *lon, double *lat){
            *lon = longitude;
            *lat = latitude;
            if(gps_readable)    return true;
            else    return false;   
        }
        
        /** 経度・緯度を取得できる関数
         * @brief 2つの配列に経度、緯度の順に値を代入する
         * @param lonlat double型 要素2の配列
         * @return データが有効かどうか 有効ならtrue, 無効ならfalse
         * @note 要素2の配列を作って、そのアドレスを引数に与えてください。
         */
        inline bool getPosition(float *lonlat){
            lonlat[0] = longitude;
            lonlat[1] = latitude;
            if(gps_readable)    return true;
            else    return false;   
        }
        
        /** 日付・時刻を取得できる関数
         * @brief 6つの変数に年、月、日、時間、分、秒の順に値を代入する
         * @param _year int型 年 ポインタ
         * @param _month int型 月 ポインタ
         * @param _day int型 日 ポインタ
         * @param _hour int型 時間 ポインタ
         * @param _minutes int型 分 ポインタ
         * @param _seconds float型 秒 ポインタ 
         * @return データが有効かどうか 有効ならtrue, 無効ならfalse
         * @note 6つ変数を作って、そのアドレスを引数に与えてください。
         */
        inline bool getUTC(int *_year, int *_month, int *_day, int *_hour, int *_minutes, float *_seconds){
            *_year = year;
            *_month = month;
            *_day = day;
            *_hour = hour;
            *_minutes = minutes;
            *_seconds = seconds; 
            if(gps_readable)    return true;
            else    return false;   
        }
        
        /** 世界協定時間の日付・時刻を取得できる関数
         * @brief 要素数6の配列に年、月、日、時間、分、秒の順に値を代入する
         * @param (*_utc) float型 秒 アドレス 
         * @return データが有効かどうか 有効ならtrue, 無効ならfalse
         * @detail 要素6の配列を作って、そのアドレスを引数に与えてください。
         */
        inline bool getUTC(float *_utc){
            _utc[0] = (float)year;
            _utc[1] = (float)month;
            _utc[2] = (float)day;
            _utc[3] = (float)hour;
            _utc[4] = (float)minutes;
            _utc[5] = seconds;
            
            if(gps_readable)    return true;
            else    return false;
        }
        
        /** 世界協定時間の日付・時刻を取得できる関数
         * @brief 要素数6の配列に年、月、日、時間、分、秒の順に値を代入する
         * @param _utc int型 秒 ポインタ 
         * @return データが有効かどうか 有効ならtrue, 無効ならfalse
         * @note 要素6の配列を作って、そのアドレスを引数に与えてください。
         */
        inline bool getUTC(int *_utc){
            _utc[0] = year;
            _utc[1] = month;
            _utc[2] = day;
            _utc[3] = hour;
            _utc[4] = minutes;
            _utc[5] = (int)seconds;
            if(gps_readable)    return true;
            else    return false;
        }
        
        /** 速度・進行方角を取得できる関数
         * @brief 2つの変数に速度、進行方角の順に値を代入する
         * @param _knot double型 経度 ポインタ [knot]
         * @param _degree double型 緯度 ポインタ [degree] 北から右回り正です。
         * @return データが有効かどうか 有効ならtrue, 無効ならfalse
         * @detail 2つ変数を作って、そのアドレスを引数に与えてください。
         */
        inline bool getSpeedVector(float *_knot, float *_degree){
            *_knot = knot;
            *_degree = degree;   
            if(gps_readable)    return true;
            else    return false;
        }
        
        /** 捕捉衛星数を取得できる関数
         * @brief 捕捉衛星数を返します。 
         * @return int型 捕捉衛星数 アドレス 
         */
        inline int Number(){
            return number;   
        }
        
        /** 標高を取得できる関数
         * @brief 標高を返します。 
         * @return double型 標高 アドレス 
         */
        inline float Height(){
            return height;   
        }
        
        
        /** 速さを取得できる関数
         * @brief 速さを返します。 
         * @return double型 速さ アドレス[knot] 
         */
        inline float Knot(){
            return knot;   
        }
        
        
        /** 進行方角を取得できる関数
         * @brief 進行方角を返します。 
         * @return double型 進行方角 アドレス 北から右回り正です。 
         */
        inline float Degree(){
            return degree;   
        }
        
        /** 目標座標までの直線距離を計算
        * @brief 距離を[m]で返します
        * @param x 目標経度
        * @param y 目標緯度
        */
        float Distance(double x, double y);
};
/////////////////
/////sample//////
/////////////////
/**
@code
#include "mbed.h"
#include "GPS_interrupt.h"
Serial pc(USBTX, USBRX);
Serial mygps(p9, p10);

GPS_interrupt gps(&mygps);//, 115200, 10, 115200);

void bootFunction(){//do not need
    pc.printf("\r\n");
    pc.printf("start LPC1768 boot phase\r\n");
    wait(0.5);
    for(int i = 0;i < 100;i++){
        pc.printf("Loading... : %3d [%%]\r", i);
        wait(0.025);
    }
    pc.printf("Loading... : %3d [%%]\r\n", 100);
    pc.printf("\t-> finished!!\r\n");
    pc.printf("System : %d Hz\r\n", SystemCoreClock );
    wait(0.5);
    pc.printf("start main program\r\n");
    wait(0.1);
    pc.printf("initialize");
    wait(0.75);
    pc.printf(" -> OK\r\n");
    wait(0.1);
    pc.printf("GPS Connecting");
    wait(0.5);
    pc.printf(".");
    wait(0.5);
    pc.printf(".");
    wait(0.5);
    pc.printf(".");
    wait(0.5);
    pc.printf(".");
    wait(0.5);
    pc.printf(".");
    wait(0.5);
    pc.printf(".");
    wait(0.5);
    while(1){
        if(gps.gps_readable)    break;   
    }
    pc.printf(" -> OK\r\n");
    pc.printf("start!!\r\n\r\n");
    wait(0.5);
}

int main() {
    
    pc.baud(115200);
    //mygps.baud(9600);
    
    bootFunction();
    
    while(1){
        double xy[2] = {0};
        float utc[6] = {0};
        gps.getPosition(xy);
        gps.getUTC(utc);
        pc.printf("\033[K");
        pc.printf("%d/%d/%d %d:%d:%02.2f ",(int)utc[0],(int)utc[1], (int)utc[2], (int)utc[3], (int)utc[4] ,utc[5]); 
        pc.printf("(%3.7fe,%3.7fn) ",xy[0], xy[1]);
        pc.printf("%d satellites, %.2f[m], %.3f[m/s], %3.2f[degree]\r", gps.Number(), gps.Height(), gps.Knot()*1852/3600, gps.Degree());   
        wait(0.1);
    }
}
@codeend
*/
#endif