SensorSharingManager (0.31) | 2008-06-04 19:07 |
SHSpur (0.1) | 2008-06-05 00:22 |
ここではSSMをつかったプログラミングの一例を示します。
SSMを利用したプログラムは、センサのデータを連続して読み込みSSMにデータを登録するセンサドライバ側と、 センサのデータを任意のタイミングで読み込むユーザプログラム側とにわかれます。
新しいセンサを導入したい場合は、それに対応したセンサドライバを用意する必要があります。 センサドライバを新しく作成する際は下記を決定する必要があります。
センサの名前はユーザプログラム側からセンサを呼び出す際に必要です。 またセンサのデータ型は、ドライバ側とそのセンサを利用するソフトウェアで共有する必要があるので、 ヘッダファイルとして提供することが必要です。
ユーザプログラム側の手順としては、
また、SSM特有の概念として、センサID(SSM_sid型)と時刻ID(int型)があります。 センサIDはファイルポインタのようなもので、センサにアクセスする際に必要です。 これはopenSSMやcreateSSMにより得られます。 時刻IDは、センサデータ中の通し番号で、データが入力される毎にインクリメントされます。
以降に利用できる関数とドライバおよびユーザ側プログラムのサンプルを載せます。
初期化
登録・オープン
書き込み・読み込み(共有メモリアクセスのみ)
プロパティの読み書き
センサのデータをSSMに書き込む例について示します。 ここでは、SensorAというセンサをSSMに適用する例を示します。
まず、SensorAの登録名を、
sensor_Aと定義します。 名前は任意ですが、ログ取り等の際にも利用しますので、あまり長くない方が良いでしょう。
つぎに、書き込みたいデータの型をSensor_A.hに次のように定義したとします。
Sensor_A.h #ifndef __SENSOR_A__ #define __SENSOR_A__ typedef struct{ double a; double b; int c; }SensorA; #endifこの際、SensorAのデータを読み込み、SSMに書き込むプログラムは次のようになります。
SensorA_driver.c #include<ssm_common.h> #include<Sensor_A.h> #include<unistd.h> //センサデータを読み込むかわりに適当なデータを生成 void receive_sensorA(SensorA *data, double *time){ static double a,b; static int c; a+=0.1; b+=0.01; c++; data->a = a; data->b = b; data->c = c; *time = gettimeSSM(); usleep(100000); } int main(int argc, char *argv[]){ SensorA sens_data; double measured_time; SSM_sid sensA_sid; initSSM(); //名前をsensor_Aで、IDを0で、0.1秒おきに来るデータを10秒間保持するよう領域を確保。 sensA_sid = createSSM_time("sensor_A", 0, sizeof(SensorA), 10, 0.1); while(1){ //SensorAのデータを何かしらの方法(例えばシリアル通信)で取得し、頑張って観測時刻を推定する関数。 receive_sensorA(&sens_data, &measured_time); //SSMへのデータの書き込み。 writeSSM(sensA_sid, (char*)&sens_data, measured_time); } }
ここではセンサデータを利用するユーザプログラム側のプログラム例について示します。
SSMではセンサの情報を様々な方法でアクセスできます。 ここではつぎの4種類のプログラム例を示します。
最新のデータにアクセスするには、readSSMの最後の引数の時刻IDに-1を入れることで可能です。
1秒おきに最新のSensorAのデータを読み込むには次の様にします。
SensorA_print.c
#include<ssm_common.h> #include<Sensor_A.h> #include<unistd.h> #include<stdio.h> int main(int argc, char *argv[]){ SensorA sens_data; double measured_time; SSM_sid sensA_sid; initSSM(); sensA_sid = openSSM("sensor_A", 0, 0); while(1){ readSSM(sensA_sid, (char*)&sens_data, &measured_time, -1); printf("time=%f a=%f b=%f c=%d\n",measured_time, sens_data.a, sens_data.b, sens_data.c); sleep(1); } }この場合、読み込む周期がセンサの更新周期が早ければ全てのデータを利用するとは限りません。
オドメトリなどを独自で計算したい場合などは得られたセンサデータ全てを利用したくなります。 ここでは時刻IDを用いることで、得られたSensorAのデータを順番に読み込む例について示します。
SensorA_print2.c
#include<ssm_common.h> #include<Sensor_A.h> #include<unistd.h> #include<stdio.h> int main(int argc, char *argv[]){ SensorA sens_data; double measured_time; SSM_sid sensA_sid; int tid; initSSM(); sensA_sid = openSSM("sensor_A", 0, 0); //最新のデータのTIDを取得する。 tid = readSSM(sensA_sid, (char*)&sens_data, &measured_time, -1); while(1){ while(readSSM(sensA_sid, (char*)&sens_data, &measured_time, tid) <= 0){ usleep(20000); //データがまだきていなければちょっと待ってみる。 } printf("time=%f tid=%d a=%f b=%f c=%d\n",measured_time, tid, sens_data.a, sens_data.b, sens_data.c); tid++; } }
readSSMは指定したTIDのセンサデータがなければ0以下の値を返します。
時刻IDもしくは時刻を指定することで、過去のデータを読み込む事ができます。
SensorA_print3.c
#include<ssm_common.h> #include<Sensor_A.h> #include<unistd.h> #include<stdio.h> int main(int argc, char *argv[]){ SensorA sens_data; double measured_time; SSM_sid sensA_sid; int tid; double now_time; initSSM(); sensA_sid = openSSM("sensor_A", 0, 0); while(1){ now_time = gettimeSSM(); //現在時刻を取得 //現在時刻の1秒前のデータを取得 tid = readSSM_time(sensA_sid, (char*)&sens_data, now_time-1, &measured_time); printf("time=%f tid=%d a=%f b=%f c=%d\n",measured_time, tid, sens_data.a, sens_data.b, sens_data.c); //その一つ後のデータを取得 tid++; readSSM(sensA_sid, (char*)&sens_data, &measured_time, tid); printf("time=%f tid=%d a=%f b=%f c=%d\n\n",measured_time, tid, sens_data.a, sens_data.b, sens_data.c); sleep(1); } }
時刻指定で読み込むことで、異なるセンサ間での同時刻のデータを読み込む事ができます。
SensorAB_print.c
#include<ssm_common.h> #include<unistd.h> #include<stdio.h> #include<Sensor_A.h> #include<Sensor_B.h> int main(int argc, char *argv[]){ SensorA sens_dataA; SensorB sens_dataB; double measured_time; SSM_sid sensA_sid, sensB_sid; int tid; double time; initSSM(); sensA_sid = openSSM("sensor_A", 0, 0); sensB_sid = openSSM("sensor_B", 0, 0); while(1){ //センサAの最新データを取得 tid = readSSM(sensA_sid, (char*)&sens_dataA, &measured_time, -1); //同時刻のデータ(もっとも近く、過去のもの)を取得 readSSM_time(sensB_sid, (char*)&sens_dataB, measured_time, &time); printf("timeA=%f timeB=%f A.a=%f B.a=%f",measured_time,time,sens_dataA.a, sens_dataB.a); sleep(1); } }
6/30付けでセンサの静的情報記録機能が追加されました。
センサの位置やステップ角、車輪径等センサ固有の情報を記録できます。
set_propertySSM(char* センサ名, int センサのID, char* 登録するデータのアドレス, int 登録するデータの大きさ); get_propertySSM(char* センサ名, int センサのID, char* 取得するデータのアドレス);
型を決める。例えば、
typedef struct{ double a; char name[10]; }SensorA_Property;等。で、登録する。
SensorA_Property sensA_property; sensA_property.a = 100; sprintf(sensA_property.name, "SensorA"); set_propertySSM("sensor_A", 0, &sensA_property, sizeof(SensorA_Property));
SensorA_Property sensA_property; get_propertySSM("sensor_A", 0, &sensA_property); printf("%s %f\n",sensA_property.name, sensA_property.a);
[PageInfo]
LastUpdate: 2008-06-09 22:35:33, ModifiedBy: etake
[License]
GNU Free Documentation License
[Permissions]
view:all, edit:login users, delete/config:members