TECH PLAY

電子工作

イベント

該当するコンテンツが見つかりませんでした

マガジン

技術ブログ

こんにちは、Insight Edgeの小林まさみつです。本記事は Insight Edge Advent Calendar 2025 の8日目の記事です。 最近は生成AIをソフトウェア領域に応用した開発をしていますが、今回は趣向を変えてハードウェアと組み合わせたシステムを作成してみたので紹介します。 目次 1. はじめに 1.1 なぜ作ったのか 1.2 完成システムの紹介 1.3 この記事で分かること 2. システム概要 2.1 全体構成図 2.2 使用技術スタック 2.3 動作の流れ 3. ハードウェア編:振動モーター制御回路 3.1 必要な部品リスト 3.2 回路図と配線 3.3 動作確認とコード 4. ソフトウェア編:姿勢判定システム 4.1 カメラ設置とPythonでの画像取得 4.2 生成AI(Bedrock Claude Sonnet 4)との連携 4.3 Arduino との通信(シリアル通信) 4.4 統合プログラム 5. 実際に使ってみて 5.1 効果を実感した点 5.2 振動の強さについて 5.3 生成AIの判定精度 6. 今後の展望 7. まとめ 1. はじめに 1.1 なぜ作ったのか 長時間のデスクワークで肩こりや腰痛に悩まされ、「姿勢を良くしなければ」と思いつつも、集中していると姿勢のことなど忘れてしまいます。 市販の姿勢矯正グッズも検討しましたが、高価なものが多く、効果も不透明。そこで「技術で解決できるのでは?」と考え、自作することにしました。 当初はエアバッグで物理的に姿勢を矯正する構想もありましたが、コストと複雑さを考慮し、 振動で姿勢の悪化を通知する シンプルなシステムに方針転換しました。 従来の画像認識ライブラリでは、照明条件や服装の変化で精度が不安定になりがちです。一方、生成AIであれば自然言語で評価基準を定義でき、より柔軟な判定が期待できます。そこで 生成AIで姿勢を評価し、振動で身体に直接フィードバックする 実験的なシステムを構築しました。 1.2 完成システムの紹介 システムは以下の3つの要素で構成されています: Webカメラ : 横から姿勢を撮影 PC : 生成AIで姿勢評価 Arduino+振動モーター : 姿勢の悪い箇所をユーザーに通知 Arduino とは、電子工作を簡単に始められる小型のコンピューター基板(=マイコン)です。 姿勢が悪くなると、該当する部位が振動して通知されます。例えば猫背なら腰が、左に傾いていれば左太ももが振動する仕組みです。 動作イメージは以下の通りです。 Webカメラが5分ごとにユーザーの姿勢を撮影 左の画像は良い姿勢、右は悪い姿勢の例です。左足が浮いており、腰も前傾していることがわかります。右側のように姿勢が悪くなったタイミングで振動モーターを動作させます。 結果に応じてArduinoに指示を送り、振動モーターを動作 結果に応じて、左足・右足・腰のいずれか、または複数が振動して姿勢の悪化を通知します。これを人の足にテープなどで固定して使用します。 1.3 この記事で分かること 本記事では、以下の内容を解説します: 生成AI活用 : AWS Bedrock Claude Sonnet 4による姿勢評価の実装方法 ハードウェア制御 : Arduino + 振動モーターの制御回路の設計と配線 システム統合 : Webカメラ ⟷ PC ⟷ Arduino間の通信の実装 2. システム概要 2.1 全体構成図 システムの全体像は以下の通りです。 カメラで撮影した画像をPCで取得し、生成AIに送信して姿勢を評価。その結果に基づいてArduinoに指示を送り、適切な振動モーターを動作させます。 各コンポーネントは疎結合で、それぞれ独立してテスト・改善できる構成になっています。 2.2 使用技術スタック システム全体で使用した技術は以下の通りです。 レイヤー 技術 用途 言語 Python 3.13 システム全体の制御 AI推論 AWS Bedrock Claude Sonnet 4 姿勢評価 画像取得 OpenCV (Python) カメラ制御 通信 pySerial PC-Arduino間 マイコン Arduino Uno モーター制御 また、利用したツールは以下の通りです。 ツール 用途 Arduino IDE Arduinoコード開発/マイコンへの書き込み Tinkercad 回路設計とシミュレーション Webカメラ こちら を参考にiPhoneをWebカメラ化しました 2.3 動作の流れ システムの動作フローは以下の通りです: 画像取得 :Webカメラが5分ごとにユーザーの姿勢を撮影する AI評価 : PythonでAWS Bedrock(Claude Sonnet 4)に画像を送信し、姿勢を評価 コマンド送信 :評価結果に応じてシリアル通信でArduinoに指示 各部位のスコアをもとに、振動すべき箇所を3ビットで表現する 左足・右足・腰の順番に0/1とし、問題がある箇所を 1 に設定 例: 000 (全て良好)、 100 (左足が悪い)、 111 (全て悪い) モーター制御 :Arduinoが該当する振動モーターを動作させる ループ :1に戻り、継続的に監視 評価頻度は5分に1回としました。 当初は30秒ごとの評価も検討しましたが、以下の理由で5分間隔を選択しました。 APIコストの削減 姿勢改善には継続的な意識づけが重要で、頻繁すぎる通知は逆効果になるため 3. ハードウェア編:振動モーター制御回路 3.1 必要な部品リスト 回路の構築に用いた部品は以下の通りです。 部品名 型番・仕様 個数 用途 マイコン Arduino Uno 1 モーター制御 振動モーター FM34E 3 触覚フィードバック トランジスタ DTC143EL 3 スイッチング 抵抗 1kΩ 3 ベース電流制限 ダイオード 1N4007 3 逆起電力保護 ブレッドボード 標準サイズ 1 配線用 ジャンパーワイヤー オス-オス 11本 回路の接続用 ジャンパーワイヤー オス-メス 6本 振動モーター接続用 ジャンパーワイヤー (必要に応じて) オス-メス 任意の本数 振動モーター延長用 振動モーターを延長する場合は、オス-メスのジャンパーワイヤーを追加で24本程度用意することを推奨します。 3.2 回路図と配線 回路図の作り方 回路設計の経験が無かったため、生成AIに回路図の作成を依頼しました。 出力された回路図をもとに、 Tinkercad でシミュレーションと配線図の作成をしました。 初心者でも簡単に始められ、無料で利用できるため非常に便利です。 基本回路(1個のモーター) まず、1個の振動モーターを制御する基本回路を説明します。 回路の動作原理: Arduinoのデジタルピン(D3)から信号を出力し、抵抗を経由してトランジスタのベースに接続します。トランジスタはスイッチとして機能し、ベースに電圧がかかるとコレクタ-エミッタ間が導通し、モーターに電流が流れます。 ダイオードはモーターと並列に逆向きで接続され、モーター停止時の逆起電力を吸収します。これにより、Arduinoや他の回路が逆電圧で破損することを防ぎます。 PWM制御の必要性: 使用する振動モーターの定格は3Vですが、Arduinoの出力は5Vです。そのまま接続すると過電圧になるため、PWM(Pulse Width Modulation)制御を使って実効電力を調整します。具体的には、 analogWrite(pin, 153) とすることで、約60%のデューティサイクル(153/255)で動作し、平均電圧を約3Vに下げることができます。 完全な配線(3個のモーター) 次に、3個のモーターを制御する完全な回路です。 配線した回路 配線時の重要な注意点: トランジスタの向き :平らな面を手前に向けて挿入します。左からエミッタ(E)、コレクタ(C)、ベース(B)の順です。 ダイオードの向き :銀色の帯のある方がカソード(+側)で、モーターのプラス側に接続します。逆に接続すると短絡の原因になります。 PWM対応ピンの使用 :Arduino Unoでは、D3/D5/D6/D9/D10/D11がPWM対応です。今回はD3/D5/D6を使用しています。 3.3 動作確認とコード Arduino IDEのシリアルモニタから手動でコマンドを送信して、動作を確認できます。 Arduinoコード // ピン定義 const int LEFT_LEG_PIN = 3; // 左脚用振動モーター const int RIGHT_LEG_PIN = 5; // 右脚用振動モーター const int WAIST_PIN = 6; // 腰用振動モーター // 振動設定 const int VIBRATION_DURATION = 5000; // 振動時間(ミリ秒) const int VIBRATION_INTENSITY = 153; // PWM値(0-255) 5V電源をモーターに約3Vで供給するため153に設定 String receivedData = ""; bool dataComplete = false; void setup() { // シリアル通信を開始(9600 baud) Serial.begin(9600); // ピンを出力モードに設定 pinMode(LEFT_LEG_PIN, OUTPUT); pinMode(RIGHT_LEG_PIN, OUTPUT); pinMode(WAIST_PIN, OUTPUT); // 初期状態:全モーター停止 analogWrite(LEFT_LEG_PIN, 0); analogWrite(RIGHT_LEG_PIN, 0); analogWrite(WAIST_PIN, 0); // 起動確認用フラッシュ startupFlash(); } void loop() { // シリアルデータが利用可能かチェック if (Serial.available()) { String receivedString = Serial.readString(); if (receivedString.length() > 0) { receivedData = receivedString; dataComplete = true; } } // データ受信完了時の処理 if (dataComplete) { processPostureFeedback(receivedData); receivedData = ""; dataComplete = false; } } void processPostureFeedback(String data) { // 3桁のバイナリ文字列を期待(例:"101") if (data.length() != 3) { Serial.println("Error: Invalid data format. Expected 3 digits."); return; } // 各桁をチェックして対応する振動を制御 bool leftLegVibrate = (data.charAt(0) == '1'); bool rightLegVibrate = (data.charAt(1) == '1'); bool waistVibrate = (data.charAt(2) == '1'); // 振動パターンを実行 executeVibrationPattern(leftLegVibrate, rightLegVibrate, waistVibrate); } void executeVibrationPattern(bool leftLeg, bool rightLeg, bool waist) { // 全モーター停止 stopAllMotors(); // 振動が必要な部位があるかチェック if (!leftLeg && !rightLeg && !waist) { return; } // 対象部位を振動 if (leftLeg) { analogWrite(LEFT_LEG_PIN, VIBRATION_INTENSITY); } if (rightLeg) { analogWrite(RIGHT_LEG_PIN, VIBRATION_INTENSITY); } if (waist) { analogWrite(WAIST_PIN, VIBRATION_INTENSITY); } // 振動時間待機 delay(VIBRATION_DURATION); // 全モーター停止 stopAllMotors(); } void stopAllMotors() { analogWrite(LEFT_LEG_PIN, 0); analogWrite(RIGHT_LEG_PIN, 0); analogWrite(WAIST_PIN, 0); } void startupFlash() { // 起動時に全モーターを短時間点灯してテスト Serial.println("System test - All motors flash"); for (int i = 0; i < 3; i++) { analogWrite(LEFT_LEG_PIN, VIBRATION_INTENSITY); analogWrite(RIGHT_LEG_PIN, VIBRATION_INTENSITY); analogWrite(WAIST_PIN, VIBRATION_INTENSITY); delay(200); stopAllMotors(); delay(200); } Serial.println("System test completed"); } 4. ソフトウェア編:姿勢判定システム 4.1 カメラ設置とPythonでの画像取得 前提:姿勢を表すためのモデル定義 以下のPydanticモデルを用いて、生成AIからの姿勢評価を受け取りArduinoに送信する形式へ変換します。 姿勢評価のPydanticモデルコード from pydantic import BaseModel, Field POSTURE_THRESHOLD = 0.7 # 姿勢スコアの閾値 class FeedbackModel (BaseModel): left_leg_score: float = Field(..., description= "左脚の姿勢スコア" , ge= 0.0 , le= 1.0 ) right_leg_score: float = Field(..., description= "右脚の姿勢スコア" , ge= 0.0 , le= 1.0 ) waist_score: float = Field(..., description= "腰の姿勢スコア" , ge= 0.0 , le= 1.0 ) remarks: str = Field( "" , description= "スコア評価の備考" ) def to_should_vibrate (self) -> str : """ 振動フィードバックが必要かどうかを判定 3桁の0, 1の組み合わせで返す。 左足・右足・腰の順番 例: - 000: 全て良好 - 100: 左足が悪い - 111: 全て悪い """ res = "" res += "1" if self.left_leg_score < POSTURE_THRESHOLD else "0" res += "1" if self.right_leg_score < POSTURE_THRESHOLD else "0" res += "1" if self.waist_score < POSTURE_THRESHOLD else "0" return res Pythonでの画像取得 OpenCVを使ってカメラから画像を取得します。 画像取得のコード import cv2 from datetime import datetime # Webカメラのキャプチャを開始 cap = cv2.VideoCapture( 0 ) # キャプチャがオープンしている間続ける while (cap.isOpened()): ret, frame = cap.read() if ret: # カメラ映像を表示 cv2.imshow( 'Webcam Live' , frame) # 's'キーが押されたらスクリーンショットを保存 if cv2.waitKey( 1 ) & 0xFF == ord ( 's' ): timestamp = datetime.now().strftime( "%Y%m%d_%H%M%S" ) filename = f "screenshot/screenshot_{timestamp}.png" cv2.imwrite(filename, frame) # 'q'キーが押されたらループから抜ける if cv2.waitKey( 1 ) & 0xFF == ord ( 'q' ): break else : break # キャプチャをリリースし、ウィンドウを閉じる cap.release() cv2.destroyAllWindows() ポイント: cv2.VideoCapture(0) の引数は環境によって異なります。複数のカメラが接続されている場合は、番号を変えて試してください。 動作確認用のため、 's' キーでスクリーンショットを保存するようにしています。最終的には5分ごとに自動で保存するロジックを追加します。 4.2 生成AI(Bedrock Claude Sonnet 4)との連携 AWS Bedrockのセットアップ AWS Bedrockを使用するには、事前にAWSアカウントとCLIの設定が必要です。 必要な準備: 1. AWSアカウントの作成 2. IAMユーザーの作成(Bedrock実行権限付与) 3. AWS CLIのインストールと設定( aws configure ) 4. Bedrock APIへのアクセス権限の確認(リージョンは ap-northeast-1 など) 姿勢評価の実装 Claude Sonnet 4に画像を送信して姿勢を評価するクラスを実装します。 Claudeを呼び出し姿勢を評価するコード import json import boto3 from model import FeedbackModel MODEL_ID = "" # Bedrockで使用するモデルIDを指定してください。 class BedrockClient (): def __init__ (self): self.client = boto3.client( 'bedrock-runtime' ) # 姿勢評価 def evaluate_posture (self, img_bytes: bytes ): system_prompt = ( "ユーザーから提供されるbase64エンコードされた画像を解析し、姿勢評価を行ってください。 \n " "画像横から撮影した人が映っています。座り姿勢が良いか悪いかを判定し、以下のJSON形式で返してください。 \n\n " "1. left_leg_score: 左脚の姿勢スコア(0-1のfloat、1が最良) \n " "2. right_leg_score: 右脚の姿勢スコア(0-1のfloat、1が最良) \n " "3. waist_score: 腰の姿勢スコア(0-1のfloat、1が最良) \n\n " "JSON形式の例: {{ \" left_leg_score \" : 0.8, \" right_leg_score \" : 0.9, \" waist_score \" : 0.7}}" ) messages = [{ "role" : "user" , "content" : [ { "image" : { "format" : "png" , "source" : { "bytes" : img_bytes } } } ] }] response = self.client.converse( modelId=MODEL_ID, system=[{ "text" : system_prompt}], inferenceConfig={ "temperature" : 0 }, messages=messages, toolConfig={ "tools" : [ { "toolSpec" : { "name" : "extract_Feedback_Model" , "description" : "inputSchemaに沿ってFeedbackというPydanticモデルを出力するツール" , "inputSchema" : { "json" : FeedbackModel.model_json_schema()} } } ], "toolChoice" : { "tool" : { "name" : "extract_Feedback_Model" } } } ) # Bedrockのレスポンスから姿勢評価結果のJSONを抽出し、FeedbackModelに変換して返す tool_res = response[ "output" ][ "message" ][ "content" ][ 0 ][ "toolUse" ][ "input" ] if isinstance (tool_res, str ): tool_res = json.loads(tool_res) return FeedbackModel(**tool_res) ポイント ユーザーから提供される画像を読み取り、バイト列としてClaude Sonnet 4に送信します。 BedrockにおけるClaudeはtoolConfigを利用することで、Pydanticモデルを用いたJSONレスポンスを受け取ることができます。一方、必ず意図した形式で返ってくるとは限らないため、必要に応じてエラーハンドリングを追加してください。 4.3 Arduino との通信(シリアル通信) シリアル通信の基礎 PythonからArduinoに指示を送るには、シリアル通信を使用します。pySerialライブラリをインストールする必要があります。 Arduinoコントローラーの実装 姿勢評価結果に基づいてArduinoに適切なコマンドを送信するクラスを作成します。 Arduinoコントローラーのコード import serial from model import FeedbackModel def run_vibration_feedback (arduino: serial.Serial, feedback: FeedbackModel) -> None : """ Arduinoを使用して振動フィードバックを提供する関数 """ # 1. フィードバックを解析 should_vibrate = feedback.to_should_vibrate() # 2. フィードバック信号をArduinoに送信 arduino.write( bytes (should_vibrate, encoding= "ascii" )) # 生成AIからのフィードバックをモック化 feedback = FeedbackModel( left_leg_score= 0.4 , right_leg_score= 0.6 , waist_score= 0.7 , remarks= "Test feedback" ) # Arduinoのシリアルポートとボーレートを設定。環境に応じて適切に変更してください。 ARDUINO_PORT = '/dev/cu.usbmodem114301' ARDUINO_BAUDRATE = 9600 # Arduinoに接続する arduino = serial.Serial(ARDUINO_PORT, ARDUINO_BAUDRATE) # 振動フィードバックを実行 run_vibration_feedback(arduino, feedback) # 接続を閉じる arduino.close() ポイント 1. 振動フィードバックの実行には、Arduinoが接続されている必要があります。 2. Arduinoのシリアルポートやボーレートは環境によって異なります。後述の確認方法を参考に適切に設定してください。 COMポートの確認方法: Windows : デバイスマネージャーで「ポート(COMとLPT)」を確認。 COM3 , COM4 など。 Mac : ターミナルで ls /dev/cu.* を実行。 /dev/cu.usbserial-XXXX など。 Linux : ターミナルで ls /dev/ttyUSB* または ls /dev/ttyACM* を実行。 Arduino IDEのシリアルモニタを開いている場合は、ポートが占有されているため、Pythonから接続できません。必ず閉じてから実行してください。また、ポート番号はArduino IDEで確認すると便利です。 4.4 統合プログラム すべてのコンポーネントを統合し、システム全体を動作させるメインプログラムです。 コード全文 main.py # main.py from datetime import datetime import cv2 import time import serial from bedrock import BedrockClient from model import FeedbackModel # Arduinoのシリアルポートとボーレートを設定。環境に応じて適切に変更してください。 ARDUINO_PORT = '/dev/cu.usbmodem114301' ARDUINO_BAUDRATE = 9600 interval_sec = 300 def get_image (frame) -> bytes : """OpenCVのフレームを画像バイトに変換して返す""" timestamp = datetime.now().strftime( "%Y%m%d_%H%M%S" ) filename = f "screenshot/screenshot_{timestamp}.png" # スクリーンショットを保存 cv2.imwrite(filename, frame) res: bytes = b "" # 画像をバイトに変換 with open (filename, "rb" ) as img_file: res = img_file.read() return res def run_capture_analysis (frame): # -> Feedback: """ OpenCVでキャプチャしたフレームを元に姿勢分析を行う関数 """ # 1. frameをbyteで送信 img_bytes = get_image(frame) # 2. Bedrockに送信して姿勢推定 bedrock_client = BedrockClient() return bedrock_client.evaluate_posture(img_bytes) def run_vibration_feedback (arduino: serial.Serial, feedback: FeedbackModel) -> None : """ Arduinoを使用して振動フィードバックを提供する関数 """ # 1. フィードバックを解析 should_vibrate = feedback.to_should_vibrate() # 2. フィードバック信号を送信 arduino.write( bytes (should_vibrate, encoding= "ascii" )) def main (): # ウェブカメラのキャプチャを開始 cap = cv2.VideoCapture( 0 ) arduino = serial.Serial(ARDUINO_PORT, ARDUINO_BAUDRATE) # キャプチャがオープンしている間続ける while (cap.isOpened()): time.sleep(interval_sec) ret, frame = cap.read() if not ret: break # デバッグ用にフレームを表示 cv2.imshow( 'Webcam Live' , frame) feedback = run_capture_analysis(frame) run_vibration_feedback(arduino, feedback) # 'q'キーが押されたらループから抜ける if cv2.waitKey( 1 ) & 0xFF == ord ( 'q' ): break # キャプチャをリリースし、ウィンドウを閉じる cap.release() cv2.destroyAllWindows() arduino.close() if __name__ == "__main__" : main() bedrock.py # bedrock.py import json import boto3 from model import FeedbackModel MODEL_ID = "" # Bedrockで使用するモデルIDを指定 class BedrockClient (): def __init__ (self): self.client = boto3.client( 'bedrock-runtime' ) # 姿勢評価 def evaluate_posture (self, img_bytes: bytes ): system_prompt = ( "ユーザーから提供されるbase64エンコードされた画像を解析し、姿勢評価を行ってください。 \n " "画像横から撮影した人が映っています。座り姿勢が良いか悪いかを判定し、以下のJSON形式で返してください。 \n\n " "1. left_leg_score: 左脚の姿勢スコア(0-1のfloat、1が最良) \n " "2. right_leg_score: 右脚の姿勢スコア(0-1のfloat、1が最良) \n " "3. waist_score: 腰の姿勢スコア(0-1のfloat、1が最良) \n\n " "JSON形式の例: {{ \" left_leg_score \" : 0.8, \" right_leg_score \" : 0.9, \" waist_score \" : 0.7}}" ) messages = [{ "role" : "user" , "content" : [ { "image" : { "format" : "png" , "source" : { "bytes" : img_bytes } } } ] }] response = self.client.converse( modelId=MODEL_ID, system=[{ "text" : system_prompt}], inferenceConfig={ "temperature" : 0 }, messages=messages, toolConfig={ "tools" : [ { "toolSpec" : { "name" : "extract_Feedback_Model" , "description" : "inputSchemaに沿ってFeedbackというPydanticモデルを出力するツール" , "inputSchema" : { "json" : FeedbackModel.model_json_schema()} } } ], "toolChoice" : { "tool" : { "name" : "extract_Feedback_Model" } } } ) # Bedrockのレスポンスから姿勢評価結果のJSONを抽出し、FeedbackModelに変換して返す tool_res = response[ "output" ][ "message" ][ "content" ][ 0 ][ "toolUse" ][ "input" ] if isinstance (tool_res, str ): tool_res = json.loads(tool_res) return FeedbackModel(**tool_res) model.py # model.py from pydantic import BaseModel, Field POSTURE_THRESHOLD = 0.7 # 姿勢スコアの閾値 class FeedbackModel (BaseModel): left_leg_score: float = Field(..., description= "左脚の姿勢スコア" , ge= 0.0 , le= 1.0 ) right_leg_score: float = Field(..., description= "右脚の姿勢スコア" , ge= 0.0 , le= 1.0 ) waist_score: float = Field(..., description= "腰の姿勢スコア" , ge= 0.0 , le= 1.0 ) remarks: str = Field( "" , description= "スコア評価の備考" ) def to_should_vibrate (self) -> str : """ 振動フィードバックが必要かどうかを判定 3桁の0, 1の組み合わせで返す。 左足・右足・腰の順番 例: - 000: 全て良好 - 100: 左足が悪い - 111: 全て悪い """ res = "" res += "1" if self.left_leg_score < POSTURE_THRESHOLD else "0" res += "1" if self.right_leg_score < POSTURE_THRESHOLD else "0" res += "1" if self.waist_score < POSTURE_THRESHOLD else "0" return res motor.ino // ピン定義 const int LEFT_LEG_PIN = 3 ; // 左脚用振動モーター const int RIGHT_LEG_PIN = 5 ; // 右脚用振動モーター const int WAIST_PIN = 6 ; // 腰用振動モーター // 振動設定 const int VIBRATION_DURATION = 5000 ; // 振動時間(ミリ秒) const int VIBRATION_INTENSITY = 153 ; // PWM値(0-255) String receivedData = "" ; bool dataComplete = false ; void setup () { // シリアル通信を開始(9600 baud) Serial. begin ( 9600 ); // ピンを出力モードに設定 pinMode (LEFT_LEG_PIN, OUTPUT); pinMode (RIGHT_LEG_PIN, OUTPUT); pinMode (WAIST_PIN, OUTPUT); // 初期状態:全モーター停止 analogWrite (LEFT_LEG_PIN, 0 ); analogWrite (RIGHT_LEG_PIN, 0 ); analogWrite (WAIST_PIN, 0 ); // 起動確認用フラッシュ startupFlash (); } void loop () { // シリアルデータが利用可能かチェック if (Serial. available ()) { String receivedString = Serial. readString (); if (receivedString. length () > 0 ) { receivedData = receivedString; dataComplete = true ; } } // データ受信完了時の処理 if (dataComplete) { processPostureFeedback (receivedData); receivedData = "" ; dataComplete = false ; } } void processPostureFeedback (String data) { // 3桁のバイナリ文字列を期待(例:"101") if (data. length () != 3 ) { Serial. println ( "Error: Invalid data format. Expected 3 digits." ); return ; } // 各桁をチェックして対応する振動を制御 bool leftLegVibrate = (data. charAt ( 0 ) == '1' ); bool rightLegVibrate = (data. charAt ( 1 ) == '1' ); bool waistVibrate = (data. charAt ( 2 ) == '1' ); // 振動パターンを実行 executeVibrationPattern (leftLegVibrate, rightLegVibrate, waistVibrate); } void executeVibrationPattern ( bool leftLeg, bool rightLeg, bool waist) { // 全モーター停止 stopAllMotors (); // 振動が必要な部位があるかチェック if (!leftLeg && !rightLeg && !waist) { return ; } // 対象部位を振動 if (leftLeg) { analogWrite (LEFT_LEG_PIN, VIBRATION_INTENSITY); } if (rightLeg) { analogWrite (RIGHT_LEG_PIN, VIBRATION_INTENSITY); } if (waist) { analogWrite (WAIST_PIN, VIBRATION_INTENSITY); } // 振動時間待機 delay (VIBRATION_DURATION); // 全モーター停止 stopAllMotors (); } void stopAllMotors () { analogWrite (LEFT_LEG_PIN, 0 ); analogWrite (RIGHT_LEG_PIN, 0 ); analogWrite (WAIST_PIN, 0 ); } void startupFlash () { // 起動時に全モーターを短時間点灯してテスト Serial. println ( "System test - All motors flash" ); for ( int i = 0 ; i < 3 ; i++) { analogWrite (LEFT_LEG_PIN, VIBRATION_INTENSITY); analogWrite (RIGHT_LEG_PIN, VIBRATION_INTENSITY); analogWrite (WAIST_PIN, VIBRATION_INTENSITY); delay ( 200 ); stopAllMotors (); delay ( 200 ); } Serial. println ( "System test completed" ); } プログラムの構成: 初期化フェーズ :カメラとArduinoを初期化 メインループ : 5分待機 カメラから画像を取得 AIで姿勢評価 Arduinoにコマンド送信 終了処理 :終了時リソースを適切に解放 5. 実際に使ってみて システムを1週間使用した結果、以下のような効果と課題が見えてきました。 5.1 効果を実感した点 最初はほぼ毎回振動させられ、そのたびに「ハッとして」姿勢を直していました。振動というフィードバックは、視覚や聴覚と比べて邪魔にならず、作業を中断させない点が良かったです。 4日目くらいから、少しずつ姿勢が改善され、振動される頻度が減ってきました。座り姿勢を意識する習慣がついたように感じます。 5.2 振動の強さについて 使用した3V振動モーターは、服の上からでもはっきりと分かるため、通知としての役割は十分果たせています。 一方で、長時間使用すると慣れてしまい、振動に対する感度が下がる傾向も見られました。振動パターンをランダム化する、または強弱をつけるなどの工夫が必要かもしれません。 5.3 生成AIの判定精度 Claude Sonnet 4の姿勢評価は想像以上に精密で、「確かにその通り」と思える判定が多くありました。 特に、微妙な体の傾きや脚の位置なども的確に指摘してくれるため、自分では気づかない姿勢の問題を発見できました。 6. 今後の展望 このシステムは実験的なプロトタイプですが、以下のような発展性があります。 複数部位への拡張 : 現在は3箇所ですが、首、肩、背中など5〜7箇所に増やすことで、より細かい姿勢の矯正が可能になります。 モーターの種類変更 : 振動モーター以外に、エアポンプとエアバッグを利用することで良い姿勢に矯正させることができます。 バッテリー駆動化 : USB給電からバッテリー駆動に変更し、ケーブルレスで使用できるようにできます。 同様の「自然言語での評価基準定義 + 物理フィードバック」のパターンは、評価が主観的になりがちな他の分野でも参考になるかもしれません。 7. まとめ 本記事を書くにあたり、大学以来久しぶりに電子工作をしました。生成AIを活用して回路図を作成し、シミュレータで動作確認をすることで、初学者でも簡単に取り組めました。ソフトウェアアプリケーションの領域だけでなく、ハードウェア制御の分野にも生成AIを活用できることを実感し、自身で取り組める範囲が広がったと感じています。本記事が、同様の課題を持つ方々の参考になれば幸いです。
こんにちは、PS-SL新卒1年目のひろです。 8/3にOSC京都2025に参加させていただきました。参加した中で特に印象に残った展示、セミナーについて紹介させていただきます。 さくらインターネット株式会社 さくらインターネット さんが行っていた「高火力シリーズ」についてのセミナーに参加させていただきました。私は、さくらインターネットさんと聞いてまず思い浮かんだのはレンタルサーバ事業で、高火力シリーズときいてどのようなサービスなんだろうと気になっていました。 今回ご紹介いただいた 「高火力シリーズ」 では、3つのGPUクラウドサービスが展開されています。今回のセミナーでは実際に生成AIを使用し、画像を生成するデモを見せていただきました。 生成AIにとってGPUはとても重要な要素です。GPUは小さなコアをたくさん持っており、大量の計算を同時にこなすような並列処理に特化しています。生成AIの学習や推論には膨大な計算が不可欠なため、GPUが活用されています。さくらインターネットさんの高火力シリーズはこのGPUを提供するサービスで、生成AIや機械学習の分野に持って来いなサービスです。 今回紹介されていた3つのサービスについてまとめます。 まず 高火力PHY 。こちらはGPUを8基搭載したベアメタルサーバーです。NVIDIA H100やH200といった超高性能なGPUを搭載したモデルが用意されています。高火力も高火力といった具合で、大規模なサービス開発に特化している印象を受けました。 次に 高火力VRT 。こちらはVM(仮想マシン)型のGPUクラウドで、NVIDIA H100、NVIDIA V100といったGPUのプランを選ぶことができます。チャットボットサービスなどの即応答性が求められるサービスに最適です。また、時間単位での課金制で 、柔軟に利用することができます。 最後に 高火力DOK 。こちらはコンテナー型GPUクラウドサービスで、作成したDockerイメージをpullし、イメージを実行することができます。こちらはバッチ処理のような終わりのある処理に適していると紹介いただきました。高火力DOKは秒単位での従量課金制で、実行時間のみコストが発生する仕組みとなっており、高火力なGPUを最小限のコストで利用できる点が大きな魅力です。AI関連のサービス開発や研究の敷居を下げてくれる素晴らしいサービスだと思いました。 今回のセミナーを通じて、「高火力シリーズ」が大規模処理、リアルタイム処理、バッチ処理といった多様なニーズをカバーしていることがよく分かりました。日本の生成AIサービスや研究を支える、土台のような存在だと感じました。 osdev-jp osdev-jp さんはOS開発に役立つ情報を収集、公開されているコミュニティで、今回は自作OSを展示されていました。 私はOS開発をしたことはなく、OSが何を行っているか大まかな知識しか持っていなかったのですが、お話していただいた内容から興味を持つことができました。特に魅力的に感じたのは、自分だけのGUIデザインやコマンドを作ることができる点と、普段何気なく使用しているPCの裏側でOSがどのような役割を果たしているのか実践的に深く学べるという点です。OS開発に関する書籍も紹介していただいたので折に触れて挑戦したいと思いました。 osdev-jpさんの展示内容。自作OSの展示です Japanese Raspberry Pi Users Group Japanese Raspberry Pi Users Group さんはRaspberry Piを用いた様々な製品、作品の展示をされていました。印象に残った展示についてまとめます。 まず、Raspberry Pi 500というRaspberry Piとキーボードが一体になっている製品です。モニターとマウスさえあればPCとして使用することが可能という、手軽で優れた製品です。自分はRaspberry Piをほとんど使用したことがなかったこともあり、キーボードと一体になっていることに驚きました。小型のモニタモジュールと一緒に使用できる様子を見せていただきました。 次にRaspberry Pi 5 + AI Cameraの展示です。AI CameraはカメラモジュールにAIが内蔵されており、モジュール側で物体検知を行えるという優れものです。小型カメラ側で検知してくれるという点に驚きました。 自分は電子工作を通ってきておりませんが、モジュールを組み合わせてアイデア次第で様々なものを作れるというのがとても魅力的で、自分でも何か作ってみたいと思いました。まずはRaspberry Piを購入するところから始めたいと思います! Japanese Raspberry Pi Users Groupさんの展示内容。Raspberry Pi 500の展示です Japanese Raspberry Pi Users Groupさんの展示内容。Raspberry Pi 5 + AI Cameraの展示です 最後に 今回OSC京都2025に参加し、これまでよく知らなかった技術のお話をたくさん聞くことができ、とても有意義な時間を過ごすことができました。もっと技術的に深い議論ができるよう精進していきたいと思います。 素敵な展示、セミナーを開催してくださった皆様、本当にありがとうございました。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 1人がこの投稿は役に立ったと言っています。 The post OSC京都2025 セミナー&展示紹介と感想 first appeared on SIOS Tech. Lab .
  みなさんこんにちは! どちらかというと猫より犬が好きな Solutions Architect の高野です。一昨年、昨年の AWS Summit Japan でご好評いただいた Chaos Kitty がさらにパワーアップして AWS Summit Japan 2025 に帰ってきました!   この記事では、2025 年の AWS Summit Japan の AWS Builders’ Fair 内の初日に展示される「Chaos Kitty で楽しくインシデント対応の基本を学ぼう! 」についてご紹介します。本展示は、システムを構築する上でも重要なレジリエンスやセキュリティをゲームを通じて楽しく学ぶことができる体験型コンテンツです。システムのレジリエンスやセキュリティを強化したい全ての方に本記事を読んでいただき、実際に AWS Summit Japan の会場まで足を運んで体験いただけると幸いです。   AWS Summit Japan 2025 の開催期間は 2025 年 6 月 25 日 (水) と 26 日 (木) の 2 日間で、会場は幕張メッセになります。 本展示は初日の 6 月 25 日 (水) のみになりますのでご注意ください。 まだ AWS Summit Japan 2025 に登録してない方は こちらのページ からご登録ください。Chaos Kitty は、AWS Expo の AWS Builders’ Fair の中にあります。詳細は こちら 。 Chaos Kitty とは?   Chaos Kitty は、AWS のアーキテクチャを物理的に表現し、インシデント対応の体験学習ができるソリューションです。Web 3 層の Web アプリケーションに異常を注入し、異常を修正するまでのタイムを競うことで、ゲーム感覚でインシデント対応の体験が行うことができます。詳細は 以前のブログ を確認下さい。 1. IoT 電球によるリアルタイムの状態可視化   物理的なブロックと電球で表現された Web 3 層アプリケーションのアーキテクチャにおいて、各コンポーネント (Amazon EC2、Amazon RDS、Amazon S3 など) の状態が IoT 電球の色で示されます。電球は、正常な場合には緑、何か異常がある場合には赤で点灯する設定になっており、設定に異常が検出された場合には、電球が緑から赤に変わる仕組みとなっています。これにより AWS 上のアプリケーションの状況をリアルタイムで監視でき、異常をすぐに検知することができます。 2. 障害挿入機能による対応訓練   IoT デバイス を操作すると AWS での設定に意図的に設定異常を注入し、IoT 電球の色が赤に変わります。ユーザーは AWS コンソールを使ってこの設定異常を特定・修復し、電球を緑に戻すゲームを行います。修復が完了すれば、修復にかかった時間が表示され、手動での対応の難しさを体感できます。 3. 自動修復機能による対応の効率化   注入された設定異常に対して、自動修復するスクリプトを実行する機能が用意されています。マネジメントコンソールを使用した手動修復と比べた自動化の優位性を実感できます。 図 1 : AWS Summit Tokyo 2025 版 Chaos Kitty 外観 図 2 : 障害注入対象の Web 3 層アプリケーション画面 新機能紹介   3 回目となる今回は、 できる限り多くの方に簡単にお試しいただけるように 以下パワーアップを行っておりますので、1 つずつご紹介します。 1. IoT 機器なしで設定異常注入・検知ができるように、Web アプリケーション機能追加 2. AWS Cloud Development Kit (AWS CDK) を活用してインフラストラクチャのコード化 (Infrastructure as Code (IaC)) を実装し、デプロイメントプロセスを標準化・自動化 3. 電子工作なしで本ソリューションが利用できるように IoT 関連のアーキテクチャ刷新 4. アプリケーション監視用のモニタリングダッシュボードに Amazon CloudWatch Application Signals を採用 IoT 機器なしで設定異常注入・検知ができるように、Web アプリケーション機能追加   今までの Chaos Kitty は IoT 機器での操作を前提としたソリューションとなっており、実際に皆様の環境にデプロイして利用いただくにはハードルが高いところがありました。そこで、今回は、今までのインシデント発生から修正までの時間測定だけ行なっていたWebアプリケーションを改修し、設定異常注入機能と、異常箇所検知・可視化機能を追加しました。これにより、IoT 機器なしで、本ソリューションをデプロイいただくだけで、インシデント対応を学習することができるようにしました。   Chaos Kitty はセキュリティ的に問題のある設定を注入する Security シナリオと、アプリケーション自体に障害を注入し利用不可にする Resilienency シナリオがあります。それぞれ 1 つだけ異常を発生させる Easy モードと複数の異常を発生させる Hard モードがあります。図 3 のような画面になっていまして、画面中央のゲームスタートボタンを押下すると、図 4 のように、タイマーがスタートし、Web 3 層アプリケーションの異常発生箇所 (図 4 の例では ALB の Security Group) が点灯し、異常箇所が分かるようになります。参加者の方はこれをヒントに AWS コンソール にログインして異常箇所の修正にチャレンジいただきます。是非タイムアタック No.1 を目指して頑張ってください! 図 3 : Chaos Kitty Web アプリケーション画面 図 4 : 障害発生時の Chaos Kitty Web アプリケーション画面 AWS CDK を活用したインフラストラクチャのコード化 (IaC)   AWS Summit Japan にご来場いただく方に限らず、本ソリューションをご利用いただけるように、アーキテクチャを一部改修し、AWS CDK を活用した IaC 化を行い、AWS Samples として公開する予定です。これにより、利用したい方はコマンド数回で本ソリューションが簡単にデプロイできるようになります。個人での学習や、社内のシステム運用者教育等のイベントにご活用いただけますと幸いです。できる限り、AWS Summit Japan 2025 開催前、遅くとも 7 月中には AWS Samples で公開を予定しておりますので、ご期待下さい! 図 5 : AWS Summit Japan 2025 版 Chaos Kitty アーキテクチャ概要 電子工作なしで本ソリューションが利用できるように IoT 関連のアーキテクチャ刷新   今まで Chaos Kitty を利用するには、Raspberry Pi に様々なソフトウェアをインストールして設定を行う必要がありました。この作業が非常に煩雑で大変なため、多くのお客様に利用いただくのが困難でした。そこで今回、IoT 回りの構成を刷新し、Echo デバイスからボタン一つで IoT 電球の色を変更できるようにアーキテクチャを刷新しました。裏側の仕組みは Alexa Skill と連携することで実現しています。本設定方法の詳細は、別途ブログにて詳しくご紹介する予定ですので、ご期待下さい! アプリケーション監視用のモニタリングダッシュボードに Amazon CloudWatch Application Signals を採用   Chaos Kitty はインシデント対応を学習するためのものであり、ゲームとしてわかりやすくするために、アプリケーションの問題箇所を電球で可視化していますが、実際のシステムではそう簡単にはいきません。実システムでは、ユーザ影響がある障害が発生しているかどうか、すぐに確認・分析できるようにするためのダッシュボードによる可視化が有効です。前回の展示では、Amazon CloudWatch dashboards を使って必要なメトリクスやログ、トレースを表示するようにダッシュボードをカスタマイズして展示していました。今回は、Amazon CloudWatch Application Signals を使った標準的なダッシュボードを使い、サービスとして重要な指標を取得して可視化できるようにしています。監視対象アプリケーションには、 AWS Distro for OpenTelemetry を組み込み CloudWatch Agent と連携することで、必要なデータを取得して、Amazon CloudWatch Application Signals のダッシュボードで表示しております。是非、最新のモニタリング機能をご体感下さい! 図 6 : CloudWatch Application Signals ダッシュボード画面   この他にも当日は、生成 AI を利用した障害分析効率化を図る AIOps を体感いただくために、AWS Japan の Solutions Architect が開発した障害分析ソリューション Failure Analysis Assistant (FA2) との連携デモをお見せします。生成 AI を活用することでどのように日々のシステム運用が効率化できるのかご体感下さい! さいごに   Chaos Kitty は実際のインシデントを模擬する形でサービスの稼働状況を電球やブロックを使ってわかりやすく表現しております。日頃クラウドサービスに慣れ親しむ機会が少ない方でも、運用におけるインシデント対応を気軽に体験いただけます。AWS Summit Japan 2025 で、皆様にお会いできることを楽しみにお待ちしております! アマゾン ウェブ サービス ジャパン 合同会社 ソリューションアーキテクト 高野 翔史 Choas Kitty は AWS Japan ソリューションアーキテクトの服部 一成、堀 貴裕、佐々 拓也、津郷 光明、河角 修、鈴木 陽三、黒木 琢央、高野 翔史が中心となって開発しております。

動画

書籍