AITRIOSを使ってWeb連携アプリを作る：ハッカソン実践知見

## はじめに

ハッカソン「風が吹けば豊能町が賑わうハッカソン」に参加し、受賞することができました。

https://www.craftstadium.com/hackathon/toyono-hackathon_20250110

AITRIOS（ソニーのエッジAIデバイス）を活用した穏やかなローカルSNS「アイスポット(iSpot)」を開発しました。このアプリは、AIカメラで地域の風景を分析し、観光客に最適な撮影位置を提案する機能 + SNSです。

本記事では、AITRIOSをWebアプリと連携させる際の実践的な知見を共有します。

時間があまりない＋Discordでキャッチアップログが大量にあったので、それを全部Claudeに投げてまとめました。AIっぽい部分と雑な部分があるのはご了承ください。でも分かるようには書いたつもりです🙇‍♂️

## AITRIOSとは

AITRIOSはソニーセミコンダクタソリューションズが提供するエッジAIプラットフォームです。AITRIOSは、カメラデバイスにAIモデルをデプロイし、エッジでのリアルタイム推論を可能にします。Console（管理画面）を通じてデバイス管理、モデルのデプロイ、推論結果の確認などが行えます。

https://www.aitrios.sony-semicon.com/

> 実際のデバイス（めっちゃ小さいです。サイズがわかるようにハンコを置きました。）
ちなみに、クリップは僕の机が散らかってた痕跡ではなくて、入ってるやつで。デバイスの初期化？ or Wifi切り替えで使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/dd15a023-6524-4b17-9227-50e7a46fdeb8.png)

### エッジAI（Edge AI）とは
端末（エッジデバイス）に搭載されたAI（人工知能）のことです。
端末で入力された情報をクラウドに送る前にAI処理を行うため、通信速度やコストの削減が可能。

<img src="https://spectee.co.jp/wp-content/uploads/2021/05/img1.png" />

> 画像参照: https://spectee.co.jp/report/edge_ai/

## 今回取り組んだこと

「アイスポット」プロジェクトでは、AITRIOSカメラを活用して以下の機能を実現しました：

1. 観光スポットでの最適な撮影位置をAIが提案
2. リアルタイムで物体検出を行い、風景と人物の構図を分析
3. WebアプリからAITRIOSデバイスの制御と推論結果の取得

特に難しかったのは、WebアプリからAITRIOSデバイスを制御し、推論結果をリアルタイムで取得する部分です。

> イメージ↓
オブジェクト認識風に表示されてるものはモックデータ <img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/b33e1034-c108-4af9-8a8c-3179434d7f67.png" />

## AITRIOS画面の説明
### Manage Device
その名の通り、デバイス管理画面。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/3e66ddaf-fc9c-4ea1-ac5a-0975da80287f.png)

### 自分のデバイスの状態を確認する画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/11f0348a-4181-4eeb-ba17-064a5df9767f.png)

### Settings
AITRIOSの設定。今回はCommand Parameterをよく使った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/1d1dfaa1-363c-4ed5-b2b9-78339772dcde.png)


## AITRIOSとWebアプリの連携方法

### 1. 開発環境の準備

まず必要なのは、AITRIOSデバイスのセットアップとConsoleへの登録です：

```
# デバイスのWi-Fi設定
NTP: 1.jp.pool.ntp.org（今回のハッカソンではこれを運営の方から指定されました）
Wi-Fi SSID: [あなたのWi-Fi]
Wi-Fi Password: [あなたのパスワード]
```
consoleページの「Setup Device」を押して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/b8daea26-8622-48ce-93f8-1b5bd91800ec.png)

このモーダルに入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/8db4390b-9799-42e3-ab3e-0ee8b05b15d6.png)


カメラのランプが正しく点灯するとセットアップ完了です（一番上のランプがオレンジから緑に変わり、2個目・3個目が消灯）。

> **aitrios運営の方へ**
カメラの取扱説明書として、カメラの使い方やランプの光り方によってどういう挙動をカメラはしてる状態なのかについて箱に入ってるといいなと思いました。

### 2. AIモデルのデプロイ

Consoleから適切なAIモデルをデプロイします。今回は物体検出用のMobileDetを使用しました：

1. Consoleにログイン
2. "Deploy to Device"メニューを選択
3. "_PRESET_Mobiledet_OD"を選択
4. 自分のデバイスを選択してDeploy

**重要**: デプロイには安定した高速なネットワークが必須です。30Mbps以下の環境ではデプロイが失敗することがありました。今回のハッカソンではなぜかmodelが落ちてしまい、会場のwifiは遅すぎてデプロイが絶望的状況でしたw

### 3. AITRIOS HUBの活用

AITRIOSとWebアプリを連携させるために「AITRIOS HUB」を活用しました。これは推論結果を取得するためのAPIを提供するツールです：
https://github.com/hoshinoresearch/AITRIOS_HUB/tree/main

```bash
# GitHubからクローン
git clone https://github.com/hoshinoresearch/AITRIOS_HUB.git
cd AITRIOS_HUB/server

# env
運営の方から聞いてenvを入れましょう。server配下にenvを作成します。
（下にenvの画像あります。xxxしか入れてません。画像用）

# Python環境の設定
python -m venv venv
source venv/bin/activate  # Windowsの場合: venv\Scripts\activate
pip install -r requirements.txt

# サーバーの起動
uvicorn AITRIOS_Hub:app_ins --reload --host 0.0.0.0 --port 8080 --no-access-log
```


<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/d44661e5-c82f-41b7-bfde-bb4fd54097f6.png" />

> イメージ↓こんな感じで、こうなるとok
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/9f8904ad-82e7-4e23-b3a5-5a0a9c9f94d7.png)


### 4. コマンドパラメータの設定
> AITRIOSはPCとWIFIに接続する必要があって、それの設定ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/7ae09272-3a92-45bb-ba6c-d5396182cd1b.png)

AITRIOSデバイスの挙動を制御するためのパラメータを設定します：

vscodeに `AITRIOS_Hub_xxx.json`といった名前のファイルを作成して↓以下を貼って編集し、
Console > Settings > Command ParameterからUploadしましょう。
```json
{
  "commands": [
    {
      "command_name": "StartUploadInferenceData",
      "parameters": {
        "Mode": 2,
        "UploadMethod": "HTTPStorage",
        "StorageName": "http://[あなたのIP]:8080",
        "StorageSubDirectoryPath": "/image",
        "FileFormat": "JPG",
        "UploadMethodIR": "HTTPStorage",
        "StorageNameIR": "http://[あなたのIP]:8080",
        "StorageSubDirectoryPathIR": "/meta",
        "CropHOffset": 0,
        "CropVOffset": 0,
        "CropHSize": 4056,
        "CropVSize": 3040,
        "NumberOfImages": 0,
        "UploadInterval": 30,
        "NumberOfInferencesPerMessage": 1,
        "PPLParameter": {
          "header": {
            "id": "00",
            "version": "01.01.00"
          },
          "dnn_output_detections": 100,
          "max_detections": 5,
          "threshold": 0.3,
          "input_width": 320,
          "input_height": 320
        }
      }
    }
  ]
}
```

### 5. WebアプリからAITRIOS HUBを呼び出す方法

以下のエンドポイントを使ってAITRIOS HUBと通信します：

```bash
# 推論開始
curl -X POST http://[サーバーIP]:8080/[デバイスID]/start_inference

# 推論結果取得
curl http://[サーバーIP]:8080/[デバイスID]/inference_result

# 推論停止
curl -X POST http://[サーバーIP]:8080/[デバイスID]/stop_inference
```

Next.jsアプリからの呼び出し例：

src/api配下にaitrios/route.tsを作成して、フロント側から /api/aitriosって感じで叩けるようにする。

postやgetの際のpathについては、AITRIOSHUBのAITRIOS_Hub.pyに以下のようなものが書いてるのですが、/start_inferenceみたいなのを叩けば良いイメージ。

```py
@app_ins.post("/{device_id}/start_inference")
def start_inference(device_id: str, request: Request) :
    logging.info("start_inference device_id: %s", device_id)
    console_api = ConsoleRESTAPI(base_url, client_id, client_secret, gcs_okta_domain)        
    print("推論開始:}")
    response = console_api.StartUploadInferenceResult(device_id)
    print(response)
    return response
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/7e08a0c1-d927-4116-b235-89bfd2aa17b3.png)

React側での実装例：
今回は写ってるものをまず物体検知したかったので、↓このように使う型を定義しておいて使えるようにしておきました。

オブジェクトidの一覧はこちらにあります。これを全部コピーしてAIに型を作ってもらいましょう。
https://coral.ai/models/object-detection/

```ts
// クラスIDから物体名を取得するためのマッピング
export const classIdToName: Record<number, string> = {
  0: "人",
  1: "自転車",
  2: "車",
  3: "オートバイ",
  4: "飛行機",
  5: "バス",
  16: "猫",
  17: "犬",
  26: "バックパック",
  32: "スーツケース",
  61: "椅子",
  62: "ソファ",
  63: "観葉植物",
  64: "ベッド",
  66: "テーブル",
  71: "テレビ",
  72: "ノートPC",
  76: "スマホ",
  83: "本",
}

// クラスIDから物体名を取得する関数
export const getClassName = (classId: number): string => {
  return classIdToName[classId] || `不明(${classId})`
}
```

## ハマりどころと解決策

### 1. デバイスアプリデプロイエラー

よく遭遇したエラー:
```
{"result":"ERROR","code":"E.SC.API.0003027","message":"The device app has not been deployed.","time":"2025-03-21T10:46:26.457750"}
```

**解決策**: 
- ConsoleのStatus画面でモデルが正しくデプロイされているか確認する
- 未設定の場合は、"Deploy to Device"からモデルを再デプロイする
- 安定した高速ネットワークを使用する（30Mbps以上推奨）

Console > Manage Device > 自分のデバイスをクリック > 右側のbarからStatus > Modelを見て何かあればok。これが僕はなぜかハッカソン中にお亡くなりになったww
急に亡くなった原因は不明。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/2ddb0519-c880-4611-b917-9571d0ce5c47.png)

#### デプロイ方法
Console > Deploy to Device > デプロイしたいものを選ぶ > 右のsidebarで出てきた "Deploy"ボタンを押す > 自分のデバイスを探してデプロイする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/405fa9c0-9ea7-4dc7-aef4-aaf22e7b8572.png)

デプロイを押せたら、↓ Manage Device > 自分のデバイス > Status > Deploymentから見れる。
（失敗しまくった痕跡がありますね。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242042/ad142ddb-616a-43c2-be51-3c04d830a6ef.png)


### 2. CORSエラー

WebアプリからAITRIOS HUB APIを直接呼び出す際、CORSエラーが発生します。

**解決策**:
1. Next.jsのAPIルートを介して呼び出す（これ推奨です）
2. AITRIOS_Hub.pyにCORS設定を追加:（多分こういう感じ。↓間違ってたらすみません）
```py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app_ins = FastAPI()

# CORSミドルウェアを追加
app_ins.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 本番環境では適切に制限することをお勧めします
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 以下、元のコード
```

### 3. 推論結果が取得できない

`inference_result`エンドポイントが空のレスポンスを返す場合があります。

**原因と解決策**:
- 推論が開始されていない → `start_inference`を実行
- 推論は開始されているが結果がない → カメラの向きやモデルの閾値を確認
- ネットワーク接続に問題がある → ポートが開放されているか確認

wifiを変えると、以下の3つをする必要があります。
1. aitriosのwifi setupのQRコード（ピンを指すやつ）
2. parameter fileのstoragename 2この変換→upload→bind
3. local webアプリからで指定している http://xxxxx:8080/ の変更

## まとめ

AITRIOSとWebアプリの連携には主に3つのステップがあります：

1. AITRIOSデバイスのセットアップとモデルのデプロイ
2. AITRIOS HUBによるAPIインターフェースの提供
3. WebアプリからのAPI呼び出しと推論結果の活用

特に、推論結果をリアルタイムで取得してWebアプリで活用することで、観光客に最適な撮影位置を提案するような高度なアプリケーションを実現できました。（いや実現したかったが正しいかもしれない）

AITRIOSのようなエッジAIデバイスとWebアプリの連携は、様々な場面で応用可能です。観光案内だけでなく、小売店での顧客分析、職場での安全確認、スマートホームなど、多様な分野で活用できるはず。

## ビジネス的な観点で一言
今回取り組んでみて、aitriosは固定で写してる環境はあまり外的要因が少ない + 流れ作業的にaitriosが動作できるというユースケースで取り組むべきだと思いました。

僕の作ったサービスは、ユーザーがスマホとaitriosを繋いで持ち歩く形なので、それはtoCに受け入れられるには何かしら工夫が必要 or 難しい。
またaitrios自体のカメラ性能（2025年3月時点）は、あまり良くないので、今回のサービスに特化してwebアプリでどう被写体を撮影すればより良い写真になるかをリアルタイムにアドバイスしてくれるようにするだけだと、aitriosを使う旨みがあまりない。ハッカソン的に技術的に取り組んでみるのが今回僕の目的だったので、それはナイスチャレンジだった。

またaitriosはアノテーションが15枚の画像で済んでモデルを作ってもらえるのが強みだと思うので、もはやそっちに特化してwebアプリを作った方が効果を発揮しやすいのでは。

例えば、ファッションの写真撮影の現場で、プロのカメラマンの近くに脚立で置いておいて何かに活用とか。

普通にaitriosの強みを分かりやすく書いてあるものがあればやりやすかったかも。。
当たり前だが、使い先をミスると、「これaitriosを使う意味がなくないか？普通に画像認識を違う方法で実装した方が技術的ハードル低くないか？」みたいなことになり得る。 `（aitriosをdisっている訳ではなく、技術ってそういうもので、ソリューションとしてベストな課題やユースケースに使った方が良いですし！）`

エッジAIの方がコスト低い or レスポンスの速さが必要とかのユースケースが多いのかな？
学習・推論を勝手にしてくれるのがアツいですよね。
<img src="https://spectee.co.jp/wp-content/uploads/2021/05/img1.png" />

> 画像参照: https://spectee.co.jp/report/edge_ai/

## 参考リンク

- [AITRIOSコンソールサンプルアプリ](https://github.com/SonySemiconductorSolutions/aitrios-sdk-cloud-app-sample-python/blob/v1/main/docs/development-docs/CloudSDK_Tutorial_SampleApp_Python_ja.adoc)
- [WebアプリからのRestAPI活用](https://qiita.com/Shibu-Shin/items/5fee9317beb14ba55c9a)
- [AITRIOS HUB GitHub](https://github.com/hoshinoresearch/AITRIOS_HUB/blob/main/README.md)
- [Claudeを使ったアプリ開発Tips](https://youtu.be/LV9pCJLj0mI)

---

ハッカソンで時間が限られている中でAITRIOSの連携に取り組みましたが、技術的なハードルを乗り越えて実際にアプリケーションを動作させることができました。

今後もエッジAIの活用範囲は広がっていくでしょう。
皆さんもぜひAITRIOSを使った開発にチャレンジしてみてください。

# 最後の最後に
ハッカソンプラットフォームCraftStadiumをやってます。
ハッカソン好きな人は見にきてください👍
運営機能も2025年4月にリリースします。

https://craftstadium.com/