ORPHE-CORE.jsはORPHE CORE Module (以後コアモジュールと呼びます)をJavaScriptから制御するためのライブラリです。 コアモジュールには大きく分けてBLE、モーションセンサ、LED機能が実装されています。開発者の皆さんはこのライブラリを使って、手軽にコアモジュールのLEDを光らせたり、モーションセンサの値を取得したりすることができます。
このチュートリアルでは、ORPHE-CORE.jsの基本的な使用方法と知識について説明します。documentページに記載されているサンプルプログラムで用いられているAPIについて簡潔に触れつつ,BLE通信とコアモジュールの振る舞いを理解することを目的とします.
ORPHE-CORE.js には、Orphe というクラスが用意されています。このクラスを使って、コアモジュールを制御することができます。 次のコードは、ORPHE-CORE.jsを使ってコアモジュールのLEDを光らせるサンプルコードです。このコードを実行し、connectと書かれたボタンを押すとコアモジュール選択ダイアログが開き、コアモジュール接続に成功すると、LEDが光ります。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ORPHE CORE JS DEMO</title>
</head>
<body>
<h1>Hello, ORPHE!</h1>
<button onclick="core.setLED(1,0);">connect</button>
<script src="https://cdn.jsdelivr.net/gh/Orphe-OSS/ORPHE-CORE.js/js/ORPHE-CORE.js"></script>
<script>
var core = new Orphe(0);
window.onload = function () {
core.setup();
}
</script>
</body>
</html>
これは、Orpheクラスのインスタンスを生成しています。引数にはコアモジュールのインデックス(コアモジュール番号)を指定します。コアモジュールは最大2つまで接続できます。インデックスには0または1を指定します。coreは様々な場所から呼び出される可能性があるので、グローバル変数として宣言するとプロトタイピングには便利でしょう。
setup()関数は、コアモジュールの初期化を行います。このsetup()では具体的にはコアモジュールに接続するキャラクタリスティックを設定することができます。特に引数を指定しない場合、デフォルトの設定(DEVICE_INFORMATION, SENSOR_VALUES, STEP_ANALYSIS)が適用されます。この3つのキャラクタリスティックは、ORPHE-CORE.jsでアクセス可能なすべてのBLEキャラクタリスティックを含んでいます。setup()を忘れると、接続するキャラクタリスティックが設定されないため、正しく動作しません。
setLED()関数は、コアモジュールのLEDを制御するための関数です。最初の引数で点灯の有無、次の引数で5種類の発酵パターンを指定します。
コアモジュールはBLE(Bluetooth Low Energy)を使ってスマートフォンやパソコンと通信します。BLE通信は、コアモジュールとスマートフォン(またはパソコン)の間でデータをやり取りするためのプロトコルです。コアモジュールではサービス(Service)とキャラクタリスティック(Characteristic)を使ってデータ通信を行い、これらサービスとキャラクタリスティックをまとめた通信プロトコルをGATT(Generic Attribute Profile)と呼びます。
コアモジュールにおけるGATTプロトコルは、以下のサービスとキャラクタリスティックで構成されています。
先程のsetup()関数では、デフォルトでDevice Information, Sensor Values, Step Analysisの3つのキャラクタリスティックが設定されるため、上記のデータを取得することができますが、例えばsetup(["DEVICE_INFORMATION"])のように引数を指定することで、特定のキャラクタリスティックのみを設定することもできます。通常はすべてアクセスできればよいので、引数を指定する必要はほとんどありません。
ここまではORPHE-CORE.jsの初期設定について説明しました。次に、コアモジュールから取得したモーションセンサ及び解析結果を取得する方法について説明します。コアモジュールには、加速度センサ、ジャイロセンサが搭載されています。これらのセンサから取得した値は、Sensor Valuesというキャラクタリスティックを通じて取得することができます。また、モーションセンサから得られた値を解析した結果は、Step Analysisというキャラクタリスティックを通じて取得することができます。Step Analysisはコアモジュールの歩行解析結果を含んでいます。
Sensor Values及びStep Analysisの値を取得するためには、begin()関数を呼び出す必要があります。それぞれのキャラクタリスティックはNotificationという形式で通信を行います。この関数を呼び出すことで、コアモジュールからの定期的にデータ送信が開始されます。begin()の引数は以下の通りです。
以下にそれぞれのキャラクタリスティックで取得できる値を示します。gotQuat(クオータニオン)のようにどちらでも共通して取得できるデータもありますが、キャラクタリスティックを間違えると値が取得できない場合があることを注意してください。各値取得に対応している gotHogeHogeという関数は、コアモジュールから値を取得した際に呼び出されるコールバック関数です。この関数をユーザ側で定義することで、コアモジュールから値が取得された場合に適時その関数が呼び出されるようになります。
では、実際にモーションセンサ値、具体的には加速度センサ値を取得するサンプルコードを示します。コアモジュールの初期化、setupを行った後、begin()関数を呼び出すことで、加速度センサ値を取得することができます。加速度センサ値の場合はSensor Valuesのキャラクタリスティックを使用する必要があるため、begin() または begin('SENSOR_VALUES')という引数を指定します。begin('STEP_ANALYSIS')で指定すると、STEP_ANALYSISキャラクタリスティック値しか取得できないため、コンソールには何も表示されなくなります。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<button onclick="mystart();">connect</button>
<script src="https://cdn.jsdelivr.net/gh/Orphe-OSS/ORPHE-CORE.js/js/ORPHE-CORE.js"
crossorigin="anonymous"></script>
<script>
var core;
window.onload = function () {
core = new Orphe(0);
core.setup();
}
function mystart() {
core.begin('SENSOR_VALUES');
core.gotAcc = function (acc) {
console.log(acc);
}
}
</script>
</body>
</html>
コアモジュールは無線通信をし、リアルタイム処理を重視してデータを送信しているためデータの欠損が発生することがあります。ORPHE-CORE.jsでは、欠損が発生した場合にlostData ()関数が呼び出されます。lostData()関数は、欠損が発生した時に呼び出されるコールバック関数です。lostData()関数は、欠損が発生した前後のデータ番号を引数として受け取ります。これにより、欠損が発生したデータの前後のデータを比較することができます。プロトタイプやリアルタイム性を重視するアプリケーション開発においてはlostData()関数の利用価値はそれほど高くありませんが、計測値結果の保存や、計測値を解析する場合はデータ欠損については注意深く観察する必要があります。コアモジュールの性能と関係なく、BLE通信環境やコアモジュールのバッテリー残量が少ない場合にもデータ欠損が発生することがありますので通信状況が悪い場合は電波状況の改善やコアモジュールの充電等も考慮してください。
どうしても計測値の欠損が許容できない場合は、iOSやandroidアプリケーションを利用して、コアモジュール内部に保存された計測値を取得することもできます。PCを利用したい場合は ORPHE ANALYTICSをご検討ください。ORPHE-CORE.jsではコアモジュール内部に保存された計測値(ログデータ)を取得するためのAPIは提供していません。
以下にデータ欠損が発生した場合にlostData()関数が呼び出されるサンプルコードを示します。実際にコアモジュールをPCから離したり、コアモジュールとPCの間に遮蔽物を置いて電波状況を変えるなどしてデータ欠損が発生する様子を観察してみましょう。lostData()関数は200Hz対応のコアモジュール3(CR-3)のみで利用可能です。 CR-2で接続した場合はエラーにはなりませんが、lostData()関数が呼び出されることはありません。また、データパケットにデータ番号が含まれているものだけが対象となるため、SENSOR_VALUESまたはSTEP_ANALYSIS_AND_SENSOR_VALUESを指定してbegin()関数を呼び出す必要があります。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<button onclick="mystart();">connect</button>
<script src="https://cdn.jsdelivr.net/gh/Orphe-OSS/ORPHE-CORE.js/js/ORPHE-CORE.js"
crossorigin="anonymous"></script>
<script>
var core;
window.onload = function () {
core = new Orphe(0);
core.setup();
}
function mystart() {
core.begin('SENSOR_VALUES');
core.gotAcc = function (acc) {
console.log(acc);
}
core.lostData = function (num, num_prev) {
console.error(`lostdata: ${num_prev} から ${num}の間でデータ欠損が発生しました`);
}
}
</script>
</body>
</html>