Weather casting with Machine Learning (SVM and SRNN).
Dependencies: EthernetInterface GraphicHandler NTPClient SRNN SVM SensorModule mbed-rtos mbed
Revision 2:20ecfe6edd71, committed 2015-02-18
- Comitter:
- yukari_hinata
- Date:
- Wed Feb 18 15:02:16 2015 +0000
- Parent:
- 1:8538381cae81
- Child:
- 3:5add3759e08a
- Commit message:
Changed in this revision
--- a/EthernetInterface.lib Mon Feb 16 07:53:45 2015 +0000 +++ b/EthernetInterface.lib Wed Feb 18 15:02:16 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/EthernetInterface/#2f204a58a350 +http://mbed.org/users/mbed_official/code/EthernetInterface/#65b0d840274c
--- a/GraphicHandler.lib Mon Feb 16 07:53:45 2015 +0000 +++ b/GraphicHandler.lib Wed Feb 18 15:02:16 2015 +0000 @@ -1,1 +1,1 @@ -GraphicHandler#459f757bd2f4 +GraphicHandler#3569342a4ab0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPServer.lib Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,1 @@ +HTTPServer#6b63b855c81e
--- a/SRNN.lib Mon Feb 16 07:53:45 2015 +0000 +++ b/SRNN.lib Wed Feb 18 15:02:16 2015 +0000 @@ -1,1 +1,1 @@ -SRNN#89a285dbc78e +SRNN#9d94330f380a
--- a/SVM.lib Mon Feb 16 07:53:45 2015 +0000 +++ b/SVM.lib Wed Feb 18 15:02:16 2015 +0000 @@ -1,1 +1,1 @@ -SVM#01a20b89db32 +SVM#792afbb0bcf3
--- a/SensorModule.lib Mon Feb 16 07:53:45 2015 +0000 +++ b/SensorModule.lib Wed Feb 18 15:02:16 2015 +0000 @@ -1,1 +1,1 @@ -SensorModule#d1f55b26ccac +SensorModule#c1c2c7c5fe82
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debug/debug.cpp Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,62 @@ +#include "debug.hpp" + +void print_mat_func(float* mat, int row, int col) +{ + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + if (j == 0) { + printf("|"); + } + float val = MATRIX_AT(mat,col,i,j); + if (val > 0) { + printf(" "); + } + printf("%3.3f ",val); + if (j == col-1) { + printf("| \r\n"); + }; + } + } +} + +void print_vec_func(float* vec, int dim) +{ + for (int i = 0; i < dim; i++) { + printf("%f ", vec[i]); + } + printf("\r\n"); +} + +void no_memory(void) +{ + error("panic: can't allocate to memory! \r\n"); + while(1); +} + +extern "C" { + +void HardFault_Handler(void) +{ + error("Hard Fault! \r\n"); + while(1); +} + +void MemManage_Handler(void) +{ + error("MemManage Fault!\n"); + while(1); +} + +void BusFault_Handler() +{ + error("BusFault Fault!\r\n"); + while(1); +} + +void UsageFault_Handler() +{ + error("Usage Fault!\r\n"); + while(1); +} + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debug/debug.hpp Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,37 @@ +#ifndef DEBUG_H_INCLUDED +#define DEBUG_H_INCLUDED + +#include "mbed.h" +#include <new> + +#include "../ml_util/ml_util.hpp" + +// Debug Macros +#define DBG(...) printf("" __VA_ARGS__) +#define PRINT_INT(x) (printf(#x " : %d \r\n", x)) +#define PRINT_FLT(x) (printf(#x " : %f \r\n", x)) + +#define PRINT_VEC(vec,dim) (printf("FILE[%s] LINE %d, %s: \r\n", __FILE__, __LINE__, (#vec)) \ + (print_vec_func((vec),(dim))) +#define PRINT_MAT(mat,row,col) (printf("FILE[%s] LINE %d, %s: \r\n", __FILE__, __LINE__, (#mat)) \ + (print_vec_func((vec),(row),(col))) + +// Debug Modules + +void print_vec_func(float* vec, int dim); + +void print_mat_func(float* mat, int row, int col); + +void write_log(char* name, ...); + +void no_memory(void); // error handler for memory allocate failing + +/* +extern void HardFault_Handler(void); +extern void MemManage_Handler(void); +extern void BusFault_Handler(void); +extern void UsageFault_Handler(void); +*/ + +#endif /* DEBUG_H_INCLUDED */ +
--- a/main.cpp Mon Feb 16 07:53:45 2015 +0000 +++ b/main.cpp Wed Feb 18 15:02:16 2015 +0000 @@ -2,9 +2,6 @@ LocalFileSystem *local_fs; // マウントポイントを定義(ディレクトリパスになる) -// 時間(global) -time_t global_time; // 現在時刻 -Mutex time_mutex; // 時間のMutex // Pointer to Class instance (global) SRNN *srnn; MCSVM *mcsvm; @@ -12,7 +9,7 @@ GraphicHandler *graphic_handler; // ネットワーク関係(global) EthernetInterface eth_if; -TCPSocketServer http_server; +HTTPServer *http_server; NTPClient ntp_client; // 系列データ @@ -22,32 +19,171 @@ float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...) FILE* seqence_data_fp; // 系列データのファイルポインタ(SRNNと計器の記録に使う) FILE* predict_data_fp; // 予測データ -Mutex seqence_data_mutex; // 系列データのMutex -Mutex predict_data_mutex; // 予測データのMutex + +// 生存報告LED +DigitalOut live_led(LED1); -// 計器/機械学習スレッド -void read_and_predict_thread(void const *arg) +int thread_count = 0; + +// 計器/機械学習タスク +void read_and_predict_task(void const *arg) { - // 1. 定期的(周期はmainが指定)にセンサーから読み出す + // ローカル変数 + int line = 0, ret; + time_t tmp_sec = get_JST(); + struct tm *tmp_tm = localtime(&tmp_sec); + float* srnn_sample = new float[LEN_DATA_SEQUENCE * DIM_SIGNAL]; // SRNNのサンプル + // 読み込みバッファ + float buf_data[DIM_SIGNAL]; + char str_buf[BUF_SIZE]; + + // while (true) { + // 時刻の取得 + // tmp_sec = get_JST(); + // tmp_tm = localtime(&tmp_sec); + + // 1. センサーから読み出す + printf("[%d] S.T.A.R.T \r\n", thread_count++); + + // printf("[%d] Reading from sensors... %02d:%02d:%02d \r\n", thread_count++, tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec); + sensor_module->read_all_sensor(); + + // データ更新 + __disable_irq(); // 割り込み禁止 + new_seqence_data[TEMPERATURE] = sensor_module->get_temperture(); + new_seqence_data[AIR_PRESSURE] = sensor_module->get_pressure(); + new_seqence_data[HUMIDITY] = sensor_module->get_humidity(); + __enable_irq(); // 割り込み許可 + + printf("T:%f P:%f H:%f \r\n", new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]); + // 2. 記録(記録ファイルが長くなっていたら, 削る) - // 3. SRNNに学習データを読み込ませる.(Mutexを使う) + printf("Write to File... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min); + // 追加書き込み + seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "a"); + check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME); + // 形式に沿った文字列を書き出す : y/m/d h:m,<temperature>,<air_pressure>,<humidity> + fprintf( seqence_data_fp, "%d/%d/%d %d:%d:%d,%f,%f,%f\n", + (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, + new_seqence_data[TEMPERATURE], new_seqence_data[AIR_PRESSURE], new_seqence_data[HUMIDITY]); + fclose( seqence_data_fp ); + // 古いデータの削除 + truncate_data_file(); + + // 3. SRNNに学習データを読み込ませる. + printf("Set SRNN sample... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min); + seqence_data_fp = fopen( SEQUENCE_DATA_NAME, "r"); + check_file_open( seqence_data_fp, SEQUENCE_DATA_NAME); + line = 0; + while( ( ret = fscanf( seqence_data_fp, " %[^\n,],%f,%f,%f", str_buf, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) { + memcpy(&(srnn_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL); + // 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)); + line++; + } + fclose( seqence_data_fp ); + srnn->set_sample(srnn_sample); + // 4. SRNNの学習/予測結果から, MCSVMで天気識別 - // 5. 予測結果のセット, 書き込み + printf("Learning... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min); + srnn->learning(); + srnn->predict(new_seqence_data); + + memcpy(new_predict_data, srnn->predict_signal, sizeof(float) * DIM_SIGNAL * PREDICT_LENGTH); + // MCSVMによる天候識別 + for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) { + // 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]); + new_predict_weather[i_predict] = mcsvm->predict_label(&(new_predict_data[i_predict * DIM_SIGNAL])); + new_predict_probability[i_predict] = mcsvm->predict_probability(&(new_predict_data[i_predict * DIM_SIGNAL])); + // printf("P_W : %d P_P : %f \r\n", new_predict_weather[i_predict], new_predict_probability[i_predict]); + } + // printf("SVM predict finished \r\n"); + + + // 5. 予測結果の書き込み + printf("Write out predict... %02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min); + predict_data_fp = fopen( PREDICT_DATA_NAME, "w"); + check_file_open( predict_data_fp, PREDICT_DATA_NAME); + for (int i_predict = 0; i_predict < PREDICT_LENGTH; i_predict++) { + // 予測時刻へ変換 + tmp_sec += PREDICT_INTERVAL_TIME; + tmp_tm = localtime(&tmp_sec); + // 気象を文字列に変換 + switch(new_predict_weather[i_predict]) { + case SHINY: + strcpy(str_buf, "shiny"); + break; + case CLOUDY: + strcpy(str_buf, "cloudy"); + break; + case RAINY: + strcpy(str_buf, "rainy"); + break; + case SNOWY: + strcpy(str_buf, "snowy"); + break; + default: + fprintf( stderr, "Error in write predict result (in weather switch). \r\n"); + break; + } + // 書き出しフォーマット : y/m/d h:m,<weather>,<temperature>,<air_pressure>,<humidity> + fprintf( predict_data_fp, "%d/%d/%d %d:%d:%d,%s,%f,%f,%f\n", + (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, + str_buf, + new_predict_data[i_predict * DIM_SIGNAL + TEMPERATURE], + new_predict_data[i_predict * DIM_SIGNAL + AIR_PRESSURE], + new_predict_data[i_predict * DIM_SIGNAL + HUMIDITY]); + } + fclose( predict_data_fp ); + + // GraphicHandlerの現在の観測/予測データのセット + graphic_handler->set_now_data(new_seqence_data); + graphic_handler->set_predict_data(new_predict_data, new_predict_weather, new_predict_probability); + + // printf("Finishing task... %02d:%02d:%02d \r\n", tmp_tm->tm_hour, tmp_tm->tm_min, tmp_tm->tm_sec); + // Thread::wait(4 * 1000); + // } + + delete [] srnn_sample; + // delete tmp_tm; <- してはいけない(戒め) + } // 描画スレッド : 優先度低め -void draw_thread(void const *arg) +void draw_task(void const *arg) { - // 1. 1分に一回, 時間を取りにいく - // 2. 描画更新 <- 学習中は止めたい... + while (true) { + // 1. 描画更新 <- 学習中は止めたい... + //printf("draw thread start. \r\n"); + if (time(NULL) % 60 == 0) { + // 一分毎に表示時間を更新 + graphic_handler->update_time(); + } + graphic_handler->update_image(); + graphic_handler->update_draw(); + //printf("draw thread finish. \r\n"); + + Thread::wait(2 * 1000); + } } // ネットワークスレッド -void network_thread(void const *arg) +void network_task(void const *arg) { - // 1. たまに時間を更新 - // 2. ポート80のListen <- 学習中は止めたい... + while (true) { + // 1. ポート80のListen <- 学習中は止めたい... + //http_server->poll(); + Thread::wait(0.5 * 1000); + } +} + +// 生存報告LEDチカ +void liveled_task(void const *arg) +{ + while (true) { + live_led = !live_led; + Thread::wait(1 * 1000); + } } // エントリ. スレッドの生成, そして待つ @@ -56,6 +192,14 @@ set_new_handler(no_memory); local_fs = new LocalFileSystem("local"); setup(); - printf("EXIT SUCESS!! \r\n"); - return 0; + + RtosTimer ml_timer(read_and_predict_task, osTimerPeriodic, NULL); + Thread draw_thread(draw_task, NULL, osPriorityBelowNormal); + Thread network_thread(network_task, NULL, osPriorityLow); + Thread liveled_thread(liveled_task, NULL); + + ml_timer.start(5 * 1000); + + Thread::wait(osWaitForever); + }
--- a/main.hpp Mon Feb 16 07:53:45 2015 +0000 +++ b/main.hpp Wed Feb 18 15:02:16 2015 +0000 @@ -6,20 +6,19 @@ #include "EthernetInterface.h" #include "NTPClient.h" +#include "HTTPServer.h" #include "MCSVM.hpp" #include "SRNN.hpp" #include "SensorModule.hpp" #include "GraphicHandler.hpp" +#include "main_util.hpp" #include "share.hpp" #include "setup.hpp" #include "./debug/debug.hpp" // -// 時間(global) -extern time_t global_time; // 現在時刻 -extern Mutex time_mutex; // 時間のMutex // Pointer to Class instance (global) extern SRNN *srnn; extern MCSVM *mcsvm; @@ -27,9 +26,14 @@ extern GraphicHandler *graphic_handler; // ネットワーク関係(global) extern EthernetInterface eth_if; -extern TCPSocketServer http_server; +extern HTTPServer *http_server; extern NTPClient ntp_client; // ファイルシステム(global) extern LocalFileSystem *local_fs; +// 系列データ(global) +extern float* new_seqence_data; // 現在の(一番新しい)系列データ +extern float* new_predict_data; // 現在の予測結果 +extern int* new_predict_weather; // 現在の予測天気 +extern float* new_predict_probability; // 現在の予測天気の確率(厳密には,確率ではない...) #endif /* MAIN_H_INCLUDED */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_util.cpp Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,69 @@ +#include "main_util.hpp" + +void check_file_open(FILE* file_p, const char* file_name) +{ + if ( file_p == NULL ) { + fprintf( stderr, "Error : file %s open faild. \r\n", file_name ); + exit(1); + } +} + +// データ系列ファイルの行数をLEN_DATA_SEQUENCEまで切り詰める +void truncate_data_file(void) +{ + FILE* dat_file_fp; + const char tmp_file_name[] = "/local/TMP_DAT.CSV"; + int line; + char trunc_buf_str[BUF_SIZE]; + // 最初に現在の行数を数える + dat_file_fp = fopen( SEQUENCE_DATA_NAME, "r"); + check_file_open( dat_file_fp, SEQUENCE_DATA_NAME); + line = 0; + while(fgets(trunc_buf_str, BUF_SIZE, dat_file_fp) != NULL) { + line++; + // printf("line %d : %s\r\n", line, trunc_buf_str); + } + // printf("current num of line : %d \r\n", line); + fclose( dat_file_fp ); + + // 切り詰め開始 + if ( line > LEN_DATA_SEQUENCE ) { + FILE* tmp_fp; + int diff_line = line - LEN_DATA_SEQUENCE; + dat_file_fp = fopen(SEQUENCE_DATA_NAME, "r"); + check_file_open( dat_file_fp, SEQUENCE_DATA_NAME ); + line = 0; + while(fgets(trunc_buf_str, BUF_SIZE, dat_file_fp) != NULL) { + line++; + if (line == diff_line) break; + } + // diff_line以降をテンポラリにコピー + tmp_fp = fopen( tmp_file_name, "w"); + check_file_open( tmp_fp, tmp_file_name ); + fflush( tmp_fp ); + fflush( dat_file_fp ); + while( fgets( trunc_buf_str, BUF_SIZE, dat_file_fp) != NULL) { + fputs( trunc_buf_str, tmp_fp); + } + //fclose( tmp_fp ); + //fclose( dat_file_fp ); + + // 更新 + tmp_fp = freopen( tmp_file_name, "r", tmp_fp); + check_file_open( tmp_fp, tmp_file_name ); + dat_file_fp = freopen(SEQUENCE_DATA_NAME, "w", dat_file_fp); + check_file_open( dat_file_fp, SEQUENCE_DATA_NAME ); + // 一時ファイルからコピー + fflush( tmp_fp ); + fflush( dat_file_fp ); + while( fgets( trunc_buf_str, BUF_SIZE, tmp_fp) != NULL) { + fputs( trunc_buf_str, dat_file_fp); + } + + fclose( dat_file_fp ); + fclose( tmp_fp ); + + // テンポラリの削除 + remove( tmp_file_name ); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_util.hpp Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,17 @@ +#ifndef MAIN_UTIL_H_INCLUDED +#define MAIN_UTIL_H_INCLUDED + +#include "main.hpp" + +// main.cppで書くと冗長なユーティリティ + +inline time_t get_JST(void) { + return (time(NULL) + (9 * 60 * 60)); +} + +extern void check_file_open(FILE*, const char*); // ファイルのオープンチェック.第一引数はファイルポインタ, 第二引数はファイル名 + // ホントはdebugだけど, オープン失敗はよく起こるので... +extern void truncate_data_file(void); // 系列データの行数をLEN_DATA_SEQUENCEに切り詰める.(先頭から削除) +extern void print_status(const char*,...); + +#endif /* MAIN_UTIL_H_INCLUDED */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ml_util/ml_util.cpp Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,21 @@ +#include "ml_util.hpp" + +void multiply_mat_vec(float* mat, // m * n 行列 + float* vec, // n * 1 ベクトル + float* result, // m * 1 計算結果ベクトル + int m, // m + int n) // n +{ + register float mat_sum; + for (int mat_mul_i = 0; mat_mul_i < m; mat_mul_i++) { + mat_sum = 0; + /* + printf("result[%d] : %p, MATRIX_AT(mat,n,mat_mul_i,mat_mul_j) : %p, vec[0] : %p", mat_mul_i, + &(result[mat_mul_i]), &(MATRIX_AT(mat,n,mat_mul_i,0)), vec); + */ + for (int mat_mul_j = 0; mat_mul_j < n; mat_mul_j++) { + mat_sum += MATRIX_AT(mat,n,mat_mul_i,mat_mul_j) * vec[mat_mul_j]; + } + result[mat_mul_i] = mat_sum; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ml_util/ml_util.hpp Wed Feb 18 15:02:16 2015 +0000 @@ -0,0 +1,84 @@ +#ifndef ML_UTIL_H_INCLUDED +#define ML_UTIL_H_INCLUDED + +#include "mbed.h" + +/* float.h がないので, FLT_MAXをここで */ +#ifndef FLT_MAX +#define FLT_MAX (0x1.fffffeP127F) // float max +#endif + +// 特に行列演算用のマクロ集 + +// 行列アクセス用マクロ. n_lenは行列の幅(length, col,列の数) +#define MATRIX_AT(ary,n_len,i,j) (ary[(((i) * (n_len)) + (j))]) + +// 2乗(ユーグリッド)ノルムを返す +inline float two_norm(float *vec, int dim) { + register float ret = 0; + for (int i=0; i < dim; i++) { + ret += powf(vec[i],2); + } + return sqrtf(ret); +} + +// 2ベクトル間の距離をユーグリッドノルムで測る. +inline float vec_dist(float *x, float *y, int dim) { + register float ret = 0; + for (int i=0; i < dim; i++) { + ret += powf(x[i] - y[i],2); + } + return sqrtf(ret); +} + +// 一様乱数の生成 : [-w,w]で生成. +inline float uniform_rand(float w) { + return (float(rand() - RAND_MAX/2) / float(RAND_MAX)) * 2 * w; +} + +// float配列の最大値を返す +inline float maxf(float* ary, int dim) { + register float max = 0; + for (int i=0; i < dim; i++) { + if (ary[i] >= max) { + max = ary[i]; + } + } + return max; +} + +// float配列の最小値を返す +inline float minf(float* ary, int dim) { + register float min = FLT_MAX; + for (int i=0; i < dim; i++) { + if (ary[i] <= min) { + min = ary[i]; + } + } + return min; +} + +// サイズm*nの行列とサイズn*1のベクトルの掛け算を計算し,結果をresultにセットする. + +extern void multiply_mat_vec(float* mat, // m * n 行列 + float* vec, // n * 1 ベクトル + float* result, // m * 1 計算結果ベクトル + int m, // m + int n); // n + +// シグモイド(ロジスティック)関数. +inline float sigmoid_func(float x){ + return (1 / (1 + expf(-x))); +} + +// 信号の正規化([0,1]の範囲に収めること:超重要) +inline float normalize_signal(float in, float max, float min){ + return float((in - min) / (max - min)); +} + +// 信号の元の領域への拡大([0,1]から元の信号値にスケール) +inline float expand_signal(float in, float max, float min){ + return float(min + (max - min) * in); +} + +#endif /* ML_UTIL_H_INCLUDED */
--- a/setup.cpp Mon Feb 16 07:53:45 2015 +0000 +++ b/setup.cpp Wed Feb 18 15:02:16 2015 +0000 @@ -8,11 +8,11 @@ int ret, line; float buf_data[DIM_SIGNAL]; - float* tmp_sample = new float[MCSVM_NUM_SAMPLES * DIM_SIGNAL]; - int* tmp_sample_label = new int[MCSVM_NUM_SAMPLES]; - float* tmp_mc_alpha = new float[MCSVM_NUM_SAMPLES * NUM_WEATHERS * (NUM_WEATHERS - 1) / 2]; + float* svm_tmp_sample = new float[MCSVM_NUM_SAMPLES * DIM_SIGNAL]; + int* svm_tmp_sample_label = new int[MCSVM_NUM_SAMPLES]; + float* svm_tmp_mc_alpha = new float[MCSVM_NUM_SAMPLES * NUM_WEATHERS * (NUM_WEATHERS - 1) / 2]; - svm_setup_fp = fopen( "/local/svm_samp.csv" , "r" ); + svm_setup_fp = fopen( "/local/SVM_SAMP.CSV" , "r" ); if( svm_setup_fp == NULL ) { fprintf( stderr, "Error in svm setup : sample file cannot open. \r \n" ); exit(1); @@ -22,29 +22,29 @@ while( ( ret = fscanf( svm_setup_fp, " %[^\n,],%f,%f,%f", buf_str, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) { if ( !strcmp(buf_str,"shiny") ) { - tmp_sample_label[line] = SHINY; + svm_tmp_sample_label[line] = SHINY; } else if ( !strcmp(buf_str,"cloudy") ) { - tmp_sample_label[line] = CLOUDY; + svm_tmp_sample_label[line] = CLOUDY; } else if ( !strcmp(buf_str,"rainy") ) { - tmp_sample_label[line] = RAINY; + svm_tmp_sample_label[line] = RAINY; } else if ( !strcmp(buf_str,"snowy") ) { - tmp_sample_label[line] = SNOWY; + svm_tmp_sample_label[line] = SNOWY; } else { continue; } - tmp_sample[line * 3] = buf_data[0]; - tmp_sample[line * 3 + 1] = buf_data[1]; - tmp_sample[line * 3 + 2] = buf_data[2]; + memcpy(&(svm_tmp_sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL); + // printf("svm sample loading.... ret : %d line : %d %s %f %f %f \r\n", ret, line, buf_str, svm_tmp_sample[line*3], svm_tmp_sample[line*3+1], svm_tmp_sample[line*3+2]); line++; - // printf("svm sample loading.... %d \r\n", line); } - // fclose( svm_setup_fp ); + mcsvm = new MCSVM(NUM_WEATHERS, DIM_SIGNAL, MCSVM_NUM_SAMPLES, svm_tmp_sample, svm_tmp_sample_label); - mcsvm = new MCSVM(NUM_WEATHERS, DIM_SIGNAL, MCSVM_NUM_SAMPLES, tmp_sample, tmp_sample_label); - - svm_setup_fp = fopen("/local/alpha.csv", "r"); + // Thank you freopen. + // Here, we should not use fclose -> fopen + svm_setup_fp = freopen("/local/SVM_ALPH.CSV", "r", svm_setup_fp ); + fflush( svm_setup_fp ); // required. + if ( svm_setup_fp == NULL ) { fprintf( stderr, "Error in open learned alpha data. \r\n"); exit(1); @@ -52,21 +52,19 @@ // 一列のデータではfscanfフォーマットがだるいので, fgetsを使用 line = 0; - while( fgets( buf_str, 20, svm_setup_fp) != NULL ) { - tmp_mc_alpha[line] = atof(buf_str); + while( fgets( buf_str, 20, svm_setup_fp ) != NULL ) { + svm_tmp_mc_alpha[line] = atof(buf_str); // printf("%d %f \r\n", line, tmp_mc_alpha[line]); line++; } - mcsvm->set_alpha(tmp_mc_alpha, MCSVM_NUM_SAMPLES, NUM_WEATHERS); + fclose( svm_setup_fp ); + + mcsvm->set_alpha(svm_tmp_mc_alpha, MCSVM_NUM_SAMPLES, NUM_WEATHERS); - delete [] tmp_sample; - delete [] tmp_sample_label; - delete [] buf_data; - delete [] tmp_mc_alpha; - delete [] buf_str; - fclose( svm_setup_fp ); - free( svm_setup_fp ); // mbed BUG - we must free file pointer. + delete [] svm_tmp_sample; + delete [] svm_tmp_sample_label; + delete [] svm_tmp_mc_alpha; } @@ -78,6 +76,7 @@ float buf_data[DIM_SIGNAL]; float* sample = new float[LEN_DATA_SEQUENCE * DIM_SIGNAL]; float* sample_maxmin = new float[DIM_SIGNAL * 2]; + char buf_str[20]; // 信号の正規化のために, 信号の最大値と最小値を決めてやる必要がある. sample_maxmin[0] = 50; @@ -87,26 +86,27 @@ sample_maxmin[4] = 100; sample_maxmin[5] = 0; // 湿度 - srnn_setup_fp = fopen( "/local/srnninit.csv" , "r" ); + srnn_setup_fp = fopen( SEQUENCE_DATA_NAME, "r"); if( srnn_setup_fp == NULL ) { - fprintf( stderr, "Error in SRNN setup. init sample file cannot open. \r\n"); + fprintf( stderr, "Error in SRNN setup. sample file cannot open. \r\n"); exit(1); } int line = 0; - while( ( ret = fscanf( srnn_setup_fp, "%f,%f,%f", &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) { + while( ( ret = fscanf( srnn_setup_fp, " %[^\n,],%f,%f,%f", buf_str, &(buf_data[0]), &(buf_data[1]), &(buf_data[2])) ) != EOF ) { memcpy(&(sample[line * DIM_SIGNAL]), buf_data, sizeof(float) * DIM_SIGNAL); // printf("sample %d : %f %f %f \r\n", line, MATRIX_AT(sample,DIM_SIGNAL,line,0), MATRIX_AT(sample,DIM_SIGNAL,line,1), MATRIX_AT(sample,DIM_SIGNAL,line,2)); line++; } + fclose( srnn_setup_fp ); + /* アドバイス:RNNにおいては,ダイナミクス(中間層のニューロン数)は多いほど良い */ srnn = new SRNN(DIM_SIGNAL, 20, LEN_DATA_SEQUENCE, PREDICT_LENGTH, sample, sample_maxmin); delete [] sample; delete [] sample_maxmin; - fclose( srnn_setup_fp ); - free( srnn_setup_fp ); + } // センサーのセットアップ. @@ -129,6 +129,7 @@ } if ( eth_if.connect() < 0 ) { + // (offlineが確定する -> offline modeへ). fprintf( stderr, "%s Ethernet connect failed. \r\n", prefix_net_str); exit(1); } @@ -138,45 +139,51 @@ // Please specify near ntp server. ex) Japan -> ntp.nict.jp:123 if (ntp_client.setTime("ntp.nict.jp") == 0) { - time_mutex.lock(); - global_time = time(NULL); - time_mutex.unlock(); - printf("%s Set time successfully! \n Time is set to (UTC): %s\r\n", prefix_net_str, ctime(&global_time)); + printf("%s Set time successfully! \r\n", prefix_net_str); } else { fprintf( stderr, "%s Error in setup time \r\n", prefix_net_str); } - //setup tcp socket - if(http_server.bind(80) < 0) { - fprintf( stderr, "%s HTTP server bind port 80 failed.\n\r", prefix_net_str); - exit(1); - } else { - printf("%s HTTP server bind successed.\n\r", prefix_net_str); - } - - if(http_server.listen(1) < 0) { - fprintf( stderr, "%s HTTP server listen failed.\n\r", prefix_net_str); - exit(1); - } else { - printf("%s HTTP server is listening...\n\r", prefix_net_str); - } + // setup http server + http_server = new HTTPServer(80, "/local/"); printf("%s IP Address : %s \r\n", prefix_net_str, eth_if.getIPAddress()); printf("%s Network setup finished! \r\n", prefix_net_str); } +// グラフィックハンドラの初期化 +static void graphic_handler_setup(void) +{ + graphic_handler = new GraphicHandler(DIM_SIGNAL, PREDICT_INTERVAL_TIME, PREDICT_LENGTH, get_JST()); +} + +// データの初期化(アロケート) +static void data_setup(void) +{ + new_seqence_data = new float[DIM_SIGNAL]; // 現在の(一番新しい)系列データ + new_predict_data = new float[DIM_SIGNAL * PREDICT_LENGTH]; // 現在の予測結果 + new_predict_weather = new int[PREDICT_LENGTH]; // 現在の予測天気 + new_predict_probability = new float[PREDICT_LENGTH]; // 現在の予測天気の確率 +} + // セットアップ. void setup(void) { - printf("SETUP START. \r\n"); + printf("SETUP START "); + printf("-------------------------- \r\n"); + mcsvm_setup(); + printf("SVM ...OK \r\n"); srnn_setup(); - printf("SRNN OK. \r\n"); - mcsvm_setup(); - printf("SVM OK. \r\n"); + printf("SRNN ...OK \r\n"); sensor_setup(); - printf("SENSOR OK. \r\n"); - network_setup(); - printf("NETWORK OK. \r\n"); - + printf("SENSOR ...OK \r\n"); + // network_setup(); + printf("NETWORK ...OK \r\n"); + graphic_handler_setup(); + printf("GRAPHIC ...OK \r\n"); + data_setup(); + printf("SHARED DATA ...OK \r\n"); + printf("SETUP SUCESS "); + printf("-------------------------- \r\n"); }
--- a/share.hpp Mon Feb 16 07:53:45 2015 +0000 +++ b/share.hpp Wed Feb 18 15:02:16 2015 +0000 @@ -1,13 +1,28 @@ #ifndef SHARE_H_INCLUDED #define SHARE_H_INCLUDED +#include "mbed.h" + +/* 共通のパラメタ類をマクロで定義 */ + #define PREDICT_LENGTH (3) // 予測系列長 #define PREDICT_INTERVAL_TIME (1 * 60 * 60) // 予測間隔 : 1h -#define LEN_DATA_SEQUENCE (100) // 観測データの履歴長 +#define LEN_DATA_SEQUENCE (50) // 観測データの履歴長 #define NUM_WEATHERS (4) // 気候の種類 #define DIM_SIGNAL (3) // 信号の次元(=センサの数) -#define MCSVM_NUM_SAMPLES (200) // MCSVMのサンプル数 +#define MCSVM_NUM_SAMPLES (120) // MCSVMのサンプル数 + +#define BUF_SIZE (250) // fprintfの時などに使われる文字列バッファの長さ + +#define SEQUENCE_DATA_NAME "/local/SEQ_DAT.CSV" // 系列データのファイル名 +#define PREDICT_DATA_NAME "/local/PRE_DAT.CSV" // 予測データのファイル名 +// 信号のインデックス +typedef enum { + TEMPERATURE = 0, // 気温 + AIR_PRESSURE = 1, // 気圧 + HUMIDITY = 2, // 湿度 +} SIGNAL_ID; // 天候を表す列挙型 typedef enum {