
Visual Studio
イベント
該当するコンテンツが見つかりませんでした
マガジン

技術ブログ
本記事は 2026 年 4 月 30 日に公開された Ankit Sharma、Brian Beach による “ Amazon Q Developer end-of-support announcement ” を翻訳したものです。 私たちが Amazon Q Developer を立ち上げたときの目標は、AI による支援を開発者の作業の流れに直接組み込むことでした。お客様は VS Code、JetBrains、Eclipse、Visual Studio にわたって Q Developer を導入し、コード生成やデバッグ、チャットベースのガイダンスに活用してきました。Q Developer は、AI が日々の開発サイクルに欠かせない存在であることを証明しました。 この 1 年で私たちが学んだのは、もっともインパクトのある AI 開発者体験はコード生成や補完にとどまらないということです。開発者には、プロジェクト全体 —— アーキテクチャ、要件、テスト、そしてコードの背後にある意図 —— を理解する AI が必要です。そのためには、専用に設計された環境が必要になります。それこそが、私たちが Kiro を構築した理由です。 Kiro とは 、仕様駆動開発(spec-driven development)のためにゼロから構築されたエージェント型の開発環境(IDE、CLI)です。個別のプロンプトに反応するのではなく、構造化された仕様をもとに計画・実装・検証をコードベース全体にわたって進めます。主な機能は次のとおりです。 Specs —— 構築したいものを構造化された自然言語の要件として定義し、Kiro がそれをもとに実装を最初から最後まで進めます。 Hooks —— ファイル保存やコミットなどのイベント発生時に自動で実行されるトリガーです。手動での操作なしに、標準の適用、テストの実行、ドキュメントの更新を行います。 Steering files —— プロジェクト単位の設定ファイルで、アーキテクチャや規約、制約についての永続的なコンテキストを Kiro に提供します。 Custom subagents —— セキュリティレビュー、API 契約の検証、インフラのプロビジョニングなど、ドメイン固有のタスクのために自分で定義できる専用の AI エージェントです。 Powers —— Kiro のエージェント的な振る舞いを自分の開発プロセスに合わせて拡張できる、組み合わせ可能な機能モジュールです。 Kiro には、現在の Q Developer で開発者が活用している機能もすべて含まれています。エージェント型コーディング、インラインチャット、ターミナル統合、そして MCP サポートです。 何が変わるのか Amazon Q Developer の IDE プラグインと有償サブスクリプションは、2027 年 4 月 30 日にサポートを終了します。お客様には Kiro への移行期間として 12 か月が用意されています。 2026 年 5 月 15 日以降、新規サインアップを受け付けなくなります。 IDE プラグインから Builder ID を用いた Q Developer 無料利用枠アカウントの新規作成、および AWS コンソールからの Q Developer サブスクリプションの新規作成はブロックされます。 モデルが変更されます。 2026 年 5 月 29 日より、Q Developer Pro では Opus 4.6 が利用できなくなります。Opus 4.5 やその他の既存モデルは引き続き利用できます。Opus 4.7 を含む最新のコーディングモデルは Kiro でのみ利用できます。 既存のお客様はアクセスを維持できます。 Q Developer Pro サブスクリプションまたは Kiro サブスクリプションを通じて Q Developer をご利用の場合、2027 年 4 月 30 日までは引き続き Q Developer の IDE プラグインにアクセスできます。2026 年 5 月 15 日の変更は、Q Developer アカウントおよびサブスクリプションの新規サインアップにのみ影響します。 IDE プラグインの掲載は継続します。 Q Developer のプラグインは、4 つの IDE マーケットプレイスすべてで引き続き公開され、ユーザーを Kiro へ案内する非推奨の通知が表示されます。移行期間中は、既存ユーザー向けに重要なバグ修正の配信が継続されます。 何が変わらないのか AWS マネジメントコンソールおよび AWS ファーストパーティの体験(AWS マーケティングサイト、AWS ドキュメントサイト、AWS Console Mobile App、チャットアプリ向け Amazon Q Developer —— Slack および Microsoft Teams)における Amazon Q Developer は、今回のサポート終了の影響を受けず、引き続き AWS のお客様にご利用いただけます。これらのプロダクトで Q Developer をお使いのお客様は、現在のサブスクリプションの特典と機能を引き続きご利用いただけます。 お客様にお願いしたいこと 今日から Kiro を試してみてください。 kiro.dev から Kiro をダウンロードし、次のプロジェクトで仕様駆動開発を体験してみてください。 ご利用の IDE に合わせた 移行ガイド をご確認ください。 移行についてご質問がある場合は、担当の AWS アカウントチームまでお問い合わせください。 私たちは AI を活用した開発の未来にわくわくしており、すべてのお客様にとってこの移行ができる限りスムーズなものとなるよう取り組んでいきます。 翻訳は App Dev Consultant の宇賀神が担当しました。
Claude Code を快適に使うための macOS デスクトップ通知セットアップ 背景 なぜ alerter を採用したのか 1. alerter のインストール 2. 通知スクリプトの作成 2-1. notify_alerter.sh(Stop / Notification hook 用) 2-2. notify_pretool.sh(PreToolUse hook 用) 3. Claude Code の hooks 設定 各 Hook の役割 4. VSCode 拡張での Notification hook の扱い 5. macOS のセキュリティ許可 6. 動作確認 通知テスト 確認項目 デバッグログ 7. alerter のプロセス管理で学んだこと 問題: プロセスのゾンビ化 対策1: --group(プロセス蓄積の防止) 対策2: --timeout(最終的なプロセス回収) 溜まったプロセスの手動クリーンアップ 8. なぜ nohup + disown が必要だったか 9. 通知のカスタマイズ 特定ツールの通知をスキップする サウンド --sender(通知アイコン) まとめ 最後に こんにちは、開発本部 開発2部 RetailHUB NetSuperグループに所属するホーク🦅アイ👁️です。 背景 弊社ではClaude を非エンジニアも含めた全社に展開しており、業務のあらゆる場面で生成AI の活用を推進しています。 そんな中、我々のチーム内でも今年3月から本格的にCursor から移行してClaude Code (VSCode 拡張機能)を日常的に使うようになってから、両者の明らかな違いを実感することになりました。 それは、Cursor が標準搭載しているmacOS デスクトップ通知機能でした。Claude Code にはその機能がないためAgent にプロンプトを投げた後、私自身が他の作業を並行しているとClaude Code 側が permission_prompt のWait でタスクが一向に完了できない状態やタスク完了状態に気付くのが随分遅れてしまうということがしばしばありました(業務効率化のためのAgent ツールなのに、、)。 Claude Code には Hooks という仕組みが用意されています。これは Stop(応答終了)や Notification(許可待ち等)、PreToolUse(ツール実行直前)といったライフサイクルイベントに対して任意のシェルコマンドを実行できる公式機能で、JSON がイベント情報として標準入力から渡ってきます。 本記事ではこの Hooks と alerter というコマンドラインツールを組み合わせて、 タスク完了・許可待ち・入力待ちの デスクトップ通知を出す 通知を クリックすると、対象プロジェクトの VSCode ウィンドウが自動でアクティブになる (全画面の別アプリ上からでも切り替わる) VSCode 拡張版 でも許可待ち通知を取りこぼさない という環境を構築した内容をまとめます。macOS 26 系(Tahoe)環境で動作確認しています。 なぜ alerter を採用したのか macOS から通知を出すだけなら選択肢は複数あります。今回の要件「通知をクリックしたら VSCode がアクティブになる」を満たせるものを比較した結果を表にまとめます。 ツール 通知表示 クリックイベントの取得 備考 terminal-notifier 環境依存 可能(旧来の定番) 公式リポジトリ の最新リリースは 2017 年 11 月(v2.0.0)で、近年の macOS での動作不具合 Issue( #307 、 #312 、 #319 ほか)が未解決のままです。私の環境(macOS 26 系)では通知が出ませんでした。 osascript ( display notification ) 動作する 不可 AppleScript 公式ドキュメント( Standard Additions: display notification )に「戻り値なし」と明記されており、クリック結果を取得する手段がありません。 alerter 動作する 可能 公式リポジトリ によれば、 terminal-notifier を Swift で書き直した後継で、macOS 13.0 以降対応。クリック時に @CONTENTCLICKED / @ACTIONCLICKED を stdout に出力するため、外部プロセスでの後処理が可能です。 alerter がクリック結果を stdout に返してくれるおかげで、「クリック → open -a "Visual Studio Code" で対象プロジェクトを開く」という連携を、標準ツールの組み合わせだけで実現できました。 1. alerter のインストール Homebrew で導入します( 公式の導入手順 に準拠)。 brew install vjeantet/tap/alerter インストール確認: which alerter # /opt/homebrew/bin/alerter alerter --version 2. 通知スクリプトの作成 2 つのスクリプトを ~/.claude/ に配置し、実行権限を付与します。前者は Stop / Notification hook 用、後者は VSCode 拡張向けの PreToolUse hook 用です。 chmod +x ~/.claude/notify_alerter.sh chmod +x ~/.claude/notify_pretool.sh 2-1. notify_alerter.sh (Stop / Notification hook 用) タスク完了通知および、CLI 版 Claude Code での許可待ち通知を処理します。Hook に渡ってくる JSON の仕様は 公式リファレンスの Stop / Notification セクション に従っています。 notification_type として permission_prompt / idle_prompt が返ってくるため、これで分岐しています。 #!/bin/bash input = $( cat ) echo " $( date ' +%H:%M:%S ' ) $input " >> /tmp/claude_notify_debug.log cwd = $( echo " $input " | jq -r ' .cwd ' ) project = $( basename " $cwd " ) notification_type = $( echo " $input " | jq -r ' .notification_type ' ) # ターミナルアプリの Bundle ID を自動検出 get_terminal_bundle_id() { if [[ -n " ${__CFBundleIdentifier} " ]] ; then echo " ${__CFBundleIdentifier} " return fi case " ${TERM_PROGRAM} " in " Apple_Terminal ") echo " com.apple.Terminal " ;; " iTerm.app ") echo " com.googlecode.iterm2 " ;; " ghostty ") echo " com.mitchellh.ghostty " ;; " WarpTerminal ") echo " dev.warp.Warp-Stable " ;; * ) local pid parent comm pid = $$ while [[ " ${pid} " -ne 1 ]] 2 >/dev/null; do parent = $( ps -p " ${pid} " -o ppid = 2 > /dev/null | tr -d ' ' ) || break [[ -z " ${parent} " ]] && break comm = $( ps -p " ${parent} " -o comm = 2 > /dev/null ) case " ${comm} " in *Terminal* ) echo " com.apple.Terminal "; return ;; *iTerm* ) echo " com.googlecode.iterm2 "; return ;; *Cursor* ) echo " com.todesktop.230313mzl4w4u92 "; return ;; *Code* ) echo " com.microsoft.VSCode "; return ;; *ghostty* ) echo " com.mitchellh.ghostty "; return ;; *warp* ) echo " dev.warp.Warp-Stable "; return ;; * ) ;; esac pid = " ${parent} " done echo "" ;; esac } BUNDLE_ID = $( get_terminal_bundle_id ) send_notification() { local message =" $1 " local sound =" $2 " local group =" $3 " local args = (--title " Claude Code " --subtitle " ${project} " --message " ${message} " ) if [[ -n " ${sound} " ]] ; then args += ( --sound " ${sound} " ) fi args += ( --sender " com.microsoft.VSCode " ) # --group: 同じグループの通知は前のプロセスを自動終了して置き換える args += ( --group " ${group :- claude-default } " ) # --timeout: プロセスのゾンビ化防止(秒)。通知自体は macOS 通知センターに残る local timeout = 86400 local timeout_file =" $HOME /.claude/notify_timeout.conf " if [[ -f " ${timeout_file} " ]] ; then timeout = $( cat " ${timeout_file} " | tr -d ' [:space:] ' ) fi args += ( --timeout " ${timeout} " ) # alerter はクリック待ちでブロックするため、nohup + disown で完全にデタッチ nohup bash -c " result= \$ (alerter $( printf ' %q ' " ${args[ @ ]} " ) 2>/dev/null) if [[ \"\$ {result} \" == \" @CONTENTCLICKED \" || \"\$ {result} \" == \" @ACTIONCLICKED \" ]] && [[ -n \" ${cwd} \" ]]; then open -a \" Visual Studio Code \" \" ${cwd} \" fi " &> /dev/null & disown } case " ${notification_type} " in " permission_prompt ") send_notification " 許可待ち " " Ping " " claude-permission " ;; " idle_prompt ") send_notification " 入力待ち " " Purr " " claude-idle " ;; " stop ") send_notification " タスク完了 " " Glass " " claude-stop " ;; * ) send_notification " 通知 " " default " " claude-other " ;; esac 2-2. notify_pretool.sh (PreToolUse hook 用) こちらは VSCode 拡張環境向けの「許可待ち通知」の代替実装です。詳細は「4. VSCode 拡張での Notification hook の扱い」で後述します。 ざっくり説明すると、次の 4 つの設定ファイルの permissions.allow リストと照合し、 自動許可されないツールの実行前にのみ 通知を送るというロジックです。 ~/.claude/settings.json (グローバル) ~/.claude/settings.local.json (グローバルローカル) $cwd/.claude/settings.json (プロジェクト) $cwd/.claude/settings.local.json (プロジェクトローカル) #!/bin/bash # PreToolUse hook: 許可が必要なツール実行前に通知を送る # settings.json の allow リストにマッチするツールはスキップする input = $( cat ) tool_name = $( echo " $input " | jq -r ' .tool_name ' ) cwd = $( echo " $input " | jq -r ' .cwd ' ) project = $( basename " $cwd " ) # 常に自動許可されるツール(通知不要) case " ${tool_name} " in Glob|Grep|TodoWrite|Agent|Skill|ToolSearch|SendMessage ) exit 0 ;; esac # ユーザー個別のスキップリスト(~/.claude/notify_skip_tools.txt) SKIP_FILE = " $HOME /.claude/notify_skip_tools.txt " if [[ -f " ${SKIP_FILE} " ]] ; then while IFS = read -r skip_tool; do [[ -z " ${skip_tool} " || " ${skip_tool} " == \# * ]] && continue if [[ " ${tool_name} " == " ${skip_tool} " ]] ; then exit 0 fi done < " ${SKIP_FILE} " fi # allow リストと照合する関数 check_allow_list() { local settings_file =" $1 " [[ -f " ${settings_file} " ]] || return # Bash ツール: コマンドプレフィックスで照合 if [[ " ${tool_name} " == " Bash " ]] ; then local command command= $( echo " $input " | jq -r ' .tool_input.command ' ) while IFS = read -r pattern; do if [[ " ${pattern} " =~ ^Bash\((.+)(:\*|\*)?\)$ ]] ; then local prefix =" ${BASH_REMATCH[ 1 ]} " prefix = " ${prefix % :* } " if [[ " ${command} " == " ${prefix} " * ]] ; then exit 0 fi fi done < < ( jq -r ' .permissions.allow[] ' " ${settings_file} " 2 > /dev/null ) fi # Read ツール: パスパターンで照合 if [[ " ${tool_name} " == " Read " ]] ; then local file_path file_path = $( echo " $input " | jq -r ' .tool_input.file_path ' ) while IFS = read -r pattern; do if [[ " ${pattern} " =~ ^Read\(//(.+)\)$ ]] ; then local path_pattern =" ${BASH_REMATCH[ 1 ]} " local path_prefix =" ${path_pattern %% /** } " if [[ " ${file_path} " == " ${path_prefix} " * ]] ; then exit 0 fi fi done < < ( jq -r ' .permissions.allow[] ' " ${settings_file} " 2 > /dev/null ) fi # MCP ツール・WebSearch 等: 完全一致で照合 while IFS = read -r pattern; do if [[ " ${pattern} " == " ${tool_name} " ]] ; then exit 0 fi done < < ( jq -r ' .permissions.allow[] ' " ${settings_file} " 2 > /dev/null ) } # グローバル設定 check_allow_list " $HOME /.claude/settings.json " check_allow_list " $HOME /.claude/settings.local.json " # プロジェクト設定 check_allow_list " $cwd /.claude/settings.json " check_allow_list " $cwd /.claude/settings.local.json " # 許可リストにマッチしない → 通知を送る echo " $( date ' +%H:%M:%S ' ) PRETOOL_NOTIFY: ${tool_name} " >> /tmp/claude_notify_debug.log nohup bash -c " timeout=86400 timeout_file= \"\$ HOME/.claude/notify_timeout.conf \" if [[ -f \"\$ {timeout_file} \" ]]; then timeout= \$ (cat \"\$ {timeout_file} \" | tr -d '[:space:]') fi result= \$ (alerter --title 'Claude Code' --subtitle ' ${project} ' --message '許可待ち: ${tool_name} ' --sound Ping --sender com.microsoft.VSCode --group claude-pretool --timeout \"\$ {timeout} \" 2>/dev/null) if [[ \"\$ {result} \" == '@CONTENTCLICKED' || \"\$ {result} \" == '@ACTIONCLICKED' ]] && [[ -n ' ${cwd} ' ]]; then open -a 'Visual Studio Code' ' ${cwd} ' fi " & > /dev/null & disown exit 0 3. Claude Code の hooks 設定 ~/.claude/settings.json の hooks セクションに以下を追加します( 公式リファレンス の書式に準拠)。 { " hooks ": { " Stop ": [ { " matcher ": "", " hooks ": [ { " type ": " command ", " command ": " echo '{ \" cwd \" : \" ' \" $(pwd) \" ' \" , \" notification_type \" : \" stop \" }' | ~/.claude/notify_alerter.sh " } ] } ] , " Notification ": [ { " matcher ": "", " hooks ": [ { " type ": " command ", " command ": " ~/.claude/notify_alerter.sh " } ] } ] , " PreToolUse ": [ { " matcher ": "", " hooks ": [ { " type ": " command ", " command ": " ~/.claude/notify_pretool.sh " } ] } ] } } 各 Hook の役割 Hook 発火タイミング 用途 VSCode 拡張 CLI Stop Claude が応答を終えて停止したタイミング 「タスク完了」通知 動作する 動作する Notification 許可待ち・入力待ちなどの通知イベント 「許可待ち」「入力待ち」通知 permission_prompt が発火しないケースあり 動作する PreToolUse ツール実行の直前 VSCode での「許可待ち」通知の代替 動作する 動作する 4. VSCode 拡張での Notification hook の扱い 公式リファレンス では、 Notification hook の notification_type として permission_prompt / idle_prompt / auth_success / elicitation_dialog の 4 種が定義されています。しかし、私の環境で動作確認したところ、 VSCode 拡張版では許可ダイアログが出ても Notification hook( permission_prompt )が発火しないケース があり、「許可待ちなのに通知が来ない」という状態になっていました。CLI 版では同じ設定で期待どおり発火しています。 そのため、VSCode 拡張で使う場合は PreToolUse hook(必ず発火する)でツール実行直前に自前で判定する という回避策を取っています。流れは以下です。 PreToolUse hook がツール実行直前に発火する notify_pretool.sh がツール名(と Bash の場合はコマンド、Read の場合はファイルパス)を受け取り、4 つの設定ファイルの permissions.allow と照合する allow リストに マッチしなかったとき だけ通知を送る(=「このあと許可ダイアログが出るはず」というタイミング) この方式であれば、 Notification hook の発火有無にかかわらず、VSCode でも CLI でも漏れなく許可待ち通知を届けられます。CLI 版では Notification hook が正常動作するため、重複しないよう --group を claude-permission と claude-pretool で分けています(後述)。 5. macOS のセキュリティ許可 alerter + open -a の組み合わせは、macOS のアクセシビリティ・オートメーション等の追加許可なしで動作しました。初回のみ通知センター側で通知の表示許可を求められる程度で、特別な設定は不要です。 6. 動作確認 通知テスト # タスク完了通知 echo ' {"cwd": " ' $( pwd ) ' ", "notification_type": "stop"} ' | ~/.claude/notify_alerter.sh # 許可待ち通知(CLI の Notification hook 用) echo ' {"cwd": " ' $( pwd ) ' ", "notification_type": "permission_prompt"} ' | ~/.claude/notify_alerter.sh 確認項目 タスク完了通知がデスクトップに表示される 許可待ち通知が表示される(VSCode: PreToolUse / CLI: Notification) VSCode アイコンが通知に表示される( --sender com.microsoft.VSCode ) 通知をクリックすると対象プロジェクトの VSCode ウィンドウがアクティブになる 全画面の別アプリ(Chrome 等)から通知をクリックしても正しいウィンドウに切り替わる 通知後に Claude が WAIT 状態にならず即座に続行する デバッグログ 通知が来ないときはデバッグログを確認します: tail -f /tmp/claude_notify_debug.log 7. alerter のプロセス管理で学んだこと 運用してみて一番ハマったのがプロセス管理です。 問題: プロセスのゾンビ化 alerter は クリックされるまで stdout をブロックし続ける 仕様です( 公式リポジトリ の README にある @CONTENTCLICKED / @ACTIONCLICKED / @TIMEOUT / @CLOSED のいずれかが出力されるまでプロセスが生きる)。通知バッジを macOS 通知センターから消去しても alerter プロセスは終了しません。放置すると各プロセスがメモリを消費し、長時間の利用で数 GB に達するケースがありました。 対策1: --group (プロセス蓄積の防止) 同じ --group の通知が新たに発行されると、前のプロセスが自動で kill されます。グループは用途別に分けており、同時に存在するプロセスは最大 4 つになる設計です: グループ 用途 claude-stop タスク完了 claude-permission 許可待ち(CLI Notification hook) claude-pretool 許可待ち(VSCode PreToolUse hook) claude-idle 入力待ち 対策2: --timeout (最終的なプロセス回収) --group だけでは最後の 4 プロセスが残り続けるため、 --timeout でプロセスの最大生存時間を設定して確実に回収します。 デフォルト: 86400 秒(1 日) カスタム: ~/.claude/notify_timeout.conf に秒数を書く # 例: 2 時間に変更 echo 7200 > ~/.claude/notify_timeout.conf なお、timeout が切れてもプロセスが終了するだけで、macOS 通知センターの通知バッジは残ります。 溜まったプロセスの手動クリーンアップ # alerter プロセス数を確認 ps aux | grep alerter | grep -v grep | wc -l # 全 alerter プロセスを終了 pkill -f alerter 8. なぜ nohup + disown が必要だったか 前述のとおり alerter はクリック待ちでブロックします。単純に (...) & でバックグラウンド実行しても、 Claude Code の hook ランナーが子プロセスの終了を待ってしまい、Claude 本体が WAIT 状態のまま止まる (トークンも消費し続けてしまう)という問題がありました。 nohup ... & で SIGHUP を無視させ、さらに disown でジョブテーブルから外すことで、hook プロセスから完全に切り離せます。これにより、通知の表示・クリック待ちとは独立して Claude が動作を継続できるようになりました。 9. 通知のカスタマイズ 特定ツールの通知をスキップする VSCode の「Edit Automatically」などセッションレベルで自動許可しているツールは settings.json に記録されないため、 ~/.claude/notify_skip_tools.txt に 1 行 1 ツール名で記載する仕組みを入れてあります: # セッションレベルで自動許可しているツール名を 1 行 1 つで記載 Edit もしくは notify_pretool.sh の先頭付近にあるスキップリスト( Glob|Grep|TodoWrite|... )に追記する方法でも同等です。 サウンド macOS 標準のサウンド名を指定できます: Ping , Purr , Glass , default , Basso , Blow , Bottle , Frog , Funk , Hero , Morse , Pop , Sosumi , Submarine , Tink 。 --sender (通知アイコン) --sender に Bundle ID を指定すると通知アイコンが変わります。現在は com.microsoft.VSCode を指定して VSCode アイコンを表示しています。 アプリ Bundle ID VSCode com.microsoft.VSCode Cursor com.todesktop.230313mzl4w4u92 Terminal com.apple.Terminal iTerm2 com.googlecode.iterm2 Ghostty com.mitchellh.ghostty ただし --sender を指定すると、そのアプリの macOS 通知設定に依存することになります。対象アプリの通知を OFF にしていると通知が表示されなくなるため注意が必要です。 まとめ 本記事では、Claude Code の Hooks 機能と alerter を組み合わせて、 タスク完了・許可待ち・入力待ちのデスクトップ通知を出す 通知クリックでプロジェクトの VSCode ウィンドウを自動でアクティブにする VSCode 拡張でも PreToolUse hook で許可待ち通知を取りこぼさない というセットアップ方法と、その過程で踏んだプロセス管理の落とし穴(ゾンビ化 → --group / --timeout / nohup + disown での回収)をご紹介しました。 Claude Code をバックグラウンドで走らせつつ他の作業を並行して進めるスタイルにおいては、「気づかずに長時間止まっていた」という時間を減らすだけで、体感の生産性が目に見えて向上します。CLI と VSCode 拡張で挙動が異なる部分は PreToolUse hook で吸収できるので、Hooks の仕様を把握したうえで自分の開発スタイルに合わせてカスタマイズしてみてください。 通知例 最後に エブリーでは、ともに働く仲間を募集しています。 テックブログを読んで少しでもエブリーに興味を持っていただけた方は、ぜひ一度カジュアル面談にお越しください! corp.every.tv
2025年10月8日、ロボット産業を揺るがす大きなニュースが飛び込んできました。 ソフトバンクグループがスイスの重電大手 ABB [1] から、ロボティクス部門を買収する記事でした。 ちょうどそのころ私はABBのロボットコントローラと連携するプログラムの開発で日夜格闘していました。 ロボット制御APIである PC-SDK [2] を使った連携を試みましたが、何度も落とし穴に落ちました。 まさに「死にゲー」をプレイしている感じです。何度も失敗を繰り返しながら、APIの動作を確認し、使い方を覚え、最適な手順を考えて1つ1つ問題やタスクを解決していきました。 この体験は今となってはPC-SDK攻略のための私のノウハウになっています。そこで印象に残った落とし穴を10個ピックアップしました。どのような落とし穴があるのか、どのようにして回避したのかを備忘録も兼ねて公開したいと思います。 --> ロボット開発の前提知識 オフラインティーチングやロボット制御APIとは何かを知りたい場合は「 産業用ロボットの教示方法とその応用 」をご覧ください。 PC-SDKとは # ここで紹介するPC-SDKとは、PCからABBのロボットコントローラ/ロボットを制御・監視するための開発キット(ライブラリ)を指します。 .NET Frameworkを使用して、Windows PC上で動作するカスタムアプリケーションを作成できます。.NET Framework依存かつ後述する通信ドライバがWindows専用のためLinuxには対応していないようです。 主な機能 コントローラ状態アクセス: ロボットコントローラの実行状態、ロボットの姿勢取得、I/O信号の読み書き プログラム操作: プログラムのロード、開始、停止 データアクセス: ロボットプログラムの変数の読み書き ファイル転送: PCとロボットコントローラ間でのファイル送受信処理 --> シミュレータ環境での利用 開発時に使用するツールとしては PC-SDK の他に RobotStudio [3] があります。RobotStudioは仮想ロボットコントローラを内包し、GUIアプリケーションでオフラインティーチングが行えるアプリケーションです。PC-SDKは、この仮想ロボットコントローラに対しても接続できるためRobotStudioがあれば実機が無くてもPC-SDKによる開発ができます。 落とし穴 ティア表 # PC-SDK利用時に遭遇する落とし穴をダメージレベルごとにランク付けしました。これをベースに落とし穴を評価します。 ランク ダメージレベル S あり得ないだろ!?どうやって回避するの?精神的ダメージを受けるレベル A え、何で?びっくりしたー。た、たぶん・・・なんとかなるよねレベル B なるほど、まあよくあるよね。やられたなぁレベル C 事前に回避可能 または 落ちても痛くないレベル あくまでも個人の感想です。 🕳️1. Web上の情報が少ない B # 落とし穴 オープンソースのライブラリを使っているとき、解らないことがあればネットで検索しますよね。同じ要領でPC-SDKに関する情報やAPIを検索すると、ほとんど情報がなくABBのサイトかStack Overflowのようなプログラミングに関する題材を扱う英語のQAサイトが表示されます。 日本語で書かれた個人サイトやABB以外のテック企業による説明などはほとんどありません。ABBのサイトもサンプルコードは非常に少ないです。そのため、英語のQAサイトを丹念に調べ、翻訳 [4] しながら内容を確認します。 ただし、あまり有用な情報が得られない場合や5年~10年前の古い情報だったりすることもあります。 対策 オフィシャルサイト(またはネット検索)からAPIリファレンスや取説などがPDFファイルでダウンロードできます。手元に置いておき1次資料としてザックリと内容を把握しておき、解らないことがあればそこから調べます。 最近はGoogleのNotebookLMを使ったりしています。APIリファレンスや取説のPDF、情報として有益なサイトをNotebookLMに登録しておけば、プロンプトで質問ができます。また要約してくれてエビデンスも表示されるので自分で検索するよりも簡単に情報にアクセスできます。 🕳️2. AIが頻繁にハルシネーションを起こす B # 落とし穴 最近は何か解らないことがあれば検索ではなくAIに問い合わせることが多いのですが、 「PC-SDKのAPI xxxx について使い方を教えて」 「xxxxを使ってxxxxxの処理のサンプルを提示して」 などプロンプト入力すると先ほどの「🕳️1. Web上の情報が少ない」の影響か、存在しないAPIや引数が間違えているコードサンプルを出力します。 さらっと自然に嘘をつきます。誤りを指摘しつつ再度プロンプト入力すると、今度は別の引数が間違っていたり、古いコードで動作しないものが出力されたりしてほとんど役に立たないことがあります。 対策 Visual Studioなどでプロジェクトを作成し、PC-SDKのライブラリを参照させ、オブジェクトブラウザでAPIを確認する PC-SDKに付属する abb.robotics.controllers.pc.xml をエディタで開きAPIに関する説明情報を参考とする 🕳️3. ロボットコントローラが見つからないことがある A # 落とし穴 APIではローカルネットワーク上で動作しているロボットコントローラを検索(UDPブロードキャスト)し、見つかったロボットコントローラに対してログインしてロボットコントローラに接続します。 RobotStudioはローカルPC上で動作しているため一瞬で接続できますが、運用環境ではロボットコントローラの検索でタイムアウトになったり、2回目の検索で検知するといった謎の現象が発生しました。 対策 ネットワークインタフェース(NIC)が複数ある環境(4とか8とか)ではどのネットワークを探せばよいのかわからないため検索時にタイムアウトとなり見つからない現象が発生していました。これを解決するには検索する前にロボットコントローラのIPアドレスを指定してあげます。 実機ロボットコントローラへの接続例 var scanner = new NetworkScanner(); // ロボットコントローラのIPアドレスを直接指定して、スキャナの探索リストに登録する // これにより、どのNICを通すべきかPC-SDKが判断する NetworkScanner.AddRemoteController("xxx.xxx.xxx.xxx"); // 事前に取得しておいたロボットコントローラのUUIDを指定して検索する var systemId = Guid.Parse("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); // systemId, 待ち時間[msec], リトライ数 var controllerInfo = scanner.Find(systemId, 1000,3); if (controllerInfo == null) { throw new Exception("コントローラが見つかりませんでした。"); } // 実機に接続 _controller = Controller.Connect(controllerInfo, ConnectionType.Standalone); IPアドレスを指定するのならFind()を使う意義は薄いと思いますが、これで解決します。 🕳️4. 制御権の獲得し忘れ C # 落とし穴 ロボットコントローラに接続し、下記のような状態変更を促す処理を行うとエラーになります。 RAPID [5] 変数の値を更新する サーボモーターをOnにする RAPIDプログラムをロード(タスク割り当て)する RAPIDプログラムを開始する 対策 コントローラにMastershipのリクエスト(書き込み権限のリクエスト)して取得してから更新します。サンプルコードや検索すれば例はいくらでも出てきますので慌てることはありません。 Mastershipのリクエスト using (Mastership.Request(_controller)) { // ここで更新処理を記述 } ただし、Mastershipのリクエストに失敗することがあります。リトライ処理を入れたり、例外処理でエラー処理を記述するなどの仕組みが必要です。 なお、コントローラの状態の取得やRAPID変数の値取得などReadOnlyなものはMastershipのリクエストは必要ありません。 🕳️5. 運用環境でロボットコントローラと接続できない S # 落とし穴 開発環境でRobotStudio上の仮想ロボットコントローラには接続できています。しかし、運用環境でロボットコントローラに接続するとIPアドレス等が正しく ping も通るのにロボットコントローラの状態が取得できない。 開発環境の構成 運用環境の構成 対策 RobotStudioをインストールすると、(裏で)ロボットコントローラと通信するためのドライバもインストールされます。これがないと通信できません。 運用環境ではRobotStudioは不要なのでインストールせず、PC-SDK(ライブラリ)だけを利用するとドライバがインストールされていないのでエラーになります。 ABBのサイトから RobotWare_Tools_and_Utilities_x.x.x.zip (x.x.xはバージョン)をダウンロードし、展開して RobotCommunicationRuntime/ABB Industrial Robot Communication Runtime.msi を実行するとドライバがインストールされPC-SDKで接続できるようになります。こんなん解らんて。 🕳️6. リモートPCから RobotStudio に接続できない C # 落とし穴 先ほどの「🕳️5. 運用環境でロボットコントローラと接続できない」を開発環境で検証しました。 PCを2台用意する 一方(Aとする)をアプリケーション動作環境とする もう一方(Bとする)をロボットコントローラとみなしてRobotStudio(仮想ロボットコントローラ)をインストールする AとBに RobotWare_Tools_and_Utilities_x.x.x.zip のドライバをインストールする AからPC-SDKでBの仮想コントローラに接続する 接続テスト環境の構成 上記を試みましたが、あえなく撃沈。接続できせんでした。 対策 RobotStudioはローカルPC上からのアクセスしか受け付けないためリモートPCからの接続はできない仕様のようです。 これはライセンスが絡んでいる(1 RobotStudio 1ライセンス)からではないでしょうか。仕方がないですね。 🕳️7. 運用環境でRAPID を実行できない A # 落とし穴 RobotStudio上ではログインして問題なくRAPIDのロードや実行ができます。しかし、運用環境ではコントローラに接続できましたが、RAPIDのロードや実行を指示すると例外が発生します。何で? 対策 ロボットコントローラに接続する際のデフォルトユーザーは Default User ですが RobotStudioと運用環境とで権限が異なっています。 様々な権限がありますが実行権限とプログラムのロード権限に違いがありました。 権限 RobotStudio 実機 実行権限 あり なし ロード権限 あり なし Default User でもRobotStudioではさまざまな権限が最初から付与されているようですが、実機では権限が付与されていないものがありました。 そのため、実機上に新しくユーザーを作成し、RobotStudio上と同じことができるように権限を付与し、そのユーザーでログインしたところ実行できました。 なお、RobotStudio上での仮想コントローラではユーザーの作成や権限を付与する機能はなく、実機コントローラでのみ可能となっているのもハマった理由として挙げられます。 🕳️8. デジタル出力ができない B # 落とし穴 ロボットコントローラには各種デバイスとデジタル信号(0 or 1)で連携するための物理インタフェース(I/Oポート)があります。この出力ポートに0または1を書き出すと例外が発生し、出力できませんでした。 対策 ABB ロボットコントローラではI/O設定で物理インタフェースのどこにデジタル出力を割り当てるかを指定します。このとき Access Level を指定します。デフォルト値では Default となっています。 Access Level はレベル毎に制御する側のコンテキストでRead/Writeが有効かどうかが異なっています。 Access Level Rapid Local Client in Auto Mode Remote Client in Auto Mode All Write Enabled Write Enabled Write Enabled AWACCESS Write Enabled Write Enabled Read Only Default Write Enabled Read Only Read Only Internal Read Only Read Only Read Only ReadOnly Read Only Read Only Read Only Auto Mode とは人が操作するのではなくプログラムでロボットを動かすモードを指します。 ロボットコントローラが Auto Mode のとき、ロボットコントローラの外部からアクセスしてI/Oを操作するときは一番右の Remote Client in Auto Mode 列となります。 ロボットプログラムの実行は Rapid 列に相当します。 今回はPC-SDKを利用して外部からロボットコントローラをプログラムで制御しているので Remote Client in Auto Mode となっています。 Access Level は Default 行となり、動作モードは Remote Client in Auto Mode 列となります。その重なり部分は Read Only となっていることがわかります。 つまり Access Level が Default だったので書き込みができない状況でした。 Access Level が All でないと書き込みできません。厳しいですね。 というわけで、デジタル出力を割り当てるときの Access Level を All にすることで無事書き込めるようになりました。 --> Information Access Level は新しく追加もできるようです。 🕳️9. 配列のデータ転送が遅い A # 落とし穴 RAPID側での配列の定義 MODULE MainModule PERS num dataArray{100}; ENDMODULE 配列に値を書き込む一般的な記述は下記となります。 // 最初に1回だけ取得しておく RapidData rd = _controller.Rapid.GetRapidData( "T_ROB1", "MainModule", "dataArray"); : using (Mastership.Request(_controller)) { for (int i = 0; i < 100; i++) { rd.WriteItem(new Num(i), i); } } このとき、rd.WriteItem()をコールするたびにネットワークアクセスします。そのためトータルで数百[msec]~数[sec]掛かります。 対策 なるべくrd.WriteItem()のコール回数を少なくし、一括でデータを設定するようにします。 RAPID側で RECORD型 で構造体を定義します。 MODULE MainModule RECORD StructData num value1; num value2; num value3; num value4; num value5; ENDRECORD : ENDMODULE C#側はその構造体をUserDefined型として参照できます。 UserDefined型に値を設定するときは以下のようにします。 // 最初に1回だけ取得しておく(RAPID側のStructDataのコピーを作成) UserDefined ud = new UserDefined(_controller.Rapid.GetRapidDataType( "T_ROB1","MainModule","StructData")); // 最初に1回だけ取得しておく(RAPID側のStructDataの参照を作成) RapidData rd = _controller.Rapid.GetRapidData( "T_ROB1","MainModule","StructData"); : using (Mastership.Request(_controller)) { int value1 = 1; int value2 = 2; int value3 = 3; int value4 = 4; int value5 = 5; // UserDefinedに設定するデータを作成 structData = $"[{value1},{value2},{value3},{value4},{value5}]"; // UserDefinedにデータを設定 ud.FillFromString2(structData); // ロボットコントローラにデータ転送 rd.Value = ud; } また、RAPIDのデータ型であるrobtargetやjointtargetは非常にデータサイズが大きいです。一部のデータのみ更新するのであればその値のみ転送し、RAPID側でデータを更新して利用することも有効です。 --> Caution ud.FillFromString2("[0,1,2,3,4,5,.....]") のように文字列リテラルで全要素を直接設定できます。しかし、巨大な構造体や配列の場合、途中までしか値が設定されていないことがありましたので注意が必要です。また、パース処理に時間が掛かりますがネットワークアクセスに比べると無視できるレベルです。 --> Caution AIでサンプルを提示してもらうと、おそらく古いAPIかと思われますが、存在しないAPIが提示されコンパイルエラーとなりました。 🕳️10. 実機でRAPIDを実行すると実行時エラーになる S # 落とし穴 RobotStudio上のシミュレータでRAPIDを実行しても問題なく動作し、プログラムの構文チェックも問題なくパスするのに、同じものを実機で動作させると実行時にエラーとなってしまう。 下記の例外が出力されたら要注意!! Operation is illegal in current execution state 実行時エラーなので状態に起因することは分かっていますが、何の状態なのかがさっぱりわかりません。コントローラのログを見ても直接的な原因が記述されていません。 「制御あるある」ですが原因不明の実行時エラーが一番辛いです。 対策 シミュレータ上では動くことから、運用環境との環境設定の違いに原因がありそうだと直感的にわかります。プログラムの開始からどこまで進むとエラーになるかをRAPIDプログラムのソースコードを全コメントアウトし、バイナリサーチ的にコメントアウトを解除して再実行する手順で探しました。(もしかしたらステップ実行で行けたかもしれません) 結果、2つ問題がありました。 I/Oの定義が実機ではされていなかった シミュレータ上で定義してあったI/Oの名前(参照するときは文字列で指定)が見つけられずに実行時エラーとなっていた 割り込みタイマーのトリガー時間が実機では早すぎた 10[msec]としていてシミュレータ上では動作していたが、実機では実行時エラーとなっていた 上記の問題の修正自体は簡単でしたが、見つけるのに手間が掛かりました。環境の違いに起因する実行時エラーにはご注意を。 リスクを軽減するための開発スケジュール # いかがだったでしょうか?大半は開発環境(RobotStudioのシミュレータ)で問題の無かったものが、運用環境(実機コントローラ)で問題となって現れたものとなっています。しかも、穴から這い上がったと思ったらまたすぐに落とされる状況がありました。挫けそうになりますよね。 開発環境では仮想コントローラに接続するユーザーに対して、セキュリティは緩く、大きな権限を持たせています。一方、運用環境ではセキュリティは厳しく、権限も最小限にしているため不具合発生するパターンがよくありました。 運用環境が遠隔地にある場合、現地での対応には人員、時間、移動距離、金銭の面で多大なコストを要する課題があります。そのため、開発・動作確認を開発環境で行い、システムテストのみを運用環境で一括実施する計画を立てた場合、不測の事態によって進捗に遅延が生じる懸念があります。 リスクを回避するため、スケジュール内に複数のマイルストーンを設け、現地での動作確認を段階的に実施することを強く推奨します。また、現地のエンジニアに検証を委託すること(なかなか難しいですが)も、費用対効果の観点から非常に有効な手段であると考えられます。 まとめ # 日本ではFANUCや安川電機(YASKAWA)といった世界トップクラスのロボティクスメーカーのマーケットシェアが高いため、欧州の雄ABBのシェアは数%程度だそうです。 ABBのロボット開発拠点はスイスにあるため、高度な技術課題については日本国内のサポートを経由し、本国の技術者へエスカレーションする場合があります。その際、時差や拠点間の連携プロセスにより、回答までに時間を要した経緯がありました。 PC-SDKについて辛口の内容ではありましたが、ロボットやロボットコントローラの機能や性能は素晴らしく、RobotStudioでのオフラインティーチング環境もトップレベルで使いやすいです。ABBのロボット部門がソフトバンクグループとなったことで日本でのシェア拡大を狙っていてもおかしくはありません。そうなると営業やサポート部門の規模や質もより重厚になると思われます。今後のABBロボット事業の展開に期待します。 今回はPC-SDKの落とし穴と題して幾つか挙げましたがRAPIDにも落とし穴が潜んでいます。機会があればそちらも記事にできればと思います。 エー・ビー・ビーと呼びます。Asea社とBrown Boveri社の合弁で設立(アセア・ブラウン・ボベリ) ↩︎ PCからABB ロボットコントローラに接続するためのSDK(ライブラリ) ↩︎ ABBが提供しているオフラインティーチング(シミュレーション)ソフトウェア ↩︎ DeepL, Google翻訳, ブラウザで右クリックして「日本語に翻訳」など ↩︎ ABBの産業用ロボットを制御するために開発された専用のプログラミング言語 ↩︎









