Weather casting with Machine Learning (SVM and SRNN).
Dependencies: EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed
main.cpp
- Committer:
- yukari_hinata
- Date:
- 2015-02-18
- Revision:
- 2:20ecfe6edd71
- Parent:
- 1:8538381cae81
- Child:
- 3:5add3759e08a
File content as of revision 2:20ecfe6edd71:
#include "main.hpp" LocalFileSystem *local_fs; // マウントポイントを定義(ディレクトリパスになる) // Pointer to Class instance (global) SRNN *srnn; MCSVM *mcsvm; SensorModule *sensor_module; GraphicHandler *graphic_handler; // ネットワーク関係(global) EthernetInterface eth_if; HTTPServer *http_server; NTPClient ntp_client; // 系列データ float* new_seqence_data; // 現在の(一番新しい)系列データ float* new_predict_data; // 現在の予測結果 int* new_predict_weather; // 現在の予測天気 float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...) FILE* seqence_data_fp; // 系列データのファイルポインタ(SRNNと計器の記録に使う) FILE* predict_data_fp; // 予測データ // 生存報告LED DigitalOut live_led(LED1); int thread_count = 0; // 計器/機械学習タスク void read_and_predict_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 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(); // データ更新 __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(); // 3. SRNNに学習データを読み込ませる. printf("Set SRNN sample... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min); seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "r"); check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME); line = 0; while( ( ret = fscanf( seqence_data_fp, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) { 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)); 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); 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"); // 5. 予測結果の書き込み printf("Write out predict... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->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); // 気象を文字列に変換 switch(new_predict_weather[i_predict]) { case SHINY: strcpy(str_buf, "shiny"); break; case CLOUDY: strcpy(str_buf, "cloudy"); break; case RAINY: strcpy(str_buf, "rainy"); break; case SNOWY: strcpy(str_buf, "snowy"); break; default: fprintf( stderr, "Error in write predict result (in weather switch). \r\n"); break; } // 書き出しフォーマット : 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, str_buf, new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE], 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_now_data(new_seqence_data); 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; <- してはいけない(戒め) } // 描画スレッド : 優先度低め void draw_task(void const *arg) { while (true) { // 1. 描画更新 <- 学習中は止めたい... //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"); Thread::wait(2 * 1000); } } // ネットワークスレッド void network_task(void const *arg) { while (true) { // 1. ポート80のListen <- 学習中は止めたい... //http_server->poll(); Thread::wait(0.5 * 1000); } } // 生存報告LEDチカ void liveled_task(void const *arg) { while (true) { live_led = !live_led; Thread::wait(1 * 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_timer.start(5 * 1000); Thread::wait(osWaitForever); }