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-22
- Revision:
- 6:29d393d430d0
- Parent:
- 5:b61f3f5b0fc8
File content as of revision 6:29d393d430d0:
#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; NTPClient ntp_client; // 系列データ float* new_seqence_data; // 現在の(一番新しい)系列データ float* new_predict_data; // 現在の予測結果 int* new_predict_weather; // 現在の予測天気 float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...) float* srnn_sample_queue; // SRNNのサンプルキュー(サンキューキュー). volatile int ml_flag; time_t now_time; struct tm* local_time_p; // 生存報告LED DigitalOut live_led(LED1); volatile int thread_count = 0; int num_data_line = 0; // 計器タスク void read_task(void const *arg) { 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(); 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); // サンプルのアップデート 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); // 形式に沿った文字列を書き出す : 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]); 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) { // キューからサンプルセット srnn->set_sample(srnn_sample_queue); // 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++) { 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("SVM predict finished \r\n"); } // 予測結果の書き込み 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; local_time_p = localtime(&now_time); // 気象を文字列に変換 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", (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], 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); } // 描画スレッド : 優先度低め void draw_task(void const *arg) { while (true) { 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) { // 一分毎に表示時間を更新 graphic_handler->update_time(); } graphic_handler->update_image(); // 画面更新 graphic_handler->update_draw(); // printf("draw thread finish. \r\n"); Thread::wait(1 * 1000); } } // ネットワークスレッド : リソースの限界. 廃止. /* void network_task(void const *arg) { while (true) { 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); } // printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc()); live_led = !live_led; Thread::wait(1000); } } // int main(void) { set_new_handler(no_memory); local_fs = new LocalFileSystem("local"); setup(); // 擬似的なロックをかける(他のスレッドを待ち状態に) ml_flag = 1; 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(PREDICT_INTERVAL_TIME); } error("unreachable here"); }