Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 {