Weather casting with Machine Learning (SVM and SRNN).

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

Committer:
yukari_hinata
Date:
Wed Feb 18 15:02:16 2015 +0000
Revision:
2:20ecfe6edd71
Parent:
1:8538381cae81
Child:
3:5add3759e08a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yukari_hinata 0:f6cdb984f638 1 #include "main.hpp"
yukari_hinata 0:f6cdb984f638 2
yukari_hinata 1:8538381cae81 3 LocalFileSystem *local_fs; // マウントポイントを定義(ディレクトリパスになる)
yukari_hinata 0:f6cdb984f638 4
yukari_hinata 0:f6cdb984f638 5 // Pointer to Class instance (global)
yukari_hinata 0:f6cdb984f638 6 SRNN *srnn;
yukari_hinata 0:f6cdb984f638 7 MCSVM *mcsvm;
yukari_hinata 1:8538381cae81 8 SensorModule *sensor_module;
yukari_hinata 1:8538381cae81 9 GraphicHandler *graphic_handler;
yukari_hinata 1:8538381cae81 10 // ネットワーク関係(global)
yukari_hinata 1:8538381cae81 11 EthernetInterface eth_if;
yukari_hinata 2:20ecfe6edd71 12 HTTPServer *http_server;
yukari_hinata 1:8538381cae81 13 NTPClient ntp_client;
yukari_hinata 0:f6cdb984f638 14
yukari_hinata 0:f6cdb984f638 15 // 系列データ
yukari_hinata 0:f6cdb984f638 16 float* new_seqence_data; // 現在の(一番新しい)系列データ
yukari_hinata 0:f6cdb984f638 17 float* new_predict_data; // 現在の予測結果
yukari_hinata 0:f6cdb984f638 18 int* new_predict_weather; // 現在の予測天気
yukari_hinata 0:f6cdb984f638 19 float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...)
yukari_hinata 0:f6cdb984f638 20 FILE* seqence_data_fp; // 系列データのファイルポインタ(SRNNと計器の記録に使う)
yukari_hinata 0:f6cdb984f638 21 FILE* predict_data_fp; // 予測データ
yukari_hinata 2:20ecfe6edd71 22
yukari_hinata 2:20ecfe6edd71 23 // 生存報告LED
yukari_hinata 2:20ecfe6edd71 24 DigitalOut live_led(LED1);
yukari_hinata 0:f6cdb984f638 25
yukari_hinata 2:20ecfe6edd71 26 int thread_count = 0;
yukari_hinata 2:20ecfe6edd71 27
yukari_hinata 2:20ecfe6edd71 28 // 計器/機械学習タスク
yukari_hinata 2:20ecfe6edd71 29 void read_and_predict_task(void const *arg)
yukari_hinata 0:f6cdb984f638 30 {
yukari_hinata 2:20ecfe6edd71 31 // ローカル変数
yukari_hinata 2:20ecfe6edd71 32 int line = 0, ret;
yukari_hinata 2:20ecfe6edd71 33 time_t tmp_sec = get_JST();
yukari_hinata 2:20ecfe6edd71 34 struct tm *tmp_tm = localtime(&tmp_sec);
yukari_hinata 2:20ecfe6edd71 35 float* srnn_sample = new float[LEN_DATA_SEQUENCE * DIM_SIGNAL]; // SRNNのサンプル
yukari_hinata 2:20ecfe6edd71 36 // 読み込みバッファ
yukari_hinata 2:20ecfe6edd71 37 float buf_data[DIM_SIGNAL];
yukari_hinata 2:20ecfe6edd71 38 char str_buf[BUF_SIZE];
yukari_hinata 2:20ecfe6edd71 39
yukari_hinata 2:20ecfe6edd71 40 // while (true) {
yukari_hinata 2:20ecfe6edd71 41 // 時刻の取得
yukari_hinata 2:20ecfe6edd71 42 // tmp_sec = get_JST();
yukari_hinata 2:20ecfe6edd71 43 // tmp_tm = localtime(&tmp_sec);
yukari_hinata 2:20ecfe6edd71 44
yukari_hinata 2:20ecfe6edd71 45 // 1. センサーから読み出す
yukari_hinata 2:20ecfe6edd71 46 printf("[%d] S.T.A.R.T \r\n", thread_count++);
yukari_hinata 2:20ecfe6edd71 47
yukari_hinata 2:20ecfe6edd71 48 // printf("[%d] Reading from sensors... %02d:%02d:%02d \r\n", thread_count++, tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec);
yukari_hinata 2:20ecfe6edd71 49 sensor_module->read_all_sensor();
yukari_hinata 2:20ecfe6edd71 50
yukari_hinata 2:20ecfe6edd71 51 // データ更新
yukari_hinata 2:20ecfe6edd71 52 __disable_irq(); // 割り込み禁止
yukari_hinata 2:20ecfe6edd71 53 new_seqence_data[TEMPERATURE] = sensor_module->get_temperture();
yukari_hinata 2:20ecfe6edd71 54 new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure();
yukari_hinata 2:20ecfe6edd71 55 new_seqence_data[HUMIDITY] = sensor_module->get_humidity();
yukari_hinata 2:20ecfe6edd71 56 __enable_irq(); // 割り込み許可
yukari_hinata 2:20ecfe6edd71 57
yukari_hinata 2:20ecfe6edd71 58 printf("T:%f P:%f H:%f \r\n", new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
yukari_hinata 2:20ecfe6edd71 59
yukari_hinata 0:f6cdb984f638 60 // 2. 記録(記録ファイルが長くなっていたら, 削る)
yukari_hinata 2:20ecfe6edd71 61 printf("Write to File... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
yukari_hinata 2:20ecfe6edd71 62 // 追加書き込み
yukari_hinata 2:20ecfe6edd71 63 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a");
yukari_hinata 2:20ecfe6edd71 64 check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
yukari_hinata 2:20ecfe6edd71 65 // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity>
yukari_hinata 2:20ecfe6edd71 66 fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n",
yukari_hinata 2:20ecfe6edd71 67 (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,
yukari_hinata 2:20ecfe6edd71 68 new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
yukari_hinata 2:20ecfe6edd71 69 fclose( seqence_data_fp );
yukari_hinata 2:20ecfe6edd71 70 // 古いデータの削除
yukari_hinata 2:20ecfe6edd71 71 truncate_data_file();
yukari_hinata 2:20ecfe6edd71 72
yukari_hinata 2:20ecfe6edd71 73 // 3. SRNNに学習データを読み込ませる.
yukari_hinata 2:20ecfe6edd71 74 printf("Set SRNN sample... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
yukari_hinata 2:20ecfe6edd71 75 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "r");
yukari_hinata 2:20ecfe6edd71 76 check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
yukari_hinata 2:20ecfe6edd71 77 line = 0;
yukari_hinata 2:20ecfe6edd71 78 while( ( ret = fscanf( seqence_data_fp, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) {
yukari_hinata 2:20ecfe6edd71 79 memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL);
yukari_hinata 2:20ecfe6edd71 80 // 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));
yukari_hinata 2:20ecfe6edd71 81 line++;
yukari_hinata 2:20ecfe6edd71 82 }
yukari_hinata 2:20ecfe6edd71 83 fclose( seqence_data_fp );
yukari_hinata 2:20ecfe6edd71 84 srnn->set_sample(srnn_sample);
yukari_hinata 2:20ecfe6edd71 85
yukari_hinata 0:f6cdb984f638 86 // 4. SRNNの学習/予測結果から, MCSVMで天気識別
yukari_hinata 2:20ecfe6edd71 87 printf("Learning... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
yukari_hinata 2:20ecfe6edd71 88 srnn->learning();
yukari_hinata 2:20ecfe6edd71 89 srnn->predict(new_seqence_data);
yukari_hinata 2:20ecfe6edd71 90
yukari_hinata 2:20ecfe6edd71 91 memcpy(new_predict_data, srnn->predict_signal, sizeof(float) * DIM_SIGNAL * PREDICT_LENGTH);
yukari_hinata 2:20ecfe6edd71 92 // MCSVMによる天候識別
yukari_hinata 2:20ecfe6edd71 93 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) {
yukari_hinata 2:20ecfe6edd71 94 // 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]);
yukari_hinata 2:20ecfe6edd71 95 new_predict_weather[i_predict] = mcsvm->predict_label(&(new_predict_data[i_predict * DIM_SIGNAL]));
yukari_hinata 2:20ecfe6edd71 96 new_predict_probability[i_predict] = mcsvm->predict_probability(&(new_predict_data[i_predict * DIM_SIGNAL]));
yukari_hinata 2:20ecfe6edd71 97 // printf("P_W : %d P_P : %f \r\n", new_predict_weather[i_predict], new_predict_probability[i_predict]);
yukari_hinata 2:20ecfe6edd71 98 }
yukari_hinata 2:20ecfe6edd71 99 // printf("SVM predict finished \r\n");
yukari_hinata 2:20ecfe6edd71 100
yukari_hinata 2:20ecfe6edd71 101
yukari_hinata 2:20ecfe6edd71 102 // 5. 予測結果の書き込み
yukari_hinata 2:20ecfe6edd71 103 printf("Write out predict... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min);
yukari_hinata 2:20ecfe6edd71 104 predict_data_fp = fopen( PREDICT_DATA_NAME, "w");
yukari_hinata 2:20ecfe6edd71 105 check_file_open( predict_data_fp, PREDICT_DATA_NAME);
yukari_hinata 2:20ecfe6edd71 106 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) {
yukari_hinata 2:20ecfe6edd71 107 // 予測時刻へ変換
yukari_hinata 2:20ecfe6edd71 108 tmp_sec += PREDICT_INTERVAL_TIME;
yukari_hinata 2:20ecfe6edd71 109 tmp_tm = localtime(&tmp_sec);
yukari_hinata 2:20ecfe6edd71 110 // 気象を文字列に変換
yukari_hinata 2:20ecfe6edd71 111 switch(new_predict_weather[i_predict]) {
yukari_hinata 2:20ecfe6edd71 112 case SHINY:
yukari_hinata 2:20ecfe6edd71 113 strcpy(str_buf, "shiny");
yukari_hinata 2:20ecfe6edd71 114 break;
yukari_hinata 2:20ecfe6edd71 115 case CLOUDY:
yukari_hinata 2:20ecfe6edd71 116 strcpy(str_buf, "cloudy");
yukari_hinata 2:20ecfe6edd71 117 break;
yukari_hinata 2:20ecfe6edd71 118 case RAINY:
yukari_hinata 2:20ecfe6edd71 119 strcpy(str_buf, "rainy");
yukari_hinata 2:20ecfe6edd71 120 break;
yukari_hinata 2:20ecfe6edd71 121 case SNOWY:
yukari_hinata 2:20ecfe6edd71 122 strcpy(str_buf, "snowy");
yukari_hinata 2:20ecfe6edd71 123 break;
yukari_hinata 2:20ecfe6edd71 124 default:
yukari_hinata 2:20ecfe6edd71 125 fprintf( stderr, "Error in write predict result (in weather switch). \r\n");
yukari_hinata 2:20ecfe6edd71 126 break;
yukari_hinata 2:20ecfe6edd71 127 }
yukari_hinata 2:20ecfe6edd71 128 // 書き出しフォーマット : y/m/d h:m,<weather>,<temperature>,<air_pressure>,<humidity>
yukari_hinata 2:20ecfe6edd71 129 fprintf( predict_data_fp, "%d/%d/%d %d:%d:%d,%s,%f,%f,%f\n",
yukari_hinata 2:20ecfe6edd71 130 (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,
yukari_hinata 2:20ecfe6edd71 131 str_buf,
yukari_hinata 2:20ecfe6edd71 132 new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE],
yukari_hinata 2:20ecfe6edd71 133 new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE],
yukari_hinata 2:20ecfe6edd71 134 new_predict_data[i_predict * DIM_SIGNAL + HUMIDITY]);
yukari_hinata 2:20ecfe6edd71 135 }
yukari_hinata 2:20ecfe6edd71 136 fclose( predict_data_fp );
yukari_hinata 2:20ecfe6edd71 137
yukari_hinata 2:20ecfe6edd71 138 // GraphicHandlerの現在の観測/予測データのセット
yukari_hinata 2:20ecfe6edd71 139 graphic_handler->set_now_data(new_seqence_data);
yukari_hinata 2:20ecfe6edd71 140 graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability);
yukari_hinata 2:20ecfe6edd71 141
yukari_hinata 2:20ecfe6edd71 142 // printf("Finishing task... %02d:%02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec);
yukari_hinata 2:20ecfe6edd71 143 // Thread::wait(4 * 1000);
yukari_hinata 2:20ecfe6edd71 144 // }
yukari_hinata 2:20ecfe6edd71 145
yukari_hinata 2:20ecfe6edd71 146 delete [] srnn_sample;
yukari_hinata 2:20ecfe6edd71 147 // delete tmp_tm; <- してはいけない(戒め)
yukari_hinata 2:20ecfe6edd71 148
yukari_hinata 0:f6cdb984f638 149 }
yukari_hinata 0:f6cdb984f638 150
yukari_hinata 0:f6cdb984f638 151 // 描画スレッド : 優先度低め
yukari_hinata 2:20ecfe6edd71 152 void draw_task(void const *arg)
yukari_hinata 0:f6cdb984f638 153 {
yukari_hinata 2:20ecfe6edd71 154 while (true) {
yukari_hinata 2:20ecfe6edd71 155 // 1. 描画更新 <- 学習中は止めたい...
yukari_hinata 2:20ecfe6edd71 156 //printf("draw thread start. \r\n");
yukari_hinata 2:20ecfe6edd71 157 if (time(NULL) % 60 == 0) {
yukari_hinata 2:20ecfe6edd71 158 // 一分毎に表示時間を更新
yukari_hinata 2:20ecfe6edd71 159 graphic_handler->update_time();
yukari_hinata 2:20ecfe6edd71 160 }
yukari_hinata 2:20ecfe6edd71 161 graphic_handler->update_image();
yukari_hinata 2:20ecfe6edd71 162 graphic_handler->update_draw();
yukari_hinata 2:20ecfe6edd71 163 //printf("draw thread finish. \r\n");
yukari_hinata 2:20ecfe6edd71 164
yukari_hinata 2:20ecfe6edd71 165 Thread::wait(2 * 1000);
yukari_hinata 2:20ecfe6edd71 166 }
yukari_hinata 0:f6cdb984f638 167 }
yukari_hinata 0:f6cdb984f638 168
yukari_hinata 0:f6cdb984f638 169
yukari_hinata 0:f6cdb984f638 170 // ネットワークスレッド
yukari_hinata 2:20ecfe6edd71 171 void network_task(void const *arg)
yukari_hinata 0:f6cdb984f638 172 {
yukari_hinata 2:20ecfe6edd71 173 while (true) {
yukari_hinata 2:20ecfe6edd71 174 // 1. ポート80のListen <- 学習中は止めたい...
yukari_hinata 2:20ecfe6edd71 175 //http_server->poll();
yukari_hinata 2:20ecfe6edd71 176 Thread::wait(0.5 * 1000);
yukari_hinata 2:20ecfe6edd71 177 }
yukari_hinata 2:20ecfe6edd71 178 }
yukari_hinata 2:20ecfe6edd71 179
yukari_hinata 2:20ecfe6edd71 180 // 生存報告LEDチカ
yukari_hinata 2:20ecfe6edd71 181 void liveled_task(void const *arg)
yukari_hinata 2:20ecfe6edd71 182 {
yukari_hinata 2:20ecfe6edd71 183 while (true) {
yukari_hinata 2:20ecfe6edd71 184 live_led = !live_led;
yukari_hinata 2:20ecfe6edd71 185 Thread::wait(1 * 1000);
yukari_hinata 2:20ecfe6edd71 186 }
yukari_hinata 0:f6cdb984f638 187 }
yukari_hinata 0:f6cdb984f638 188
yukari_hinata 0:f6cdb984f638 189 // エントリ. スレッドの生成, そして待つ
yukari_hinata 0:f6cdb984f638 190 int main(void)
yukari_hinata 0:f6cdb984f638 191 {
yukari_hinata 0:f6cdb984f638 192 set_new_handler(no_memory);
yukari_hinata 1:8538381cae81 193 local_fs = new LocalFileSystem("local");
yukari_hinata 0:f6cdb984f638 194 setup();
yukari_hinata 2:20ecfe6edd71 195
yukari_hinata 2:20ecfe6edd71 196 RtosTimer ml_timer(read_and_predict_task, osTimerPeriodic, NULL);
yukari_hinata 2:20ecfe6edd71 197 Thread draw_thread(draw_task, NULL, osPriorityBelowNormal);
yukari_hinata 2:20ecfe6edd71 198 Thread network_thread(network_task, NULL, osPriorityLow);
yukari_hinata 2:20ecfe6edd71 199 Thread liveled_thread(liveled_task, NULL);
yukari_hinata 2:20ecfe6edd71 200
yukari_hinata 2:20ecfe6edd71 201 ml_timer.start(5 * 1000);
yukari_hinata 2:20ecfe6edd71 202
yukari_hinata 2:20ecfe6edd71 203 Thread::wait(osWaitForever);
yukari_hinata 2:20ecfe6edd71 204
yukari_hinata 0:f6cdb984f638 205 }