位置情報

概要

本製品にはGNSSの電波を受信して位置情報を取得する機能を搭載しています。ここではレシピ言語から位置情報を取得する方法を紹介します。

位置情報取得機能の特徴

内蔵のGNSS受信機能の特徴を以下に示します。

位置情報の制御

位置情報の取得は該当のAPIをコールすることで、GNSSのハードウェアをONにしてGNSSのスキャンを開始します。GNSSは環境によって位置測位時間が変わることから、捕捉出来るまで処理を待たせる方法と捕捉したタイミングでイベントを発行する使い方がAPIで選択が出来ます。

位置情報の制御API

位置情報を制御するAPIは以下となります。

API 内容
1 MMG_GetGNSS() GNSS位置情報を取得するAPI

MMG_GetGNSS ()

GNSS位置情報を取得するAPIです。
1回だけ取得を行う方法と繰り返し取得を行う方法の2種類あります。

MMG_GetGNSS(int32 timeout, uint8 event_id, uint8 mode)
   timeout  : APIのタイムアウト時間[msec]
   event_id : 非同期実行の場合API処理完了後のイベントID1254
         同期実行の場合0EAPI_SYNC_RESULT
   mode     : 動作の指定
        MMG_GNSS_END 0              位置測位の停止
        MMG_GNSS_START_ONESHOT 1    1回だけ位置情報の測位をする非同期/同期
        MMG_GNSS_START_POLLING 2    1秒毎の繰り返しで位置情報の測位をする非同期のみ
    event_id=0の時にmode=2の指定は禁止です

※測位できる時間は環境にも影響するため、同期実行で利用される際には位置情報の取得用のAPIのタイムアウト値に注意ください。


位置情報(緯度経度)の値の取り方

取得した位置情報は、タスク間のデータ引継ぎ用メモリに格納されています。
APIのrcplib_TASK_GetArg()を利用して取り出します。

メモリの番号 内容 説明
rcplib_TASK_GetArg(0) double 緯度(latitude) 単位 [deg] (-90.0~+90.0) ※latitude=99999.0(MMG_GET_GNSS_RESULT)の場合は位置情報以外の通知
rcplib_TASK_GetArg(1) double 緯度(longitude) 単位 [deg] (-180.0~+180.0) ※latitudeが位置情報以外の通知の場合、longitudeはその内容になります。("modemMgrTask.h"の「API実行時のリザルトコード」参照)

非同期処理と同期処理の使い方

GNSS位置情報を取得するAPIを「非同期」で使用する際には、第2引数のevent_idに1-254の値を入れてAPIコールを行います。非同期のAPIコールはすぐにアプリケーションのコンテキストがもどってくるため、第1引数のAPIタイムアウト時間は意味を持ちません。
GNSS_UNSYNC

GNSS位置情報を取得するAPIを「同期」で使用する際には、第2引数のevent_idに0の値を入れてAPIコールを行います。同期のAPIコールはGNSSが捕捉出来るか、指定したTIMEOUT時間が過ぎるのどちらかまではアプリケーションのコンテキストが止まります。位置情報が捕捉出来たら次を実行するなどの連続した処理にはこちらの使い方が向いています。
GNSS_UNSYNC

SDKのサンプルコード内に非同期と同期のそれぞれの使い方のコードがありますので詳細はそちらをご参照願います。


コード例

位置情報を10分周期的に取得し、取得できた値を保存する例。
10分のタイマーを設定し、10分毎にMMG_GetGNSS()を1回だけ取得を試みます。

#include "eventLib.h"
#include "modemMgrTask.h"
#include "logAPI.h"
#include "olcAPI.h"

//////////////////////////////////////////////////////////////////
// internal define //
//////////////////////////////////////////////////////////////////
// 内部非同期イベント
#define EVENT_INIT   0
#define EVENT_TIMER  1
#define EVENT_GNSS_NOTIFY 2

// 10分タイマー値
#define TIMER_ID  0
#define GNSS_TIMER  1000*60*10 //60秒*10 = 10分

//GNSSタイムアウト値
#define TIMEOUT 60*1000 //1分

//////////////////////////////////////////////////////////////////
// event driven task process //
//////////////////////////////////////////////////////////////////
#ifdef C_SYNTAX
void main_loop(){
    WAIT_REQUEST_EVENT_QUEUE
#endif // C_SYNTAX
    rcplib_TASK_InitArg();

    uint16 event_id;
    event_id = rcplib_SV_Read(ENGINE_SVITEM_ID_TASKEVENTITEM_EVENT_ID);

    // 初期設定
    if(event_id == EVENT_INIT) {
        event_init();
    }
        // 周期イベント
    else if(event_id == EVENT_TIMER) {
        event_timer();
    }
    // GNSS受信イベント受信時の処理
    else if(event_id == EVENT_GNSS_NOTIFY) {
        event_gnss_notify(rcplib_TASK_GetArg(0), rcplib_TASK_GetArg(1));
    }
#ifdef C_SYNTAX
}
#endif // C_SYNTAX

//////////////////////////////////////////////////////////////////
// event function //
//////////////////////////////////////////////////////////////////

// 初期化処理
func event_init() {
    // 10分周期タイマー設定
    rcplib_TIMER_Create(TIMER_ID,GNSS_TIMER,1,EVENT_TIMER); 
    rcplib_TIMER_Start(TIMER_ID);

    // GNSS取得開始
    MMG_GetGNSS(TIMEOUT, EVENT_GNSS_NOTIFY, MMG_GNSS_START_ONESHOT);
}

// 10分周期イベント
func event_timer() {
    // GNSS取得再開
    MMG_GetGNSS(TIMEOUT, EVENT_GNSS_NOTIFY, MMG_GNSS_START_ONESHOT);
}

// GNSS受信のイベント処理
func event_gnss_notify(double latitude, double longitude) {
    str msg_1[18];        // GNSSログ出力用の文字列変数
    str msg_2[18];

    if(latitude == MMG_GET_GNSS_RESULT) {
        // エラー値の場合 MMG_GET_GNSS_RESULT==99999 
        rcplib_FORMAT_String(msg_1, "Error:%d        ", longitude);
        OLC_DisplayChar(OLC_CHAR_FORCE,0,0,msg_1);
        rcplib_LOG_Print(msg_1);
        MMG_GetGNSS(TIMEOUT, EVENT_GNSS_NOTIFY, MMG_GNSS_END);
    } else {
        // 取得に成功した緯度経度を保存
        rcplib_FORMAT_String(msg_1, "lat:%9.7f       ", latitude);
        rcplib_FORMAT_String(msg_2, "lon:%9.7f       ", longitude);
        OLC_DisplayChar(OLC_CHAR_FORCE,0,0,msg_1);
        OLC_DisplayChar(OLC_CHAR_FORCE,18,0,msg_2);
        rcplib_LOG_Print(msg_1);
        rcplib_LOG_Print(msg_2);
   }
    return(0);
}

サンプルコードの解説

「0101_ボタン長押しでGNSS位置測位1秒ポーリング開始⇔停止」

このサンプルコードではボタンを押下後にGNSSのスキャンを非同期処理で開始します。スキャンが完了してGNSSの位置測位が完了すると、受信イベントが発行され、latitudeとlongtudeの位置情報をログに出力します。もう一度ボタン押下すると、GNSSのスキャンが停止します。

「0102_GNSS位置測位を同期実行で10分毎に開始⇔停止」

このサンプルコードでは電源起動後10分周期のタイマーをセットすると共に、GNSSのスキャンを2分タイムアウトでの同期処理で開始します。2分以内にGNSSの位置情報が取得出来たらその情報をログに出力します。その後GNSSのスキャンを停止して、10分の周期タイマーの満了を待ちます。10分の周期タイマーが満了すると再度GNSSのスキャンを開始し、上記の処理を繰り返します。

関連情報等

各サンプルコードについて動作確認を行っておりますが、全ての環境において動作を保証するものではありません。正しく動作することを確認の上でご利用ください。

対応機種:KC4-C-100A/KC4-C-101A