Weather casting with Machine Learning (SVM and SRNN).

Dependencies:   EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed

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");
 
 }