梶研 [FA見学 & リアルタイムでスマホの姿勢を表示するアプリ(完成)]
2024年07月16日
FA見学 & リアルタイムでスマホの姿勢を表示するアプリ(完成)
出席率
- 3年セミナー:??%
スケジュール
短期的な予定
- [ ] mocopi と お料理センシング
- [x] シーンとランドマークを決める(~2月上旬)
- [x] SVM で動作判別する
- [x] 機械学習を深める
- [ ] お料理センシング
- [x] お料理でどんな動作があるかを知る
- [x] レシピを決める
- [x] 関節を3次元座標に変換する
- [ ]
関節を2次元座標に変換する - [x] ST-GCN を大体理解
- [ ] ST-GCN で動作推定
- [ ] 伊達巻きで動作推定する
- [ ] レシピ(手順書)を元に動作推定を補う
- [ ] 論文書く
- [ ] 発表
- [ ] BookWorm
- [x] Pasori と デスクトップアプリを接続する(技術検証)
- [x] nfc読み込み機能 & 画面を作る
- [ ] API と連携させる
- [x] 管理者画面を作る
進捗報告
ST-GCN
夏休みに託します
FA見学した
MEEさんの名古屋製作所にいった
昼ごはん
(工場の写真はありません)
Webエンジニアだけで人生終えるのは勿体無いと改めて感じた.
<p style="font-size:13px">人工衛星とか夢があるなぁ(鎌倉でやってるらしい)</p>
リアルタイムでスマホの姿勢を表示するアプリ
前回
センシング側: React Native
表示側: Tauri
通信: Socket(TCP)
フィルタ: 相補フィルタ→(Madgwickフィルタ)
で、ほぼできた. 動いているときの姿勢推定が上手くいかない
作り直した!!!
- React Native の開発環境が気に入らない
- dev環境を開きづらい
- ビルドが expoのクラウド上 でしかできない
- もっと汎用的にしたい
- アプリインストールするの面倒
- 同じネットワーク内でしかできない
修正後の構成
React Native → Kotlin: 始めからスマホで見れる機能あるし、なんでもできるし
Socket(TCP) → Bluetooth: ネットワークに依存したくない
ありがとうございます.
<br /><br /><br /><br />
Kotlin 辞めた!!!
Android Studio 使いづらい!!
ショトカキー何一つ分からん
時間ないのに Kotlin を学ぶのは間違えている!!
修正後の構成2
センシング側: React(ブラウザ)
表示側: React(ブラウザ)
API側: Python(Fast API)
通信: WebSocket
フィルタ: Madgwickフィルタ
- 加速度と角速度はWebでも取れる
- 表示もWebで簡単にできる
- インストール不要!!
- API側(Python)で処理すればフィルタを転用できる
- インターネットに繋がっていればどこでもOK
ぜひ使ってください :sore-web-de-dekimasu:
(モバイル版もあります)
APIサーバつくる
簡単にできた
@app.post("/api/raw")
async def post_raw_data(req: Request):
data = await req.json()
sensorData = validate_sensor_data(data) # データが正しい形式か確認
quaternions = filter.update(sensorData) # フィルターを適用
response_data = {"quaternions": quaternions}
# データを WebSocket で接続しているクライアントに送信
await manager.send_text(json.dumps(response_data))
# 返す
return response_data @app.websocket("/ws/posture")
async def websocket_endpoint(websocket: WebSocket):
# WebSocket 接続を管理するクラスに登録
await manager.connect(websocket)
try:
while True:
# メッセージを受信
data = await websocket.receive_text()
# 全てのクライアントにメッセージを送信
await manager.send_text(f"Received: {data}")
except WebSocketDisconnect:
# WebSocket 接続が切断された場合は解除
manager.disconnect(websocket) フィルタは西先輩にアウトソーシングしました.
ありがとうございます
センシング側をつくる
devicemotionイベントで加速度と角速度を取得できた
export function useSensor(callack?: Callback & CallbackPromise) {
...
useEffect(() => {
if (!isPermissionGranted) return;
window.addEventListener('devicemotion', handleMotion);
return () => {
window.removeEventListener('devicemotion', handleMotion);
};
}, [isPermissionGranted, handleMotion]);
... const [sensorData, { requestPermission }] = useSensor(async (data) => await fetchSensorData(data)); 表示側
websocket を扱うためのカスタムフック作った!!
export const useWS = (url: string, callBack: CallBack) => {
const [ws, setWS] = useState(() => new WebSocket(url));
useEffect(() => {
ws.onmessage = (e) => {
const data = JSON.parse(e.data);
console.log(data);
callBack(data);
};
return () => {
ws.close();
};
}, []);
function send<T>(data: T): boolean {
if (ws.readyState !== ws.OPEN) return false;
ws.send(JSON.stringify(data));
return true;
}
function reConnect() {
setWS(new WebSocket(url));
}
return { send, reConnect } as const;
}; useWS(url.href, (data) => {
const isValid = quatResponseSchema.safeParse(data);
if (!isValid.success) return;
setQuaternion(isValid.data.quaternions[0]);
}); いい感じにデプロイした
APIを梶研サーバにデプロイした
uvicorn + FastAPI でデプロイするときは --host 0.0.0.0 をつけよう
例: uvicorn main:app --host 0.0.0.0
省略
(鹿さんありがとうございます)
荒ぶった
問題点
- Madgwickフィルタのサンプリングレートが間違えていた
- とりあえず 100fps にしていたが実際は60fps
- 通信が不安定
- 0.5秒に1回まとめて送っていた
- データ量の問題(?)かなにかで遅延がすごい
- センサデータが変化するたびに送信するようにした
- 単位間違えた
DeviceMotionEventのrotationRateはdeg/sだった. (rad/sのつもりだった)
- Hooks の使い方ミスった
- ダメ:
const [ws, setWS] = useState(new WebSocket(url));- WebSocket に接続してから、渡す
- マウント時であれば保持, それ以外は無視
- 良い:
const [ws, setWS] = useState(() => new WebSocket(url));- WebSocket に接続する関数を渡す(接続はしていない)
- マウント時であれば接続してから保持, それ以外は無視
- めっちゃ接続&切断しまくってた
- ダメ:
リポジトリ
API側: https://github.com/kajiLabTeam/realtime-de-smartphone-no-posture-wo-show-suruzo-server
センシング側: https://github.com/kajiLabTeam/realtime-de-smartphone-no-posture-wo-show-suruzo-sensing-web
表示側: https://github.com/kajiLabTeam/realtime-de-smartphone-no-posture-wo-show-suruzo-display
デプロイ先
取得側: https://realtime-zou-sensing.satooru.dev
表示側: https://realtime-zou-display.satooru.dev
一旦個人の Cloudflare Pages にデプロイしています.
必要であれば梶研 Cloudflare にデプロイしてください
(環境変数を設定する必要があります)
進路関係
余談
Mrs. GREEN APPLE のライブ行った
<br /><br /><br />
<p style="font-size:20px">ネタバレ注意!!!</p>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
新曲もりもりで最高です
<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">⚠️ネタバレ注意<br>7月6日 Mrs.GreenApple のゼンジン未到とヴェルトラウム銘々編無事終了<br>めちゃくちゃ楽しかったぜ!!<br>magicだけ撮影オッケーになったから撮ってきたぜ!<a href="https://twitter.com/hashtag/Mrs%EA%93%B8GREENAPPLE?src=hash&refsrc=twsrc%5Etfw">#MrsꓸGREENAPPLE</a> <a href="https://twitter.com/hashtag/%E3%82%BC%E3%83%B3%E3%82%B8%E3%83%B3?src=hash&refsrc=twsrc%5Etfw">#ゼンジン</a> <a href="https://twitter.com/hashtag/%E3%83%9F%E3%82%BB%E3%82%B9?src=hash&refsrc=twsrc%5Etfw">#ミセス</a> <a href="https://twitter.com/hashtag/%E3%82%BC%E3%83%B3%E3%82%B8%E3%83%B3%E6%9C%AA%E5%88%B0%E3%81%A8%E3%83%B4%E3%82%A7%E3%83%AB%E3%83%88%E3%83%A9%E3%82%A6%E3%83%A0?src=hash&refsrc=twsrc%5Etfw">#ゼンジン未到とヴェルトラウム</a> <a href="https://twitter.com/hashtag/MrsGREENAPPLE?src=hash&refsrc=twsrc%5Etfw">#MrsGREENAPPLE</a> <a href="https://twitter.com/hashtag/%E3%83%8E%E3%82%A8%E3%83%93%E3%82%A2%E3%82%B9%E3%82%BF%E3%82%B8%E3%82%A2%E3%83%A0%E7%A5%9E%E6%88%B8?src=hash&refsrc=twsrc%5Etfw">#ノエビアスタジアム神戸</a> <a href="https://twitter.com/hashtag/%E3%83%8E%E3%82%A8%E3%82%B9%E3%82%BF?src=hash&refsrc=twsrc%5Etfw">#ノエスタ</a> <a href="https://twitter.com/hashtag/magic?src=hash&refsrc=twsrc%5Etfw">#magic</a> <a href="https://t.co/AdiKF7w5zO">pic.twitter.com/AdiKF7w5zO</a></p>— ミズキ🏳️🌈 (@mizuki09232003) <a href="https://twitter.com/mizuki09232003/status/1809584134345617834?ref_src=twsrc%5Etfw">July 6, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
自分の声入ってたので拾った動画
※ この曲だけ撮影OKでした
<iframe width="1214" height="683" src="https://www.youtube.com/embed/xk7czF1H2No" title="Mrs. GREEN APPLE 看板すごい" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>