#include #include #include #include #include #include #include #include #include #define DEBUG 1 #define IS_LITTLE_ENDIAN 1 #include "SylphideProcessor.h" #include "SylphideStream.h" typedef double float_sylph_t; #include "analyze_common.h" struct Options : public GlobalOptions { typedef GlobalOptions super_t; bool log_is_ubx; ///< ubx2ubxを実現するためのフラグ Options() : super_t(), log_is_ubx(false) {} ~Options(){} /** * コマンドに与えられた設定を読み解く * * @param spec コマンド * @return (bool) 解読にヒットした場合はtrue、さもなければfalse */ bool check_spec(const char *spec){ using std::cerr; using std::endl; static const char *available_keys[] = { "start_gpst", "start-gpst", "end_gpst", "end-gpst", "out", "in_sylphide"}; const char *value; if(value = get_value(spec, "log_is_ubx")){ log_is_ubx = is_true(value); std::cerr << "log_is_ubx" << ": " << (log_is_ubx ? "true" : "false") << std::endl; return true; } for(int i(0); i < sizeof(available_keys) / sizeof(available_keys[0]); i++){ if(value = get_value(spec, available_keys[i])){ return super_t::check_spec(spec); } } return false; } } options; using namespace std; typedef SylphideProcessor<> Processor_t; typedef Processor_t::G_Observer_t G_Observer_t; #define BUFFER_SIZE (PAGE_SIZE * 1) // 32 #define OBSERVER_SIZE (PAGE_SIZE * 32) // 1024 int good_packet(0); int bad_packet(0); double itow_0x0106(0); bool read_continue(true); /** * Gページ(u-bloxのGPS)の処理用関数 * Gページの内容が正しいかvalidateで確認した後、実処理を行うこと。 * {class, id} = {0x01, 0x02}のとき位置情報 * {class, id} = {0x01, 0x12}のとき速度情報 * {class, id} = {0x01, 0x03}のとき受信機状態 * {class, id} = {0x01, 0x04}のときDOP * {class, id} = {0x01, 0x06}のとき解情報 * {class, id} = {0x01, 0x30}のとき衛星情報 * {class, id} = {0x02, 0x10}のとき生情報 * * @param obsrever Gページのオブザーバー */ void g_packet_handler(const G_Observer_t &observer){ if(!observer.validate()){ bad_packet++; return; } G_Observer_t::packet_type_t packet_type(observer.packet_type()); if((packet_type.mclass == 0x01) && (packet_type.mid == 0x06)){ G_Observer_t::solution_t solution(observer.fetch_solution()); if(solution.status_flags & G_Observer_t::solution_t::TOW_VALID){ itow_0x0106 = observer.fetch_ITOW(); } if(itow_0x0106 >= options.end_gpstime){ read_continue = false; return; } } if(itow_0x0106 < options.start_gpstime){return;} good_packet++; for(int i = 0; i < observer.current_packet_size(); i++){ options.out() << observer[i]; } } /** * ファイル等のストリームからページ単位で切り出す関数 * * @param in ストリーム */ void stream_processor(istream &in){ char buffer[PAGE_SIZE]; char *buffer_head(buffer); int read_count_max(sizeof(buffer)); if(options.log_is_ubx){ buffer[0] = 'G'; buffer_head++; read_count_max--; } Processor_t processor(OBSERVER_SIZE); // ストリーム処理機を生成 processor.set_g_handler(g_packet_handler); // Gページの際の処理を登録 int count(0); while(read_continue && (!in.eof())){ count++; in.read(buffer_head, read_count_max); if(in.gcount() < read_count_max){ continue; } processor.process(buffer, sizeof(buffer)); } } int main(int argc, char *argv[]){ //stream_processor(cin); cerr << "log2ubx." << endl; if(argc < 2){ cerr << "Usage: (exe) log.dat [options]" << endl; return -1; } // ログファイルの指定 istream &in(options.spec2istream(argv[1])); options._out = NULL; // options for(int i(2); i < argc; i++){ if(options.check_spec(argv[i])){continue;} cerr << "Unknown option!! : " << argv[i] << endl; return -1; } // デフォルトの出力先の指定 if(!options._out){ string out_fname(argv[1]); string::size_type index = out_fname.find_last_of('.'); if(index != string::npos){ out_fname.erase(index); } out_fname.append(".ubx"); cerr << "Output : "; options._out = &(options.spec2ostream(out_fname.c_str(), true)); } // SylphideProtocolで着ていた場合はそれに対応 if(options.in_sylphide){ SylphideIStream sylphide_in(in, PAGE_SIZE); stream_processor(sylphide_in); }else{ stream_processor(in); } cerr << "Good, Bad = " << good_packet << ", " << bad_packet << endl; return 0; }