NALGO研究部の笹川です。
先日JINS MEMEを買ってみたので、何かしらデータを取得して遊んでみようと思いました。
※JINS MEME (公式サイト)は、メガネブランドJINSから販売されているセンサー付きのメガネ製品です。良い姿勢で作業した時間割合を記録する等、「ココロとカラダのセルフケアメガネ」としての機能があるみたいです!
最終目標は社内Web会議で手軽、低負荷に使えるアバターカメラです。1
ひとまずメガネをかけてドキュメントを読んだり、既存の記事を当たったりしてみると、Unityを使用したりiOSアプリをビルドしたりする物のようで、少し腰が重い感じ。
また、現在はSDKが非公開のようです。
JINS MEMEのSDKは非公開になっています。ご利用を希望の方はサポート宛にお問い合わせください。
どうしたものか2と考えていると、Loggerアプリによるデータ取得という記載があり、どうやらJINS側で公開しているiOSアプリから任意のプログラムに対してWebSocketでデータを送ってくれるようです。今回はこちらを使います。
今回の構成
以下のように手持ちのスマホからデスクトップPC上のPythonプログラムにWebSocket接続します。Pythonを使う理由は特にないですが、たまたまWebSocketサーバーのサンプルプログラムを持っていたのでPythonにします。
Pythonプログラム
こちらが今回のPythonプログラムです。
import asyncio
from websockets import serve # type: ignore
async def handler(websocket) -> None:
"""WebSocketのmain処理。"""
while True:
msg = await websocket.recv()
print("msg received")
print(f"{msg}") # 現状は受信したメッセージをprintするだけ
async def start_server() -> None:
"""WebSocket待ち受けを開始する."""
print("Start")
await serve(
handler,
"0.0.0.0",
19999,
)
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(start_server())
asyncio.get_event_loop().run_forever()
このプログラムを実行し、LoggerアプリからIPアドレスを指定して接続すると、以下のようなメッセージがダーッと流れてきます。
{"sequenceNumber":160,"accZ":-15.375,"blinkSpeed":0,"yaw":0,"accY":8.3125,"eyeMoveDown":0,"fitError":0,"accX":-1.625,"noiseStatus":false,"pitch":0,"eyeMoveRight":0,"roll":0,"powerLeft":5,"walking":false,"blinkStrength":0,"eyeMoveLeft":0,"eyeMoveUp":0}
msg received
{"blinkSpeed":0,"eyeMoveLeft":0,"eyeMoveRight":0,"accX":-3.125,"pitch":0,"noiseStatus":false,"yaw":0,"roll":0,"fitError":0,"powerLeft":5,"accZ":-14.0625,"walking":false,"eyeMoveUp":0,"accY":7.9375,"blinkStrength":0,"sequenceNumber":161,"eyeMoveDown":0}
msg received
{"sequenceNumber":162,"accZ":-14.1875,"blinkSpeed":0,"yaw":0,"accY":7.0625,"eyeMoveDown":0,"fitError":0,"accX":-3.125,"noiseStatus":false,"pitch":0,"eyeMoveRight":0,"roll":0,"powerLeft":5,"walking":false,"blinkStrength":0,"eyeMoveLeft":0,"eyeMoveUp":0}
msg received
{"sequenceNumber":163,"accZ":-16.75,"blinkSpeed":0,"yaw":0,"accY":7.375,"eyeMoveDown":0,"fitError":0,"accX":0,"noiseStatus":false,"pitch":0,"eyeMoveRight":0,"roll":0,"powerLeft":5,"walking":false,"blinkStrength":0,"eyeMoveLeft":0,"eyeMoveUp":0}
msg received
{"blinkSpeed":0,"eyeMoveLeft":0,"eyeMoveRight":0,"accX":1.75,"noiseStatus":false,"pitch":0,"yaw":0,"powerLeft":5,"fitError":0,"walking":false,"accZ":-16.9375,"roll":0,"accY":7.75,"blinkStrength":0,"eyeMoveUp":0,"sequenceNumber":164,"eyeMoveDown":0}
msg received
{"roll":0,"yaw":0,"blinkStrength":0,"accZ":-16.75,"accY":8,"blinkSpeed":0,"fitError":0,"powerLeft":5,"walking":false,"eyeMoveLeft":0,"eyeMoveUp":0,"sequenceNumber":165,"accX":0.625,"noiseStatus":false,"pitch":0,"eyeMoveDown":0,"eyeMoveRight":0}
msg received
{"accY":6.0625,"eyeMoveLeft":0,"eyeMoveUp":0,"sequenceNumber":166,"eyeMoveRight":0,"noiseStatus":false,"blinkSpeed":0,"accX":-1.125,"pitch":0,"yaw":0,"accZ":-14.5625,"blinkStrength":0,"roll":0,"walking":false,"fitError":0,"powerLeft":5,"eyeMoveDown":0}
msg received
{"sequenceNumber":167,"accZ":-13.9375,"blinkSpeed":0,"yaw":0,"accY":3.1875,"eyeMoveDown":0,"fitError":0,"accX":-2.375,"noiseStatus":false,"pitch":0,"eyeMoveRight":0,"roll":0,"powerLeft":5,"walking":false,"blinkStrength":0,"eyeMoveLeft":0,"eyeMoveUp":0}
msg received
{"roll":0,"yaw":0,"blinkStrength":0,"accZ":-14.625,"accY":1.125,"blinkSpeed":0,"fitError":0,"powerLeft":5,"walking":false,"eyeMoveLeft":0,"eyeMoveUp":2,"sequenceNumber":168,"accX":-1.9375,"noiseStatus":true,"pitch":0,"eyeMoveDown":0,"eyeMoveRight":2}
msg received
{"sequenceNumber":169,"accZ":-14.9375,"blinkSpeed":0,"yaw":0,"accY":-0.0625,"eyeMoveDown":0,"fitError":0,"accX":-1.75,"noiseStatus":true,"pitch":0,"eyeMoveRight":0,"roll":0,"powerLeft":5,"walking":false,"blinkStrength":0,"eyeMoveLeft":0,"eyeMoveUp":0}
次回はこれらの値から頭や目の角度といった情報を取り出してみたいと思います。(姿勢推定のような計算が必要?)