Weather casting with Machine Learning (SVM and SRNN).

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

Committer:
yukari_hinata
Date:
Thu Feb 19 08:20:46 2015 +0000
Revision:
3:5add3759e08a
Parent:
2:20ecfe6edd71
Child:
4:00da8e8c7e2a
a bit of stable ver

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 1:8538381cae81 12 NTPClient ntp_client;
yukari_hinata 0:f6cdb984f638 13
yukari_hinata 0:f6cdb984f638 14 // 系列データ
yukari_hinata 0:f6cdb984f638 15 float* new_seqence_data; // 現在の(一番新しい)系列データ
yukari_hinata 0:f6cdb984f638 16 float* new_predict_data; // 現在の予測結果
yukari_hinata 0:f6cdb984f638 17 int* new_predict_weather; // 現在の予測天気
yukari_hinata 0:f6cdb984f638 18 float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...)
yukari_hinata 0:f6cdb984f638 19 FILE* seqence_data_fp; // 系列データのファイルポインタ(SRNNと計器の記録に使う)
yukari_hinata 0:f6cdb984f638 20 FILE* predict_data_fp; // 予測データ
yukari_hinata 2:20ecfe6edd71 21
yukari_hinata 3:5add3759e08a 22 volatile int ml_flag;
yukari_hinata 3:5add3759e08a 23 time_t now_time;
yukari_hinata 3:5add3759e08a 24 struct tm* local_time_p;
yukari_hinata 3:5add3759e08a 25
yukari_hinata 2:20ecfe6edd71 26 // 生存報告LED
yukari_hinata 2:20ecfe6edd71 27 DigitalOut live_led(LED1);
yukari_hinata 0:f6cdb984f638 28
yukari_hinata 3:5add3759e08a 29 volatile int thread_count = 0;
yukari_hinata 3:5add3759e08a 30 int open_count = 0;
yukari_hinata 3:5add3759e08a 31
yukari_hinata 3:5add3759e08a 32 // 計器タスク
yukari_hinata 3:5add3759e08a 33 void read_task(void const *arg)
yukari_hinata 3:5add3759e08a 34 {
yukari_hinata 3:5add3759e08a 35 // char str_buf[BUF_SIZE];
yukari_hinata 3:5add3759e08a 36
yukari_hinata 3:5add3759e08a 37
yukari_hinata 3:5add3759e08a 38 // データ更新
yukari_hinata 3:5add3759e08a 39 // __disable_irq(); // 割り込み禁止
yukari_hinata 3:5add3759e08a 40 sensor_module->read_all_sensor();
yukari_hinata 3:5add3759e08a 41 new_seqence_data[TEMPERATURE] = sensor_module->get_temperture();
yukari_hinata 3:5add3759e08a 42 new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure();
yukari_hinata 3:5add3759e08a 43 new_seqence_data[HUMIDITY] = sensor_module->get_humidity();
yukari_hinata 3:5add3759e08a 44 printf("T:%f P:%f H:%f \r\n", new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
yukari_hinata 3:5add3759e08a 45 graphic_handler->set_now_data(new_seqence_data);
yukari_hinata 3:5add3759e08a 46 // __enable_irq(); // 割り込み許可
yukari_hinata 3:5add3759e08a 47
yukari_hinata 2:20ecfe6edd71 48
yukari_hinata 3:5add3759e08a 49 /*
yukari_hinata 3:5add3759e08a 50 sprintf( str_buf, "%d/%d/%d %d:%d:%d,%.2f,%.2f,%.2f\n",
yukari_hinata 3:5add3759e08a 51 (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,
yukari_hinata 3:5add3759e08a 52 new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
yukari_hinata 3:5add3759e08a 53 */
yukari_hinata 3:5add3759e08a 54 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a");
yukari_hinata 3:5add3759e08a 55 // check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
yukari_hinata 3:5add3759e08a 56
yukari_hinata 3:5add3759e08a 57 // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity>
yukari_hinata 3:5add3759e08a 58 fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n",
yukari_hinata 3:5add3759e08a 59 (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,
yukari_hinata 3:5add3759e08a 60 new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
yukari_hinata 3:5add3759e08a 61 // fputs( str_buf, seqence_data_fp );
yukari_hinata 3:5add3759e08a 62 fclose( seqence_data_fp );
yukari_hinata 3:5add3759e08a 63
yukari_hinata 3:5add3759e08a 64 }
yukari_hinata 3:5add3759e08a 65
yukari_hinata 3:5add3759e08a 66 // 機械学習タスク
yukari_hinata 3:5add3759e08a 67 void ml_task(void const *arg)
yukari_hinata 0:f6cdb984f638 68 {
yukari_hinata 2:20ecfe6edd71 69 // ローカル変数
yukari_hinata 2:20ecfe6edd71 70 int line = 0, ret;
yukari_hinata 3:5add3759e08a 71 //float* srnn_sample = new float[LEN_DATA_SEQUENCE * DIM_SIGNAL]; // SRNNのサンプル
yukari_hinata 3:5add3759e08a 72 float srnn_sample[LEN_DATA_SEQUENCE * DIM_SIGNAL];
yukari_hinata 2:20ecfe6edd71 73 // 読み込みバッファ
yukari_hinata 2:20ecfe6edd71 74 float buf_data[DIM_SIGNAL];
yukari_hinata 3:5add3759e08a 75 char str_buf[BUF_SIZE], str_dummy[50], str_dum1[10], str_dum2[10], str_dum3[10];
yukari_hinata 2:20ecfe6edd71 76
yukari_hinata 3:5add3759e08a 77 printf("[%d] M.L.S.T.A.R.T \r\n", thread_count++);
yukari_hinata 2:20ecfe6edd71 78
yukari_hinata 2:20ecfe6edd71 79 // 3. SRNNに学習データを読み込ませる.
yukari_hinata 3:5add3759e08a 80 printf("Set SRNN sample... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min);
yukari_hinata 2:20ecfe6edd71 81 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "r");
yukari_hinata 2:20ecfe6edd71 82 check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
yukari_hinata 3:5add3759e08a 83 // まず、行数を数える
yukari_hinata 3:5add3759e08a 84 while( fgets( str_buf, seqence_data_fp) != NULL ) {
yukari_hinata 3:5add3759e08a 85 }
yukari_hinata 2:20ecfe6edd71 86 line = 0;
yukari_hinata 2:20ecfe6edd71 87 while( ( ret = fscanf( seqence_data_fp, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) {
yukari_hinata 3:5add3759e08a 88 if (line == LEN_DATA_SEQUENCE) break;
yukari_hinata 2:20ecfe6edd71 89 memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL);
yukari_hinata 3:5add3759e08a 90 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 91 line++;
yukari_hinata 2:20ecfe6edd71 92 }
yukari_hinata 3:5add3759e08a 93
yukari_hinata 3:5add3759e08a 94 /*
yukari_hinata 3:5add3759e08a 95 while( fgets( str_buf, BUF_SIZE, seqence_data_fp) != NULL ) {
yukari_hinata 3:5add3759e08a 96 if (line == LEN_DATA_SEQUENCE) break;
yukari_hinata 3:5add3759e08a 97 printf("%s \r", str_buf);
yukari_hinata 3:5add3759e08a 98 //sscanf( str_buf, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) )
yukari_hinata 3:5add3759e08a 99 sscanf( str_buf, "%[^,],%[^,],%[^,],%[^,]", str_dummy
yukari_hinata 3:5add3759e08a 100 , str_dum1
yukari_hinata 3:5add3759e08a 101 , str_dum2
yukari_hinata 3:5add3759e08a 102 , str_dum3);
yukari_hinata 3:5add3759e08a 103 srnn_sample[line * DIM_SIGNAL] = float(atof(str_dum1));
yukari_hinata 3:5add3759e08a 104 srnn_sample[line * DIM_SIGNAL + 1] = float(atof(str_dum2));
yukari_hinata 3:5add3759e08a 105 srnn_sample[line * DIM_SIGNAL + 2] = float(atof(str_dum3));
yukari_hinata 3:5add3759e08a 106 printf(" str : %s , f0 : %f , f1 : %f , f2 : %f \r\n", str_dummy
yukari_hinata 3:5add3759e08a 107 , srnn_sample[line * DIM_SIGNAL]
yukari_hinata 3:5add3759e08a 108 , srnn_sample[line * DIM_SIGNAL + 1]
yukari_hinata 3:5add3759e08a 109 , srnn_sample[line * DIM_SIGNAL + 2]);
yukari_hinata 3:5add3759e08a 110 // memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL);
yukari_hinata 3:5add3759e08a 111 line++;
yukari_hinata 3:5add3759e08a 112 }
yukari_hinata 3:5add3759e08a 113 */
yukari_hinata 3:5add3759e08a 114
yukari_hinata 2:20ecfe6edd71 115 fclose( seqence_data_fp );
yukari_hinata 2:20ecfe6edd71 116 srnn->set_sample(srnn_sample);
yukari_hinata 2:20ecfe6edd71 117
yukari_hinata 0:f6cdb984f638 118 // 4. SRNNの学習/予測結果から, MCSVMで天気識別
yukari_hinata 3:5add3759e08a 119 printf("Learning... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min);
yukari_hinata 2:20ecfe6edd71 120 srnn->learning();
yukari_hinata 2:20ecfe6edd71 121 srnn->predict(new_seqence_data);
yukari_hinata 3:5add3759e08a 122 // 金曜日ここから
yukari_hinata 2:20ecfe6edd71 123 memcpy(new_predict_data, srnn->predict_signal, sizeof(float) * DIM_SIGNAL * PREDICT_LENGTH);
yukari_hinata 2:20ecfe6edd71 124 // MCSVMによる天候識別
yukari_hinata 2:20ecfe6edd71 125 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) {
yukari_hinata 2:20ecfe6edd71 126 // 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 127 new_predict_weather[i_predict] = mcsvm->predict_label(&(new_predict_data[i_predict * DIM_SIGNAL]));
yukari_hinata 2:20ecfe6edd71 128 new_predict_probability[i_predict] = mcsvm->predict_probability(&(new_predict_data[i_predict * DIM_SIGNAL]));
yukari_hinata 2:20ecfe6edd71 129 // printf("P_W : %d P_P : %f \r\n", new_predict_weather[i_predict], new_predict_probability[i_predict]);
yukari_hinata 2:20ecfe6edd71 130 }
yukari_hinata 3:5add3759e08a 131 printf("SVM predict finished \r\n");
yukari_hinata 2:20ecfe6edd71 132
yukari_hinata 2:20ecfe6edd71 133 // 5. 予測結果の書き込み
yukari_hinata 3:5add3759e08a 134 printf("Write out predict... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min);
yukari_hinata 2:20ecfe6edd71 135 predict_data_fp = fopen( PREDICT_DATA_NAME, "w");
yukari_hinata 2:20ecfe6edd71 136 check_file_open( predict_data_fp, PREDICT_DATA_NAME);
yukari_hinata 2:20ecfe6edd71 137 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) {
yukari_hinata 2:20ecfe6edd71 138 // 予測時刻へ変換
yukari_hinata 3:5add3759e08a 139 now_time += PREDICT_INTERVAL_TIME;
yukari_hinata 3:5add3759e08a 140 local_time_p = localtime(&now_time);
yukari_hinata 2:20ecfe6edd71 141 // 気象を文字列に変換
yukari_hinata 2:20ecfe6edd71 142 switch(new_predict_weather[i_predict]) {
yukari_hinata 2:20ecfe6edd71 143 case SHINY:
yukari_hinata 2:20ecfe6edd71 144 strcpy(str_buf, "shiny");
yukari_hinata 2:20ecfe6edd71 145 break;
yukari_hinata 2:20ecfe6edd71 146 case CLOUDY:
yukari_hinata 2:20ecfe6edd71 147 strcpy(str_buf, "cloudy");
yukari_hinata 2:20ecfe6edd71 148 break;
yukari_hinata 2:20ecfe6edd71 149 case RAINY:
yukari_hinata 2:20ecfe6edd71 150 strcpy(str_buf, "rainy");
yukari_hinata 2:20ecfe6edd71 151 break;
yukari_hinata 2:20ecfe6edd71 152 case SNOWY:
yukari_hinata 2:20ecfe6edd71 153 strcpy(str_buf, "snowy");
yukari_hinata 2:20ecfe6edd71 154 break;
yukari_hinata 2:20ecfe6edd71 155 default:
yukari_hinata 2:20ecfe6edd71 156 fprintf( stderr, "Error in write predict result (in weather switch). \r\n");
yukari_hinata 2:20ecfe6edd71 157 break;
yukari_hinata 2:20ecfe6edd71 158 }
yukari_hinata 2:20ecfe6edd71 159 // 書き出しフォーマット : y/m/d h:m,<weather>,<temperature>,<air_pressure>,<humidity>
yukari_hinata 2:20ecfe6edd71 160 fprintf( predict_data_fp, "%d/%d/%d %d:%d:%d,%s,%f,%f,%f\n",
yukari_hinata 3:5add3759e08a 161 (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,
yukari_hinata 2:20ecfe6edd71 162 str_buf,
yukari_hinata 2:20ecfe6edd71 163 new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE],
yukari_hinata 2:20ecfe6edd71 164 new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE],
yukari_hinata 2:20ecfe6edd71 165 new_predict_data[i_predict * DIM_SIGNAL + HUMIDITY]);
yukari_hinata 2:20ecfe6edd71 166 }
yukari_hinata 2:20ecfe6edd71 167 fclose( predict_data_fp );
yukari_hinata 2:20ecfe6edd71 168
yukari_hinata 3:5add3759e08a 169 // GraphicHandlerの現在予測データのセット
yukari_hinata 2:20ecfe6edd71 170 graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability);
yukari_hinata 2:20ecfe6edd71 171
yukari_hinata 3:5add3759e08a 172 // delete [] srnn_sample;
yukari_hinata 3:5add3759e08a 173 // delete local_time_p; <- してはいけない(戒め)
yukari_hinata 2:20ecfe6edd71 174
yukari_hinata 0:f6cdb984f638 175 }
yukari_hinata 0:f6cdb984f638 176
yukari_hinata 0:f6cdb984f638 177 // 描画スレッド : 優先度低め
yukari_hinata 2:20ecfe6edd71 178 void draw_task(void const *arg)
yukari_hinata 0:f6cdb984f638 179 {
yukari_hinata 2:20ecfe6edd71 180 while (true) {
yukari_hinata 3:5add3759e08a 181
yukari_hinata 3:5add3759e08a 182 if (ml_flag) {
yukari_hinata 3:5add3759e08a 183 Thread::signal_wait(0x3, osWaitForever);
yukari_hinata 3:5add3759e08a 184 }
yukari_hinata 2:20ecfe6edd71 185 // 1. 描画更新 <- 学習中は止めたい...
yukari_hinata 3:5add3759e08a 186 printf("draw thread start. \r\n");
yukari_hinata 2:20ecfe6edd71 187 if (time(NULL) % 60 == 0) {
yukari_hinata 2:20ecfe6edd71 188 // 一分毎に表示時間を更新
yukari_hinata 2:20ecfe6edd71 189 graphic_handler->update_time();
yukari_hinata 2:20ecfe6edd71 190 }
yukari_hinata 2:20ecfe6edd71 191 graphic_handler->update_image();
yukari_hinata 2:20ecfe6edd71 192 graphic_handler->update_draw();
yukari_hinata 3:5add3759e08a 193 printf("draw thread finish. \r\n");
yukari_hinata 3:5add3759e08a 194 Thread::wait(1 * 1000);
yukari_hinata 2:20ecfe6edd71 195
yukari_hinata 2:20ecfe6edd71 196 }
yukari_hinata 0:f6cdb984f638 197 }
yukari_hinata 0:f6cdb984f638 198
yukari_hinata 0:f6cdb984f638 199
yukari_hinata 3:5add3759e08a 200 // ネットワークスレッド : リソースの限界. 廃止.
yukari_hinata 3:5add3759e08a 201 /*
yukari_hinata 2:20ecfe6edd71 202 void network_task(void const *arg)
yukari_hinata 0:f6cdb984f638 203 {
yukari_hinata 2:20ecfe6edd71 204 while (true) {
yukari_hinata 3:5add3759e08a 205 while (ml_flag) {
yukari_hinata 3:5add3759e08a 206 Thread::signal_wait(0x3);
yukari_hinata 3:5add3759e08a 207 }
yukari_hinata 3:5add3759e08a 208 // 1. ポート80のListen
yukari_hinata 3:5add3759e08a 209 http_server->poll();
yukari_hinata 3:5add3759e08a 210 // for (int dum = 0; dum < 10000; dum++) ;
yukari_hinata 3:5add3759e08a 211 net_led = !net_led;
yukari_hinata 3:5add3759e08a 212 // Thread::wait(500);
yukari_hinata 2:20ecfe6edd71 213 }
yukari_hinata 2:20ecfe6edd71 214 }
yukari_hinata 3:5add3759e08a 215 */
yukari_hinata 2:20ecfe6edd71 216
yukari_hinata 2:20ecfe6edd71 217 // 生存報告LEDチカ
yukari_hinata 2:20ecfe6edd71 218 void liveled_task(void const *arg)
yukari_hinata 2:20ecfe6edd71 219 {
yukari_hinata 2:20ecfe6edd71 220 while (true) {
yukari_hinata 3:5add3759e08a 221 if (ml_flag) {
yukari_hinata 3:5add3759e08a 222 Thread::signal_wait(0x1, osWaitForever);
yukari_hinata 3:5add3759e08a 223 }
yukari_hinata 2:20ecfe6edd71 224 live_led = !live_led;
yukari_hinata 3:5add3759e08a 225 Thread::wait(1000);
yukari_hinata 2:20ecfe6edd71 226 }
yukari_hinata 0:f6cdb984f638 227 }
yukari_hinata 0:f6cdb984f638 228
yukari_hinata 3:5add3759e08a 229 //
yukari_hinata 0:f6cdb984f638 230 int main(void)
yukari_hinata 0:f6cdb984f638 231 {
yukari_hinata 0:f6cdb984f638 232 set_new_handler(no_memory);
yukari_hinata 1:8538381cae81 233 local_fs = new LocalFileSystem("local");
yukari_hinata 0:f6cdb984f638 234 setup();
yukari_hinata 2:20ecfe6edd71 235
yukari_hinata 3:5add3759e08a 236 ml_flag = 1;
yukari_hinata 3:5add3759e08a 237
yukari_hinata 3:5add3759e08a 238 Thread draw_thread(draw_task, NULL, osPriorityNormal, 2000);
yukari_hinata 3:5add3759e08a 239 Thread liveled_thread(liveled_task, NULL, osPriorityLow, 200);
yukari_hinata 3:5add3759e08a 240
yukari_hinata 3:5add3759e08a 241 // Thread read_thread(read_task, NULL, osPriorityNormal);
yukari_hinata 2:20ecfe6edd71 242
yukari_hinata 3:5add3759e08a 243 osThreadSetPriority(Thread::gettid() ,osPriorityHigh);
yukari_hinata 3:5add3759e08a 244 while (true) {
yukari_hinata 3:5add3759e08a 245 Thread::wait(4 * 1000);
yukari_hinata 3:5add3759e08a 246 now_time = get_JST();
yukari_hinata 3:5add3759e08a 247 local_time_p = localtime(&now_time);
yukari_hinata 3:5add3759e08a 248 read_task(NULL);
yukari_hinata 3:5add3759e08a 249 // truncate_data_file();
yukari_hinata 3:5add3759e08a 250 ml_task(NULL);
yukari_hinata 3:5add3759e08a 251 ml_flag = 0;
yukari_hinata 3:5add3759e08a 252 liveled_thread.signal_set(0x1);
yukari_hinata 3:5add3759e08a 253 draw_thread.signal_set(0x3);
yukari_hinata 3:5add3759e08a 254 }
yukari_hinata 2:20ecfe6edd71 255
yukari_hinata 3:5add3759e08a 256 printf("finished.");
yukari_hinata 3:5add3759e08a 257
yukari_hinata 3:5add3759e08a 258 return 1;
yukari_hinata 2:20ecfe6edd71 259
yukari_hinata 0:f6cdb984f638 260 }