Weather casting with Machine Learning (SVM and SRNN).

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

Committer:
yukari_hinata
Date:
Sun Feb 22 01:06:19 2015 +0000
Revision:
6:29d393d430d0
Parent:
5:b61f3f5b0fc8
add svm sample data

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 5:b61f3f5b0fc8 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 5:b61f3f5b0fc8 19 float* srnn_sample_queue; // SRNNのサンプルキュー(サンキューキュー).
yukari_hinata 2:20ecfe6edd71 20
yukari_hinata 3:5add3759e08a 21 volatile int ml_flag;
yukari_hinata 3:5add3759e08a 22 time_t now_time;
yukari_hinata 3:5add3759e08a 23 struct tm* local_time_p;
yukari_hinata 3:5add3759e08a 24
yukari_hinata 2:20ecfe6edd71 25 // 生存報告LED
yukari_hinata 2:20ecfe6edd71 26 DigitalOut live_led(LED1);
yukari_hinata 0:f6cdb984f638 27
yukari_hinata 3:5add3759e08a 28 volatile int thread_count = 0;
yukari_hinata 5:b61f3f5b0fc8 29 int num_data_line = 0;
yukari_hinata 3:5add3759e08a 30
yukari_hinata 3:5add3759e08a 31 // 計器タスク
yukari_hinata 3:5add3759e08a 32 void read_task(void const *arg)
yukari_hinata 3:5add3759e08a 33 {
yukari_hinata 3:5add3759e08a 34
yukari_hinata 5:b61f3f5b0fc8 35 FILE* seqence_data_fp;
yukari_hinata 3:5add3759e08a 36
yukari_hinata 5:b61f3f5b0fc8 37 // データ読み出し
yukari_hinata 3:5add3759e08a 38 sensor_module->read_all_sensor();
yukari_hinata 3:5add3759e08a 39 new_seqence_data[TEMPERATURE] = sensor_module->get_temperture();
yukari_hinata 3:5add3759e08a 40 new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure();
yukari_hinata 3:5add3759e08a 41 new_seqence_data[HUMIDITY] = sensor_module->get_humidity();
yukari_hinata 3:5add3759e08a 42 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 43 graphic_handler->set_now_data(new_seqence_data);
yukari_hinata 3:5add3759e08a 44
yukari_hinata 5:b61f3f5b0fc8 45 // サンプルのアップデート
yukari_hinata 5:b61f3f5b0fc8 46 update_srnn_sample(srnn_sample_queue, new_seqence_data);
yukari_hinata 5:b61f3f5b0fc8 47
yukari_hinata 5:b61f3f5b0fc8 48 // ログの追加
yukari_hinata 3:5add3759e08a 49 seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a");
yukari_hinata 4:00da8e8c7e2a 50 check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME);
yukari_hinata 3:5add3759e08a 51
yukari_hinata 3:5add3759e08a 52 // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity>
yukari_hinata 3:5add3759e08a 53 fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n",
yukari_hinata 3:5add3759e08a 54 (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 55 new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]);
yukari_hinata 3:5add3759e08a 56 fclose( seqence_data_fp );
yukari_hinata 3:5add3759e08a 57
yukari_hinata 5:b61f3f5b0fc8 58 // ログファイルの切り詰め
yukari_hinata 5:b61f3f5b0fc8 59 num_data_line++;
yukari_hinata 5:b61f3f5b0fc8 60 if ( num_data_line > SUITABLE_LOG_LENGTH ) {
yukari_hinata 5:b61f3f5b0fc8 61 // コメント:この関数はファイルポインタの開け閉めが激しい為, 頻繁に使うと落ちる可能性あり
yukari_hinata 5:b61f3f5b0fc8 62 truncate_data_file(SUITABLE_LOG_LENGTH);
yukari_hinata 5:b61f3f5b0fc8 63 }
yukari_hinata 5:b61f3f5b0fc8 64
yukari_hinata 3:5add3759e08a 65 }
yukari_hinata 3:5add3759e08a 66
yukari_hinata 3:5add3759e08a 67 // 機械学習タスク
yukari_hinata 3:5add3759e08a 68 void ml_task(void const *arg)
yukari_hinata 0:f6cdb984f638 69 {
yukari_hinata 5:b61f3f5b0fc8 70 // キューからサンプルセット
yukari_hinata 5:b61f3f5b0fc8 71 srnn->set_sample(srnn_sample_queue);
yukari_hinata 3:5add3759e08a 72
yukari_hinata 5:b61f3f5b0fc8 73 // SRNNの学習/予測結果から, MCSVMで天気識別
yukari_hinata 5:b61f3f5b0fc8 74 // printf("Learning... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min);
yukari_hinata 2:20ecfe6edd71 75 srnn->learning();
yukari_hinata 2:20ecfe6edd71 76 srnn->predict(new_seqence_data);
yukari_hinata 2:20ecfe6edd71 77 memcpy(new_predict_data, srnn->predict_signal, sizeof(float) * DIM_SIGNAL * PREDICT_LENGTH);
yukari_hinata 2:20ecfe6edd71 78 // MCSVMによる天候識別
yukari_hinata 2:20ecfe6edd71 79 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) {
yukari_hinata 2:20ecfe6edd71 80 new_predict_weather[i_predict] = mcsvm->predict_label(&(new_predict_data[i_predict * DIM_SIGNAL]));
yukari_hinata 2:20ecfe6edd71 81 new_predict_probability[i_predict] = mcsvm->predict_probability(&(new_predict_data[i_predict * DIM_SIGNAL]));
yukari_hinata 2:20ecfe6edd71 82 }
yukari_hinata 5:b61f3f5b0fc8 83 // printf("SVM predict finished \r\n");
yukari_hinata 5:b61f3f5b0fc8 84 }
yukari_hinata 2:20ecfe6edd71 85
yukari_hinata 5:b61f3f5b0fc8 86 // 予測結果の書き込み
yukari_hinata 5:b61f3f5b0fc8 87 void write_predict_task(void const* arg)
yukari_hinata 5:b61f3f5b0fc8 88 {
yukari_hinata 5:b61f3f5b0fc8 89
yukari_hinata 5:b61f3f5b0fc8 90 FILE* predict_data_fp;
yukari_hinata 5:b61f3f5b0fc8 91 char str_buf[BUF_SIZE];
yukari_hinata 3:5add3759e08a 92 printf("Write out predict... %02d:%02d \r\n", local_time_p->tm_hour, local_time_p->tm_min);
yukari_hinata 2:20ecfe6edd71 93 predict_data_fp = fopen( PREDICT_DATA_NAME, "w");
yukari_hinata 2:20ecfe6edd71 94 check_file_open( predict_data_fp, PREDICT_DATA_NAME);
yukari_hinata 5:b61f3f5b0fc8 95
yukari_hinata 2:20ecfe6edd71 96 for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) {
yukari_hinata 2:20ecfe6edd71 97 // 予測時刻へ変換
yukari_hinata 3:5add3759e08a 98 now_time += PREDICT_INTERVAL_TIME;
yukari_hinata 3:5add3759e08a 99 local_time_p = localtime(&now_time);
yukari_hinata 2:20ecfe6edd71 100 // 気象を文字列に変換
yukari_hinata 2:20ecfe6edd71 101 switch(new_predict_weather[i_predict]) {
yukari_hinata 2:20ecfe6edd71 102 case SHINY:
yukari_hinata 2:20ecfe6edd71 103 strcpy(str_buf, "shiny");
yukari_hinata 2:20ecfe6edd71 104 break;
yukari_hinata 2:20ecfe6edd71 105 case CLOUDY:
yukari_hinata 2:20ecfe6edd71 106 strcpy(str_buf, "cloudy");
yukari_hinata 2:20ecfe6edd71 107 break;
yukari_hinata 2:20ecfe6edd71 108 case RAINY:
yukari_hinata 2:20ecfe6edd71 109 strcpy(str_buf, "rainy");
yukari_hinata 2:20ecfe6edd71 110 break;
yukari_hinata 2:20ecfe6edd71 111 case SNOWY:
yukari_hinata 2:20ecfe6edd71 112 strcpy(str_buf, "snowy");
yukari_hinata 2:20ecfe6edd71 113 break;
yukari_hinata 2:20ecfe6edd71 114 default:
yukari_hinata 2:20ecfe6edd71 115 fprintf( stderr, "Error in write predict result (in weather switch). \r\n");
yukari_hinata 2:20ecfe6edd71 116 break;
yukari_hinata 2:20ecfe6edd71 117 }
yukari_hinata 2:20ecfe6edd71 118 // 書き出しフォーマット : y/m/d h:m,<weather>,<temperature>,<air_pressure>,<humidity>
yukari_hinata 2:20ecfe6edd71 119 fprintf( predict_data_fp, "%d/%d/%d %d:%d:%d,%s,%f,%f,%f\n",
yukari_hinata 3:5add3759e08a 120 (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 121 str_buf,
yukari_hinata 2:20ecfe6edd71 122 new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE],
yukari_hinata 2:20ecfe6edd71 123 new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE],
yukari_hinata 2:20ecfe6edd71 124 new_predict_data[i_predict * DIM_SIGNAL + HUMIDITY]);
yukari_hinata 2:20ecfe6edd71 125 }
yukari_hinata 5:b61f3f5b0fc8 126
yukari_hinata 2:20ecfe6edd71 127 fclose( predict_data_fp );
yukari_hinata 2:20ecfe6edd71 128
yukari_hinata 3:5add3759e08a 129 // GraphicHandlerの現在予測データのセット
yukari_hinata 2:20ecfe6edd71 130 graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability);
yukari_hinata 2:20ecfe6edd71 131
yukari_hinata 0:f6cdb984f638 132 }
yukari_hinata 0:f6cdb984f638 133
yukari_hinata 0:f6cdb984f638 134 // 描画スレッド : 優先度低め
yukari_hinata 2:20ecfe6edd71 135 void draw_task(void const *arg)
yukari_hinata 0:f6cdb984f638 136 {
yukari_hinata 2:20ecfe6edd71 137 while (true) {
yukari_hinata 3:5add3759e08a 138
yukari_hinata 3:5add3759e08a 139 if (ml_flag) {
yukari_hinata 4:00da8e8c7e2a 140 Thread::signal_wait(0x2, osWaitForever);
yukari_hinata 3:5add3759e08a 141 }
yukari_hinata 5:b61f3f5b0fc8 142 //printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc());
yukari_hinata 4:00da8e8c7e2a 143
yukari_hinata 4:00da8e8c7e2a 144 // printf("draw thread start. \r\n");
yukari_hinata 2:20ecfe6edd71 145 if (time(NULL) % 60 == 0) {
yukari_hinata 2:20ecfe6edd71 146 // 一分毎に表示時間を更新
yukari_hinata 2:20ecfe6edd71 147 graphic_handler->update_time();
yukari_hinata 2:20ecfe6edd71 148 }
yukari_hinata 2:20ecfe6edd71 149 graphic_handler->update_image();
yukari_hinata 4:00da8e8c7e2a 150 // 画面更新
yukari_hinata 2:20ecfe6edd71 151 graphic_handler->update_draw();
yukari_hinata 4:00da8e8c7e2a 152 // printf("draw thread finish. \r\n");
yukari_hinata 3:5add3759e08a 153 Thread::wait(1 * 1000);
yukari_hinata 2:20ecfe6edd71 154
yukari_hinata 2:20ecfe6edd71 155 }
yukari_hinata 0:f6cdb984f638 156 }
yukari_hinata 0:f6cdb984f638 157
yukari_hinata 0:f6cdb984f638 158
yukari_hinata 3:5add3759e08a 159 // ネットワークスレッド : リソースの限界. 廃止.
yukari_hinata 3:5add3759e08a 160 /*
yukari_hinata 2:20ecfe6edd71 161 void network_task(void const *arg)
yukari_hinata 0:f6cdb984f638 162 {
yukari_hinata 2:20ecfe6edd71 163 while (true) {
yukari_hinata 3:5add3759e08a 164 while (ml_flag) {
yukari_hinata 3:5add3759e08a 165 Thread::signal_wait(0x3);
yukari_hinata 3:5add3759e08a 166 }
yukari_hinata 3:5add3759e08a 167 // 1. ポート80のListen
yukari_hinata 3:5add3759e08a 168 http_server->poll();
yukari_hinata 3:5add3759e08a 169 // for (int dum = 0; dum < 10000; dum++) ;
yukari_hinata 3:5add3759e08a 170 net_led = !net_led;
yukari_hinata 3:5add3759e08a 171 // Thread::wait(500);
yukari_hinata 2:20ecfe6edd71 172 }
yukari_hinata 2:20ecfe6edd71 173 }
yukari_hinata 3:5add3759e08a 174 */
yukari_hinata 2:20ecfe6edd71 175
yukari_hinata 2:20ecfe6edd71 176 // 生存報告LEDチカ
yukari_hinata 2:20ecfe6edd71 177 void liveled_task(void const *arg)
yukari_hinata 2:20ecfe6edd71 178 {
yukari_hinata 2:20ecfe6edd71 179 while (true) {
yukari_hinata 3:5add3759e08a 180 if (ml_flag) {
yukari_hinata 3:5add3759e08a 181 Thread::signal_wait(0x1, osWaitForever);
yukari_hinata 3:5add3759e08a 182 }
yukari_hinata 5:b61f3f5b0fc8 183 // printf("sp : %d, pc : %d \r\n", __current_sp(), __current_pc());
yukari_hinata 5:b61f3f5b0fc8 184
yukari_hinata 2:20ecfe6edd71 185 live_led = !live_led;
yukari_hinata 3:5add3759e08a 186 Thread::wait(1000);
yukari_hinata 2:20ecfe6edd71 187 }
yukari_hinata 0:f6cdb984f638 188 }
yukari_hinata 0:f6cdb984f638 189
yukari_hinata 3:5add3759e08a 190 //
yukari_hinata 0:f6cdb984f638 191 int main(void)
yukari_hinata 0:f6cdb984f638 192 {
yukari_hinata 0:f6cdb984f638 193 set_new_handler(no_memory);
yukari_hinata 1:8538381cae81 194 local_fs = new LocalFileSystem("local");
yukari_hinata 5:b61f3f5b0fc8 195
yukari_hinata 0:f6cdb984f638 196 setup();
yukari_hinata 2:20ecfe6edd71 197
yukari_hinata 5:b61f3f5b0fc8 198 // 擬似的なロックをかける(他のスレッドを待ち状態に)
yukari_hinata 3:5add3759e08a 199 ml_flag = 1;
yukari_hinata 3:5add3759e08a 200
yukari_hinata 5:b61f3f5b0fc8 201 Thread draw_thread(draw_task, NULL, osPriorityNormal, 800);
yukari_hinata 3:5add3759e08a 202 Thread liveled_thread(liveled_task, NULL, osPriorityLow, 200);
yukari_hinata 5:b61f3f5b0fc8 203
yukari_hinata 3:5add3759e08a 204 osThreadSetPriority(Thread::gettid() ,osPriorityHigh);
yukari_hinata 3:5add3759e08a 205 while (true) {
yukari_hinata 4:00da8e8c7e2a 206 ml_flag = 1;
yukari_hinata 5:b61f3f5b0fc8 207 // 現在時刻取得(ロギングに用いる)
yukari_hinata 4:00da8e8c7e2a 208 now_time = time(NULL);
yukari_hinata 3:5add3759e08a 209 local_time_p = localtime(&now_time);
yukari_hinata 5:b61f3f5b0fc8 210 // センサ読み込み, 機械学習, 予測データセット
yukari_hinata 6:29d393d430d0 211 //read_task(NULL);
yukari_hinata 3:5add3759e08a 212 ml_task(NULL);
yukari_hinata 5:b61f3f5b0fc8 213 write_predict_task(NULL);
yukari_hinata 3:5add3759e08a 214 ml_flag = 0;
yukari_hinata 5:b61f3f5b0fc8 215 // シグナルにより他スレッドの再開
yukari_hinata 3:5add3759e08a 216 liveled_thread.signal_set(0x1);
yukari_hinata 4:00da8e8c7e2a 217 draw_thread.signal_set(0x2);
yukari_hinata 5:b61f3f5b0fc8 218 Thread::wait(PREDICT_INTERVAL_TIME);
yukari_hinata 3:5add3759e08a 219 }
yukari_hinata 5:b61f3f5b0fc8 220
yukari_hinata 4:00da8e8c7e2a 221 error("unreachable here");
yukari_hinata 2:20ecfe6edd71 222
yukari_hinata 0:f6cdb984f638 223 }