Weather casting with Machine Learning (SVM and SRNN).

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

Revision:
3:5add3759e08a
Parent:
2:20ecfe6edd71
Child:
4:00da8e8c7e2a
--- a/main.cpp	Wed Feb 18 15:02:16 2015 +0000
+++ b/main.cpp	Thu Feb 19 08:20:46 2015 +0000
@@ -9,7 +9,6 @@
 GraphicHandler  *graphic_handler;
 // ネットワーク関係(global)
 EthernetInterface    eth_if;
-HTTPServer           *http_server;
 NTPClient            ntp_client;
 
 // 系列データ
@@ -20,74 +19,107 @@
 FILE*  seqence_data_fp;    // 系列データのファイルポインタ(SRNNと計器の記録に使う)
 FILE*  predict_data_fp;    // 予測データ
 
+volatile int ml_flag;
+time_t now_time;
+struct tm* local_time_p;
+
 // 生存報告LED
 DigitalOut live_led(LED1);
 
-int thread_count = 0;
+volatile int thread_count = 0;
+int open_count = 0;
+
+// 計器タスク
+void read_task(void const *arg)
+{
+    // char str_buf[BUF_SIZE];
+
+
+    // データ更新
+    // __disable_irq(); // 割り込み禁止
+    sensor_module->read_all_sensor();
+    new_seqence_data[TEMPERATURE]  = sensor_module->get_temperture();
+    new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure();
+    new_seqence_data[HUMIDITY]     = sensor_module->get_humidity();
+    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);
+    // __enable_irq();  // 割り込み許可
+
 
-// 計器/機械学習タスク
-void read_and_predict_task(void const *arg)
+    /*
+    sprintf( str_buf, "%d/%d/%d %d:%d:%d,%.2f,%.2f,%.2f\n",
+                        (local_time_p->tm_year + 1900), (local_time_p->tm_mon + 1), local_time_p->tm_mday, local_time_p->tm_hour, local_time_p->tm_min, local_time_p->tm_sec,
+                        new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
+                        */
+    seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a");
+    // check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
+
+    // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity>
+    fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n",
+             (local_time_p->tm_year + 1900), (local_time_p->tm_mon + 1), local_time_p->tm_mday, local_time_p->tm_hour, local_time_p->tm_min, local_time_p->tm_sec,
+             new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
+    // fputs( str_buf, seqence_data_fp );
+    fclose( seqence_data_fp );
+
+}
+
+// 機械学習タスク
+void ml_task(void const *arg)
 {
     // ローカル変数
     int line = 0, ret;
-    time_t tmp_sec = get_JST();
-    struct tm *tmp_tm = localtime(&tmp_sec);
-    float* srnn_sample = new float[LEN_DATA_SEQUENCE * DIM_SIGNAL];            // SRNNのサンプル
+    //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];
-
-    // while (true) {
-    // 時刻の取得
-    // tmp_sec = get_JST();
-    // tmp_tm = localtime(&tmp_sec);
-
-    // 1. センサーから読み出す
-    printf("[%d] S.T.A.R.T \r\n", thread_count++);
-
-    // printf("[%d] Reading from sensors... %02d:%02d:%02d \r\n", thread_count++, tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec);
-    sensor_module->read_all_sensor();
+    char  str_buf[BUF_SIZE], str_dummy[50], str_dum1[10], str_dum2[10], str_dum3[10];
 
-    // データ更新
-    __disable_irq(); // 割り込み禁止
-    new_seqence_data[TEMPERATURE]  = sensor_module->get_temperture();
-    new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure();
-    new_seqence_data[HUMIDITY]     = sensor_module->get_humidity();
-    __enable_irq();  // 割り込み許可
-
-    printf("T:%f P:%f H:%f \r\n", new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
-
-    // 2. 記録(記録ファイルが長くなっていたら, 削る)
-    printf("Write to File... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
-    // 追加書き込み
-    seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a");
-    check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
-    // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity>
-    fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n",
-             (tmp_tm->tm_year + 1900), (tmp_tm->tm_mon + 1), tmp_tm->tm_mday, tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec,
-             new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
-    fclose( seqence_data_fp );
-    // 古いデータの削除
-    truncate_data_file();
+    printf("[%d] M.L.S.T.A.R.T \r\n", thread_count++);
 
     // 3. SRNNに学習データを読み込ませる.
-    printf("Set SRNN sample... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
+    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);
+    // まず、行数を数える
+    while( fgets( str_buf, seqence_data_fp) != NULL ) {
+        }
     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", 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));
+        printf("sample %d : %s %f %f %f \r\n", 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++;
     }
+
+    /*
+    while( fgets( str_buf, BUF_SIZE, seqence_data_fp) != NULL ) {
+        if (line == LEN_DATA_SEQUENCE) break;
+        printf("%s \r", 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);
+        srnn_sample[line * DIM_SIGNAL] = float(atof(str_dum1));
+        srnn_sample[line * DIM_SIGNAL + 1] = float(atof(str_dum2));
+        srnn_sample[line * DIM_SIGNAL + 2] = float(atof(str_dum3));
+        printf(" str : %s , f0 : %f , f1 : %f , f2 : %f \r\n", 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", tmp_tm->tm_hour, tmp_tm->tm_min);
+    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++) {
@@ -96,17 +128,16 @@
         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. 予測結果の書き込み
-    printf("Write out predict... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
+    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++) {
         // 予測時刻へ変換
-        tmp_sec += PREDICT_INTERVAL_TIME;
-        tmp_tm = localtime(&tmp_sec);
+        now_time += PREDICT_INTERVAL_TIME;
+        local_time_p = localtime(&now_time);
         // 気象を文字列に変換
         switch(new_predict_weather[i_predict]) {
             case SHINY:
@@ -127,7 +158,7 @@
         }
         // 書き出しフォーマット : y/m/d h:m,<weather>,<temperature>,<air_pressure>,<humidity>
         fprintf( predict_data_fp, "%d/%d/%d %d:%d:%d,%s,%f,%f,%f\n",
-                 (tmp_tm->tm_year + 1900), (tmp_tm->tm_mon + 1), tmp_tm->tm_mday, tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec,
+                 (local_time_p->tm_year + 1900), (local_time_p->tm_mon + 1), local_time_p->tm_mday, local_time_p->tm_hour, local_time_p->tm_min, local_time_p->tm_sec,
                  str_buf,
                  new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE],
                  new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE],
@@ -135,16 +166,11 @@
     }
     fclose( predict_data_fp );
 
-    // GraphicHandlerの現在の観測/予測データのセット
-    graphic_handler->set_now_data(new_seqence_data);
+    // GraphicHandlerの現在予測データのセット
     graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability);
 
-    // printf("Finishing task... %02d:%02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec);
-    // Thread::wait(4 * 1000);
-    // }
-
-    delete [] srnn_sample;
-    // delete tmp_tm; <- してはいけない(戒め)
+    // delete [] srnn_sample;
+    // delete local_time_p; <- してはいけない(戒め)
 
 }
 
@@ -152,54 +178,83 @@
 void draw_task(void const *arg)
 {
     while (true) {
+
+        if (ml_flag) {
+            Thread::signal_wait(0x3, osWaitForever);
+        }
         // 1. 描画更新 <- 学習中は止めたい...
-        //printf("draw thread start. \r\n");
+        printf("draw thread start. \r\n");
         if (time(NULL) % 60 == 0) {
             // 一分毎に表示時間を更新
             graphic_handler->update_time();
         }
         graphic_handler->update_image();
         graphic_handler->update_draw();
-        //printf("draw thread finish. \r\n");
+        printf("draw thread finish. \r\n");
+        Thread::wait(1 * 1000);
 
-        Thread::wait(2 * 1000);
     }
 }
 
 
-// ネットワークスレッド
+// ネットワークスレッド : リソースの限界. 廃止.
+/*
 void network_task(void const *arg)
 {
     while (true) {
-        // 1. ポート80のListen <- 学習中は止めたい...
-        //http_server->poll();
-        Thread::wait(0.5 * 1000);
+        while (ml_flag) {
+            Thread::signal_wait(0x3);
+        }
+        // 1. ポート80のListen
+        http_server->poll();
+        // for (int dum = 0; dum < 10000; dum++) ;
+        net_led = !net_led;
+        // Thread::wait(500);
     }
 }
+*/
 
 // 生存報告LEDチカ
 void liveled_task(void const *arg)
 {
     while (true) {
+        if (ml_flag) {
+            Thread::signal_wait(0x1, osWaitForever);
+        }
         live_led = !live_led;
-        Thread::wait(1 * 1000);
+        Thread::wait(1000);
     }
 }
 
-// エントリ. スレッドの生成, そして待つ
+//
 int main(void)
 {
     set_new_handler(no_memory);
     local_fs = new LocalFileSystem("local");
     setup();
 
-    RtosTimer ml_timer(read_and_predict_task, osTimerPeriodic, NULL);
-    Thread draw_thread(draw_task, NULL, osPriorityBelowNormal);
-    Thread network_thread(network_task, NULL, osPriorityLow);
-    Thread liveled_thread(liveled_task, NULL);
+    ml_flag = 1;
+
+    Thread draw_thread(draw_task, NULL, osPriorityNormal, 2000);
+    Thread liveled_thread(liveled_task, NULL, osPriorityLow, 200);
+
+    // Thread read_thread(read_task, NULL, osPriorityNormal);
 
-    ml_timer.start(5 * 1000);
+    osThreadSetPriority(Thread::gettid() ,osPriorityHigh);
+    while (true) {
+        Thread::wait(4 * 1000);
+        now_time = get_JST();
+        local_time_p = localtime(&now_time);
+        read_task(NULL);
+        // truncate_data_file();
+        ml_task(NULL);
+        ml_flag = 0;
+        liveled_thread.signal_set(0x1);
+        draw_thread.signal_set(0x3);
+    }
 
-    Thread::wait(osWaitForever);
+    printf("finished.");
+
+    return 1;
 
 }