Weather casting with Machine Learning (SVM and SRNN).
Dependencies: EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed
main.cpp
00001 #include "main.hpp" 00002 00003 LocalFileSystem *local_fs; // マウントポイント 00004 00005 // Pointer to Class instance (global) 00006 SRNN *srnn; 00007 MCSVM *mcsvm; 00008 SensorModule *sensor_module; 00009 GraphicHandler *graphic_handler; 00010 // ネットワーク関係(global) 00011 EthernetInterface eth_if; 00012 NTPClient ntp_client; 00013 00014 // 系列データ 00015 float* new_seqence_data; // 現在の(一番新しい)系列データ 00016 float* new_predict_data; // 現在の予測結果 00017 int* new_predict_weather; // 現在の予測天気 00018 float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...) 00019 float* srnn_sample_queue; // SRNNのサンプルキュー(サンキューキュー). 00020 00021 volatile int ml_flag; 00022 time_t now_time; 00023 struct tm* local_time_p; 00024 00025 // 生存報告LED 00026 DigitalOut live_led(LED1); 00027 00028 volatile int thread_count = 0; 00029 int num_data_line = 0; 00030 00031 // 計器タスク 00032 void read_task(void const *arg) 00033 { 00034 00035 FILE* seqence_data_fp; 00036 00037 // データ読み出し 00038 sensor_module->read_all_sensor(); 00039 new_seqence_data[TEMPERATURE] = sensor_module->get_temperture(); 00040 new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure(); 00041 new_seqence_data[HUMIDITY] = sensor_module->get_humidity(); 00042 printf("T:%f P:%f H:%f \r\n", new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]); 00043 graphic_handler->set_now_data(new_seqence_data); 00044 00045 // サンプルのアップデート 00046 update_srnn_sample(srnn_sample_queue, new_seqence_data); 00047 00048 // ログの追加 00049 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a"); 00050 check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME); 00051 00052 // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity> 00053 fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n", 00054 (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, 00055 new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]); 00056 fclose( seqence_data_fp ); 00057 00058 // ログファイルの切り詰め 00059 num_data_line++; 00060 if ( num_data_line > SUITABLE_LOG_LENGTH ) { 00061 // コメント:この関数はファイルポインタの開け閉めが激しい為, 頻繁に使うと落ちる可能性あり 00062 truncate_data_file(SUITABLE_LOG_LENGTH); 00063 } 00064 00065 } 00066 00067 // 機械学習タスク 00068 void ml_task(void const *arg) 00069 { 00070 // キューからサンプルセット 00071 srnn->set_sample(srnn_sample_queue); 00072 00073 // SRNNの学習/予測結果から, MCSVMで天気識別 00074 // printf("Learning... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min); 00075 srnn->learning(); 00076 srnn->predict(new_seqence_data); 00077 memcpy(new_predict_data, srnn->predict_signal, sizeof(float) * DIM_SIGNAL * PREDICT_LENGTH); 00078 // MCSVMによる天候識別 00079 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) { 00080 new_predict_weather[i_predict] = mcsvm->predict_label(&(new_predict_data[i_predict * DIM_SIGNAL])); 00081 new_predict_probability[i_predict] = mcsvm->predict_probability(&(new_predict_data[i_predict * DIM_SIGNAL])); 00082 } 00083 // printf("SVM predict finished \r\n"); 00084 } 00085 00086 // 予測結果の書き込み 00087 void write_predict_task(void const* arg) 00088 { 00089 00090 FILE* predict_data_fp; 00091 char str_buf[BUF_SIZE]; 00092 printf("Write out predict... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min); 00093 predict_data_fp = fopen( PREDICT_DATA_NAME, "w"); 00094 check_file_open( predict_data_fp, PREDICT_DATA_NAME); 00095 00096 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) { 00097 // 予測時刻へ変換 00098 now_time += PREDICT_INTERVAL_TIME; 00099 local_time_p = localtime(&now_time); 00100 // 気象を文字列に変換 00101 switch(new_predict_weather[i_predict]) { 00102 case SHINY: 00103 strcpy(str_buf, "shiny"); 00104 break; 00105 case CLOUDY: 00106 strcpy(str_buf, "cloudy"); 00107 break; 00108 case RAINY: 00109 strcpy(str_buf, "rainy"); 00110 break; 00111 case SNOWY: 00112 strcpy(str_buf, "snowy"); 00113 break; 00114 default: 00115 fprintf( stderr, "Error in write predict result (in weather switch). \r\n"); 00116 break; 00117 } 00118 // 書き出しフォーマット : y/m/d h:m,<weather>,<temperature>,<air_pressure>,<humidity> 00119 fprintf( predict_data_fp, "%d/%d/%d %d:%d:%d,%s,%f,%f,%f\n", 00120 (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, 00121 str_buf, 00122 new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE], 00123 new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE], 00124 new_predict_data[i_predict * DIM_SIGNAL + HUMIDITY]); 00125 } 00126 00127 fclose( predict_data_fp ); 00128 00129 // GraphicHandlerの現在予測データのセット 00130 graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability); 00131 00132 } 00133 00134 // 描画スレッド : 優先度低め 00135 void draw_task(void const *arg) 00136 { 00137 while (true) { 00138 00139 if (ml_flag) { 00140 Thread::signal_wait(0x2, osWaitForever); 00141 } 00142 //printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc()); 00143 00144 // printf("draw thread start. \r\n"); 00145 if (time(NULL) % 60 == 0) { 00146 // 一分毎に表示時間を更新 00147 graphic_handler->update_time(); 00148 } 00149 graphic_handler->update_image(); 00150 // 画面更新 00151 graphic_handler->update_draw(); 00152 // printf("draw thread finish. \r\n"); 00153 Thread::wait(1 * 1000); 00154 00155 } 00156 } 00157 00158 00159 // ネットワークスレッド : リソースの限界. 廃止. 00160 /* 00161 void network_task(void const *arg) 00162 { 00163 while (true) { 00164 while (ml_flag) { 00165 Thread::signal_wait(0x3); 00166 } 00167 // 1. ポート80のListen 00168 http_server->poll(); 00169 // for (int dum = 0; dum < 10000; dum++) ; 00170 net_led = !net_led; 00171 // Thread::wait(500); 00172 } 00173 } 00174 */ 00175 00176 // 生存報告LEDチカ 00177 void liveled_task(void const *arg) 00178 { 00179 while (true) { 00180 if (ml_flag) { 00181 Thread::signal_wait(0x1, osWaitForever); 00182 } 00183 // printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc()); 00184 00185 live_led = !live_led; 00186 Thread::wait(1000); 00187 } 00188 } 00189 00190 // 00191 int main(void) 00192 { 00193 set_new_handler(no_memory); 00194 local_fs = new LocalFileSystem("local"); 00195 00196 setup(); 00197 00198 // 擬似的なロックをかける(他のスレッドを待ち状態に) 00199 ml_flag = 1; 00200 00201 Thread draw_thread(draw_task, NULL, osPriorityNormal, 800); 00202 Thread liveled_thread(liveled_task, NULL, osPriorityLow, 200); 00203 00204 osThreadSetPriority(Thread::gettid() ,osPriorityHigh); 00205 while (true) { 00206 ml_flag = 1; 00207 // 現在時刻取得(ロギングに用いる) 00208 now_time = time(NULL); 00209 local_time_p = localtime(&now_time); 00210 // センサ読み込み, 機械学習, 予測データセット 00211 //read_task(NULL); 00212 ml_task(NULL); 00213 write_predict_task(NULL); 00214 ml_flag = 0; 00215 // シグナルにより他スレッドの再開 00216 liveled_thread.signal_set(0x1); 00217 draw_thread.signal_set(0x2); 00218 Thread::wait(PREDICT_INTERVAL_TIME); 00219 } 00220 00221 error("unreachable here"); 00222 00223 }
Generated on Wed Jul 13 2022 17:43:04 by 1.7.2