Weather casting with Machine Learning (SVM and SRNN).

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

Files at this revision

API Documentation at this revision

Comitter:
yukari_hinata
Date:
Wed Feb 18 15:02:16 2015 +0000
Parent:
1:8538381cae81
Child:
3:5add3759e08a
Commit message:

Changed in this revision

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
GraphicHandler.lib Show annotated file Show diff for this revision Revisions of this file
HTTPServer.lib Show annotated file Show diff for this revision Revisions of this file
SRNN.lib Show annotated file Show diff for this revision Revisions of this file
SVM.lib Show annotated file Show diff for this revision Revisions of this file
SensorModule.lib Show annotated file Show diff for this revision Revisions of this file
debug/debug.cpp Show annotated file Show diff for this revision Revisions of this file
debug/debug.hpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.hpp Show annotated file Show diff for this revision Revisions of this file
main_util.cpp Show annotated file Show diff for this revision Revisions of this file
main_util.hpp Show annotated file Show diff for this revision Revisions of this file
ml_util/ml_util.cpp Show annotated file Show diff for this revision Revisions of this file
ml_util/ml_util.hpp Show annotated file Show diff for this revision Revisions of this file
setup.cpp Show annotated file Show diff for this revision Revisions of this file
share.hpp Show annotated file Show diff for this revision Revisions of this file
--- 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 {