Weather casting with Machine Learning (SVM and SRNN).
Dependencies: EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed
Diff: main.cpp
- Revision:
- 5:b61f3f5b0fc8
- Parent:
- 4:00da8e8c7e2a
- Child:
- 6:29d393d430d0
--- a/main.cpp Thu Feb 19 13:53:12 2015 +0000 +++ b/main.cpp Thu Feb 19 19:21:16 2015 +0000 @@ -1,6 +1,6 @@ #include "main.hpp" -LocalFileSystem *local_fs; // マウントポイントを定義(ディレクトリパスになる) +LocalFileSystem *local_fs; // マウントポイント // Pointer to Class instance (global) SRNN *srnn; @@ -16,8 +16,7 @@ float* new_predict_data; // 現在の予測結果 int* new_predict_weather; // 現在の予測天気 float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...) -FILE* seqence_data_fp; // 系列データのファイルポインタ(SRNNと計器の記録に使う) -FILE* predict_data_fp; // 予測データ +float* srnn_sample_queue; // SRNNのサンプルキュー(サンキューキュー). volatile int ml_flag; time_t now_time; @@ -27,15 +26,15 @@ DigitalOut live_led(LED1); volatile int thread_count = 0; -int open_count = 0; +int num_data_line = 0; // 計器タスク void read_task(void const *arg) { - // char str_buf[BUF_SIZE]; + FILE* seqence_data_fp; - // データ更新 + // データ読み出し sensor_module->read_all_sensor(); new_seqence_data[TEMPERATURE] = sensor_module->get_temperture(); new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure(); @@ -43,6 +42,10 @@ printf("T:%f P:%f H:%f \r\n", new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]); graphic_handler->set_now_data(new_seqence_data); + // サンプルのアップデート + update_srnn_sample(srnn_sample_queue, new_seqence_data); + + // ログの追加 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a"); check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME); @@ -52,115 +55,44 @@ new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]); fclose( seqence_data_fp ); + // ログファイルの切り詰め + num_data_line++; + if ( num_data_line > SUITABLE_LOG_LENGTH ) { + // コメント:この関数はファイルポインタの開け閉めが激しい為, 頻繁に使うと落ちる可能性あり + truncate_data_file(SUITABLE_LOG_LENGTH); + } + } // 機械学習タスク void ml_task(void const *arg) { - // ローカル変数 - int line = 0, diff_line; - //float* srnn_sample = new float[LEN_DATA_SEQUENCE * DIM_SIGNAL]; // SRNNのサンプル - float srnn_sample[LEN_DATA_SEQUENCE * DIM_SIGNAL]; - // 読み込みバッファ - float buf_data[DIM_SIGNAL]; - char str_buf[BUF_SIZE], str_dummy[50], str_dum1[10], str_dum2[10], str_dum3[10]; - - printf("[%d] M.L.S.T.A.R.T \r\n", thread_count++); - - // 3. SRNNに学習データを読み込ませる. - printf("Set SRNN sample... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min); - seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "r"); - check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME); - // まず、行数を数える - line = 0; - while( fgets( str_buf, BUF_SIZE, seqence_data_fp) != NULL ) { - line++; - } - printf(" line : %d \r\n", line); - // 差分行の計算 - diff_line = (line - LEN_DATA_SEQUENCE); - rewind( seqence_data_fp ); - printf(" go to line : %d \r\n", diff_line); - line = 0; - // 差分行までfpを移動 - fflush( seqence_data_fp ); - while( fgets( str_buf, BUF_SIZE, seqence_data_fp) != NULL ) { - line++; - if ( line == diff_line ) break; - } - // 最新LEN_DATA_SEQUENCE個のデータを読み込む. - line = 0; - /* - while( ( ret = fscanf( seqence_data_fp, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) { - if (line == LEN_DATA_SEQUENCE) break; - memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL); - printf("sample %d : %s %f %f %f \r\n", diff_line + line, str_buf, MATRIX_AT(srnn_sample,DIM_SIGNAL,line,0), MATRIX_AT(srnn_sample,DIM_SIGNAL,line,1), MATRIX_AT(srnn_sample,DIM_SIGNAL,line,2)); - line++; - } - */ + // キューからサンプルセット + srnn->set_sample(srnn_sample_queue); - while( fgets( str_buf, BUF_SIZE, seqence_data_fp) != NULL ) { - if (line == LEN_DATA_SEQUENCE) break; - if (open_count > 20) - printf("%d %s \r", line, str_buf); - - //sscanf( str_buf, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) - sscanf( str_buf, "%[^,],%[^,],%[^,],%[^,]", str_dummy - , str_dum1 - , str_dum2 - , str_dum3); - - // エラーハンドル... 仕様か過失かわからないが, 19回目以降に開いたファイルはおかしい. - buf_data[0] = float(atof(str_dum1)); - buf_data[1] = float(atof(str_dum2)); - buf_data[2] = float(atof(str_dum3)); - // 直前の結果+乱数 - if ( line >= 1 ) { - if (fabsf(buf_data[TEMPERATURE] - srnn_sample[(line-1) * DIM_SIGNAL]) > 30) - buf_data[TEMPERATURE] = (srnn_sample[(line-1) * DIM_SIGNAL + TEMPERATURE] + uniform_rand(1)); - if (fabsf(buf_data[AIR_PRESSURE] - srnn_sample[(line-1) * DIM_SIGNAL + AIR_PRESSURE]) > 30) - buf_data[AIR_PRESSURE] = (srnn_sample[(line-1) * DIM_SIGNAL + 1] + uniform_rand(1)); - if (fabsf(buf_data[HUMIDITY] - srnn_sample[(line-1) * DIM_SIGNAL + 2]) > 30) - buf_data[HUMIDITY] = (srnn_sample[(line-1) * DIM_SIGNAL + HUMIDITY] + uniform_rand(1)); - } - - memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL); - /* - srnn_sample[line * DIM_SIGNAL] = buf_data[0]; - srnn_sample[line * DIM_SIGNAL + 1] = buf_data[1]; - srnn_sample[line * DIM_SIGNAL + 2] = buf_data[2]; - */ - - if (open_count > 20) - printf(" %d str : %s , f0 : %f , f1 : %f , f2 : %f \r\n", line, str_dummy - , srnn_sample[line * DIM_SIGNAL] - , srnn_sample[line * DIM_SIGNAL + 1] - , srnn_sample[line * DIM_SIGNAL + 2]); - // memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL); - line++; - } - - fclose( seqence_data_fp ); - srnn->set_sample(srnn_sample); - - // 4. SRNNの学習/予測結果から, MCSVMで天気識別 - printf("Learning... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min); + // SRNNの学習/予測結果から, MCSVMで天気識別 + // printf("Learning... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min); srnn->learning(); srnn->predict(new_seqence_data); memcpy(new_predict_data, srnn->predict_signal, sizeof(float) * DIM_SIGNAL * PREDICT_LENGTH); // MCSVMによる天候識別 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) { - // printf("predict_data[%d] : %f %f %f \r\n", i_predict, new_predict_data[i_predict * DIM_SIGNAL], new_predict_data[i_predict * DIM_SIGNAL + 1], new_predict_data[i_predict * DIM_SIGNAL + 2]); new_predict_weather[i_predict] = mcsvm->predict_label(&(new_predict_data[i_predict * DIM_SIGNAL])); new_predict_probability[i_predict] = mcsvm->predict_probability(&(new_predict_data[i_predict * DIM_SIGNAL])); - // printf("P_W : %d P_P : %f \r\n", new_predict_weather[i_predict], new_predict_probability[i_predict]); } - printf("SVM predict finished \r\n"); + // printf("SVM predict finished \r\n"); +} - // 5. 予測結果の書き込み +// 予測結果の書き込み +void write_predict_task(void const* arg) +{ + + FILE* predict_data_fp; + char str_buf[BUF_SIZE]; printf("Write out predict... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min); predict_data_fp = fopen( PREDICT_DATA_NAME, "w"); check_file_open( predict_data_fp, PREDICT_DATA_NAME); + for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) { // 予測時刻へ変換 now_time += PREDICT_INTERVAL_TIME; @@ -191,14 +123,12 @@ new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE], new_predict_data[i_predict * DIM_SIGNAL + HUMIDITY]); } + fclose( predict_data_fp ); // GraphicHandlerの現在予測データのセット graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability); - // delete [] srnn_sample; - // delete local_time_p; <- してはいけない(戒め) - } // 描画スレッド : 優先度低め @@ -209,6 +139,7 @@ if (ml_flag) { Thread::signal_wait(0x2, osWaitForever); } + //printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc()); // printf("draw thread start. \r\n"); if (time(NULL) % 60 == 0) { @@ -249,6 +180,8 @@ if (ml_flag) { Thread::signal_wait(0x1, osWaitForever); } + // printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc()); + live_led = !live_led; Thread::wait(1000); } @@ -259,28 +192,32 @@ { set_new_handler(no_memory); local_fs = new LocalFileSystem("local"); - + setup(); - // graphic_handler->draw_log("setup finish"); + // 擬似的なロックをかける(他のスレッドを待ち状態に) ml_flag = 1; - Thread draw_thread(draw_task, NULL, osPriorityNormal, 2000); + Thread draw_thread(draw_task, NULL, osPriorityNormal, 800); Thread liveled_thread(liveled_task, NULL, osPriorityLow, 200); - + osThreadSetPriority(Thread::gettid() ,osPriorityHigh); while (true) { ml_flag = 1; + // 現在時刻取得(ロギングに用いる) now_time = time(NULL); local_time_p = localtime(&now_time); + // センサ読み込み, 機械学習, 予測データセット read_task(NULL); ml_task(NULL); + write_predict_task(NULL); ml_flag = 0; + // シグナルにより他スレッドの再開 liveled_thread.signal_set(0x1); draw_thread.signal_set(0x2); - Thread::wait(2 * 1000); + Thread::wait(PREDICT_INTERVAL_TIME); } - + error("unreachable here"); }