Weather casting with Machine Learning (SVM and SRNN).
Dependencies: EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed
Diff: main.cpp
- 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; }