#ifndef __EEM_COMMON_OPTIONS_H__ #define __EEM_COMMON_OPTIONS_H__ #include #include #include #include #include #include #include static int rowstr2index(const char *rowstr){ // 数字で指定された場合 if((*rowstr >= '0') && (*rowstr <= '9')){ return atoi(rowstr); } // "AA"などExcelの列名で指定された場合 int res(0), chr2int, index(-1); while( (rowstr[++index] != 0) && (((rowstr[index] <= 'Z') && ((chr2int = (rowstr[index] - 'A')) >= 0)) || ((rowstr[index] <= 'z') && ((chr2int = (rowstr[index] - 'a')) >= 0)))){ res *= 26; res += (chr2int + 1); } return (res - 1); } // 共通するオプション struct Options { typedef std::vector vector_cp_t; double log_start, log_end, manuv_start, freq_sampling; vector_cp_t skip_coef; vector_cp_t &skip_states; // 別名 vector_cp_t state_init_values; vector_cp_t state_init_P; vector_cp_t input_init_Q; vector_cp_t obs_init_R; vector_cp_t stationary_values; char *method_type; double ftr_freq_min, ftr_freq_max; int ftr_freq_step; bool ftr_autodiff; int wfr_cascade; double wfr_threshold, wfr_ifading; double tascg_offset, aoffset, boffset; double phi_offset, theta_offset, psi_offset; Options() : log_start(0), log_end(std::numeric_limits::max()), manuv_start(0), freq_sampling(50), skip_coef(), skip_states(skip_coef), state_init_values(), state_init_P(), input_init_Q(), obs_init_R(), stationary_values(), method_type(NULL), ftr_freq_min(0.4), ftr_freq_max(40), ftr_freq_step(20), ftr_autodiff(false), wfr_cascade(0), wfr_threshold(1E-3), wfr_ifading(0), tascg_offset(0), aoffset(0), boffset(0), phi_offset(0), theta_offset(0), psi_offset(0) {} ~Options(){} bool check_spec(char *str){ #define CHECK_OPTION(name, operation) \ if(std::strstr(str, "--" #name "=") == str){ \ char *spec(str + strlen("--" #name "=")); \ std::cerr << #name << ": " << spec << std::endl; \ {operation;} \ return true; \ } // 時刻関係の処理 // --log_start=(time) CHECK_OPTION(log_start, log_start = atof(spec)); // --log_end=(time) CHECK_OPTION(log_end, log_end = atof(spec)); // --manuv_start=(time) CHECK_OPTION(manuv_start, manuv_start = atof(spec)); // 係数に関する処理 // --skip=(coef_name) CHECK_OPTION(skip, skip_coef.push_back(spec)); // --init=(coef_name,value) CHECK_OPTION(init, state_init_values.push_back(spec)); // --initP=(coef_name,P_value) CHECK_OPTION(initP, state_init_P.push_back(spec)); // --initQ=(input_value_name,Q_value) CHECK_OPTION(initQ, input_init_Q.push_back(spec)); // --initR=(obs_value_name,R_value) CHECK_OPTION(initR, obs_init_R.push_back(spec)); // --sta=(sta_value_name,value) CHECK_OPTION(sta, stationary_values.push_back(spec)); // --method=(type) --filter=(type) CHECK_OPTION(method, method_type = spec); CHECK_OPTION(filter, method_type = spec); // FTRに関するパラメータ // --ftr_freq_min=(freq) CHECK_OPTION(ftr_freq_min, ftr_freq_min = atof(spec)); // --ftr_freq_max=(freq) CHECK_OPTION(ftr_freq_max, ftr_freq_max = atof(spec)); // --ftr_freq_step=(int) CHECK_OPTION(ftr_freq_step, ftr_freq_step = atoi(spec)); // --ftr_freq_step=(0:off, 1:on) CHECK_OPTION(ftr_autodiff, ftr_autodiff = (atoi(spec) != 0)); // WFRに関するパラメータ // --wfr_cascade=(int) CHECK_OPTION(wfr_cascade, // カスケードの段数 wfr_cascade = atoi(spec)); // --wfr_threshold=(value) CHECK_OPTION(wfr_threshold, // 閾値 wfr_threshold = atof(spec)); // --wfr_ifading=(value) CHECK_OPTION(wfr_ifading, // 入力のフェーディング wfr_ifading = atof(spec)); // 対気機速に対する補正 CHECK_OPTION(tascg_offset, tascg_offset = atof(spec)); // 迎角、横滑り角に対する補正(ピトー管の取り付け誤差) CHECK_OPTION(aoffset, aoffset = atof(spec)); CHECK_OPTION(alpha_offset, aoffset = atof(spec)); CHECK_OPTION(boffset, boffset = atof(spec)); CHECK_OPTION(beta_offset, boffset = atof(spec)); // 姿勢角に対する補正 CHECK_OPTION(phi_offset, phi_offset = atof(spec)); CHECK_OPTION(theta_offset, theta_offset = atof(spec)); CHECK_OPTION(theta_offset, psi_offset = atof(spec)); #undef CHECK_OPTION return false; } } options; // 縦の解析用 struct LongitudinalOptions { int dt_row; // スロットル入力の列 int de_row; // エレベータ入力の列 double dt_trim; // スロットル中立のパルス長(0は自動設定) double de_trim; // エレベータ中立のパルス長(0は自動設定) double dt_sf; // スロットルのパルス長からスラスト[N]へのSF double de_sf; // エレベータのパルス長から舵角[rad]へのSF LongitudinalOptions() : dt_row('O' - 'A'), de_row('Q' - 'A'), dt_trim(0), de_trim(0), dt_sf(2.980562274 / 4077), de_sf(deg2rad(25.9 + 28.1) / (3868 - 2387)) {}; ~LongitudinalOptions(){} bool check_spec(char *str){ #define CHECK_OPTION(name, operation) \ if(std::strstr(str, "--" #name "=") == str){ \ char *spec(str + strlen("--" #name "=")); \ std::cerr << #name << ": " << spec << std::endl; \ {operation;} \ return true; \ } // --dt=(row/row_index) CHECK_OPTION(dt, dt_row = rowstr2index(spec)); // --de=(row/row_index) CHECK_OPTION(de, de_row = rowstr2index(spec)); // --dt_sf=(value) CHECK_OPTION(dt_sf, dt_sf = atof(spec)); // --de_sf=(value) CHECK_OPTION(de_sf, de_sf = atof(spec)); // --dt_trim=(value) CHECK_OPTION(dt_trim, dt_trim = atof(spec)); // --de_trim=(value) CHECK_OPTION(de_trim, de_trim = atof(spec)); #undef CHECK_OPTION return false; } } options_lng; // 横の解析用 struct LateralOptions { int dr_row; // ラダー入力の列 int da_row; // エルロン入力の列 double dr_trim; // ラダー中立のパルス長(0は自動設定) double da_trim; // エルロン中立のパルス長(0は自動設定) double dr_sf; // ラダーのパルス長から舵角[rad]へのSF double da_sf; // エルロンのパルス長から舵角[rad]へのSF LateralOptions() : dr_row('S' - 'A'), da_row('P' - 'A'), dr_trim(0), da_trim(0), dr_sf(deg2rad(25.9 + 28.1) / (3868 - 2387)), da_sf(deg2rad(25.9 + 28.1) / (3868 - 2387)) {} ~LateralOptions(){} bool check_spec(char *str){ #define CHECK_OPTION(name, operation) \ if(std::strstr(str, "--" #name "=") == str){ \ char *spec(str + strlen("--" #name "=")); \ std::cerr << #name << ": " << spec << std::endl; \ {operation;} \ return true; \ } // --dr=(row/row_index) CHECK_OPTION(dr, dr_row = rowstr2index(spec)); // --da=(row/row_index) CHECK_OPTION(da, da_row = rowstr2index(spec)); // --dr_sf=(row) CHECK_OPTION(dr_sf, dr_sf = atof(spec)); // --da_sf=(row) CHECK_OPTION(da_sf, da_sf = atof(spec)); // --dr_trim=(value) CHECK_OPTION(dr_trim, dr_trim = atof(spec)); // --de_trim=(value) CHECK_OPTION(da_trim, da_trim = atof(spec)); #undef CHECK_OPTION return false; } } options_lat; #endif /* __EEM_COMMON_OPTIONS_H__ */