Weather casting with Machine Learning (SVM and SRNN).
Dependencies: EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed
main.cpp@6:29d393d430d0, 2015-02-22 (annotated)
- 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?
User | Revision | Line number | New 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 | } |