/********************************************************************** Ti⇒経過秒変換処理 種別:sub (1)処理概要 パラメータで指定したTIを衛星時刻に変換して通知する。 (2)呼出形式 int ti2es ( const char *estimated_utc, uint32_t eti_base, double *elapsed_seconds, uint32_t *eti_ext[, uint32_t day] ) (3)パラメタ説明 ・ estimated_utc (入力/char) 処理するデータの時刻を指定する。(YYYYMMDDhhmmss) ・ eti_base (入力/uint32_t) 変換する時刻 (TI) を指定する。値は31.25msec(2^-5sec) ・ elapsed_seconds (出力/double) 変換した衛星時刻が格納される。(単位:秒) ・ eti_ext (出力/uint32_t) 対応するETIが格納される。(単位:サイクル数) ・ day(入力/uint32_t) 時刻校正表の検索範囲。(単位:±日) 省略可。省略時は範囲無制限として処理する。 ・ 復帰値 (出力/int) RET_NORMAL :正常終了 RET_BEFORE_FIRST_RECORD :校正結果が衛星時刻校正表の最初のレコード以前(最初のレコードからの外挿) RET_AFTER_LAST_RECORD :校正結果が衛星時刻校正表の最終レコード以降(最終レコードからの外挿) RET_BETWEEN_DISCONT_RECORDS :校正結果がTI不連続区間に該当(外挿した) RET_PARAM_ERR :入力パラメータチェックエラー RET_FILE_UNSET_ERR :ファイルパス未設定 RET_FILE_OPEN_ERR :ファイルオープンエラー RET_FILE_READ_ERR :ファイルリードエラー RET_OUT_OF_RANGE_ERR :指定範囲に該当TI無し RET_RUNOUT_OF_EXT_ERR :ETI拡張部のパーティション部、ETI機上拡張部の領域を使い切った RET_CALC_ERR :算出不可 (4) 作成日 2011/02/10 共通化 2012/11/15 Ver2.0 y.yoneda インデントの調整 2012/11/21 Ver2.0 y.yoneda Ver2.0 対応 2013/06/14 Ver2.1.0 fips 校正表最新の時刻よりも未来の時刻を指定且つ、校正表最新のTIよりも小さいTIを指定 された場合、1サイクル先の未来時刻ではなく、過去側の時刻を計算するように修正 (校正表先頭に対しても同様) 2013/07/26 Ver2.1.1 fips 予想時刻が不連続区間且つ、その両ペアのTIが昇順である場合に、指定TIが両ペアのTIの 間に挟まれない場合でも計算するように修正 校正表の先頭以前、最終以降の判定を分離 2013/08/ Vre3.0.0 fips 検索範囲のための引数を追加(day2) 不連続区間での計算に用いるレートの検索方法変更 (計算に使用するTI-UTCペアに一番近いレートとする) 2014/09/01 Ver3.0.2 fae 連続区間の校正まで処理継続するように修正 2015/02/24 Ver3.1.0 fae 検索範囲に洩れる区間がないように修正 estimated_utcの文字数チェックを追加して14bytes固定使用するように修正 2015/10/02 Ver3.1.1 fae 未来側の範囲外に最も近い解があり且つ、過去側の範囲内に解がある場合に、 過去側の解を採用するように修正 2015/12/22 Ver3.1.2 fae 過去側の解が存在する場合でも未来側の解を検索し、過去側/未来側で もっとも近い方を解とするように修正 連続・不連続に関わらず、ロールオーバー検出時に返すETI拡張部はインクリメント またはデクリメントするように修正 ***********************************************************************/ #include #include #include /* Add Ver2.0 */ #include #include #include #include "TimeCal_type.h" /* Chg Ver2.0 */ #include "SATCA_com.h" int proc_ti2es(const char *estimated_utc, uint32_t eti_base, double *elapsed_seconds, uint32_t *eti_ext, uint32_t day, uint32_t day2); /* Chg Ver3.0.0 day2追加 */ void get_rec_range(double In_SATsec, TiTm_tbl *titm, TiTm_work *wktitm); void read_tbl_TPktTI(TiTm_tbl *titm, TiTm_work *wktitm); int search_pair_after(int top, int last, double search_Sec, TiTm_tbl *titm); void search_before(int start_rec, TiTm_tbl *titm, TiTm_work *wktitm); void search_after(int start_rec, TiTm_tbl *titm, TiTm_work *wktitm); int between_pair(int read_cnt, TiTm_tbl *titm, TiTm_work *wktitm, int kako_flg); int discontinuity_cal(int read_cnt, int kako, TiTm_tbl *titm, TiTm_work *wktitm, int rollover); int rtn_update(int read_cnt, int kako, TiTm_tbl *titm, TiTm_work *wktitm, double rate, int rollover, int rc); /* Chg Ver3.0.0 int raterec -> double rate */ void rtn_eq_update(int read_cnt, TiTm_tbl *titm, TiTm_work *wktitm); int func_ti2es(const char *estimated_utc, uint32_t eti_base, double *elapsed_seconds, ... ) { int ir; uint32_t a; uint32_t *eti_ext; /* 入力パラメータ(固定引数) */ uint32_t day = (uint32_t)UINT32_MAX; /* 入力パラメータ(可変引数) */ uint32_t day2 = (uint32_t)UINT32_MAX; /* 入力パラメータ(可変引数)Add Ver3.0.0 */ va_list arg; va_start(arg, elapsed_seconds); /* elapsed_secondsを最終仮引数として使用 */ eti_ext = (uint32_t *)va_arg(arg, uint32_t *); a = va_arg(arg, uint32_t); if(a != UINT32_MAX){ day = a; /* add Ver3.0.0 */ a = va_arg(arg, uint32_t); if(a != UINT32_MAX){ day2 = a; }else{ day2 = day; } } va_end(arg); ir = proc_ti2es(estimated_utc, eti_base, elapsed_seconds, eti_ext, day, day2); return(ir); } /* Chg Ver3.0.0 day2追加 */ int proc_ti2es(const char *estimated_utc, uint32_t eti_base, double *elapsed_seconds, uint32_t *eti_ext, uint32_t day, uint32_t day2) { /****************************************************************/ /* 領域定義 */ /****************************************************************/ static TiTm_tbl titm; /* 基準時刻設定領域 */ static TiTm_work wktitm; /* 作業領域 */ double In_SATsec; int ir; char cwk[50]; /* Chg Ver3.0.0 day2のチェック追加 *//* Chg Ver3.1.0 estimated_utcチェック追加 */ if( elapsed_seconds == NULL || eti_ext == NULL || ((day == (uint32_t)0) && (day2 == (uint32_t)0)) || estimated_utc == NULL || strlen(estimated_utc) < 14 ) { return(RET_PARAM_ERR); } /****************************************************************/ /* 初めての呼び出し時、衛星時刻校正表を読み込む */ /****************************************************************/ memset( cwk, 0x00, sizeof(cwk) ); memcpy( cwk, estimated_utc, 14 ); /* Chg Ver3.1.0 strcpy -> memcpy */ strcat( cwk, "000000" ); /* 入力の指定時刻を経過秒形式に変換 */ ir = utc2es( TIME_STR_KIND_MMDD, cwk, &In_SATsec ); /* Chg Ver2.0 */ if( ir != RET_NORMAL ) { /* Chg Ver2.0 */ #ifdef DBG_TITM printf("ti2es[%d] utc2es Error!! return-code[%d] [%s]\n",__LINE__, ir, cwk ); #endif return(ir); } #ifdef DBG_TITM printf( "ti2es[%d] ti2es :****************************************************** \n", __LINE__ ) ; printf( "ti2es[%d] estimated_utc[%s] In_SATsec[%f] check_ti[%u] \n", __LINE__, estimated_utc, In_SATsec, eti_base ) ; #endif /* Chg Ver2.0 以降の処理を全面的に変更 */ /* 作業領域の初期化 */ wktitm.In_Ti_d = eti_base; wktitm.In_SATsec_d = In_SATsec; wktitm.Satt = 0.0; wktitm.ETI = 0; wktitm.rtn = RET_OUT_OF_RANGE_ERR; wktitm.subsec = -1.0; wktitm.first = 0; wktitm.last = 0; wktitm.search_end = FLAG_OFF; wktitm.In_day = day; wktitm.In_daysec = (double)day * DAY_SEC; wktitm.In_day2 = day2; /* Add Ver3.0.0 day2 */ wktitm.In_daysec2 = (double)day2 * DAY_SEC; /* Add Ver3.0.0 day2 */ if( day > (uint32_t)SEARCH_DAY_COUNT_HALF ) { wktitm.day = (uint32_t)SEARCH_DAY_COUNT_HALF; wktitm.daysec = (double)SEARCH_DAY_COUNT_HALF * DAY_SEC; } else { wktitm.day = day; wktitm.daysec = (double)day * DAY_SEC; } /* Add Ver3.0.0 day2 */ if( day2 > (uint32_t)SEARCH_DAY_COUNT_HALF ) { wktitm.day2 = (uint32_t)SEARCH_DAY_COUNT_HALF; wktitm.daysec2 = (double)SEARCH_DAY_COUNT_HALF * DAY_SEC; } else { wktitm.day2 = day2; wktitm.daysec2 = (double)day2 * DAY_SEC; } /*************************************************************************** <処理解説> ・入力指定時刻を中心として、指定検索範囲の時刻校正表を読み込み、 入力eti_baseに対応する時刻が指定時刻に一番近い情報を取得する。 ・指定検索範囲が一度に読み込めるレコード数の範囲より広い場合、 中心の入力指定時刻から外側(過去側&未来側)に向かって、再読み込み を繰り返すことで対処する。 ・検索を入力指定時刻に近い情報から処理することにより、入力eti_baseに対応 する時刻が取得できたら、それが指定時刻に一番近い情報となる。 ******************************************************************************/ uint32_t bef_end = day; /* 0以下:end */ uint32_t aft_end = day2; /* 0以下:end Chg Ver3.0.0 day -> day2 */ int bef_aft_flg = 1; /* 0:bef,!=0:aft */ double bef_SATsec = In_SATsec; double aft_SATsec = In_SATsec; while( 1 ) { ir = TiTm_Init_Sat( &titm, In_SATsec, wktitm.day, wktitm.day2 ); /* 衛星時刻校正表データの抽出 Chg Ver3.0.0 day2追加 */ if( ir != RET_NORMAL ) { #ifdef DBG_TITM printf("ti2es[%d] TiTm_Init_Sat Error!! return-code[%d] [%s]\n",__LINE__, ir, titm.SATCA_Init.fname ); #endif return(ir); } get_rec_range( In_SATsec, &titm, &wktitm ); /* 探索範囲を設定 */ #ifdef DBG_TITM printf("ti2es[%d] Read[%s] file_rec[%d]==Table_rec[0] \n",__LINE__, titm.SATCA_Init.fname, titm.SATCA_top_rec ); printf("ti2es[%d] first_rec[%d] last_rec[%d] \n",__LINE__, wktitm.first, wktitm.last ); #endif /* 抽出データ内から、eti_baseに対応する時刻が指定時刻に一番近い情報を取得する */ read_tbl_TPktTI( &titm, &wktitm ); /* 入力TimePacketTI対応経過秒取得 */ if( wktitm.search_end == FLAG_ON ) { /* 探索終了フラグONによる終了 */ break; } if( (wktitm.first <= 1) && (titm.SATCA_cnv_topflg == 1) ) { bef_end = 0; /* 先頭レコード展開済み */ } if( (wktitm.last >= (titm.SATCA_cnv_rdcnt-1)) && (titm.SATCA_cnv_endflg == 1) ) { aft_end = 0; /* 最終レコード展開済み */ } if( (bef_aft_flg != 0 || aft_end <= 0) && wktitm.subsec >= 0 && wktitm.rtn == RET_NORMAL ) { /* Chg Ver3.0.2 終了条件追加(wktitm.rtn == RET_NORMAL) */ break; /* 取得情報あり */ } if( bef_end <= 0 && aft_end <= 0 ) { break; /* 指定範囲検査済み */ } if( (bef_aft_flg != 0 && bef_end <= 0) || (bef_aft_flg == 0 && aft_end > 0) ) { aft_SATsec += (wktitm.daysec + wktitm.daysec2); /* Chg Ver3.1.0 加算修正(wktitm.daysec2 * 2 -> wktitm.daysec + wktitm.daysec2) */ In_SATsec = aft_SATsec; aft_end -= wktitm.day2; bef_aft_flg = 1; } else { bef_SATsec -= (wktitm.daysec + wktitm.daysec2); /* Chg Ver3.1.0 減算修正(wktitm.daysec * 2 -> wktitm.daysec + wktitm.daysec2) */ In_SATsec = bef_SATsec; bef_end -= wktitm.day; bef_aft_flg = 0; } } *elapsed_seconds = wktitm.Satt; *eti_ext = wktitm.ETI; #ifdef DBG_TITM printf( "ti2es[%d] :elapsed_seconds[%f] \n", __LINE__, wktitm.Satt) ; printf( "ti2es[%d] :eti_ext[%d] \n", __LINE__, wktitm.ETI ) ; printf( "ti2es[%d] :****************************************************** ti2es \n", __LINE__ ) ; #endif return( wktitm.rtn ); } /****************************************************************/ /* 指定経過秒を挟むペアの検索処理 */ /* top :検索レコード範囲の最初 */ /* last :検索レコード範囲の最後 */ /* search_Sec :検索する経過秒の指定 */ /* titm :時刻校正用変換テーブルポインタ */ /* 戻り値:指定経過秒を挟むペアの未来側レコード */ /* */ /* ※入力指定時刻が抽出データ範囲内であることが呼び出し条件 */ /****************************************************************/ int search_pair_after( int top, int last, double search_Sec, TiTm_tbl *titm ) { int pos = 1; int top_pos = top; int last_pos = last; #ifdef DBG_TITM printf( "ti2es[%d] \n", __LINE__ ); #endif if( top_pos < last_pos ) { while(1) { if( (top_pos == last_pos) || ((top_pos+1) == last_pos) ) { break; } pos = top_pos + (last_pos - top_pos) / 2; if( search_Sec == titm->SATCA_cnv_tbl[pos].tpktTI_SATsec ) { top_pos = pos; last_pos = top_pos + 1; break; } else if( search_Sec < titm->SATCA_cnv_tbl[pos].tpktTI_SATsec ) { last_pos = pos; } else { top_pos = pos; } } } return(last_pos); } /****************************************************************/ /* 探索範囲の最後の位置を取得する */ /****************************************************************/ void get_rec_range( double In_SATsec, TiTm_tbl *titm, TiTm_work *wktitm ) { int pos = titm->SATCA_cnv_rdcnt - 1; int top_pos = 0; int last_pos = 0; double Search_SATsec = In_SATsec - wktitm->daysec; #ifdef DBG_TITM printf( "ti2es[%d] \n", __LINE__ ); #endif wktitm->In_SATsec_w = In_SATsec; top_pos = search_pair_after( 0, pos, Search_SATsec, titm ); if( (top_pos - OVERLAP_READ_COUNT) > 1 ) { top_pos -= OVERLAP_READ_COUNT; } else top_pos = 0; wktitm->first = top_pos; Search_SATsec = In_SATsec + wktitm->daysec2; last_pos = search_pair_after( 0, pos, Search_SATsec, titm ); if( (last_pos + OVERLAP_READ_COUNT) < (titm->SATCA_cnv_rdcnt - 1) ) { last_pos += OVERLAP_READ_COUNT; } else last_pos = titm->SATCA_cnv_rdcnt - 1; wktitm->last = last_pos; return; } /****************************************************************/ /* 入力TimePacketTI対応経過秒取得 */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /****************************************************************/ void read_tbl_TPktTI( TiTm_tbl *titm, TiTm_work *wktitm ) { int read_cnt = 0; int discontinuity = 0; double subsec_back = -2.0; #ifdef DBG_TITM printf( "ti2es[%d] read_tbl_TPktTI start : In_SATsec_d[%f] first[%f] last[%f]\n", __LINE__, wktitm->In_SATsec_d, titm->SATCA_cnv_tbl[wktitm->first].tpktTI_SATsec, titm->SATCA_cnv_tbl[wktitm->last].tpktTI_SATsec ) ; #endif if( titm->SATCA_cnv_tbl[wktitm->first].tpktTI_SATsec < wktitm->In_SATsec_d && wktitm->In_SATsec_d <= titm->SATCA_cnv_tbl[wktitm->last].tpktTI_SATsec ) { /* 入力指定時刻が抽出データ範囲内 */ read_cnt = search_pair_after(wktitm->first, wktitm->last, wktitm->In_SATsec_d, titm); /* 入力指定時刻を挟むペアを探す */ if( wktitm->In_Ti_d == titm->SATCA_cnv_tbl[read_cnt-1].tpktTI ) { /* ペアの過去側TIが一致 */ rtn_eq_update(read_cnt-1, titm, wktitm); } else { int ret = between_pair(read_cnt, titm, wktitm, FLAG_OFF); if( ret == DATA_UPDATE ) { /* 不連続区間の過去・未来からの外挿で返却情報が登録された */ wktitm->search_end = FLAG_ON; return; } } if( wktitm->subsec >= 0 ) { if( wktitm->Satt <= wktitm->In_SATsec_d ) { /* 未来側の検索と計算処理 */ search_after(read_cnt+1, titm, wktitm); } else { /* 過去側の検索と計算処理 */ search_before(read_cnt-1, titm, wktitm); } /* 返却情報が登録されているので、これ以上の検索および計算は不要 */ #ifdef DBG_TITM printf( "ti2es[%d] read_tbl_TPktTI end \n", __LINE__ ) ; #endif if( wktitm->rtn == RET_NORMAL ) { /* Add Ver3.1.0 FLAG_ON条件追加 */ wktitm->search_end = FLAG_ON; } return; } /* 過去側の検索と計算処理 */ search_before(read_cnt-1, titm, wktitm); // Del Ver3.1.2 未来側の検索と計算処理実施(最も近い解を求めるため) // if( wktitm->subsec >= 0 && wktitm->rtn == RET_NORMAL ) { /* Add Ver3.1.0 終了条件追加 */ // wktitm->search_end = FLAG_ON; // return; // } /* 未来側の検索と計算処理 */ search_after(read_cnt+1, titm, wktitm); #ifdef DBG_TITM printf( "ti2es[%d] read_tbl_TPktTI end \n", __LINE__ ) ; #endif if( wktitm->subsec >= 0 && wktitm->rtn == RET_NORMAL ) { /* Chg Ver3.0.2 終了条件追加(wktitm->rtn == RET_NORMAL) */ wktitm->search_end = FLAG_ON; } return; } /* 入力指定時刻が抽出データ範囲外の場合、抽出したレコード分ループして処理する */ if( titm->SATCA_cnv_tbl[wktitm->last].tpktTI_SATsec < wktitm->In_SATsec_d ) { /* 抽出データは入力指定時刻より過去側に位置するので、過去側に向かって探索する */ search_before(wktitm->last, titm, wktitm); /* Ver2.1 2013/06/14 add 過去側の時刻計算も行う*/ search_before(wktitm->last-1, titm, wktitm); } else { /* 抽出データは入力指定時刻より未来側に位置するので、未来側に向かって探索する */ search_after(wktitm->first, titm, wktitm); /* Ver2.1 2013/06/14 add 未来側の時刻計算も行う*/ search_after(wktitm->first+1, titm, wktitm); } #ifdef DBG_TITM printf( "ti2es[%d] read_tbl_TPktTI end \n", __LINE__ ) ; #endif return; } /****************************************************************/ /* 過去側に向かって探索し、ペア間処理を行う */ /* start_rec :探索開始レコードを指す */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /****************************************************************/ void search_before(int start_rec, TiTm_tbl *titm, TiTm_work *wktitm) { int read_cnt = start_rec; double subsec_back = wktitm->subsec; double limit_subsec = wktitm->In_SATsec_d - subsec_back; double limit_daysec = wktitm->In_SATsec_w - wktitm->daysec; #ifdef DBG_TITM printf( "ti2es[%d] \n", __LINE__ ); #endif while( read_cnt >= 0 ) { between_pair(read_cnt, titm, wktitm, FLAG_ON); if( subsec_back >= 0 ) { if( (wktitm->subsec < subsec_back) || (titm->SATCA_cnv_tbl[read_cnt-1].tpktTI_SATsec < limit_subsec) ) { /* 返却情報更新 または 探索範囲オーバー */ break; } } else { if( (wktitm->subsec >= 0) || (titm->SATCA_cnv_tbl[read_cnt-1].tpktTI_SATsec < limit_daysec) ) { /* 返却情報登録 または 探索範囲オーバー */ break; } } read_cnt--; } return; } /****************************************************************/ /* 未来側に向かって探索し、ペア間処理を行う */ /* start_rec :探索開始レコードを指す */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /****************************************************************/ void search_after(int start_rec, TiTm_tbl *titm, TiTm_work *wktitm) { int read_cnt = start_rec; double subsec_back = wktitm->subsec; double limit_subsec = wktitm->In_SATsec_d + subsec_back; double limit_daysec = wktitm->In_SATsec_w + wktitm->daysec2; /* Chg Ver3.0.0 wktitm->daysec -> wktitm->daysec2 */ #ifdef DBG_TITM printf( "ti2es[%d] \n", __LINE__ ); #endif while( read_cnt < (wktitm->last + 1) ) { between_pair(read_cnt, titm, wktitm, FLAG_OFF); if( subsec_back >= 0 ) { if( (wktitm->subsec < subsec_back) || (titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec > limit_subsec) ) { /* 返却情報更新 または 探索範囲オーバー */ break; } } else { if( (wktitm->subsec >= 0) || (titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec > limit_daysec) ) { /* 返却情報登録 または 探索範囲オーバー */ break; } } read_cnt++; } return; } /****************************************************************/ /* ペア間処理 */ /* read_cnt :ペアの未来側レコードを指す */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /****************************************************************/ int between_pair(int read_cnt, TiTm_tbl *titm, TiTm_work *wktitm, int kako_flg) { int discontinuity = 0; int ret = 0; #ifdef DBG_TITM printf( "ti2es[%d] read_cnt[%d] kako_flg[%d] topflg[%d] lastflg[%d] \n", __LINE__, read_cnt, kako_flg, titm->SATCA_cnv_topflg, titm->SATCA_cnv_endflg ); #endif /* 20130726 ver2.1.1 move 先頭、最終からの処理を分離 */ if( titm->SATCA_cnv_topflg != 0 && read_cnt == 0 ) { /* 先頭レコードから計算 */ if( wktitm->In_Ti_d < titm->SATCA_cnv_tbl[0].tpktTI ) { rtn_update(0, 0, titm, wktitm, titm->SATCA_cnv_tbl[0+0].tpktTI_dT, 0, RET_BEFORE_FIRST_RECORD); if( titm->SATCA_cnv_endflg != 0 && read_cnt == (titm->SATCA_cnv_rdcnt - 1) ) { rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, ROLL_OVER_MINUS, RET_AFTER_LAST_RECORD); } } else { rtn_update(0, 0, titm, wktitm, titm->SATCA_cnv_tbl[0+0].tpktTI_dT, ROLL_OVER_PLUS, RET_BEFORE_FIRST_RECORD); if( titm->SATCA_cnv_endflg != 0 && read_cnt == (titm->SATCA_cnv_rdcnt - 1) ) { rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, 0, RET_AFTER_LAST_RECORD); } } } else if( titm->SATCA_cnv_endflg != 0 && read_cnt == (titm->SATCA_cnv_rdcnt - 1) ) { /* 指定tiが最終レコード以降:最終時刻外挿計算登録 */ int read_cntE = titm->SATCA_cnv_rdcnt - 1; if( titm->SATCA_cnv_tbl[read_cntE].quality_flag[0] != 'E' ) { if( titm->SATCA_cnv_tbl[read_cntE].tpktTI < wktitm->In_Ti_d ) { rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, 0, RET_AFTER_LAST_RECORD); } else { rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, ROLL_OVER_MINUS, RET_AFTER_LAST_RECORD); } } else { /* 最終レコードが不連続区間 */ int raterec = 1; while( read_cntE - raterec > 0 ) { if( titm->SATCA_cnv_tbl[read_cntE - raterec].quality_flag[0] != 'E' ) { /* 直近過去の有効なレートを使用して、最終時刻外挿計算登録 */ if( titm->SATCA_cnv_tbl[read_cntE].tpktTI < wktitm->In_Ti_d ) { rtn_update(read_cntE, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cntE-raterec].tpktTI_dT, 0, RET_AFTER_LAST_RECORD); } else { rtn_update(read_cntE, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cntE-raterec].tpktTI_dT, ROLL_OVER_MINUS, RET_AFTER_LAST_RECORD); } break; } raterec++; } } } if( (read_cnt-kako_flg) >= 0 && wktitm->In_Ti_d == titm->SATCA_cnv_tbl[read_cnt-kako_flg].tpktTI ) { rtn_eq_update(read_cnt-kako_flg, titm, wktitm); return(ret); } else if( read_cnt != 0 && titm->SATCA_cnv_tbl[read_cnt-1].tpktTI < wktitm->In_Ti_d && wktitm->In_Ti_d < titm->SATCA_cnv_tbl[read_cnt].tpktTI ) { /* 範囲内にtiあり:昇順区間 */ if( titm->SATCA_cnv_tbl[read_cnt].quality_flag[0] != 'E' ) { /* 連続区間 */ rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, 0, RET_NORMAL); } else { discontinuity = 1; /* 不連続区間処理要 */ } } else if( read_cnt != 0 && titm->SATCA_cnv_tbl[read_cnt].tpktTI < titm->SATCA_cnv_tbl[read_cnt-1].tpktTI ) { if ( titm->SATCA_cnv_tbl[read_cnt-1].tpktTI < wktitm->In_Ti_d ) { /* 範囲内にtiあり:反転区間の反転前 */ if( titm->SATCA_cnv_tbl[read_cnt].quality_flag[0] != 'E' ) { rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, ROLL_OVER_PLUS, RET_NORMAL); } else { discontinuity = 1; /* 不連続区間処理要 */ } } else if( wktitm->In_Ti_d < titm->SATCA_cnv_tbl[read_cnt].tpktTI ) { /* 範囲内にtiあり:反転区間の反転後 */ if( titm->SATCA_cnv_tbl[read_cnt].quality_flag[0] != 'E' ) { rtn_update(read_cnt, 0, titm, wktitm, titm->SATCA_cnv_tbl[read_cnt+0].tpktTI_dT, 0, RET_NORMAL); } else { discontinuity = 1; /* 不連続区間処理要 */ } } } /* 20130726 ver2.1.1 add --start-- */ else if( (read_cnt != 0 && titm->SATCA_cnv_tbl[read_cnt-1].tpktTI < titm->SATCA_cnv_tbl[read_cnt].tpktTI) && titm->SATCA_cnv_tbl[read_cnt].quality_flag[0] == 'E' ) { discontinuity = 1; } /* 20130726 ver2.1.1 add --end-- */ if( discontinuity == 1 ) { int ret1,ret2; /* 不連続区間処理:①過去側からの算出 */ if ( titm->SATCA_cnv_tbl[read_cnt-1].tpktTI < wktitm->In_Ti_d ) { ret1 = discontinuity_cal(read_cnt-1, 1, titm, wktitm, 0); } else { ret1 = discontinuity_cal(read_cnt-1, 1, titm, wktitm, ROLL_OVER_MINUS); } /* 不連続区間処理:②未来側からの算出 */ if ( titm->SATCA_cnv_tbl[read_cnt].tpktTI < wktitm->In_Ti_d ) { ret2 = discontinuity_cal(read_cnt, 0, titm, wktitm, ROLL_OVER_PLUS); } else { ret2 = discontinuity_cal(read_cnt, 0, titm, wktitm, 0); } if( ret1 != CALC_BREAK && ret2 != CALC_BREAK ) { ret = DATA_UPDATE; } } #ifdef DBG_TITM printf( "ti2es[%d] rec_no[%d] SATsec[%f] ti[%f] discontinuity[%d] \n", __LINE__ , read_cnt, titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec, titm->SATCA_cnv_tbl[read_cnt].tpktTI, discontinuity ); #endif return(ret); } /****************************************************************/ /* 不連続区間外挿計算処理 */ /* read_cnt :計算の基となるレコードを指す */ /* kako :read_cntがペアの過去側なら 1 */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /* rollover :ロールオーバーなら 1 */ /****************************************************************/ int discontinuity_cal(int read_cnt, int kako, TiTm_tbl *titm, TiTm_work *wktitm, int rollover) { int raterec = 0; int ret = 0; double rate = 0.0; /* Add Ver3.0.0 */ /* Add Ver3.0.0 レート検索 */ rate = find_valid_rate(read_cnt, titm); if( rate < 0.0 ){ return(ret); } #ifdef DBG_TITM printf( "ti2es[%d] \n", __LINE__ ); #endif // if( titm->SATCA_cnv_tbl[read_cnt].quality_flag[0] == 'E' ) { // int rec_cnt = 1; // while( 1 ) { // if( (read_cnt - rec_cnt) > 0 ) { // if( titm->SATCA_cnv_tbl[read_cnt - rec_cnt].quality_flag[0] != 'E' ) { // /* 直近過去の有効なレートを使用して、最終時刻外挿計算登録 */ // raterec -= rec_cnt; // break; // } // } // if( (read_cnt + rec_cnt) < (wktitm->last + 1) ) { // if( titm->SATCA_cnv_tbl[read_cnt + rec_cnt].quality_flag[0] != 'E' ) { // /* 直近未来の有効なレートを使用して、最終時刻外挿計算登録 */ // raterec = rec_cnt; // break; // } // } // if( (read_cnt - rec_cnt) <= 0 && (read_cnt + rec_cnt) >= (wktitm->last + 1) ) { // /* 有効なレートが見つからなかった */ // return(ret); // } // rec_cnt++; // } // } if( rollover == 0 ){ // ret = rtn_update(read_cnt, kako, titm, wktitm, raterec, rollover, RET_BETWEEN_DISCONT_RECORDS); ret = rtn_update(read_cnt, kako, titm, wktitm, rate, rollover, RET_BETWEEN_DISCONT_RECORDS); }else{ // ret = rtn_update(read_cnt, kako, titm, wktitm, raterec, rollover, RET_BETWEEN_DISCONT_RECORDS_WITH_ROLLOVER); ret = rtn_update(read_cnt, kako, titm, wktitm, rate, rollover, RET_BETWEEN_DISCONT_RECORDS_WITH_ROLLOVER); } return(ret); } /****************************************************************/ /* 復帰情報更新処理 */ /* read_cnt :計算の基となるレコードを指す */ /* kako :read_cntがペアの過去側なら 1 */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /* raterec :read_cnt以外のレコードのレートを使用する !=0 */ /* rollover :ロールオーバーなら 1 */ /* rc :復帰コード */ /* */ /* update Ver3.0.0 第5引数をraterec -> rate */ /****************************************************************/ int rtn_update(int read_cnt, int kako, TiTm_tbl *titm, TiTm_work *wktitm, double rate, int rollover, int rc) { double setsat; double subsec; /* double rate; */ /* Del Ver3.0.0 */ double subTi; int rtn = NOT_UPDATE; #ifdef DBG_TITM printf( "ti2es[%d] rec_no[%d] \n", __LINE__, read_cnt ); #endif /* raterec != 0:指定レコード以外のレコードのレートを使用する場合 */ /* rate = titm->SATCA_cnv_tbl[read_cnt+raterec].tpktTI_dT; */ /* Del Ver3.0.0 */ /* 指定tiとレコードtiの差分算出 */ subTi = titm->SATCA_cnv_tbl[read_cnt].tpktTI - wktitm->In_Ti_d; /* ロールオーバーに伴うMAX値加減算 */ if( rollover == ROLL_OVER_PLUS ) { subTi += titm->SATCA_Init.xffmax + 1; } else if( rollover == ROLL_OVER_MINUS ) { subTi -= titm->SATCA_Init.xffmax + 1; } /* 経過秒の算出 */ setsat = titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec - subTi * rate; if( rc == RET_BETWEEN_DISCONT_RECORDS || rc == RET_BETWEEN_DISCONT_RECORDS_WITH_ROLLOVER ) { /* 不連続区間処理の場合、算出結果がペア間外なら登録情報の更新をしない */ if( kako != 0 ) { if( (setsat < titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec) || (titm->SATCA_cnv_tbl[read_cnt+1].tpktTI_SATsec < setsat) ) { /* 最後まで登録情報が算出できない場合は RET_OUT_OF_RANGE_ERR となる */ return(CALC_BREAK); } } else { if( (setsat < titm->SATCA_cnv_tbl[read_cnt-1].tpktTI_SATsec) || (titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec < setsat) ) { /* 最後まで登録情報が算出できない場合は RET_OUT_OF_RANGE_ERR となる */ return(CALC_BREAK); } } } if( wktitm->In_SATsec_d > wktitm->In_daysec ) { if( setsat < (wktitm->In_SATsec_d - wktitm->In_daysec) || (wktitm->In_SATsec_d + wktitm->In_daysec2) < setsat ) { /* 算出結果が指定範囲外になった場合、戻り値を変更する */ rc = RET_OUT_OF_RANGE_ERR; if( wktitm->rtn >=0 ){ /* Add Ver3.0.0 */ return(rtn); } } } else { if( setsat < 0 || (wktitm->In_SATsec_d + wktitm->In_daysec2) < setsat ) { /* 算出結果が指定範囲外になった場合、戻り値を変更する */ rc = RET_OUT_OF_RANGE_ERR; if( wktitm->rtn >=0 ){ /* Add Ver3.0.0 */ return(rtn); } } } /* 指定経過秒と算出経過秒の差分算出 */ if( setsat <= wktitm->In_SATsec_d ) { subsec = wktitm->In_SATsec_d - setsat; } else { subsec = setsat - wktitm->In_SATsec_d; } /* 経過秒の差分が、既に登録されている情報より小さい場合、登録情報を更新する *//* Add Ver.3.1.1 (wktitm->rtn < 0) */ if( wktitm->subsec < 0 || subsec < wktitm->subsec || wktitm->rtn < 0 ) { wktitm->Satt = setsat; // Chg Ver3.1.2 返すEXTのインクリメント/デクリメント条件変更 // if( rc == RET_BETWEEN_DISCONT_RECORDS_WITH_ROLLOVER || (rc == RET_AFTER_LAST_RECORD && rollover != 0 ) ) { // /* 不連続区間および最終レコード以降でロールオーバーありの場合、返すEXTをインクリメントまたはデクリメントする */ // *}* if( rollover != 0 ) { /* ロールオーバーありの場合、返すEXTをインクリメントまたはデクリメントする */ uint32_t eti_ext; if( subTi < 0 ) { eti_ext = titm->SATCA_cnv_tbl[read_cnt].ETI + 1; } else { eti_ext = titm->SATCA_cnv_tbl[read_cnt].ETI - 1; } /* ETIフラグの状態を反映する */ if( (titm->SATCA_cnv_tbl[read_cnt].ETI & ETI_FLAG_PATTERN) == 0 ) { /* ETIフラグoffの衛星時刻校正表の場合 */ #ifdef RET_RUNOUT_OF_EXT_ERR if( (eti_ext & ETI_FLAG_PATTERN) != 0 ) { rc = RET_RUNOUT_OF_EXT_ERR; } #endif wktitm->ETI = eti_ext & ETI_FLAG_MASK_PATTERN; } else { /* ETIフラグonの衛星時刻校正表の場合 */ #ifdef RET_RUNOUT_OF_EXT_ERR if( (eti_ext & ETI_FLAG_PATTERN) == 0 ) { rc = RET_RUNOUT_OF_EXT_ERR; } #endif wktitm->ETI = eti_ext | ETI_FLAG_PATTERN; } } else { wktitm->ETI = titm->SATCA_cnv_tbl[read_cnt].ETI; } wktitm->rtn = rc; wktitm->subsec = subsec; rtn = DATA_UPDATE; } #ifdef DBG_TITM if(rtn == DATA_UPDATE) printf( "ti2es[%d] ---------> RET_SAT[%f] subsec[%f] RET_ETI[%u] ret[%d] -update- \n", __LINE__ , wktitm->Satt, wktitm->subsec, wktitm->ETI, wktitm->rtn); else printf( "ti2es[%d] ---------> RET_SAT[%f] subsec[%f] RET_ETI[%u] ret[%d] -not update- \n", __LINE__ , setsat, subsec, titm->SATCA_cnv_tbl[read_cnt].ETI, rc); #endif return(rtn); } /****************************************************************/ /* 一致レコード復帰情報更新処理 */ /* read_cnt :計算の基となるレコードを指す */ /* titm :時刻校正用変換テーブルポインタ */ /* wktitm :作業領域ポインタ */ /****************************************************************/ void rtn_eq_update(int read_cnt, TiTm_tbl *titm, TiTm_work *wktitm) { double subsec; #ifdef DBG_TITM printf( "ti2es[%d] \n", __LINE__ ); #endif if( titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec <= wktitm->In_SATsec_d ) { subsec = wktitm->In_SATsec_d - titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec; } else { subsec = titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec - wktitm->In_SATsec_d; } if( wktitm->subsec < 0 || subsec < wktitm->subsec ) { wktitm->Satt = titm->SATCA_cnv_tbl[read_cnt].tpktTI_SATsec; wktitm->ETI = titm->SATCA_cnv_tbl[read_cnt].ETI; wktitm->rtn = RET_NORMAL; wktitm->subsec = subsec; } #ifdef DBG_TITM printf( "ti2es[%d] ---------> RET_SAT[%f] subsec[%f] RET_ETI[%u] ret[%d]\n", __LINE__ , wktitm->Satt, wktitm->subsec, wktitm->ETI, wktitm->rtn ); #endif return; }