<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ロボ &gt; ロボティクス on M1KE BL0G</title><link>https://www.m1ke.org/categories/robo_robotics/</link><description>Recent content in ロボ &gt; ロボティクス on M1KE BL0G</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><copyright>mike</copyright><atom:link href="https://www.m1ke.org/categories/robo_robotics/index.xml" rel="self" type="application/rss+xml"/><item><title>ロボット発話のパラフレーズが意味を壊す問題とNLIによる対策</title><link>https://www.m1ke.org/p/%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E7%99%BA%E8%A9%B1%E3%81%AE%E3%83%91%E3%83%A9%E3%83%95%E3%83%AC%E3%83%BC%E3%82%BA%E3%81%8C%E6%84%8F%E5%91%B3%E3%82%92%E5%A3%8A%E3%81%99%E5%95%8F%E9%A1%8C%E3%81%A8nli%E3%81%AB%E3%82%88%E3%82%8B%E5%AF%BE%E7%AD%96/</link><pubDate>Wed, 14 Oct 2026 23:20:00 +0900</pubDate><guid>https://www.m1ke.org/p/%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E7%99%BA%E8%A9%B1%E3%81%AE%E3%83%91%E3%83%A9%E3%83%95%E3%83%AC%E3%83%BC%E3%82%BA%E3%81%8C%E6%84%8F%E5%91%B3%E3%82%92%E5%A3%8A%E3%81%99%E5%95%8F%E9%A1%8C%E3%81%A8nli%E3%81%AB%E3%82%88%E3%82%8B%E5%AF%BE%E7%AD%96/</guid><description>&lt;img src="https://www.m1ke.org/p/%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E7%99%BA%E8%A9%B1%E3%81%AE%E3%83%91%E3%83%A9%E3%83%95%E3%83%AC%E3%83%BC%E3%82%BA%E3%81%8C%E6%84%8F%E5%91%B3%E3%82%92%E5%A3%8A%E3%81%99%E5%95%8F%E9%A1%8C%E3%81%A8nli%E3%81%AB%E3%82%88%E3%82%8B%E5%AF%BE%E7%AD%96/paraphrase.jpg" alt="Featured image of post ロボット発話のパラフレーズが意味を壊す問題とNLIによる対策" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sevilla-Salcedo et al. (2023) &amp;ldquo;Using Large Language Models to Shape Social Robots&amp;rsquo; Speech&amp;rdquo;（IJIMAI Vol.8 No.3）は、社会的ロボットの定型発話を単調にしないため、LLMでパラフレーズ（言い換え）を生成する仕組みを提案している論文&lt;/li&gt;
&lt;li&gt;この論文には、パラフレーズによって意味そのものが変わってしまった失敗例が報告されている。例えば「¿Cómo te llamas?（お名前は？）」が「¿Cómo se llama la llama?（そのリャマの名前は？）」にパラフレーズされてしまうケース&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/" &gt;SPRING: 高齢者介護施設における社会的ロボットの実証実験&lt;/a&gt;でも、LLMによる対話生成が「受診前は断食すべき」という世界知識ハルシネーションを起こした例が報告されている&lt;/li&gt;
&lt;li&gt;どちらの論文も、BLEU・BERTスコアといった自動評価指標だけでは、この種の意味の変質を十分に検出できていなかった。パラフレーズ生成後に、生成文が本当に元の意味を保っているかを検証する技術を整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="なぜbleubertスコアだけでは不十分か"&gt;なぜBLEU・BERTスコアだけでは不十分か&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IJIMAI論文では、パラフレーズの質をBLEU（語彙的な類似度）とBERTスコア（埋め込みベースの意味的な類似度）の2つで評価していた&lt;/li&gt;
&lt;li&gt;BLEUはそもそも「元の文とどれだけ違うか」を測る指標で、パラフレーズ生成では逆に「元の文に似すぎていない」ことが望ましいとされるため、意味保持そのものの検証には向かない&lt;/li&gt;
&lt;li&gt;BERTスコアはトークンの埋め込み類似度に基づく指標のため、単語の重なりが大きい文同士には高いスコアを出しやすい。「¿Cómo te llamas?」と「¿Cómo se llama la llama?」のように、単語の大部分が共通していながら、質問の対象（相手の名前 vs リャマの名前）が入れ替わってしまうような構造的な意味の反転は、検出しづらい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nliによるパラフレーズの意味保持フィルタリング"&gt;NLIによるパラフレーズの意味保持フィルタリング&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Klemen &amp;amp; Robnik-Šikonja (2021) &amp;ldquo;Extracting and filtering paraphrases by bridging natural language inference and paraphrasing&amp;rdquo;（arXiv:2111.07119）は、NLI（Natural Language Inference、自然言語推論）を使って、パラフレーズの正しさを機械的に検証する、具体的で検証可能な手法を提案している&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="双方向含意というアイデア"&gt;双方向含意というアイデア&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2つの文A・Bが「AはBを含意し（entail）、かつBもAを含意する」という双方向含意（bidirectional entailment）の関係にあるとき、AとBはパラフレーズであるとみなす、というのがこの手法の基本的な考え方&lt;/li&gt;
&lt;li&gt;逆に言えば、どちらか一方でも含意が崩れていれば、意味が変わってしまった「偽のパラフレーズ」とみなせる&lt;/li&gt;
&lt;li&gt;実際の判定には、含意確率に対する閾値（argmaxで判定する方法に加えて、0.75・0.90というより厳しい閾値）が使われ、閾値を上げるほど適合率が上がる一方で再現率は下がる、というトレードオフになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="実際の検証結果"&gt;実際の検証結果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;BERT・multilingual BERT・RoBERTa（base/large）・XLM-RoBERTa（base/large）というNLIモデルを、SNLI（約57万件）・MNLI（約41万件）・XNLI（15言語、11.25万件）というNLIデータセットで検証している&lt;/li&gt;
&lt;li&gt;この基準を既存のパラフレーズデータセットに適用したところ、QQPでは14.9万件中1.3万件（9.0%）、MRPCでは3,900件中230件（5.9%）が、実は意味の異なる「偽のパラフレーズ」として検出された&lt;/li&gt;
&lt;li&gt;手動検証でも、フィルタリングで除外されたペアの90%以上が、実際に意味の異なる非パラフレーズだったことが確認されている&lt;/li&gt;
&lt;li&gt;英語で学習した1つのモデルを15言語に適用する多言語設定でも、ドイツ語・フランス語で約80%の精度でパラフレーズを抽出できており、多言語のHRIシステムにも応用しやすい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="hriのパラフレーズ生成への応用"&gt;HRIのパラフレーズ生成への応用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IJIMAI論文のパイプラインでは、パラフレーズ生成後の検証はBERTスコアのみで、NLIベースの検証は使われていなかった&lt;/li&gt;
&lt;li&gt;仮に「¿Cómo te llamas?」と「¿Cómo se llama la llama?」のペアに双方向含意のチェックを追加していれば、前者は「名前を聞かれているのが話し相手」、後者は「名前を聞かれているのがリャマ」という点で、互いに含意し合わないため、このペアは機械的に弾けた可能性がある&lt;/li&gt;
&lt;li&gt;SPRING論文・IJIMAI論文はどちらも、高齢者や認知機能に配慮が必要な利用者を対象にしている。意味がわずかに変わっただけでも混乱を招きやすい対象であることを踏まえると、生成後にNLIベースの意味保持チェックを挟む追加コストは、十分に見合うと考えられる&lt;/li&gt;
&lt;li&gt;具体的には、パラフレーズ生成→NLIモデルで双方向含意を判定→含意が崩れていれば元の定型文にフォールバック、という追加ステップを、既存のパラフレーズ生成パイプラインの後段に挟む形になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IJIMAI論文のパラフレーズ生成には、意味が変わってしまう失敗例が実際に報告されており、BLEU・BERTスコアだけではこの種の失敗を十分に検出できていなかった&lt;/li&gt;
&lt;li&gt;Klemen &amp;amp; Robnik-Šikonja (2021)のNLIベースの双方向含意フィルタリングは、QQP・MRPCという既存データセットから5〜9%の「偽のパラフレーズ」を検出できる、具体的で検証済みの手法&lt;/li&gt;
&lt;li&gt;ロボットの発話パラフレーズのように、特に意味の正確さが重要なHRIの文脈でも、生成後にNLIベースの検証ステップを挟むことで、意味ドリフトを機械的に検出し、元の定型文にフォールバックすることができる可能性がある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sevilla-Salcedo, J., Fernández-Rodicio, E., Martín-Galván, L., Castro-González, Á., Castillo, J. C., &amp;amp; Salichs, M. A. (2023). &amp;ldquo;Using Large Language Models to Shape Social Robots&amp;rsquo; Speech&amp;rdquo; International Journal of Interactive Multimedia and Artificial Intelligence, Vol. 8, No. 3 (DOI:10.9781/ijimai.2023.07.008、&lt;a class="link" href="ijimai8_3_1.pdf" &gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Klemen, M., &amp;amp; Robnik-Šikonja, M. (2021). &amp;ldquo;Extracting and filtering paraphrases by bridging natural language inference and paraphrasing&amp;rdquo; (&lt;a class="link" href="https://arxiv.org/abs/2111.07119" target="_blank" rel="noopener"
&gt;arXiv:2111.07119&lt;/a&gt;、&lt;a class="link" href="klemen2021-nli-paraphrase.pdf" &gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/" &gt;SPRING: 高齢者介護施設における社会的ロボットの実証実験&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://teachingutopians.com/2020/05/24/writing-skills-how-to-paraphrase-in-easy-steps-a-comprehensive-guide/" target="_blank" rel="noopener"
&gt;How To Paraphrase In Six Easy Steps - A Comprehensive Writing Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Séverin Lemaignan論文チェック: ROS4HRI標準化論文</title><link>https://www.m1ke.org/p/s%C3%A9verin-lemaignan%E8%AB%96%E6%96%87%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-ros4hri%E6%A8%99%E6%BA%96%E5%8C%96%E8%AB%96%E6%96%87/</link><pubDate>Wed, 14 Oct 2026 16:20:00 +0900</pubDate><guid>https://www.m1ke.org/p/s%C3%A9verin-lemaignan%E8%AB%96%E6%96%87%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-ros4hri%E6%A8%99%E6%BA%96%E5%8C%96%E8%AB%96%E6%96%87/</guid><description>&lt;img src="https://www.m1ke.org/p/s%C3%A9verin-lemaignan%E8%AB%96%E6%96%87%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-ros4hri%E6%A8%99%E6%BA%96%E5%8C%96%E8%AB%96%E6%96%87/lemaignan-thumb.png" alt="Featured image of post Séverin Lemaignan論文チェック: ROS4HRI標準化論文" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;・&lt;a class="link" href="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/" &gt;SPRING: 高齢者介護施設における社会的ロボットの実証実験&lt;/a&gt;で、ROS4HRIのエコシステムや、それを実際の医療現場で使った実証実験を整理してきた&lt;/li&gt;
&lt;li&gt;Séverin Lemaignanは、PAL RoboticsでROS4HRIの開発に携わった研究者の1人（Mohamed &amp;amp; Lemaignan 2021でROS4HRIを提案し、2023年にREP-155として標準化）。今回は、その標準化内容をまとめたRos, Lemaignan, Ferrini, Andriella, Irisarri (2023) &amp;ldquo;ROS4HRI: Standardising an Interface for Human-Robot Interaction&amp;rdquo;（HRI 2023 Workshop &amp;ldquo;Advancing HRI Research and Benchmarking Through Open-Source Ecosystems&amp;rdquo;、ストックホルム）を、実際にPDFを読んで確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="論文の問題意識-hriにおけるベンチマークの困難さ"&gt;論文の問題意識: HRIにおけるベンチマークの困難さ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HRI（Human-Robot Interaction）研究では、人間の振る舞いの複雑さ・多様さゆえに、ベンチマークと再現性の確保が本質的に難しい&lt;/li&gt;
&lt;li&gt;それに加えて、標準的かつオープンソースなソフトウェアプラットフォームが存在しないことが、問題をさらに悪化させている&lt;/li&gt;
&lt;li&gt;唯一広く使われているのは、Aldebaran社のNAOqiフレームワーク（Nao・Pepperロボット向け）だが、オープンソースではなく、Aldebaran製ロボット以外では使えない&lt;/li&gt;
&lt;li&gt;ROS4HRIは、Mohamed &amp;amp; Lemaignan（2021, IROS）で提案され、2022年にROS REP-155として正式に標準化された。ROS上に構築され、特定のロボットに依存しない設計になっている&lt;/li&gt;
&lt;li&gt;論文は、ROS4HRIがベンチマーキング・再現性の問題を改善する理由として、(1) 異なるアルゴリズム間で直接性能比較できる共通インターフェースの確立、(2) あるソフトウェア基盤から別の基盤への移行をシステム全体から透過的にする、持続可能なソフトウェア開発の支援、の2点を挙げている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="人間のidモデル-4種類のid"&gt;人間のIDモデル: 4種類のID&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で扱った4種類のID（Face・Body・Voice・Person）について、論文では以下のように詳述されている&lt;/li&gt;
&lt;li&gt;Face・Body・VoiceのIDは非永続的で、特徴が失われた時点（例えば人物がロボットの視界から外れた時点）で、そのIDはもう意味を持たなくなる。異なる検出器同士が、人物が再出現した際に同じIDを再割り当てしようと試みる必要はない、という設計方針も明記されている&lt;/li&gt;
&lt;li&gt;Person IDは永続的で、一度割り当てられると、ロボットの知識として永続的に残り続ける&lt;/li&gt;
&lt;li&gt;&lt;code&gt;person_&amp;lt;personID&amp;gt;&lt;/code&gt;フレームは、&lt;code&gt;/humans/persons/&amp;lt;personID&amp;gt;/location_confidence&lt;/code&gt;の値と合わせて解釈する必要があり、以下の3つのケースに分かれる
&lt;ul&gt;
&lt;li&gt;追跡中（personIDが設定され、face/body/voiceのいずれかのIDが設定されている）: &lt;code&gt;location_confidence&lt;/code&gt;は1で、&lt;code&gt;person_&amp;lt;personID&amp;gt;&lt;/code&gt;フレームは、利用可能なface/skeleton/音源定位などの最良の推定位置と同じ場所に置かれる&lt;/li&gt;
&lt;li&gt;現在は見えていないが、過去の位置情報がある: &lt;code&gt;location_confidence&lt;/code&gt;は0より大きく1未満の値になり、その間は&lt;code&gt;person_&amp;lt;personID&amp;gt;&lt;/code&gt;フレームが配信され続ける&lt;/li&gt;
&lt;li&gt;存在は分かっているが位置情報が全くない（例えば対話を通じて存在を知った場合）: &lt;code&gt;location_confidence&lt;/code&gt;は0になり、TFフレームは配信されない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="人体キネマティクスモデル"&gt;人体キネマティクスモデル&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS4HRIは、人体の運動学的モデルの表現にURDF規格を採用している&lt;/li&gt;
&lt;li&gt;人体は15個のリンクが18個の関節（頭・肩・肘・膝・腰・腰部）で接続された構造として表現される&lt;/li&gt;
&lt;li&gt;人によって身長・体格が異なるため、身体が検出されるたびに、観測された身長を主パラメータとして、標準的な人体測定学の比率から肩幅などの他の寸法を導出した、カスタムのURDFモデルを生成する&lt;/li&gt;
&lt;li&gt;生成されたURDFモデルは、bodyIDをキーにROSパラメータサーバーに登録され、ネットワーク上の他のノードから利用できるようになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rosトピック構造とフレーム規約"&gt;ROSトピック構造とフレーム規約&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;全てのトピックは&lt;code&gt;/humans&lt;/code&gt;というグローバルな名前空間の下にまとめられ、&lt;code&gt;/humans/faces&lt;/code&gt;・&lt;code&gt;/humans/bodies&lt;/code&gt;・&lt;code&gt;/humans/voices&lt;/code&gt;・&lt;code&gt;/humans/persons&lt;/code&gt;・&lt;code&gt;/humans/interactions&lt;/code&gt;という5つのサブ名前空間に分かれる&lt;/li&gt;
&lt;li&gt;顔・身体・声・人物のフレーム命名規則について、論文では座標系の原点の定義まで踏み込んで説明している&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;フレーム&lt;/th&gt;
&lt;th&gt;原点の定義&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;body_&amp;lt;bodyID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;両腰の中間点。x軸は前方、z軸は頭方向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;face_&amp;lt;faceID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;セリオン（鼻と額がなす角の最も深い正中点）。x軸は前方、z軸は頭頂方向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head_&amp;lt;bodyID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;骨格トラッカーが頭部姿勢を推定できる場合に配信される、セリオン位置のフレーム。&lt;code&gt;face_&amp;lt;faceID&amp;gt;&lt;/code&gt;と整合性を取ることが、顔検出器・骨格トラッカー双方の責任とされる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gaze_&amp;lt;faceID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;face_&amp;lt;faceID&amp;gt;&lt;/code&gt;と同じ位置だが、カメラの光学フレームの慣習（z軸が前方、y軸が下方）に従う&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="intents意図の設計"&gt;Intents（意図）の設計&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2023年3月時点のREP-155は、知覚側のみをカバーしており、行動・振る舞いの標準化はまだ扱われていない。プラットフォーム・アプリケーションに依存する部分が大きく、標準化が難しいため&lt;/li&gt;
&lt;li&gt;論文では、ロボットが実行すべき操作の抽象的な記述として、Intent（意図）の標準化に向けた最初の試みを紹介している&lt;/li&gt;
&lt;li&gt;Androidのintentに着想を得つつ、ROSのintentはユーザーが開始した（明示的・暗黙的な）意図を捉えることを主眼に設計されている。例えば、タッチスクリーンのボタン操作（明示的）、チャットボットとの対話結果（暗黙的・明示的）、ロボットを見るという行動（暗黙的）などが対象になる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hri_actions_msgs/Intent&lt;/code&gt;というROSメッセージ型として表現され、&lt;code&gt;/intents&lt;/code&gt;トピックに配信される。ユーザーの活動を追跡するノード（タッチスクリーン・対話マネージャー・動作認識など）が発行し、アプリケーションコントローラーがそれを受け取って、行動のスケジューリング・リソース配分（2つの動作が同時に使われないようにするなど）を行う&lt;/li&gt;
&lt;li&gt;Intentは、intent種別・data（主題役割に基づくJSONオブジェクト）・source（ユーザーかロボット自身か）・modality（伝達手段）・priority（任意）・confidence（0〜1）というフィールドを持つ&lt;/li&gt;
&lt;li&gt;副作用のない短い反応的な応答（天気を聞く、バッテリー残量を確認するなど）には、Intentの仕組みは使うべきではないとされている。ロボットの状態・リソースに影響しないため&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="可視化ツール"&gt;可視化ツール&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;共通インターフェースの提供に加えて、システムの挙動を理解・分析するための可視化ツールも、&lt;code&gt;hri_rviz&lt;/code&gt;パッケージなどとして提供されている&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ツール&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Humans&lt;/td&gt;
&lt;td&gt;顔・身体のバウンディングボックス、顔のランドマーク、2D骨格の関節を、ROSの画像ストリーム上に可視化するrvizプラグイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skeletons 3D&lt;/td&gt;
&lt;td&gt;RobotModelに着想を得た、複数の検出済み身体を関節状態・位置・向きに基づいて3D骨格として可視化するrvizプラグイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TF (HRI)&lt;/td&gt;
&lt;td&gt;標準のtfツールの再実装。IDが&lt;code&gt;/humans/*/tracked&lt;/code&gt;から消えると、関連するフレームが即座にシーンから削除される&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rqt_human_radar&lt;/td&gt;
&lt;td&gt;ロボットの基準フレーム（base linkなど）に対する人物の位置を、レーダーのような視点で表示するrqtプラグイン&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="pal-ariとの関係今後の展望"&gt;PAL ARIとの関係・今後の展望&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;論文の最後では、PAL Robotics社の社会的ロボットARI（Cooper et al. 2020、2019年初出荷）の認知アーキテクチャを、ROS4HRIの上に構築中であることが述べられている&lt;/li&gt;
&lt;li&gt;ARIは、SHAPES・SPRING・TALBOT・PRO-CARED（EUプロジェクト）、NHOA・RAADICAL・AMIBA（国内プロジェクト）など、高齢者介護・支援ロボティクスに関する多数の研究プロジェクトで使われてきた。&lt;a class="link" href="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/" &gt;SPRINGの実証実験&lt;/a&gt;も、このプロジェクト群の1つにあたる&lt;/li&gt;
&lt;li&gt;ARIのアーキテクチャは、(1) 人間の知覚パイプライン（ロボットの周囲の人物への気づきを拡張する）と、(2) 自然言語処理パイプライン（音声認識・音声分離・音源定位・対話管理）の2本柱で構成される&lt;/li&gt;
&lt;li&gt;今後の方向性として、(1) インタラクションの可視化・記録ツールの拡充、(2) 表情認識・ジェスチャー認識・声の識別といった社会的機能の拡充、(3) コミュニティとのさらなる連携、(4) ROS4HRIのROS 2への移植、の4点が挙げられている。実際にROS4HRIはその後ROS 2に移植され、&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で扱った現在のエコシステムに繋がっている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ros, Lemaignan他 (2023)は、ROS4HRI（REP-155）の標準化内容を、HRI研究のベンチマーキング・再現性問題への対応として位置づけた論文&lt;/li&gt;
&lt;li&gt;Face/Body/VoiceIDの非永続性・PersonIDの永続性、&lt;code&gt;location_confidence&lt;/code&gt;による&lt;code&gt;person_&amp;lt;personID&amp;gt;&lt;/code&gt;フレームの3パターンの扱い、15リンク・18関節の人体キネマティクスモデルなど、&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で扱った内容の設計根拠が、この論文で詳しく説明されている&lt;/li&gt;
&lt;li&gt;2023年時点では知覚側の標準化が中心で、行動側の標準化はIntent（Androidのintentに着想を得た、ユーザー起点の意図の抽象表現）として初期段階にあった&lt;/li&gt;
&lt;li&gt;可視化ツール（Humans・Skeletons 3D・TF (HRI)・rqt_human_radar）の存在が、ROS4HRIがオープンな開発・デバッグエコシステムとしても機能していることを示している&lt;/li&gt;
&lt;li&gt;ARIロボットの認知アーキテクチャをROS4HRI上に構築する計画が述べられており、これが&lt;a class="link" href="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/" &gt;SPRINGの実証実験&lt;/a&gt;のような、後の大規模な実証研究に繋がっている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ros, R., Lemaignan, S., Ferrini, L., Andriella, A., &amp;amp; Irisarri, A. (2023). &amp;ldquo;ROS4HRI: Standardising an Interface for Human-Robot Interaction.&amp;rdquo; In &lt;em&gt;2023 ACM/IEEE International Conference on Human-Robot Interaction (HRI) Workshop on Advancing HRI Research and Benchmarking Through Open-Source Ecosystems&lt;/em&gt;, Stockholm, Sweden. (&lt;a class="link" href="https://academia.skadge.org/publis/ros2023ros4hri.pdf" target="_blank" rel="noopener"
&gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Mohamed, Y., &amp;amp; Lemaignan, S. (2021). &amp;ldquo;ROS for Human-Robot Interaction.&amp;rdquo; In &lt;em&gt;2021 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)&lt;/em&gt;. (&lt;a class="link" href="https://doi.org/10.1109/IROS51168.2021.9636816" target="_blank" rel="noopener"
&gt;DOI:10.1109/IROS51168.2021.9636816&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Cooper, S., Di Fava, A., Vivas, C., Marchionni, L., &amp;amp; Ferro, F. (2020). &amp;ldquo;ARI: The social assistive robot and companion.&amp;rdquo; In &lt;em&gt;2020 29th IEEE International Conference on Robot and Human Interactive Communication (RO-MAN)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/" &gt;SPRING: 高齢者介護施設における社会的ロボットの実証実験&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>SPRING: 高齢者介護施設における社会的ロボットの実証実験</title><link>https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/</link><pubDate>Wed, 14 Oct 2026 16:10:00 +0900</pubDate><guid>https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/</guid><description>&lt;img src="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-thumb.jpg" alt="Featured image of post SPRING: 高齢者介護施設における社会的ロボットの実証実験" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で、&lt;code&gt;hri_person_manager&lt;/code&gt;（Mr. Potato algorithm）やPAL Robotics ARIといった、ROS4HRIのエコシステムを構成する要素を整理した&lt;/li&gt;
&lt;li&gt;Alameda-Pineda, Addlesee, Hernández García他 (2024) &amp;ldquo;Socially Pertinent Robots in Gerontological Healthcare&amp;rdquo;（arXiv:2404.07560）は、これらの要素を組み合わせた実際のシステムを、高齢者介護施設で60人以上の患者・付添人を対象に検証した論文。ROS4HRIが実際の医療現場でどう使われているかの実例として、内容を整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="論文の概要"&gt;論文の概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EUのHorizon 2020プロジェクト「SPRING」の成果として、フランス・パリのBroca老年医学デイケア病院で、会話可能な社会的ロボットを実際の患者・付添人に使ってもらい、受容性（Acceptability）とユーザビリティを検証した実証研究&lt;/li&gt;
&lt;li&gt;著者は、SPRINGプロジェクトに参加する複数機関にまたがる44名（筆頭著者はAlameda-Pineda、Addlesee、Hernández García）&lt;/li&gt;
&lt;li&gt;臨床試験として登録されており（NCT05089799）、フランスの倫理審査委員会（CPP Ouest II）・パリ大学の倫理委員会の承認を得て実施された&lt;/li&gt;
&lt;li&gt;arXivプレプリント（2404.07560）として公開された後、共著者Angus Addlesee氏のLinkedIn投稿によれば、International Journal of Social Roboticsに正式に掲載された&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用ロボット-pal-robotics-ari"&gt;使用ロボット: PAL Robotics ARI&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用されたロボットは、PAL Robotics社のARI。&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で紹介した対応ロボットの1つ&lt;/li&gt;
&lt;li&gt;身長1.65m、差動二輪駆動の移動ベース、タッチスクリーン付きの胴体、可動する腕、LCDの目を持つ表情豊かな頭部を備える&lt;/li&gt;
&lt;li&gt;センサーとして、胴体前面の4マイクアレイ、頭部のRGBカメラ、胸部・背面の180度魚眼カメラ2台を搭載する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="システムアーキテクチャ-8つのモジュール"&gt;システムアーキテクチャ: 8つのモジュール&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;システム全体は、知覚系・行動系あわせて8つのモジュールで構成され、ROS 1 Noetic上で、52個のROSノードが170以上のトピック・アクションを介して通信する構成になっている&lt;/li&gt;
&lt;li&gt;論文のFig. 2（アーキテクチャ全体図）を見ると、センサー（マイクアレイ・頭部カメラ・魚眼カメラ・RGB-Dカメラ）からアクチュエータ（スピーカー・モーター）まで、各モジュールがどう繋がっているかが一目で分かる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig2-architecture.png"
width="2481"
height="1140"
srcset="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig2-architecture_hu_e9eff62dcff61e01.png 480w, https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig2-architecture_hu_dcf17ebf77e9ccf4.png 1024w"
loading="lazy"
alt="Fig. 2 Overview of the SPRING architecture. Each box represents either a sensor (microphone array, fisheye camera, frontal camera, or RGB-D camera), an actuator (loudspeaker, robot motors), or a module (perception or action) corresponding to the subsections of Sect. 2"
class="gallery-image"
data-flex-grow="217"
data-flex-basis="522px"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;マイクアレイ・頭部カメラ・魚眼カメラがSpeech Processing・Human Localisationに入り、そこからBehaviour Analysisを経てPerson Managerに集約される。RGB-DカメラはSelf-Localisation専用の入力になっている&lt;/li&gt;
&lt;li&gt;Person Managerに統合された人物情報は、Multi-party ConversationとNon-verbal Behaviourの両方に渡され、それぞれSpeech Synthesis（スピーカー）とMotors &amp;amp; Actuators（モーター）という、ロボットの実際の出力に繋がる&lt;/li&gt;
&lt;li&gt;Experimenter Interfaceは、Multi-party Conversation・Non-verbal Behaviourの両方と接続されており、実験者がシステムの挙動をリアルタイムに監視・介入できるようになっている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="知覚系"&gt;知覚系&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;モジュール&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Self-Localisation&lt;/td&gt;
&lt;td&gt;RTABMapとHLOC（Hierarchical-Localisation）を組み合わせ、90%のクエリで位置誤差1cm未満・回転誤差0.2度未満という精度で自己位置推定を行う&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human Localisation&lt;/td&gt;
&lt;td&gt;視覚トラッカーFairMOTと、音源方向推定（GCC-PHAT）を組み合わせて人物を追跡する。姿勢推定にOpenPose、グループ検出にGCFFアルゴリズムを使う&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech Processing&lt;/td&gt;
&lt;td&gt;音声強調（Mixture of Deep Experts、Sep-TFAnet）、VAD・音源方向・話者埋め込み（ECAPA-TDNN）の抽出、NVIDIA RIVAによる音声認識という多段パイプライン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human Behaviour Analysis&lt;/td&gt;
&lt;td&gt;視線先の検出、視線分析によるエンゲージメント（社会的受容）の自動検出、表情感情認識（FER）、音声感情認識（SER）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Person Manager&lt;/td&gt;
&lt;td&gt;ROS4HRI標準の実装で、顔・身体・声の特徴を1人の人物に統合する。&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で扱ったMr. Potato algorithmがここで使われている&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="補足-person-managerによる特徴統合の具体例"&gt;補足: Person Managerによる特徴統合の具体例&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;論文のFig. 3は、Person Managerが実際にどうMr. Potato algorithmを使って、顔・身体・声をグループ・人物に統合するかを、具体的な数値例で示している&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig3-personmanager.png"
width="2481"
height="1280"
srcset="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig3-personmanager_hu_4e6856709f0c8453.png 480w, https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig3-personmanager_hu_d61f9211f1cc9579.png 1024w"
loading="lazy"
alt="Fig. 3 Example of the processing of social features by the person manager. Faces, voices, bodies, persons, and groups are denoted by different colours. Edge numbers represent the likelihood of two nodes being associated. The relations graph generated by the perception module is shown on the left, and the changed graph by the person manager to maximise the overall likelihood on the right."
class="gallery-image"
data-flex-grow="193"
data-flex-basis="465px"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;左側が、知覚モジュール（顔検出・骨格追跡・音源定位など）が個別に出力した、ノード（Body・Voice・Face・Person・Group）間の関連尤度グラフ。例えば「Body 1」と「Voice 2」の間には尤度0.9のエッジがあり、強く関連していそうだと分かる&lt;/li&gt;
&lt;li&gt;右側が、Person Managerがこのグラフ全体の尤度を最大化するように調整した後の結果。左側で灰色になっていた弱い関連（例えば「Face 1」周りの0.1・0.6・0.2・0.8といったエッジ）は切り捨てられ、代わりに新しい&lt;code&gt;Person 3&lt;/code&gt;が追加されて、&lt;code&gt;Body 1&lt;/code&gt;・&lt;code&gt;Voice 2&lt;/code&gt;と紫色のエッジで結び直されている&lt;/li&gt;
&lt;li&gt;キャプションの注記にあるように、&lt;code&gt;Body 1&lt;/code&gt;と&lt;code&gt;Voice 2&lt;/code&gt;という2つの特徴が、どの既存のPersonにも十分な尤度で結びつかなかったため、Person Managerが新しい匿名の人物&lt;code&gt;Person 3&lt;/code&gt;を生成して割り当てている。これは、&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;で触れたMr. Potato algorithmの要件「特徴に紐づく人物が見つからない場合は匿名の人物に紐付ける」が、実際にどう動くかを示す具体例になっている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="行動系"&gt;行動系&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;モジュール&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Multi-party Conversation Manager&lt;/td&gt;
&lt;td&gt;LLMを組み込んだ対話システムで、複数人が同時に参加する会話の目的追跡や、「誰に話しかけられているか」の認識を行う&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-verbal Behaviour Generation&lt;/td&gt;
&lt;td&gt;Petri-Net Plannerをベースにした行動マネージャーに、ジェスチャー・視線のコントローラー、人の存在を考慮した経路計画（MPCベースのSocial Navigation Controller）を組み合わせる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Experimenter Interface&lt;/td&gt;
&lt;td&gt;タブレットから実験者がシステムを監視・操作するためのインターフェース&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="補足-petri-netの基礎"&gt;補足: Petri Netの基礎&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Behaviour Manager（行動マネージャー）が基盤にしているPetri-Net Planner（PNP、Dondrup et al. 2019）を理解するため、Petri net自体の基礎を、Bonet &amp;amp; Haslum (2011) &amp;ldquo;Petri Nets (for Planners)&amp;quot;（ICAPS 2011チュートリアル）を読んで確認した&lt;/li&gt;
&lt;li&gt;Petri netは、プレース（場所）・トランジション（遷移）・有向アーク（矢印）からなる離散イベントシステムのモデル化手法。C.A. Petriが1960年代に考案した&lt;/li&gt;
&lt;li&gt;各プレースは0個以上の「トークン」を持つことができ、トークンの配置全体を「マーキング（marking、ロボットの行動文脈でいえば「今の状態」）」と呼ぶ&lt;/li&gt;
&lt;li&gt;あるトランジションは、入力アークで繋がる全てのプレースにトークンがあるとき「発火可能（enabled）」になる。発火すると、入力側のプレースからトークンを消費し、出力側のプレースにトークンを生成する&lt;/li&gt;
&lt;li&gt;複数のトランジションが同時に発火可能な場合、どれが発火するかは非決定的（non-deterministic）に決まる。これが、Petri netが複数のタスクの並行実行や、状態に応じた分岐を自然に表現できる理由になっている&lt;/li&gt;
&lt;li&gt;特に「safe（1-bounded）」なPetri net（各プレースのトークンが常に0か1）は、プレースを命題（fluent）とみなせるため、STRIPS/PDDL形式のプランニング問題（各atomをプレース、各grounded actionをトランジションとして、前提条件を入力アーク・効果を出力アークに対応させる）に直接変換できる&lt;/li&gt;
&lt;li&gt;SPRING論文のPNPは、この枠組みを使って、ロボットの行動（発話・ジェスチャー・視線・ナビゲーションなど）をPetri-Netのプランとして表現し、複数のPetri-Netマシンを並行実行しながら、ROSのトピック・アクションで実際の制御に繋げている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="補足-social-navigation-controller人の存在を考慮した経路計画"&gt;補足: Social Navigation Controller（人の存在を考慮した経路計画）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;「人の存在を考慮した経路計画」の具体的な仕組みが、論文のFig. 5に示されている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig5-navigation.png"
width="808"
height="605"
srcset="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig5-navigation_hu_ce96a9961aaee7f8.png 480w, https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig5-navigation_hu_97c6d89a7833a841.png 1024w"
loading="lazy"
alt="Fig. 5 The social navigation controller integrates the social space of persons and groups (coloured contours indicate their cost) to plan a trajectory (blue) towards the target person without disturbing the conversational group"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;人物・会話グループの位置を中心に、2Dガウス関数的な「社会的空間」のコスト分布（等高線で図示）を定義する。コストは、向き・移動方向・立っているか座っているかといった状態に応じて変化する&lt;/li&gt;
&lt;li&gt;経路計画は、この社会的空間のコストと、障害物の占有マップのコストを組み合わせた損失関数$J$を最小化する形で、モーター出力の制御軌道を最適化する&lt;/li&gt;
&lt;li&gt;図の例では、ロボットが右上のTarget Personに向かう際に、左側の2つの会話グループ（コンター表示）を避けるように、青い経路が迂回して描かれている。グループの真ん中（Group Centre）を突っ切らないよう、コストの低い領域を縫うように経路が計画されている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="実験の概要"&gt;実験の概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;フランス・パリのBroca老年医学デイケア病院で、2つの波に分けて実験を実施した&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;波&lt;/th&gt;
&lt;th&gt;期間&lt;/th&gt;
&lt;th&gt;参加者&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wave 1&lt;/td&gt;
&lt;td&gt;2023年5月〜7月&lt;/td&gt;
&lt;td&gt;20名（患者15名、付添人5名）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wave 2&lt;/td&gt;
&lt;td&gt;2023年9月〜2024年1月&lt;/td&gt;
&lt;td&gt;43名（患者33名、付添人10名）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;合計63名が参加し、1回のインタラクションは5〜10分程度&lt;/li&gt;
&lt;li&gt;ロボット搭載のカメラ・マイクと、外部カメラで記録を取り、インタビューの書き起こしは合計1,142分（418ページ）に及ぶ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="評価結果"&gt;評価結果&lt;/h2&gt;
&lt;h3 id="aessusという2つの指標"&gt;AES・SUSという2つの指標&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;受容性の評価には、Acceptability E-Scale（AES、6項目、6〜30点、消費者に受け入れられる目安は25/30）と、System Usability Scale（SUS、10項目、0〜100点、目安は72/100）という、2つの標準化された尺度を使っている&lt;/li&gt;
&lt;li&gt;内部一貫性（信頼性）は、AESでCronbachのα=0.87、SUSでα=0.86と報告されている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="スコアの結果"&gt;スコアの結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;波&lt;/th&gt;
&lt;th&gt;対象&lt;/th&gt;
&lt;th&gt;AESスコア&lt;/th&gt;
&lt;th&gt;SUSスコア&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wave 1&lt;/td&gt;
&lt;td&gt;患者&lt;/td&gt;
&lt;td&gt;14.7（±5.73）&lt;/td&gt;
&lt;td&gt;45.5（±20.21）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wave 1&lt;/td&gt;
&lt;td&gt;付添人&lt;/td&gt;
&lt;td&gt;18.0（±4.64）&lt;/td&gt;
&lt;td&gt;55.0（±28.28）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wave 2&lt;/td&gt;
&lt;td&gt;患者&lt;/td&gt;
&lt;td&gt;20.7（±6.25）&lt;/td&gt;
&lt;td&gt;56.8（±12.63）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wave 2&lt;/td&gt;
&lt;td&gt;付添人&lt;/td&gt;
&lt;td&gt;21.0（±3.30）&lt;/td&gt;
&lt;td&gt;57.5（±10.40）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;AESスコアは、Wave 1（平均15.5、SD5.88）からWave 2（平均20.8、SD5.20）にかけて、統計的に有意に上昇した（F(1,52)=10.42、p&amp;lt;.001、η²=.17）&lt;/li&gt;
&lt;li&gt;この改善は、主に音声認識のファインチューニングと、対話管理へのLLM統合によるものとされている&lt;/li&gt;
&lt;li&gt;好まれる用途を尋ねたところ（Fig. 8）、エンターテインメント（40%）、健康リスクなしでの社会的交流の促進（30%）、受診準備の補助（23%）、受付・案内（5%）、道案内（2%）という割合だった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig8-usecases.png"
width="824"
height="795"
srcset="https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig8-usecases_hu_778fac7148e2e4fa.png 480w, https://www.m1ke.org/p/spring-%E9%AB%98%E9%BD%A2%E8%80%85%E4%BB%8B%E8%AD%B7%E6%96%BD%E8%A8%AD%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%A4%BE%E4%BC%9A%E7%9A%84%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A8%BC%E5%AE%9F%E9%A8%93/spring-fig8-usecases_hu_db97859fd0e9388b.png 1024w"
loading="lazy"
alt="Fig. 8 Proportions of use-case preferred choice"
class="gallery-image"
data-flex-grow="103"
data-flex-basis="248px"
&gt;&lt;/p&gt;
&lt;h2 id="倫理的な懸念と限界"&gt;倫理的な懸念と限界&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;半構造化インタビューからは、以下のような懸念が挙がった
&lt;ul&gt;
&lt;li&gt;データのプライバシー・透明性: データの保存方針が不明確なことへの不快感&lt;/li&gt;
&lt;li&gt;外見: 機械的な見た目よりも、より温かみのあるデザインを求める声&lt;/li&gt;
&lt;li&gt;医療現場でのミスへのリスク: 人間による監督があることで一定程度は緩和されている&lt;/li&gt;
&lt;li&gt;感情的な依存のリスク: 特に脆弱な立場の利用者において懸念される&lt;/li&gt;
&lt;li&gt;雇用代替への不安&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;研究自体の限界としては、以下が挙げられている
&lt;ul&gt;
&lt;li&gt;インタラクションを拒否する人は対象から除外されたため、「拒否の認識」自体は評価できていない&lt;/li&gt;
&lt;li&gt;実験にはNVIDIA RTX A6000（48GBメモリ）クラスの外部GPUが必要で、実運用上の制約になる&lt;/li&gt;
&lt;li&gt;マルチパーティ対話や、人を考慮した経路計画の能力自体は、病院内で正式には評価されていない&lt;/li&gt;
&lt;li&gt;医療従事者側の受け止め方は評価対象に含まれていない&lt;/li&gt;
&lt;li&gt;実験室が20m²未満と小さかったため、自己位置推定・ナビゲーション自体は「自明」な難易度だった&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPRINGプロジェクトは、PAL Robotics ARIをベースに、ROS4HRI標準のPerson Manager（Mr. Potato algorithm）を含む8モジュール・52 ROSノードからなるシステムを構築し、フランスの老年医学デイケア病院で63名の患者・付添人を対象に実証実験を行った&lt;/li&gt;
&lt;li&gt;AES・SUSという標準化された受容性・ユーザビリティ指標で評価した結果、Wave 1からWave 2にかけてスコアが統計的に有意に改善しており、音声認識の精度向上とLLMによる対話管理の強化が主な要因とされている&lt;/li&gt;
&lt;li&gt;利用者はエンターテインメント・社会的交流の促進としての利用を好んだ一方、データのプライバシー・外見の温かみ・医療現場でのミスのリスク・感情的依存・雇用代替への不安といった、倫理的な懸念も半構造化インタビューから得られている&lt;/li&gt;
&lt;li&gt;著者らは、本研究を「60人以上の実際の患者・付添人を対象に、これほど高度なインタラクションアーキテクチャを検証した初めての事例」と位置づけている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Alameda-Pineda, X., Addlesee, A., Hernández García, D., et al. (2024). &amp;ldquo;Socially Pertinent Robots in Gerontological Healthcare&amp;rdquo; (&lt;a class="link" href="https://arxiv.org/abs/2404.07560" target="_blank" rel="noopener"
&gt;arXiv:2404.07560&lt;/a&gt;)。International Journal of Social Robotics掲載版のPDFは&lt;a class="link" href="s12369-025-01330-6.pdf" &gt;こちら&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.linkedin.com/posts/angusaddlesee_our-final-spring-project-paper-has-just-activity-7392137797932830720-UvZ6" target="_blank" rel="noopener"
&gt;Angus Addlesee氏によるLinkedIn投稿&lt;/a&gt; - 本論文がInternational Journal of Social Roboticsに掲載された旨の告知&lt;/li&gt;
&lt;li&gt;Bonet, B., &amp;amp; Haslum, P. (2011). &amp;ldquo;Petri Nets (for Planners)&amp;rdquo; (ICAPS 2011 Tutorial) (&lt;a class="link" href="icaps11-petri.pdf" &gt;PDF&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>差動二輪ロボットの駆動系とAMCL・SLAM・Nav2</title><link>https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/</link><pubDate>Wed, 14 Oct 2026 11:00:00 +0900</pubDate><guid>https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/</guid><description>&lt;img src="https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/canon.png" alt="Featured image of post 差動二輪ロボットの駆動系とAMCL・SLAM・Nav2" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros2%E3%81%AE%E6%A6%82%E5%BF%B5%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;ROS2の概念を理解するためのメモ&lt;/a&gt;でTF2・SLAM・Nav2・Gazeboの概念をざっと整理したが、「ホイールのオドメトリとLiDARが、具体的にAMCL・SLAM・Nav2のどこに入り、どう使われるのか」という駆動系（ドライブトレイン）側の繋がりが曖昧だった&lt;/li&gt;
&lt;li&gt;そこで、Gazebo上での差動二輪駆動（Differential Drive）のシミュレーションを起点に、オドメトリ・LiDARがAMCL・SLAM・Nav2にどう流れていくのかを整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="全体像-駆動系からナビゲーションまでのデータの流れ"&gt;全体像: 駆動系からナビゲーションまでのデータの流れ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;大まかな処理の流れは以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;順序&lt;/th&gt;
&lt;th&gt;段階&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;駆動系シミュレーション&lt;/td&gt;
&lt;td&gt;Gazeboが、ホイールの関節の回転からロボットの移動をシミュレートし、オドメトリを計算する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;センサーシミュレーション&lt;/td&gt;
&lt;td&gt;Gazeboが、LiDARセンサーをシミュレートし、距離測定データを生成する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;自己位置推定&lt;/td&gt;
&lt;td&gt;AMCL（既知の地図がある場合）またはSLAM（地図がない場合）が、オドメトリとLiDARデータから、地図上での自己位置を推定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;経路計画・制御&lt;/td&gt;
&lt;td&gt;Nav2が、推定された自己位置とLiDARベースのコストマップを使って、経路を計画し、速度指令（&lt;code&gt;cmd_vel&lt;/code&gt;）を出す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;駆動系への反映&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cmd_vel&lt;/code&gt;がGazeboの駆動系シミュレーションに戻され、ロボットが実際に動く&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;つまり、駆動系（1・5）とセンサー（2）がGazebo側の入出力、自己位置推定（3）とナビゲーション（4）がROS 2側の処理という役割分担になっており、この2つがオドメトリ・LiDARデータ・&lt;code&gt;cmd_vel&lt;/code&gt;を通じて閉じたループを作っている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tfツリー全体像"&gt;TFツリー全体像&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;このループを理解する上で軸になるのが、TF2が管理する座標フレームのツリー&lt;/li&gt;
&lt;li&gt;代表的な構成は以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;map -&amp;gt; odom -&amp;gt; base_footprint -&amp;gt; base_link -&amp;gt; base_laser（LiDARなど各センサーのフレーム）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;変換&lt;/th&gt;
&lt;th&gt;発行元&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;odom&lt;/code&gt; -&amp;gt; &lt;code&gt;base_footprint&lt;/code&gt;（実質的に&lt;code&gt;base_link&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;駆動系シミュレーション（Gazeboのプラグイン、実機ではモータードライバ側）&lt;/td&gt;
&lt;td&gt;ホイールの回転から計算した、ロボット自身の移動量（オドメトリ）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt; -&amp;gt; &lt;code&gt;odom&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AMCLまたはSLAM&lt;/td&gt;
&lt;td&gt;オドメトリの誤差を、LiDARと地図の照合で補正した分のズレ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;base_footprint&lt;/code&gt; -&amp;gt; &lt;code&gt;base_link&lt;/code&gt;、&lt;code&gt;base_link&lt;/code&gt; -&amp;gt; &lt;code&gt;base_laser&lt;/code&gt;など&lt;/td&gt;
&lt;td&gt;&lt;code&gt;robot_state_publisher&lt;/code&gt;（URDFから自動計算）&lt;/td&gt;
&lt;td&gt;ロボット本体の構造に対する、各フレーム・センサーの固定された取り付け位置&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;重要なのは、AMCL・SLAMは&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;系の変換を書き換えるのではなく、それとは別に&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;の変換を発行するという点&lt;/li&gt;
&lt;li&gt;&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;系は駆動系が出し続けるオドメトリそのもの（ドリフトを含む、短期的には滑らかだが長期的にはズレていく値）であり、AMCL・SLAMはそのズレを、別のレイヤーで補正する役割分担になっている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="tf2の仕組み-分散システム前提の座標変換ライブラリ"&gt;TF2の仕組み: 分散システム前提の座標変換ライブラリ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TF2は、複数のノードに分かれて動く分散システムであることを前提にした、座標変換のためのライブラリ&lt;/li&gt;
&lt;li&gt;各ノードが、自分の知っている2つのフレーム間の位置・姿勢関係を&lt;code&gt;transform_broadcaster&lt;/code&gt;で発行し、それらを集約することで、ロボット全体の全フレームが繋がった1つのツリーが構築される&lt;/li&gt;
&lt;li&gt;位置・姿勢を知りたい側は、&lt;code&gt;transform_listener&lt;/code&gt;でこのツリーをたどり、任意の2フレーム間の変換を取得する&lt;/li&gt;
&lt;li&gt;位置は$x, y, z$（メートル単位）、姿勢はクォータニオン（四元数）で表現される&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/ros-view-frames.jpg"
width="1896"
height="3154"
srcset="https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/ros-view-frames_hu_db8723f01de7cfd8.jpg 480w, https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/ros-view-frames_hu_5769e8c94a150ae9.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="60"
data-flex-basis="144px"
&gt;&lt;/p&gt;
&lt;h3 id="ros座標フレームの一覧"&gt;ROS座標フレームの一覧&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ここまで出てきた&lt;code&gt;map&lt;/code&gt;・&lt;code&gt;odom&lt;/code&gt;・&lt;code&gt;base_footprint&lt;/code&gt;・&lt;code&gt;base_link&lt;/code&gt;・&lt;code&gt;base_laser&lt;/code&gt;は、ROSのコミュニティで広く使われている座標フレームの命名規約（移動ロボット向けの標準規約REP-105ほか）に沿ったもので、それぞれの役割は以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/ros-tf-tree.jpg"
width="634"
height="420"
srcset="https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/ros-tf-tree_hu_c7aed50964be87a7.jpg 480w, https://www.m1ke.org/p/%E5%B7%AE%E5%8B%95%E4%BA%8C%E8%BC%AA%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E9%A7%86%E5%8B%95%E7%B3%BB%E3%81%A8amclslamnav2/ros-tf-tree_hu_343a6d989ce1944a.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="362px"
&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;フレーム&lt;/th&gt;
&lt;th&gt;種類&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ワールド座標&lt;/td&gt;
&lt;td&gt;ロボットが位置する世界座標系。REP-105によれば、Z軸が上向きで、地図に対する位置は長期的にほとんどドリフトしないが、再位置推定のタイミングで不連続にジャンプすることがある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;odom&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ワールド座標（ローカルに連続）&lt;/td&gt;
&lt;td&gt;オドメトリ（車輪エンコーダなどの距離計）を積分した座標系。REP-105によれば連続的でなめらかな一方、実際の世界座標（&lt;code&gt;map&lt;/code&gt;）とは長期的にズレ（ドリフト）ていく。このズレを補正するのが、前述の&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;変換&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;base_footprint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ローカル座標&lt;/td&gt;
&lt;td&gt;&lt;code&gt;base_link&lt;/code&gt;を地面に投影したフレーム。XY座標・向きは&lt;code&gt;base_link&lt;/code&gt;と連動するが、Z座標は常に地面の高さ（0）に固定される。2Dのナビゲーションアルゴリズムが、ロボットを平面上の点として扱えるようにするためのフレーム&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;base_link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ローカル座標&lt;/td&gt;
&lt;td&gt;ロボット本体に固定された基準フレーム。車体の実際の高さ・姿勢を含む、ロボットそのものの位置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;base_laser&lt;/code&gt;（本記事では&lt;code&gt;laser_link&lt;/code&gt;と表記）&lt;/td&gt;
&lt;td&gt;ローカル座標&lt;/td&gt;
&lt;td&gt;LiDARなどのレーザースキャナが取り付けられている位置を表すフレーム。具体的な名前はロボットごとに異なる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt;と&lt;code&gt;odom&lt;/code&gt;はどちらも世界座標だが、&lt;code&gt;map&lt;/code&gt;は長期的に正確な代わりに不連続、&lt;code&gt;odom&lt;/code&gt;は連続的だが長期的にはズレていくという、正反対の性質を持つ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;base_footprint&lt;/code&gt;・&lt;code&gt;base_link&lt;/code&gt;・&lt;code&gt;base_laser&lt;/code&gt;はどれもロボット本体を基準にしたローカル座標で、&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_footprint&lt;/code&gt;の変換さえ分かれば、そこから先は固定されたロボットの構造（URDF）だけで計算できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gazeboでの駆動系シミュレーション"&gt;Gazeboでの駆動系シミュレーション&lt;/h2&gt;
&lt;h3 id="差動二輪駆動の仕組み"&gt;差動二輪駆動の仕組み&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;差動二輪駆動（Differential Drive）は、左右2つの独立した駆動輪の回転速度の差で、前進・後退・旋回を実現する機構&lt;/li&gt;
&lt;li&gt;左右輪の角速度を$\omega_L$、$\omega_R$、ホイール半径を$r$、ホイール間距離（トレッド）を$L$とすると、ロボット本体の並進速度$v$と角速度$\omega$は以下の式で計算される&lt;/li&gt;
&lt;/ul&gt;
$$
v = \frac{r(\omega_R + \omega_L)}{2}, \quad \omega = \frac{r(\omega_R - \omega_L)}{L}
$$&lt;ul&gt;
&lt;li&gt;Nav2やteleopノードが&lt;code&gt;cmd_vel&lt;/code&gt;（並進速度$v$・角速度$\omega$）を指令すると、駆動系はこの式を逆に解いて、左右輪それぞれの目標角速度を求める&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gz-simのdiffdriveシステムプラグイン"&gt;gz-simのDiffDriveシステムプラグイン&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;現行のGazebo（gz-sim、旧Ignition Gazebo）では、&lt;code&gt;DiffDrive&lt;/code&gt;というシステムプラグインが、この差動二輪駆動のシミュレーションとオドメトリ計算をまとめて担う&lt;/li&gt;
&lt;li&gt;実際にソースを確認したところ、役割は以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;入力トピック&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model/&amp;lt;モデル名&amp;gt;/cmd_vel&lt;/code&gt;（&lt;code&gt;geometry_msgs/Twist&lt;/code&gt;、トピック名は&lt;code&gt;&amp;lt;topic&amp;gt;&lt;/code&gt;タグで変更可能）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;出力トピック（オドメトリ）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model/&amp;lt;モデル名&amp;gt;/odometry&lt;/code&gt;（&lt;code&gt;&amp;lt;odom_topic&amp;gt;&lt;/code&gt;タグで変更可能）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;出力トピック（TF）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model/&amp;lt;モデル名&amp;gt;/tf&lt;/code&gt;（&lt;code&gt;&amp;lt;tf_topic&amp;gt;&lt;/code&gt;タグで変更可能）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主なパラメータ&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;left_joint&amp;gt;&lt;/code&gt;・&lt;code&gt;&amp;lt;right_joint&amp;gt;&lt;/code&gt;（ホイールの関節名）、&lt;code&gt;&amp;lt;wheel_separation&amp;gt;&lt;/code&gt;（ホイール間距離、デフォルト1.0m）、&lt;code&gt;&amp;lt;wheel_radius&amp;gt;&lt;/code&gt;（ホイール半径、デフォルト0.2m）、&lt;code&gt;&amp;lt;odom_publish_frequency&amp;gt;&lt;/code&gt;（オドメトリ配信周波数、デフォルト50Hz）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;発行するTF&lt;/td&gt;
&lt;td&gt;&lt;code&gt;frame_id&lt;/code&gt;は&lt;code&gt;&amp;lt;モデル名&amp;gt;/odom&lt;/code&gt;、&lt;code&gt;child_frame_id&lt;/code&gt;は&lt;code&gt;&amp;lt;モデル名&amp;gt;/&amp;lt;ホイールが接続されたリンク名&amp;gt;&lt;/code&gt;がデフォルト&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;つまり、SDF（Gazeboのロボット記述形式）やURDFの中でこのプラグインに左右ホイールの関節名と、ホイール半径・間距離を指定するだけで、&lt;code&gt;cmd_vel&lt;/code&gt;を受け取って物理的にホイールを回転させ、その回転量から上の式を使ってオドメトリを逆算し、&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;相当のTFとトピックを配信してくれる&lt;/li&gt;
&lt;li&gt;ROSとの橋渡し（&lt;code&gt;ros_gz_bridge&lt;/code&gt;）を使うことで、これらのGazebo側トピックを、ROS 2標準の&lt;code&gt;/cmd_vel&lt;/code&gt;・&lt;code&gt;/odom&lt;/code&gt;トピックに変換して繋ぎ込む&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="オドメトリのドリフトという前提"&gt;オドメトリのドリフトという前提&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;このDiffDriveプラグインが計算するオドメトリは、ホイールの回転量だけから並進・回転を積分しているため、実機ではスリップ（ホイールの空転・横滑り）やエンコーダのノイズによって、時間が経つほど実際の位置とズレていく（ドリフトする）&lt;/li&gt;
&lt;li&gt;Gazeboでも、タイヤと地面の摩擦パラメータ次第でこのスリップが再現されるため、オドメトリ単体では長時間・長距離の自己位置推定には使えない、という実機と同じ制約がシミュレーション上でも成り立つ&lt;/li&gt;
&lt;li&gt;このドリフトを補正するのが、後述のAMCL・SLAMの役割になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gazeboでのlidarシミュレーション"&gt;GazeboでのLiDARシミュレーション&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GazeboのLiDARセンサープラグインは、仮想空間内でレイを飛ばして周囲のオブジェクトとの交差点を計算することで、実際のLiDARと同じ形式の距離測定データ（&lt;code&gt;sensor_msgs/LaserScan&lt;/code&gt;、各角度ごとの距離値の配列）を生成する&lt;/li&gt;
&lt;li&gt;このセンサーも、URDF上で&lt;code&gt;base_link&lt;/code&gt;からの相対位置・向きを指定したリンク（例えば&lt;code&gt;laser_link&lt;/code&gt;）に取り付ける形で定義し、&lt;code&gt;robot_state_publisher&lt;/code&gt;がそのリンクのTFフレームを自動的に配信する&lt;/li&gt;
&lt;li&gt;出力は、ROS 2標準では&lt;code&gt;/scan&lt;/code&gt;トピックとして配信され、このトピックを後述のAMCL・SLAM・Nav2のコストマップが共通して利用する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="amcl-オドメトリとlidarで自己位置を補正する"&gt;AMCL: オドメトリとLiDARで自己位置を補正する&lt;/h2&gt;
&lt;h3 id="パーティクルフィルタの基本"&gt;パーティクルフィルタの基本&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AMCL（Adaptive Monte Carlo Localization）は、既知の地図上でのロボットの自己位置を、パーティクルフィルタで推定する手法&lt;/li&gt;
&lt;li&gt;「ロボットがここにいるかもしれない」という仮説を、数百〜数千個の粒子（パーティクル、それぞれが位置・向きの候補）として保持し、センサー情報が入るたびに、尤度の高い粒子を生き残らせ、低い粒子を淘汰する、というリサンプリングを繰り返す&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="動作モデルオドメトリと観測モデルlidar"&gt;動作モデル（オドメトリ）と観測モデル（LiDAR）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;実際にリポジトリで確認したところ、AMCLは&lt;code&gt;odom&lt;/code&gt;（オドメトリ）・&lt;code&gt;scan&lt;/code&gt;（LiDARのスキャン）・&lt;code&gt;map&lt;/code&gt;（既知の地図）・&lt;code&gt;initialpose&lt;/code&gt;（初期位置の手動指定）をsubscribeし、&lt;code&gt;particlecloud&lt;/code&gt;（粒子群の可視化用）・&lt;code&gt;amcl_pose&lt;/code&gt;（推定された自己位置）をpublishする&lt;/li&gt;
&lt;li&gt;動作モデルは、直前のオドメトリの変化量を使って、各粒子を同じだけ移動させる。ただし、ドリフトを考慮して、移動量にはランダムなノイズを加える&lt;/li&gt;
&lt;li&gt;観測モデルは、各粒子の位置から見たときに、今回のLiDARスキャンがどれだけ「地図と一致していそうか」を計算し、一致度が高い粒子ほど尤度を高くする&lt;/li&gt;
&lt;li&gt;この2つを組み合わせることで、「オドメトリでおおよその動きを予測し、LiDARと地図の照合でその予測を補正する」というベイズフィルタ的な推定を、観測が入るたびに繰り返す&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="map---odom変換の補正という役割"&gt;map -&amp;gt; odom変換の補正という役割&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AMCLは、&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;のTFを書き換えるのではなく、&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;のTFを配信することで、地図座標系での自己位置を表現する&lt;/li&gt;
&lt;li&gt;つまり、駆動系（DiffDriveプラグイン）が出し続ける生のオドメトリはそのまま残しつつ、AMCLがその上に「このオドメトリ座標系は、実際の地図上ではこれだけズレている」という補正値を重ねる、というレイヤー構造になっている&lt;/li&gt;
&lt;li&gt;このため、AMCLが何らかの理由で推定に失敗しても、&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;自体は駆動系から配信され続けるため、システム全体が完全に座標情報を失うことはない&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="slam-地図がない場合はslam_toolboxが代わりを担う"&gt;SLAM: 地図がない場合はslam_toolboxが代わりを担う&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AMCLは「既知の地図」が前提になっているため、未知の環境ではそもそも使えない&lt;/li&gt;
&lt;li&gt;そこで使われるのが、2D LiDARベースのSLAMとしてよく使われる&lt;code&gt;slam_toolbox&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;AMCLとの違いは以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;AMCL&lt;/th&gt;
&lt;th&gt;slam_toolbox&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;前提&lt;/td&gt;
&lt;td&gt;既知の地図が必要&lt;/td&gt;
&lt;td&gt;地図は不要（走行しながら作る）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;役割&lt;/td&gt;
&lt;td&gt;自己位置推定のみ&lt;/td&gt;
&lt;td&gt;自己位置推定＋地図作成（SLAM）を同時に行う&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;使う情報&lt;/td&gt;
&lt;td&gt;オドメトリ＋LiDARスキャン＋既存の地図&lt;/td&gt;
&lt;td&gt;オドメトリ＋LiDARスキャンのスキャンマッチングで地図を構築・更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内部構造&lt;/td&gt;
&lt;td&gt;パーティクルフィルタ&lt;/td&gt;
&lt;td&gt;ポーズグラフ（過去の位置同士の関係をグラフ化）とループクロージャ（同じ場所に戻ったことを検出して誤差を補正）の最適化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;発行するTF・トピック&lt;/td&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;、および&lt;code&gt;/map&lt;/code&gt;（占有格子地図）、&lt;code&gt;/slam_toolbox/pose&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;slam_toolboxも、AMCLと同様にオドメトリとLiDARスキャンを使ってスキャンマッチングを行い、その結果をもとに&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;のTFを配信する、という同じレイヤー構造を取る&lt;/li&gt;
&lt;li&gt;つまり、AMCLとSLAMは「地図を使うか作るか」の違いであり、駆動系（オドメトリ）・LiDARからの入力の受け方、&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;という出力の形は共通している&lt;/li&gt;
&lt;li&gt;作成した地図を保存しておけば、以降はAMCLで既知の地図として使い回せる、という使い分けになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="slamとamclは同時に動かさない"&gt;SLAMとAMCLは同時に動かさない&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AMCLとslam_toolboxは、どちらも&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;のTFを配信する役割を持つため、両者を同時に動かすとこの変換が競合してしまう&lt;/li&gt;
&lt;li&gt;通常の運用では、地図作成中はslam_toolboxが地図と自己位置の両方を提供し、地図が完成した後はAMCLに切り替えて、既知の地図上での自己位置推定に専念するという使い分けが基本になる&lt;/li&gt;
&lt;li&gt;つまり「地図作成フェーズ（SLAM）」と「運用フェーズ（AMCL）」を明確に切り分け、同じタイミングでは片方しか動かさないのが前提&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="発展-意味情報を加えるowlrdfとsemantic-slam"&gt;発展: 意味情報を加えるOWL/RDFとSemantic SLAM&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ここまでのSLAM・AMCLは、あくまで「空間のどこに壁や障害物があるか」という幾何学的な情報を扱う技術で、「その場所が何をする場所なのか」という意味までは扱わない&lt;/li&gt;
&lt;li&gt;OWL（Web Ontology Language）・RDF（Resource Description Framework）は、場所やオブジェクトに「101号室は病室」「薬品庫はスタッフ専用エリア」といった意味・関係をオントロジー・知識グラフとして記述するための標準規格で、SLAM・AMCLとは独立した、意味情報を載せるためのレイヤーにあたる&lt;/li&gt;
&lt;li&gt;通常のSLAMが「そこに壁や物体がある」という幾何学的な地図しか作らないのに対し、Semantic SLAM（意味的SLAM）は「それはドアなのか机なのか部屋なのか」といった意味ラベルも地図に結びつける研究分野で、OWL/RDFはこの意味情報を整理する手段の1つとして使われることがあるが、必須というわけではない&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/" &gt;ROS4HRIの仕組み&lt;/a&gt;のLLM対応チュートリアルで触れた&lt;code&gt;knowledge_core&lt;/code&gt;も、OWL/RDFベースの記号的な知識ベースであり、位置情報そのものではなく、その位置・場所が持つ意味を扱う用途で使われている&lt;/li&gt;
&lt;li&gt;整理すると、SLAM（地図を作る）→AMCL（地図上で位置を知る）→OWL/RDF（その位置・場所に意味を与える）という積み重ねで理解すると分かりやすいが、OWL/RDFはSLAM・AMCLの必須要素ではなく、必要に応じて追加する別レイヤー&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nav2との接続-コストマップと速度指令"&gt;Nav2との接続: コストマップと速度指令&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AMCL・SLAMが&lt;code&gt;amcl_pose&lt;/code&gt;（またはそれに相当するTF）として自己位置を確定させると、Nav2はそれをもとにグローバルプランナーで大まかな経路を計画し、コントローラー（ローカルプランナー）が直近の障害物を避けながら実際の速度指令を計算する&lt;/li&gt;
&lt;li&gt;この「直近の障害物」を表すのがコストマップで、&lt;code&gt;/scan&lt;/code&gt;のLiDARデータがリアルタイムに反映される。地図上の静的な障害物（グローバルコストマップ）と、今まさにLiDARが検出している動的な障害物（ローカルコストマップ）の両方に、同じ&lt;code&gt;/scan&lt;/code&gt;データが使われる&lt;/li&gt;
&lt;li&gt;最終的にコントローラーが計算した速度指令が&lt;code&gt;cmd_vel&lt;/code&gt;として配信され、それが駆動系シミュレーション（DiffDriveプラグイン）に渡って実際にホイールが回り、ロボットが移動する。この移動がまた新しいオドメトリ・LiDARスキャンを生み、ループが続いていく&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Gazebo上の駆動系シミュレーション（差動二輪駆動の場合はgz-simのDiffDriveプラグイン）は、&lt;code&gt;cmd_vel&lt;/code&gt;を受けてホイールを回転させ、その回転量からオドメトリを逆算し、&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;のTFとトピックを配信する&lt;/li&gt;
&lt;li&gt;このオドメトリは、ホイールの回転だけから積分した値のため、実機・シミュレーション問わずドリフトする。この誤差を補正するのが、既知の地図があるときのAMCL、地図がないときのslam_toolboxの役割&lt;/li&gt;
&lt;li&gt;AMCL・slam_toolboxはどちらも、オドメトリ（動作モデル／スキャンマッチングの初期値）とLiDARスキャン（観測モデル／地図とのマッチング）を使い、&lt;code&gt;odom&lt;/code&gt;-&amp;gt;&lt;code&gt;base_link&lt;/code&gt;自体は書き換えず、別レイヤーの&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;というTFを配信することで、地図座標系での自己位置を補正する&lt;/li&gt;
&lt;li&gt;両者とも&lt;code&gt;map&lt;/code&gt;-&amp;gt;&lt;code&gt;odom&lt;/code&gt;を配信するため、同時には動かさず、地図作成フェーズ（SLAM）と運用フェーズ（AMCL）を切り分けて使う&lt;/li&gt;
&lt;li&gt;Nav2は、この自己位置と、LiDARスキャンから作られるコストマップをもとに経路計画・障害物回避を行い、最終的な速度指令&lt;code&gt;cmd_vel&lt;/code&gt;を駆動系に戻すことで、駆動系→センサー→自己位置推定→ナビゲーション→駆動系という1つの閉じたループが成立する&lt;/li&gt;
&lt;li&gt;SLAM・AMCLが扱うのはあくまで幾何学的な位置情報で、「その場所が何をする場所か」という意味はOWL/RDFのような別レイヤー（Semantic SLAMという研究分野も含む）で扱う、必須ではない拡張領域になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/ros2%E3%81%AE%E6%A6%82%E5%BF%B5%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;ROS2の概念を理解するためのメモ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/gazebosim/gz-sim/tree/main/src/systems/diff_drive" target="_blank" rel="noopener"
&gt;gazebosim/gz-sim - DiffDrive system plugin - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros-navigation/navigation2/tree/main/nav2_amcl" target="_blank" rel="noopener"
&gt;ros-navigation/navigation2 - nav2_amcl - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/SteveMacenski/slam_toolbox" target="_blank" rel="noopener"
&gt;SteveMacenski/slam_toolbox - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros-navigation/navigation2" target="_blank" rel="noopener"
&gt;ros-navigation/navigation2 - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://memo.soarcloud.com/ros%E3%81%AE%E5%BA%A7%E6%A8%99%E5%A4%89%E6%8F%9Btf%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/" target="_blank" rel="noopener"
&gt;ROSの座標変換TFについて&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>ROS4HRIの仕組み</title><link>https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/</link><pubDate>Tue, 13 Oct 2026 16:30:00 +0900</pubDate><guid>https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/</guid><description>&lt;img src="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/ros4hri.png" alt="Featured image of post ROS4HRIの仕組み" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS上でHRI（Human-Robot Interaction、人間とロボットのインタラクション）を扱うための標準規格・OSSツール群であるROS4HRIについて、仕組みを整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ros4hriとは"&gt;ROS4HRIとは&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS REP-155として仕様化された、ROS 1・ROS 2の両方に対応する、人間の認識・表現のための標準的なメッセージ型・規約&lt;/li&gt;
&lt;li&gt;「ロボットが共有空間の中で人間を意味のある形で認識・解釈・応答できるようにする」ことを目的とした、オープンソースのリソース群&lt;/li&gt;
&lt;li&gt;EUの資金援助を受けて開発されており、Apache 2.0ライセンスで公開されている&lt;/li&gt;
&lt;li&gt;REP-155自体は、骨格追跡・顔認識・音声処理といった分野で、ROSエコシステムの他の分野ほど広く受け入れられた共通インターフェースがなかったという問題意識から作られている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rep-155の仕様"&gt;REP-155の仕様&lt;/h2&gt;
&lt;h3 id="4種類のid"&gt;4種類のID&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;REP-155は、人物を4種類のIDで表現する&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;永続性&lt;/th&gt;
&lt;th&gt;割り当て元&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Person ID&lt;/td&gt;
&lt;td&gt;永続的なUUID。セッションを超えて同一人物を表す&lt;/td&gt;
&lt;td&gt;顔認識・声認識など、人物識別が可能なノード&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Face ID&lt;/td&gt;
&lt;td&gt;非永続的。顔がフレームから外れると無効になる&lt;/td&gt;
&lt;td&gt;顔検出ノード&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Body ID&lt;/td&gt;
&lt;td&gt;非永続的。骨格が追跡されている間だけ有効&lt;/td&gt;
&lt;td&gt;骨格追跡ノード&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voice ID&lt;/td&gt;
&lt;td&gt;非永続的&lt;/td&gt;
&lt;td&gt;音声分離ノード&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="トピックの名前空間"&gt;トピックの名前空間&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;全てのHRI関連トピックは&lt;code&gt;/humans/&lt;/code&gt;以下に置かれ、&lt;code&gt;faces&lt;/code&gt;・&lt;code&gt;bodies&lt;/code&gt;・&lt;code&gt;voices&lt;/code&gt;・&lt;code&gt;persons&lt;/code&gt;・&lt;code&gt;interactions&lt;/code&gt;という5つのサブ名前空間に分かれる&lt;/li&gt;
&lt;li&gt;例えば&lt;code&gt;/humans/faces/&amp;lt;faceID&amp;gt;/cropped&lt;/code&gt;のように、個々の実体（顔など）ごとの名前空間を持つことで、下流のノードが情報を追加していける&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="なぜ単一のfaceメッセージではなく分割するのか"&gt;なぜ単一のFaceメッセージではなく分割するのか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仮に全ての顔情報をまとめた汎用的な1つのFaceメッセージを発行する設計にすると、1つのノードが顔に関する全ての情報を先に統合しなければならなくなり、モジュール性が損なわれる&lt;/li&gt;
&lt;li&gt;そのため、切り出し・表情認識・ランドマーク検出といった個々の情報を、別々のノードがそれぞれのサブトピックに発行する設計になっている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="座標フレーム"&gt;座標フレーム&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;REP-120の慣習に従い、以下のような座標フレームが定義されている&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;フレーム&lt;/th&gt;
&lt;th&gt;原点&lt;/th&gt;
&lt;th&gt;軸の向き&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;face_&amp;lt;faceID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;セリオン（両目の中間点）&lt;/td&gt;
&lt;td&gt;x軸が前方、z軸が頭頂方向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;body_&amp;lt;bodyID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;腰の中間点&lt;/td&gt;
&lt;td&gt;x軸が前方、z軸が頭方向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gaze_&amp;lt;faceID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;face_&amp;lt;faceID&amp;gt;&lt;/code&gt;と同じ位置&lt;/td&gt;
&lt;td&gt;z軸が視線方向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;person_&amp;lt;personID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;追跡中はface/bodyフレームと同じ位置、そうでなければ最後に確認された位置&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;person_&amp;lt;personID&amp;gt;&lt;/code&gt;フレームの位置は、&lt;code&gt;location_confidence&lt;/code&gt;（位置の確信度）によって扱いが変わる。追跡中は1.0、最近見えていた場合は1.0未満、既知だが一度も観測されていない場合は0になる&lt;/li&gt;
&lt;li&gt;人体のキネマティックモデルは、頭・胴体・肩・肘・手首・腰・膝・足首など15個の主要なリンクで構成され、URDFが&lt;code&gt;/human_description_&amp;lt;bodyID&amp;gt;&lt;/code&gt;としてパラメータサーバーに動的に読み込まれる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="視線の非対称性"&gt;視線の非対称性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;「AがBを見ている」という関係は、必ずしも「BもAを見ている」ことを意味しない。視線（Gaze）は送り手（sender）と受け手（receiver）の非対称な関係として表現される&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="kinematic-model-of-the-human"&gt;Kinematic Model of the Human&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/frames.png"
width="1057"
height="729"
srcset="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/frames_hu_aa30b165b4aca593.png 480w, https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/frames_hu_b9d0f50b0fcd0085.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="144"
data-flex-basis="347px"
&gt;&lt;/p&gt;
&lt;p&gt;The main 15 links defined on the human body are presented in the above diagram. Frames orientations and naming are based on REP-103 and REP-120. Right: render of the reference URDF model of the human body in rviz.&lt;/p&gt;
&lt;h2 id="全体像-ros4hriエコシステムの構成"&gt;全体像: ROS4HRIエコシステムの構成&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;公式サイト（ros4hri.github.io）で確認すると、ROS4HRIは単なるメッセージ規約ではなく、「知覚→人物統合→インタラクションのスキル→UI・可視化」という一連の流れを、パッケージ群として提供するエコシステムになっている&lt;/li&gt;
&lt;li&gt;大まかな処理の流れは以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;順序&lt;/th&gt;
&lt;th&gt;段階&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;知覚（Perception）&lt;/td&gt;
&lt;td&gt;カメラ・マイクから、顔・身体・声を個別に検出する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;人物統合（Person Fusion）&lt;/td&gt;
&lt;td&gt;検出された顔・身体・声を、hri_person_managerが1人の人物として統合する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;インタラクションスキル（Interaction Skills）&lt;/td&gt;
&lt;td&gt;統合された人物の情報を使って、発話・注視・ナビゲーション・動作・把持といった、標準化された「スキル」をロボットに実行させる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;UI・可視化（UI &amp;amp; Visualization）&lt;/td&gt;
&lt;td&gt;開発中のデバッグや、ロボットの対話用インターフェースの構築に使う&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="パッケージのカテゴリ一覧"&gt;パッケージのカテゴリ一覧&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;公式サイトでは、パッケージは大きく5つのカテゴリに分けられている&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;コアライブラリ・メッセージ&lt;/td&gt;
&lt;td&gt;hri_msgsなど、全体の基盤となるメッセージ定義・ライブラリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚（Perception）&lt;/td&gt;
&lt;td&gt;顔・身体・音声の検出と、それらを人物に統合する機能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インタラクションスキル&lt;/td&gt;
&lt;td&gt;発話・ナビゲーション・操作など、ロボットに実行させる標準化された動作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可視化・デバッグ&lt;/td&gt;
&lt;td&gt;開発時の確認・デバッグ用のツール&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI構築&lt;/td&gt;
&lt;td&gt;対話的なユーザーインターフェースを作るための部品&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;下の表では、「知覚」と「インタラクションスキル」をさらに細かいサブカテゴリ（知覚（顔）・知覚（身体）など）に分けて示している&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="カテゴリ別パッケージ一覧"&gt;カテゴリ別パッケージ一覧&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリ&lt;/th&gt;
&lt;th&gt;パッケージ&lt;/th&gt;
&lt;th&gt;役割&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;コアライブラリ・メッセージ&lt;/td&gt;
&lt;td&gt;hri_msgs&lt;/td&gt;
&lt;td&gt;顔・身体・声・人物に関する標準メッセージ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コアライブラリ・メッセージ&lt;/td&gt;
&lt;td&gt;hri_actions_msgs&lt;/td&gt;
&lt;td&gt;HRIのIntent（意図）に関する標準アクション&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コアライブラリ・メッセージ&lt;/td&gt;
&lt;td&gt;human_description&lt;/td&gt;
&lt;td&gt;人体の標準URDFモデル&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コアライブラリ・メッセージ&lt;/td&gt;
&lt;td&gt;libhri（C++）／pyhri（Python）&lt;/td&gt;
&lt;td&gt;ROS4HRIトピックを簡単に扱うためのライブラリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚（顔）&lt;/td&gt;
&lt;td&gt;hri_face_detect&lt;/td&gt;
&lt;td&gt;顔検出・ランドマーク・視線&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚（顔）&lt;/td&gt;
&lt;td&gt;hri_emotion_recognizer&lt;/td&gt;
&lt;td&gt;表情認識&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚（顔）&lt;/td&gt;
&lt;td&gt;hri_face_identification&lt;/td&gt;
&lt;td&gt;顔の識別・認識&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚（身体）&lt;/td&gt;
&lt;td&gt;hri_body_detect&lt;/td&gt;
&lt;td&gt;身体に関する知覚機能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚（音声）&lt;/td&gt;
&lt;td&gt;asr_vosk&lt;/td&gt;
&lt;td&gt;音声特徴の抽出・発話区間検出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人物追跡・統合&lt;/td&gt;
&lt;td&gt;hri_face_body_matcher&lt;/td&gt;
&lt;td&gt;顔と身体のマッチング&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人物追跡・統合&lt;/td&gt;
&lt;td&gt;hri_person_manager&lt;/td&gt;
&lt;td&gt;人物への統合（Mr. Potato algorithm）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人物追跡・統合&lt;/td&gt;
&lt;td&gt;hri_engagement&lt;/td&gt;
&lt;td&gt;エンゲージメント（関わりの度合い）の追跡&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インタラクションスキル&lt;/td&gt;
&lt;td&gt;Communication&lt;/td&gt;
&lt;td&gt;発話・対話（Say、Chat、Ask）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インタラクションスキル&lt;/td&gt;
&lt;td&gt;Interaction&lt;/td&gt;
&lt;td&gt;社会的インタラクション（LookAt、LookFor、LED、Expressions）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インタラクションスキル&lt;/td&gt;
&lt;td&gt;Navigation&lt;/td&gt;
&lt;td&gt;ナビゲーション（Navigate、Waypoints、Zones）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インタラクションスキル&lt;/td&gt;
&lt;td&gt;Motions&lt;/td&gt;
&lt;td&gt;動作実行（関節・直交座標系の軌道）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インタラクションスキル&lt;/td&gt;
&lt;td&gt;Manipulation&lt;/td&gt;
&lt;td&gt;操作（Grasp、Place、ハンド制御）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;開発ツール&lt;/td&gt;
&lt;td&gt;rpk&lt;/td&gt;
&lt;td&gt;スキル・タスク・アプリケーションのパッケージ生成器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;開発ツール&lt;/td&gt;
&lt;td&gt;architecture_schemas / architecture_tools / std_skills&lt;/td&gt;
&lt;td&gt;スキル定義のJSONスキーマ・検証・標準メッセージ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可視化・デバッグ&lt;/td&gt;
&lt;td&gt;hri_rviz&lt;/td&gt;
&lt;td&gt;RVizでの3Dスケルトン等の可視化プラグイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可視化・デバッグ&lt;/td&gt;
&lt;td&gt;hri_visualization&lt;/td&gt;
&lt;td&gt;カメラ画像への顔・身体・表情のオーバーレイ表示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可視化・デバッグ&lt;/td&gt;
&lt;td&gt;rqt_human_radar / rqt_chat&lt;/td&gt;
&lt;td&gt;人物のレーダー表示／対話デバッグ用チャットUI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可視化・デバッグ&lt;/td&gt;
&lt;td&gt;interaction_sim&lt;/td&gt;
&lt;td&gt;HRI研究用のROS 2シミュレーション環境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI構築&lt;/td&gt;
&lt;td&gt;ui_server / ui_msgs / ros-qml-plugin&lt;/td&gt;
&lt;td&gt;QMLを使った対話的UIの表示・ROS連携&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="対応ロボット"&gt;対応ロボット&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;区分&lt;/th&gt;
&lt;th&gt;ロボット&lt;/th&gt;
&lt;th&gt;特徴&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;商用&lt;/td&gt;
&lt;td&gt;PAL TIAGo&lt;/td&gt;
&lt;td&gt;7自由度アーム＋昇降トルソーを持つ、研究向けモバイルマニピュレータ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;商用&lt;/td&gt;
&lt;td&gt;PAL TIAGo Pro&lt;/td&gt;
&lt;td&gt;両腕7自由度、画面・LEDなどの対話機能を強化した上位版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;商用&lt;/td&gt;
&lt;td&gt;PAL TIAGo Pro Head&lt;/td&gt;
&lt;td&gt;表情豊かな頭部のみの単体版。社会的信号・視線研究向け&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;商用&lt;/td&gt;
&lt;td&gt;PAL ARI&lt;/td&gt;
&lt;td&gt;受付・案内・エンターテインメント向けの、表情豊かな顔とジェスチャーを持つ社会的ロボット&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSS・研究用&lt;/td&gt;
&lt;td&gt;EMOROBCARE&lt;/td&gt;
&lt;td&gt;ICMAT/IIIA（CSIC）が開発する、自閉症療育向けの低コストな社会的ロボット（球状の台座＋3自由度の頭部）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;開発元のPAL Robotics社自身が、TIAGo・ARIといった商用ロボットシリーズを展開しており、ROS4HRIはこれらのロボットの人間認識基盤としても使われている&lt;/li&gt;
&lt;li&gt;EUのHorizon Europe研究助成を受けて開発されている&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="メッセージ定義-hri_msgs"&gt;メッセージ定義: hri_msgs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS4HRIでは、人間の認識結果を表現するための専用メッセージ型が定義されている。実際にリポジトリをクローンして、&lt;code&gt;msg/&lt;/code&gt;以下の17種類のファイルを確認した&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="カテゴリ一覧"&gt;カテゴリ一覧&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;17種類のメッセージは、内容に応じて5つのカテゴリに分けられる&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリ&lt;/th&gt;
&lt;th&gt;対象&lt;/th&gt;
&lt;th&gt;含まれるメッセージ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;顔・表情&lt;/td&gt;
&lt;td&gt;顔から読み取れる情報&lt;/td&gt;
&lt;td&gt;Expression、FacialActionUnits、FacialLandmarks、Gaze&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;身体&lt;/td&gt;
&lt;td&gt;身体から読み取れる情報&lt;/td&gt;
&lt;td&gt;Skeleton2D、Gesture、BodyPosture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;属性・音声&lt;/td&gt;
&lt;td&gt;年齢・性別や、音声から読み取れる情報&lt;/td&gt;
&lt;td&gt;SoftBiometrics、AudioFeatures、LiveSpeech&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;集団・ID管理・関係性&lt;/td&gt;
&lt;td&gt;複数の人物・特徴の間の関係&lt;/td&gt;
&lt;td&gt;Group、IdsList、IdsMatch、EngagementLevel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;幾何的なプリミティブ型&lt;/td&gt;
&lt;td&gt;他のメッセージから使われる座標の基礎型&lt;/td&gt;
&lt;td&gt;NormalizedPointOfInterest2D、NormalizedPointOfInterest2DStamped、NormalizedRegionOfInterest2D&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="顔表情に関するメッセージ"&gt;顔・表情に関するメッセージ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;メッセージ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Expression&lt;/td&gt;
&lt;td&gt;表情を、カテゴリ（neutral、angry、happyなど25種類、Chambers 2020年MSc論文・Ekmanの基本6感情モデルに基づく）と、Valence/Arousalモデル（感情のpositive/negative度を表すvalence、興奮度を表すarousal、それぞれ-1.0〜+1.0）の両方で表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FacialActionUnits&lt;/td&gt;
&lt;td&gt;Ekmanが開発したFACS（Facial Action Coding System）の命名に従い、99種類のAU（Action Unit、表情を作る顔の部位ごとの動き）それぞれの強度と確信度を配列で表す。頭の向き・視線の向き・顔の可視性なども含む&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FacialLandmarks&lt;/td&gt;
&lt;td&gt;dlib・OpenPoseの規約に従った70点の顔のランドマーク（輪郭・眉・目・鼻・口など）を、正規化された2D座標の配列として表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gaze&lt;/td&gt;
&lt;td&gt;視線の送り手（sender）と受け手（receiver）の人物IDを表す。空文字列はロボット自身を意味する&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/facs2.jpg"
width="966"
height="483"
srcset="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/facs2_hu_f4bd2933d5d3b9b4.jpg 480w, https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/facs2_hu_706c7be41836cd4f.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="200"
data-flex-basis="480px"
&gt;
&lt;img src="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/FACS.jpg"
width="2223"
height="4000"
srcset="https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/FACS_hu_1e718d7aef739844.jpg 480w, https://www.m1ke.org/p/ros4hri%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/FACS_hu_3b1924587118d1f9.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="55"
data-flex-basis="133px"
&gt;&lt;/p&gt;
&lt;h3 id="身体に関するメッセージ"&gt;身体に関するメッセージ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;メッセージ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Skeleton2D&lt;/td&gt;
&lt;td&gt;OpenPoseのCOCOモデルの規約に従い、鼻・両肩・両肘・両手首・両腰・両膝・両足首・両目・両耳という18点の骨格キーポイントを、正規化された2D座標の配列として表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gesture&lt;/td&gt;
&lt;td&gt;手を顔に当てる・腕を組む・手を挙げる・手を振るといった、身体から検出されるジェスチャーを表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BodyPosture&lt;/td&gt;
&lt;td&gt;立っている・座っている・しゃがんでいる・寝ているという、身体の姿勢を記号的に表す&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="属性音声に関するメッセージ"&gt;属性・音声に関するメッセージ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;メッセージ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SoftBiometrics&lt;/td&gt;
&lt;td&gt;推定した年齢・性別を、それぞれの確信度（confidence）付きで表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AudioFeatures&lt;/td&gt;
&lt;td&gt;INTERSPEECH 2009 Emotion Challengeで選定された16種類の音声特徴（ゼロ交差率、RMSフレームエネルギー、ピッチ、調波対雑音比、MFCC1〜12）を、openSMILEツールキットで抽出した値として表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveSpeech&lt;/td&gt;
&lt;td&gt;音声認識の途中結果（incremental）と最終結果（final）、その確信度、ISO 639-1の言語コード＋ISO 3166-1の地域コードによるlocale（例: en_GB）を表す&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="集団id管理関係性に関するメッセージ"&gt;集団・ID管理・関係性に関するメッセージ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;メッセージ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Group&lt;/td&gt;
&lt;td&gt;グループIDと、そのグループに属する人物IDのリストを表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IdsList&lt;/td&gt;
&lt;td&gt;顔ID・身体ID・人物IDなど、ROS4HRIのIDのリストを表す汎用的なメッセージ。例えば&lt;code&gt;/humans/faces/tracked&lt;/code&gt;で、現在検出されている顔のIDの一覧が配信される&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IdsMatch&lt;/td&gt;
&lt;td&gt;一時的なID（顔・身体・声）と永続的なID（人物）の対応候補を、確信度付きで表す。確信度0.0は「この2つは対応しない」という意味を持つ特別な値。&lt;code&gt;/humans/candidate_matches&lt;/code&gt;に配信され、Mr. Potato algorithmの入力になる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EngagementLevel&lt;/td&gt;
&lt;td&gt;人間がロボットにどれだけ関わっているかを、unknown・disengaged・engaging・engaged・disengagingという5段階の離散値で表す。&lt;code&gt;/humans/persons/&amp;lt;person_id&amp;gt;/engagement_status&lt;/code&gt;で配信される&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="幾何的なプリミティブ型"&gt;幾何的なプリミティブ型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Skeleton2DやFacialLandmarksなど、複数のメッセージから共通して使われる、座標を表すための基礎的な型も定義されている&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;型&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NormalizedPointOfInterest2D&lt;/td&gt;
&lt;td&gt;正規化された（0.0〜1.0の範囲の）点の座標（x, y）と、その点の確信度（c）を表す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NormalizedPointOfInterest2DStamped&lt;/td&gt;
&lt;td&gt;NormalizedPointOfInterest2Dにタイムスタンプ付きヘッダを加えたもの&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NormalizedRegionOfInterest2D&lt;/td&gt;
&lt;td&gt;正規化された矩形領域を、左上（xmin, ymin）と右下（xmax, ymax）の座標と確信度（c）で表す&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="hri_actions_msgs-アクション意図の定義"&gt;hri_actions_msgs: アクション・意図の定義&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;hri_msgsが「知覚（Perception）」側のメッセージを扱うのに対し、hri_actions_msgsは「アクション（Action）」側、つまりロボットに何をさせるか・人間が何を意図しているかを表すメッセージを扱う&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="intent-意図の表現"&gt;Intent: 意図の表現&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Androidのintentに着想を得た、ロボットに実行させたい操作を抽象的に表すメッセージ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;intent&lt;/code&gt;（どの操作か）と、&lt;code&gt;data&lt;/code&gt;（JSON形式のパラメータ）という2つの必須フィールドを持つ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data&lt;/code&gt;の中身は、動作主（agent）・対象（object）・目的地（goal）・受け手（recipient）という、言語学の主題役割（thematic role）に基づくキーで指定する&lt;/li&gt;
&lt;li&gt;例えば「キッチンにいるLukeに食材を持っていって」は、&lt;code&gt;intent: BRING_OBJECT&lt;/code&gt;、&lt;code&gt;data: {&amp;quot;object&amp;quot;: &amp;quot;groceries&amp;quot;, &amp;quot;goal&amp;quot;: &amp;quot;kitchen_1&amp;quot;, &amp;quot;recipient&amp;quot;: &amp;quot;person_luke&amp;quot;}&lt;/code&gt;のように表現される&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;定義済みIntent&lt;/th&gt;
&lt;th&gt;意味&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAW_USER_INPUT&lt;/td&gt;
&lt;td&gt;意図の抽出に失敗した場合のフォールバック&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ENGAGE_WITH&lt;/td&gt;
&lt;td&gt;相手と関わりたい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MOVE_TO&lt;/td&gt;
&lt;td&gt;指定した場所に移動する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GUIDE&lt;/td&gt;
&lt;td&gt;誰かをどこかへ案内する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GRAB_OBJECT / BRING_OBJECT / PLACE_OBJECT&lt;/td&gt;
&lt;td&gt;物を取る／持っていく／置く&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GREET&lt;/td&gt;
&lt;td&gt;挨拶する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SAY&lt;/td&gt;
&lt;td&gt;指定したテキストを話す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PRESENT_CONTENT&lt;/td&gt;
&lt;td&gt;画面などで決められたコンテンツを提示する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PERFORM_MOTION&lt;/td&gt;
&lt;td&gt;ダンスや手を振るなどの動作を実行する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;START_ACTIVITY / STOP_ACTIVITY&lt;/td&gt;
&lt;td&gt;スクリプト化された振る舞いの開始・停止&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAKEUP / SUSPEND&lt;/td&gt;
&lt;td&gt;システムの再起動・休止&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;Intentには、他にも&lt;code&gt;source&lt;/code&gt;（ロボット自身・リモート監督者・不明な相手のどれが発した意図か。REP-155準拠の場合は人物IDも使える）、&lt;code&gt;modality&lt;/code&gt;（発話・動作・タッチスクリーン・内部処理のどれで伝えられたか）、&lt;code&gt;priority&lt;/code&gt;（0〜255）、&lt;code&gt;confidence&lt;/code&gt;（0.0〜1.0）といったフィールドがある&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="その他のメッセージ"&gt;その他のメッセージ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;メッセージ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ActivityList&lt;/td&gt;
&lt;td&gt;START_ACTIVITY／STOP_ACTIVITY Intentで起動できる、アクティビティ名の一覧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ClosedCaption&lt;/td&gt;
&lt;td&gt;発話者ID・テキスト・localeを持つ、字幕（クローズドキャプション）表示用のメッセージ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LookAtWithStyle&lt;/td&gt;
&lt;td&gt;注視対象の3D座標に加え、目だけ／頭だけ／両方（デフォルト）という、視線の動かし方のスタイルを指定する&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="アクション定義"&gt;アクション定義&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS 2のAction（Goal・Result・Feedbackからなる、時間のかかる処理向けの通信方式）として、以下のようなものが定義されている&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;アクション&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LookAt&lt;/td&gt;
&lt;td&gt;指定した3D座標を注視する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ApplicationControl&lt;/td&gt;
&lt;td&gt;下位のアプリケーションコントローラーにJSON形式のパラメータを渡す&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SelfPresentation&lt;/td&gt;
&lt;td&gt;自己紹介などの、複数のフレーズからなる発話を実行し、進行状況（現在のフレーズ数／総フレーズ数）をフィードバックする&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FaceOverlay&lt;/td&gt;
&lt;td&gt;顔のディスプレイに画像・アニメーションを重ねて表示する。表示時間・レイヤー（背景／前景）・レイアウト（両目に表示／左右の目ごとなど）・スケール・位置・フェード効果を指定できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PointTrajectory&lt;/td&gt;
&lt;td&gt;複数の3D座標点と、それぞれに到達する時刻を指定し、軌道を描かせる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="hri_person_manager-顔身体声を1人の人物に統合する"&gt;hri_person_manager: 顔・身体・声を1人の人物に統合する&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;カメラ・マイクなど複数のセンサーから得られる顔・身体・声の検出結果は、それぞれ別々に検出されるが、それらが同じ1人の人物のものだと紐付けなければ、ロボットは人間を1人の人物として認識できない&lt;/li&gt;
&lt;li&gt;hri_person_managerは、検出された顔・身体・声を集約し、一貫した「人物（person）」として扱い、それぞれの検出結果への紐付けを外部に公開するノード&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mr-potato-algorithm"&gt;Mr. Potato algorithm&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;他のノード（顔認識ノードなど）が&lt;code&gt;/humans/candidate_matches&lt;/code&gt;に投稿する、IdsMatchメッセージ（特徴同士・特徴と人物の対応候補、確信度付き）を受け取り、確率的なグラフ（person features graph）を構築する&lt;/li&gt;
&lt;li&gt;アルゴリズムは、クローンしたリポジトリの&lt;code&gt;doc/ALGORITHM.md&lt;/code&gt;に、以下のような形式的な定義がある
&lt;ul&gt;
&lt;li&gt;特徴（feature）: 顔・身体・声のいずれか&lt;/li&gt;
&lt;li&gt;許容されるパス（permissible path）: 同じ種類のノードを2つ以上含まない経路。尤度はパス上の尤度の積&lt;/li&gt;
&lt;li&gt;関連（association）: 閾値（デフォルト0.5）を超える尤度の許容パスで結ばれた、ノードの連結集合&lt;/li&gt;
&lt;li&gt;要件として、(1) 全ての関連の尤度の合計を最大化する、(2) 全ての特徴は必ず1人の人物（匿名も含む）に紐付く、(3) 人物に紐付かない特徴は匿名の人物に紐付ける、(4) 間接的なパスが切れた場合も、尤度が閾値を超えていれば直接的な関連として安定的に維持する、という4点が定義されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;この手法は、&amp;ldquo;Probabilistic fusion of persons&amp;rsquo; body features: the Mr. Potato algorithm&amp;quot;という論文として発表されている（DOI: 10.1145/3610977.3637479）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="パラメータ"&gt;パラメータ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パラメータ&lt;/th&gt;
&lt;th&gt;デフォルト値&lt;/th&gt;
&lt;th&gt;意味&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;match_threshold&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;顔・身体・声を同じ人物とみなす最小尤度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reference_frame&lt;/td&gt;
&lt;td&gt;map&lt;/td&gt;
&lt;td&gt;人物のTFフレームを配信する基準フレーム。固定された基準フレームを使うことで、人物が一度カメラの視界から外れても、最後に見えた位置に留まり続ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;personal_distance&lt;/td&gt;
&lt;td&gt;1.2m&lt;/td&gt;
&lt;td&gt;近接学（proxemics）に基づく、個人距離圏の上限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;social_distance&lt;/td&gt;
&lt;td&gt;3.6m&lt;/td&gt;
&lt;td&gt;社会距離圏の上限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;public_distance&lt;/td&gt;
&lt;td&gt;20m&lt;/td&gt;
&lt;td&gt;公共距離圏の上限&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="主なトピック"&gt;主なトピック&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;トピック&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/humans/candidate_matches&lt;/td&gt;
&lt;td&gt;他ノードから受け取る、特徴同士・特徴と人物の対応候補&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/humans/persons/known・/humans/persons/tracked&lt;/td&gt;
&lt;td&gt;人物の一覧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/humans/persons/in_{personal|social|public}_space&lt;/td&gt;
&lt;td&gt;各近接圏にいる人物の一覧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/humans/persons/&amp;lt;person_id&amp;gt;/proxemic_space&lt;/td&gt;
&lt;td&gt;個々の人物の近接圏&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/humans/graph&lt;/td&gt;
&lt;td&gt;特徴同士の対応関係をDOT形式で可視化したもの&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="hri_engagement-視線と距離からエンゲージメントを検出する"&gt;hri_engagement: 視線と距離からエンゲージメントを検出する&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;実際にリポジトリをクローンして確認したところ、&lt;code&gt;hri_engagement&lt;/code&gt;は、Webb, Giuliani, Lemaignan (2022) &amp;ldquo;Measuring Visual Social Engagement from Proxemics and Gaze&amp;rdquo;（RO-MAN 2022、DOI: 10.1109/RO-MAN53752.2022.9900801）で定義された「visual social engagement」指標を使って、人物ごとのエンゲージメント状態を検出するノード&lt;/li&gt;
&lt;li&gt;この指標は、ロボットと人物の距離と、相互注視（お互いがお互いを見ているか）の度合いを組み合わせたもの。カメラに映っている人物ごとに、この指標を一定時間窓で時間方向にフィルタリングし、結果を&lt;code&gt;EngagementLevel&lt;/code&gt;として&lt;code&gt;/humans/persons/&amp;lt;person_id&amp;gt;/engagement_status&lt;/code&gt;に配信する&lt;/li&gt;
&lt;li&gt;動作には、&lt;code&gt;hri_face_detect&lt;/code&gt;・&lt;code&gt;hri_face_identification&lt;/code&gt;・&lt;code&gt;hri_person_manager&lt;/code&gt;が事前に起動している必要がある。&lt;code&gt;/humans/persons/tracked&lt;/code&gt;と&lt;code&gt;/humans/persons/&amp;lt;person_id&amp;gt;/face_id&lt;/code&gt;をsubscribeし、エンゲージメント状態に加えて、人物が「関わっている」と判定されると&lt;code&gt;hri_actions_msgs/Intent&lt;/code&gt;の&lt;code&gt;ENGAGE_WITH&lt;/code&gt;を&lt;code&gt;/intents&lt;/code&gt;にpublishする&lt;/li&gt;
&lt;li&gt;主なパラメータは以下の通り（&lt;code&gt;config/00-default.yaml&lt;/code&gt;で確認）&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パラメータ&lt;/th&gt;
&lt;th&gt;デフォルト値&lt;/th&gt;
&lt;th&gt;意味&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;reference_frame&lt;/td&gt;
&lt;td&gt;sellion_link&lt;/td&gt;
&lt;td&gt;距離・相互注視を計算する基準となる、ロボット側の視線方向フレーム&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_distance&lt;/td&gt;
&lt;td&gt;4.0m&lt;/td&gt;
&lt;td&gt;これより遠い人物は自動的にDISENGAGEDとみなされる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;field_of_view&lt;/td&gt;
&lt;td&gt;60度&lt;/td&gt;
&lt;td&gt;人物・ロボット双方の「注意」の半画角。相手がこの範囲外なら見ていないとみなされる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;engagement_threshold&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;ENGAGING/DISENGAGINGと判定する閾値&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;observation_window&lt;/td&gt;
&lt;td&gt;10秒&lt;/td&gt;
&lt;td&gt;エンゲージメントレベルを計算する時間窓。大きいほど判定が安定する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rate&lt;/td&gt;
&lt;td&gt;10Hz&lt;/td&gt;
&lt;td&gt;エンゲージメントレベルを計算・配信する周期&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;後述するIROS22のチュートリアルで自作する、相互視線の指標$M_{RP}$・$S_{RP}$は、次に見るWebb, Giuliani, Lemaignan (2022)論文で提案されている指標と、構造的にほぼ同じもの&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="webb-giuliani-lemaignan-2022論文を読む"&gt;Webb, Giuliani, Lemaignan (2022)論文を読む&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenAlex経由で、UWE Bristolのリポジトリに置かれたオープンアクセス版の要旨を確認した（IEEE Xplore本体・UWEリポジトリのPDFは、どちらもアクセスがブロックされ直接は読めなかった）&lt;/li&gt;
&lt;li&gt;この論文は、集団に近づいていく際に人がやり取りする、言葉・非言語の社会的シグナルに着目し、オンラインで88人の参加者を集めたデータ収集実験を行っている。参加者には、ソーシャルなやり取りを伴うゲームをオンラインでプレイしてもらい、その際の行動データを収集した&lt;/li&gt;
&lt;li&gt;中心的な貢献は、proxemics（参加者間の距離）と相互注視（mutual gaze）という2つの社会的シグナルから導かれる、新しい視覚的エンゲージメント指標の提案&lt;/li&gt;
&lt;li&gt;要旨によれば、相互注視の指標は「両者それぞれの光軸からの距離の積を、参加者間の距離で割ったもの」という数式で定式化されている。これは、&lt;code&gt;hri_engagement&lt;/code&gt;のパラメータにあった&lt;code&gt;field_of_view&lt;/code&gt;（光軸からの許容角度）や&lt;code&gt;max_distance&lt;/code&gt;（距離の上限）の設計とも整合する&lt;/li&gt;
&lt;li&gt;この指標を使って、参加者ごとに固有の「インタラクションスタイル」のプロファイルを作れることを示している。一方で、性格特性（パーソナリティ）とこのインタラクションパターンとの間には、明確な相関は見られなかったと報告されている&lt;/li&gt;
&lt;li&gt;つまり、IROS22のチュートリアルで扱った$M_{RP}$（光軸からの距離の積）・$S_{RP}$（それを参加者間の距離で正規化したもの）という式は、学習用に簡略化されたものではなく、この論文で提案された指標そのものの構造を踏襲したものだったと分かる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="libhri-人間の認識結果への簡単なアクセス"&gt;libhri: 人間の認識結果への簡単なアクセス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS4HRIの各トピックを生のまま扱う代わりに、&lt;code&gt;HRIListener&lt;/code&gt;というクラスを通じて、検出された人間・顔・身体をオブジェクトとして扱える、簡易的なAPIを提供する&lt;/li&gt;
&lt;li&gt;C++実装の&lt;code&gt;hri&lt;/code&gt;パッケージと、それをPybind11でラップしたPython版の&lt;code&gt;pyhri&lt;/code&gt;パッケージがある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="チュートリアル"&gt;チュートリアル&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS4HRIには、公式サイトの新しいチュートリアルと、IROS22で行われた（ROS 1 Noetic時代の）より古いチュートリアルの、2種類がある&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新しいチュートリアル-llm対応インタラクティブアプリの構築"&gt;新しいチュートリアル: LLM対応インタラクティブアプリの構築&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;公式サイトには「ROS4HRIの知覚・スキルを使って、LLM対応のインタラクティブアプリを構築する」という、実践的なチュートリアルが用意されている&lt;/li&gt;
&lt;li&gt;使われているツール・ノードは以下の通り&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;層&lt;/th&gt;
&lt;th&gt;ツール・ノード&lt;/th&gt;
&lt;th&gt;役割&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;知覚&lt;/td&gt;
&lt;td&gt;gscam&lt;/td&gt;
&lt;td&gt;Webカメラの映像を配信&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚&lt;/td&gt;
&lt;td&gt;hri_face_detect&lt;/td&gt;
&lt;td&gt;顔検出（確信度の閾値付き）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知覚&lt;/td&gt;
&lt;td&gt;hri_emotion_recognizer&lt;/td&gt;
&lt;td&gt;検出した顔からの表情分類&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知識・推論&lt;/td&gt;
&lt;td&gt;knowledge_core&lt;/td&gt;
&lt;td&gt;OWL/RDFベースの記号的な知識ベース（Webビューア付き）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知識・推論&lt;/td&gt;
&lt;td&gt;hri_person_manager&lt;/td&gt;
&lt;td&gt;顔・身体・声を1人の人物に統合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;対話&lt;/td&gt;
&lt;td&gt;dialogue_manager&lt;/td&gt;
&lt;td&gt;発話の入出力管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;対話&lt;/td&gt;
&lt;td&gt;ollama&lt;/td&gt;
&lt;td&gt;ローカルLLM推論（カスタムのチャットボットが利用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;対話&lt;/td&gt;
&lt;td&gt;rqt_chat&lt;/td&gt;
&lt;td&gt;テキストでの対話確認用プラグイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可視化&lt;/td&gt;
&lt;td&gt;rqt_human_radar&lt;/td&gt;
&lt;td&gt;検出した人物・空間的な関係のレーダー表示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;制御・表出&lt;/td&gt;
&lt;td&gt;interaction_sim&lt;/td&gt;
&lt;td&gt;2Dのソーシャルインタラクション・シミュレーター&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;このチュートリアルで出てくるGUIは、ロボット・人間のアバターをSVGで描いた2Dの見下ろし型シミュレーター（&lt;code&gt;interaction_sim&lt;/code&gt;）と、procedural（手続き的）に生成された目だけの表情豊かなロボットの顔の2種類がある。アニメ風に見えたのは、おそらくこのどちらか&lt;/li&gt;
&lt;li&gt;手順は、Part 0（Docker環境構築）→Part 1（顔検出の動作確認）→Part 2（シミュレーターと知識ベースの導入）→Part 3（&lt;code&gt;rpk&lt;/code&gt;でミッションコントローラーを生成し、&lt;code&gt;/skill/say&lt;/code&gt;での発話や、検出した表情をロボットの表情にそのまま反映する「感情ミラーリング」を実装）→Part 4（ollamaでのLLM統合、意図抽出のプロンプト設計、知識ベースを使ったコンテキスト付与）という流れで進む&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="古いチュートリアル-iros22のros4hri完全ウォークスルー"&gt;古いチュートリアル: IROS22のROS4HRI完全ウォークスルー&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS 1 Noetic時代に、IROS22で実施された、1日がかりの完全なチュートリアル&lt;/li&gt;
&lt;li&gt;題材として「OfficeBots」という、HRI研究用のマルチプレイヤーゲーム型シミュレーターを使っている。キャラクターを選んでプレイする、ゲームらしい見た目のGUIを持つ&lt;/li&gt;
&lt;li&gt;3部構成になっている&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パート&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Part 1&lt;/td&gt;
&lt;td&gt;OfficeBotsを使い、ROS4HRIのAPIに触れながら、視線の合致度（mutual gaze）を使ったエンゲージメント推定器を自作する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Part 2&lt;/td&gt;
&lt;td&gt;Webカメラの実データを使い、顔検出（hri_face_detect）・骨格検出（hri_fullbody）・ジェスチャー認識（waving検出）を実装する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Part 3&lt;/td&gt;
&lt;td&gt;Rasaで作ったチャットボットと、音声認識結果（LiveSpeech）を統合した、マルチモーダルなチャットボットを完成させる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;Part 1のエンゲージメント推定は、ロボットと人物が互いを見ている度合いを表す相互視線の指標$M_{RP}$（ロボットの視野内での人物の位置と、人物の視野内でのロボットの位置、それぞれの光軸からの距離の積）と、それを距離で正規化した社会的エンゲージメントの指標$S_{RP}=\min(1, M_{RP}/\text{dist}(R,P))$を使う&lt;/li&gt;
&lt;li&gt;Part 2のhri_face_detect・hri_fullbody（2D/3D骨格検出）はどちらもGoogleのMediaPipeを使っている。骨格検出の結果はrobot_state_publisherとhuman_descriptionパッケージのURDFを使って、3Dの関節状態・TFツリーとして公開される&lt;/li&gt;
&lt;li&gt;waving（手を振る）ジェスチャーの検出は、肩・肘・手首の間の距離（肩肘間・肘手首間・肩手首間）が、それぞれ特定の範囲（0.1〜0.25、0.1〜0.25、0.15〜0.25）に収まるかどうかで判定する、シンプルな閾値ベースの手法&lt;/li&gt;
&lt;li&gt;Part 3では、音声認識結果を&lt;code&gt;/humans/voices/&amp;lt;id&amp;gt;/speech&lt;/code&gt;からRasaのチャットボットサーバーに送り、その応答を&lt;code&gt;/say&lt;/code&gt;トピック（ROS4HRI標準ではない、OfficeBots独自のトピック）でロボットに発話させる&lt;/li&gt;
&lt;li&gt;顔と人物の対応付けも、&lt;code&gt;rostopic pub /humans/candidate_matches hri_msgs/IdsMatch&lt;/code&gt;のように、手動でIdsMatchメッセージを配信することで体験できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="今後の展望-生理指標への拡張sense4hri"&gt;今後の展望: 生理指標への拡張（Sense4HRI）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Scheibl, Leichert, Görmez, Wrede (2026, Bielefeld University) &amp;ldquo;Sense4HRI: A ROS 2 HRI Framework for Physiological Sensor Integration and Synchronized Logging&amp;rdquo;（arXiv:2603.19914）は、ROS4HRIを生理指標（EEG・ECG・PPGなど）の統合に拡張する論文&lt;/li&gt;
&lt;li&gt;生理信号はHRIにおけるユーザーの心理状態の推定に重要性が増しているが、ROS 2ベースのHRIフレームワークには、こうしたデータストリームを標準化された形で統合する再利用可能な仕組みがまだ無いという問題意識から提案されている&lt;/li&gt;
&lt;li&gt;センサードライバと解釈ロジックを分離し、&lt;code&gt;PhysioRaw.msg&lt;/code&gt;という汎用的なメッセージ形式、ROS4HRIの命名規則に準拠した階層的なトピック名、複数センサーを同期させるためのデバイス側タイムスタンプなどを導入している&lt;/li&gt;
&lt;li&gt;Polar社のECG・PPGセンサーと表情認識を統合したプロトタイプで、複数モダリティを組み合わせた感情状態の推定を実証している&lt;/li&gt;
&lt;li&gt;ROS4HRI自体はこれまで顔・身体・声・表情といった外部から観測できる情報を中心にしていたが、Sense4HRIのような拡張によって、生理指標という内部状態の推定も同じ命名規則・名前空間の中に統合していく方向性が今後見込まれる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS4HRI（REP-155）は、ROS上で人間を認識・表現するための標準的なメッセージ型・規約を定めた、OSSのフレームワーク&lt;/li&gt;
&lt;li&gt;REP-155は、Person ID（永続）・Face/Body/Voice ID（非永続）という4種類のIDと、&lt;code&gt;/humans/&lt;/code&gt;以下の名前空間、&lt;code&gt;face_&amp;lt;faceID&amp;gt;&lt;/code&gt;などの座標フレームを定義している。汎用的な単一メッセージではなく、サブトピックに分割することでモジュール性を確保している&lt;/li&gt;
&lt;li&gt;全体としては、知覚（顔・身体・声の検出）→人物統合（Mr. Potato algorithm）→インタラクションスキル（発話・注視・ナビゲーション・操作）→UI・可視化という流れを、一貫したパッケージ群として提供するエコシステムになっている&lt;/li&gt;
&lt;li&gt;開発元のPAL Robotics社のTIAGo・ARIといった商用ロボットや、CSICのEMOROBCAREのような研究用ロボットで実際に使われている&lt;/li&gt;
&lt;li&gt;hri_msgsが、表情（カテゴリ＋Valence/Arousal）・FACS準拠のAU・顔のランドマーク・視線・骨格・ジェスチャー・姿勢・年齢性別・音声特徴・音声認識結果・グループ・ID対応候補（IdsMatch）・エンゲージメント・座標のプリミティブ型を含む、全17種類のメッセージ型を定義している&lt;/li&gt;
&lt;li&gt;hri_actions_msgsが、知覚の反対側にあたる「アクション」側として、Androidのintentに着想を得たIntent（主題役割に基づくdata、14種類の定義済みIntent）や、LookAt・FaceOverlay・SelfPresentationといったROS 2 Actionを定義している&lt;/li&gt;
&lt;li&gt;hri_person_managerが、別々に検出される顔・身体・声を、確率的グラフマッチング（Mr. Potato algorithm、尤度の積で計算される許容パスと、要件を満たす最大尤度の分割）によって1人の人物として統合する&lt;/li&gt;
&lt;li&gt;近接学に基づく3つの距離圏（personal/social/public）と、固定された基準フレームによる位置の記憶も、hri_person_managerの機能の一部&lt;/li&gt;
&lt;li&gt;hri_engagementが、ロボットと人物の距離・相互注視を組み合わせたvisual social engagement指標（Webb, Giuliani, Lemaignan 2022、88人参加のオンライン実験で提案）を使い、人物ごとのエンゲージメント状態を検出する。判定にはhri_person_managerが必要で、エンゲージしたと判定するとIntentのENGAGE_WITHを発行する。IROS22チュートリアルの$M_{RP}$・$S_{RP}$も、この論文と同じ構造の指標&lt;/li&gt;
&lt;li&gt;libhriが、これらの情報にオブジェクト指向的にアクセスできる簡易APIを提供する&lt;/li&gt;
&lt;li&gt;公式サイトのLLM対応チュートリアルでは、知覚（顔検出・表情認識）・知識ベース（knowledge_core）・対話（ollamaによるローカルLLM）・シミュレーター（interaction_sim）までを一通り組み合わせた、実践的な構築手順が示されている&lt;/li&gt;
&lt;li&gt;IROS22の古いチュートリアルでは、OfficeBotsというゲーム型シミュレーターを使い、相互視線に基づくエンゲージメント推定・骨格検出によるジェスチャー認識・Rasaチャットボットの統合を、実際にコードを書きながら体験できる&lt;/li&gt;
&lt;li&gt;Sense4HRIのように、ROS4HRIの命名規則・名前空間を踏襲しつつ、生理指標のような新しいモダリティを統合する拡張も登場している&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://ros4hri.github.io/" target="_blank" rel="noopener"
&gt;ROS4HRI 公式サイト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://ros4hri.github.io/tutorials/interactive-social-robots/zero-to-llm.html" target="_blank" rel="noopener"
&gt;Build a complete LLM-enabled interactive app - ROS4HRI Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://wiki.ros.org/hri/Tutorials/ROS4HRI-walk-through" target="_blank" rel="noopener"
&gt;ROS4HRI Complete walk-through - ROS Wiki (IROS22)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.ros.org/reps/rep-0155.html" target="_blank" rel="noopener"
&gt;REP 155 &amp;ndash; Conventions, Topics, Interfaces for Perception in Human-Robot Interaction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Scheibl, M., Leichert, J., Görmez, S., &amp;amp; Wrede, B. (2026). &amp;ldquo;Sense4HRI: A ROS 2 HRI Framework for Physiological Sensor Integration and Synchronized Logging&amp;rdquo; (&lt;a class="link" href="https://arxiv.org/abs/2603.19914" target="_blank" rel="noopener"
&gt;arXiv:2603.19914&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros4hri" target="_blank" rel="noopener"
&gt;ros4hri - GitHub Organization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros4hri/hri_msgs" target="_blank" rel="noopener"
&gt;ros4hri/hri_msgs - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros4hri/hri_actions_msgs" target="_blank" rel="noopener"
&gt;ros4hri/hri_actions_msgs - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros4hri/libhri" target="_blank" rel="noopener"
&gt;ros4hri/libhri - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros4hri/hri_person_manager" target="_blank" rel="noopener"
&gt;ros4hri/hri_person_manager - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Probabilistic fusion of persons&amp;rsquo; body features: the Mr. Potato algorithm&amp;rdquo; (&lt;a class="link" href="https://doi.org/10.1145/3610977.3637479" target="_blank" rel="noopener"
&gt;DOI:10.1145/3610977.3637479&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ros4hri/hri_engagement" target="_blank" rel="noopener"
&gt;ros4hri/hri_engagement - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Webb, N., Giuliani, M., &amp;amp; Lemaignan, S. (2022). &amp;ldquo;Measuring Visual Social Engagement from Proxemics and Gaze&amp;rdquo; (&lt;a class="link" href="https://doi.org/10.1109/RO-MAN53752.2022.9900801" target="_blank" rel="noopener"
&gt;DOI:10.1109/RO-MAN53752.2022.9900801&lt;/a&gt;、&lt;a class="link" href="https://uwe-repository.worktribe.com/output/10106389" target="_blank" rel="noopener"
&gt;オープンアクセス版&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/Facial_Action_Coding_System" target="_blank" rel="noopener"
&gt;Facial Action Coding System - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>ROS2の概念を理解するためのメモ</title><link>https://www.m1ke.org/p/ros2%E3%81%AE%E6%A6%82%E5%BF%B5%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%83%A2/</link><pubDate>Tue, 25 Aug 2026 12:00:00 +0900</pubDate><guid>https://www.m1ke.org/p/ros2%E3%81%AE%E6%A6%82%E5%BF%B5%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%83%A2/</guid><description>&lt;img src="https://www.m1ke.org/p/ros2%E3%81%AE%E6%A6%82%E5%BF%B5%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%83%A2/ros2.png" alt="Featured image of post ROS2の概念を理解するためのメモ" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;業務でROS2を使う必要が出てきた&lt;/li&gt;
&lt;li&gt;しかし、正直あまりROS2を触っていない&lt;/li&gt;
&lt;li&gt;そこで、自分向けにROS2の基本的な考え方と用語をAIで整理したログ&lt;/li&gt;
&lt;li&gt;さくっと全体概念を理解するのが目的&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ros2とは"&gt;ROS2とは&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Robot Operating System 2の略だが、OS（オペレーティングシステム）そのものではない&lt;/li&gt;
&lt;li&gt;ロボット向けのソフトウェアを作るためのミドルウェア兼フレームワーク&lt;/li&gt;
&lt;li&gt;「センサーで取得した値を処理して、モーターに指令を送る」といった、ロボットの各機能をバラバラのプログラム（後述のノード）として作り、それらを通信でつなげて1つのロボットとして動かす、という考え方が中心にある&lt;/li&gt;
&lt;li&gt;前身のROS1に対して、以下のような改善が入っている
&lt;ul&gt;
&lt;li&gt;通信の基盤にDDSという業界標準の仕組みを採用し、単一障害点（後述）をなくした&lt;/li&gt;
&lt;li&gt;リアルタイム性や、Windows・組み込み環境への対応が強化された&lt;/li&gt;
&lt;li&gt;セキュリティ機能が追加された&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ディストリビューションとインストール"&gt;ディストリビューションとインストール&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2は、毎年1回コードネームつきのバージョン（ディストリビューション）がリリースされる&lt;/li&gt;
&lt;li&gt;全てのバージョンがLTS（長期サポート）というわけではなく、偶数年リリースのものがLTS（サポート期間5年）、奇数年リリースのものは短期サポート（サポート期間約1年半）になっている
主なLTS版は以下の通り。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コードネーム&lt;/th&gt;
&lt;th&gt;リリース年&lt;/th&gt;
&lt;th&gt;対応Ubuntu&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Humble Hawksbill&lt;/td&gt;
&lt;td&gt;2022年&lt;/td&gt;
&lt;td&gt;Ubuntu 22.04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jazzy Jalisco&lt;/td&gt;
&lt;td&gt;2024年&lt;/td&gt;
&lt;td&gt;Ubuntu 24.04&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;迷ったら、その時点の最新LTS版を、対応するUbuntuのバージョンに入れるのが基本&lt;/li&gt;
&lt;li&gt;ROS1と違い、ROS2はOSのバージョンとの結びつきが強いため、Ubuntuのバージョンを先に決めてから、対応するROS2のバージョンを選ぶことになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="全体アーキテクチャ"&gt;全体アーキテクチャ&lt;/h2&gt;
&lt;h3 id="ddsdata-distribution-service"&gt;DDS（Data Distribution Service）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2の通信を裏で支えているミドルウェアの規格&lt;/li&gt;
&lt;li&gt;「マスターレス」という特徴があり、ROS1にあった&lt;code&gt;roscore&lt;/code&gt;のような、通信を仲介する中央サーバーが存在しない&lt;/li&gt;
&lt;li&gt;各ノードが自律的にお互いを見つけて（Discoveryと呼ぶ）、直接データをやり取りする&lt;/li&gt;
&lt;li&gt;中央サーバーがないため、その1台が落ちるとシステム全体が止まる、という単一障害点の問題が起きにくい&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ノードnode"&gt;ノード（Node）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2における処理の最小単位&lt;/li&gt;
&lt;li&gt;1つのノードが、1つのプログラム（プロセス）に対応する&lt;/li&gt;
&lt;li&gt;例えば「カメラ画像を取得するノード」「物体検出をするノード」「モーターを制御するノード」のように、機能ごとにノードを分けて作る&lt;/li&gt;
&lt;li&gt;ノード同士は、後述のTopic・Service・Actionという3つの方式で通信する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ノード間の通信"&gt;ノード間の通信&lt;/h2&gt;
&lt;p&gt;ノード同士の通信には、目的に応じて3つの方式がある。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;通信の形&lt;/th&gt;
&lt;th&gt;用途の例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Topic&lt;/td&gt;
&lt;td&gt;非同期のpub/sub&lt;/td&gt;
&lt;td&gt;センサーの値を流し続ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;同期的なリクエスト/レスポンス&lt;/td&gt;
&lt;td&gt;一度だけの問い合わせ・設定変更&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action&lt;/td&gt;
&lt;td&gt;非同期＋進捗報告＋キャンセル可能&lt;/td&gt;
&lt;td&gt;時間のかかる動作（アーム移動など）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="topicトピック"&gt;Topic（トピック）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;特定の名前（トピック名）に対して、データを送り続ける側（Publisher）と、受け取り続ける側（Subscriber）が非同期に繋がる仕組み&lt;/li&gt;
&lt;li&gt;PublisherとSubscriberはお互いの存在を意識しなくてよく、同じトピック名にさえ繋がれば、何対何でも通信できる&lt;/li&gt;
&lt;li&gt;センサーの値のように、継続的に流れてくるデータに向いている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="serviceサービス"&gt;Service（サービス）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;関数呼び出しのように、リクエストを送って、その場でレスポンスを待つ同期的な通信&lt;/li&gt;
&lt;li&gt;「今の設定値を教えて」「このパラメータを変更して」のような、1回のやり取りで完結する処理に向いている&lt;/li&gt;
&lt;li&gt;レスポンスが返るまで基本的に待つことになるので、時間のかかる処理には向かない&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="actionアクション"&gt;Action（アクション）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Serviceに、進捗報告（フィードバック）とキャンセル機能を足したような仕組み&lt;/li&gt;
&lt;li&gt;「アームを目標位置まで動かす」のように、時間がかかり、途中経過を知りたかったり、途中で中断したくなったりする処理に向いている&lt;/li&gt;
&lt;li&gt;内部的にはTopicとServiceの組み合わせで実現されている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="メッセージ型インターフェース"&gt;メッセージ型・インターフェース&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Topic・Service・Actionでやり取りするデータの型（インターフェース）は、それぞれ&lt;code&gt;.msg&lt;/code&gt;・&lt;code&gt;.srv&lt;/code&gt;・&lt;code&gt;.action&lt;/code&gt;という専用のファイル形式で定義される
標準で用意されている型は、目的別のパッケージにまとまっている。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パッケージ&lt;/th&gt;
&lt;th&gt;主な型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;std_msgs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Int32・String・Boolなど、基本的な型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;geometry_msgs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Twist（速度）・Pose（位置・姿勢）など、幾何情報の型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sensor_msgs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Image・LaserScan・PointCloud2など、センサーデータの型&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;標準の型で足りない場合は、自分のパッケージ内に&lt;code&gt;.msg&lt;/code&gt;ファイルなどを作って独自の型を定義できる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 interface show &amp;lt;型名&amp;gt;&lt;/code&gt;で、その型がどんなフィールドを持つか確認できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cmd_vel速度指令"&gt;cmd_vel（速度指令）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ロボットを動かすための速度指令に、事実上の標準として使われているトピック名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;geometry_msgs/Twist&lt;/code&gt;（または&lt;code&gt;TwistStamped&lt;/code&gt;）という、並進速度（linear）と回転速度（angular）を持つメッセージ型を使う&lt;/li&gt;
&lt;li&gt;Nav2の出力や、キーボード操作用のteleopノードなど、様々なノードがこの&lt;code&gt;/cmd_vel&lt;/code&gt;にpublishし、ロボット側のモーター制御ノードがそれをsubscribeして実際に動かす、という流れが一般的&lt;/li&gt;
&lt;li&gt;複数のノードが同時に&lt;code&gt;/cmd_vel&lt;/code&gt;を出そうとすると競合するため、優先順位をつけて1つの指令にまとめる&lt;code&gt;twist_mux&lt;/code&gt;のようなノードがよく使われる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="qosquality-of-service"&gt;QoS（Quality of Service）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DDSが持つ、通信の品質を細かく設定できる仕組み&lt;/li&gt;
&lt;li&gt;ROS1にはなかった、ROS2特有の重要な概念
代表的な設定項目は以下の通り。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;設定項目&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reliability&lt;/td&gt;
&lt;td&gt;通信の信頼性。多少データが欠けてもいいから速さを優先する（Best Effort）か、確実に届ける（Reliable）か&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durability&lt;/td&gt;
&lt;td&gt;新しく繋がったSubscriberに対して、過去のデータも渡すかどうか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;History&lt;/td&gt;
&lt;td&gt;直近何件分のデータを保持しておくか&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;PublisherとSubscriberでQoSの設定が噛み合っていないと、通信自体が繋がらないことがあるため、初心者がハマりやすいポイントの1つ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="開発の基本的な流れ"&gt;開発の基本的な流れ&lt;/h2&gt;
&lt;h3 id="ワークスペース"&gt;ワークスペース&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2のプロジェクト全体を置く作業ディレクトリ&lt;/li&gt;
&lt;li&gt;中に&lt;code&gt;src/&lt;/code&gt;ディレクトリを作り、その下に複数のパッケージ（後述）を置く構成が基本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;colcon build&lt;/code&gt;というビルドツールで、ワークスペース内の全パッケージをまとめてビルドする&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="パッケージ"&gt;パッケージ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2における、機能をまとめる単位（1つ以上のノードやライブラリをまとめたもの）&lt;/li&gt;
&lt;li&gt;各パッケージには&lt;code&gt;package.xml&lt;/code&gt;（パッケージの情報・依存関係を書くファイル）が必須&lt;/li&gt;
&lt;li&gt;ビルド方式によって、以下のように使うファイルが変わる
&lt;ul&gt;
&lt;li&gt;C++の場合: &lt;code&gt;CMakeLists.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pythonの場合: &lt;code&gt;setup.py&lt;/code&gt;（&lt;code&gt;ament_python&lt;/code&gt;というビルドタイプを使う）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rosdepとワークスペースのsource"&gt;rosdepとワークスペースのsource&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;パッケージが依存する外部ライブラリを、OSのパッケージマネージャ経由で解決してくれるツールが&lt;code&gt;rosdep&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ワークスペースの&lt;code&gt;src/&lt;/code&gt;以下にある全パッケージの依存関係を、&lt;code&gt;rosdep install --from-paths src -y --ignore-src&lt;/code&gt;のようなコマンドでまとめて解決できる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;colcon build&lt;/code&gt;でビルドした後は、&lt;code&gt;source install/setup.bash&lt;/code&gt;を実行しないと、ビルドしたパッケージがシェルから認識されない&lt;/li&gt;
&lt;li&gt;「ビルドは通ったのに&lt;code&gt;ros2 run&lt;/code&gt;できない」というのは、大抵このsourceのし忘れが原因で、初心者が最初につまずきやすいポイントの1つ&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="基本的なコマンド"&gt;基本的なコマンド&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ros2 run &amp;lt;パッケージ名&amp;gt; &amp;lt;実行ファイル名&amp;gt;&lt;/code&gt;: 1つのノードを実行する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 launch &amp;lt;パッケージ名&amp;gt; &amp;lt;launchファイル名&amp;gt;&lt;/code&gt;: 複数のノードをまとめて起動する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 node list&lt;/code&gt;: 今動いているノードの一覧を見る&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 topic list&lt;/code&gt; / &lt;code&gt;ros2 topic echo &amp;lt;トピック名&amp;gt;&lt;/code&gt;: トピックの一覧確認・流れているデータの確認&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 service list&lt;/code&gt;: サービスの一覧を見る&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rviz2&lt;/code&gt;: センサーの値やロボットの状態を可視化するツール&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rqt&lt;/code&gt;: ノードの構成やログをGUIで確認できるツール&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="最小限のコード例rclpy"&gt;最小限のコード例（rclpy）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ここまでは概念の説明だったので、実際に最小限のノードを書いてみる&lt;/li&gt;
&lt;li&gt;以下は、Pythonのクライアントライブラリ&lt;code&gt;rclpy&lt;/code&gt;を使った、シンプルなPublisherの例&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;rclpy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rclpy.node&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;std_msgs.msg&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MinimalPublisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;minimal_publisher&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publisher_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_publisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;topic&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timer_callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;timer_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Hello World: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publisher_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_logger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Publishing: &amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rclpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MinimalPublisher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rclpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;destroy_node&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rclpy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shutdown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;ポイント
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Node&lt;/code&gt;を継承したクラスを作るのが基本形&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_publisher&lt;/code&gt;でPublisherを作り、&lt;code&gt;create_timer&lt;/code&gt;で一定間隔ごとに&lt;code&gt;timer_callback&lt;/code&gt;を呼ぶ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rclpy.spin(node)&lt;/code&gt;で、ノードを動かし続ける（この中で、後述のExecutorがコールバックを回している）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Subscriberの場合は&lt;code&gt;create_subscription&lt;/code&gt;を使い、メッセージが届くたびに呼ばれるコールバック関数を登録する形になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="executor"&gt;Executor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ノード内の複数のコールバック（タイマー・Subscriberなど）を、実際にどう実行するかを管理する仕組み&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rclpy.spin(node)&lt;/code&gt;を呼ぶと、内部でデフォルトのExecutor（SingleThreadedExecutor）が動き、登録されたコールバックを順番に処理する&lt;/li&gt;
&lt;li&gt;シングルスレッドのExecutorだと、1つのコールバックの処理が終わるまで次のコールバックは実行されない
&lt;ul&gt;
&lt;li&gt;時間のかかる処理を1つのコールバックに書いてしまうと、他のコールバック（他のトピックの受信など）がその間ブロックされてしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;複数のコールバックを並行して処理したい場合は、MultiThreadedExecutorを使う&lt;/li&gt;
&lt;li&gt;「トピックが来ているはずなのに反応が遅い/来ない」という不具合の原因が、実はExecutorのブロッキングだった、というのはよくあるハマりどころ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="実行時の設定と制御"&gt;実行時の設定と制御&lt;/h2&gt;
&lt;h3 id="パラメータparameters"&gt;パラメータ（Parameters）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ノードに渡す設定値のこと。プログラムを書き換えずに、動作を外から調整できる仕組み&lt;/li&gt;
&lt;li&gt;例えば「カメラのフレームレート」「しきい値」のような値を、パラメータとして持たせることが多い&lt;/li&gt;
&lt;li&gt;コマンドでの確認・操作
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ros2 param list&lt;/code&gt;: あるノードが持つパラメータの一覧を見る&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 param get &amp;lt;ノード名&amp;gt; &amp;lt;パラメータ名&amp;gt;&lt;/code&gt;: 値を取得する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 param set &amp;lt;ノード名&amp;gt; &amp;lt;パラメータ名&amp;gt; &amp;lt;値&amp;gt;&lt;/code&gt;: 値を変更する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;実際の運用では、パラメータを1つずつ&lt;code&gt;set&lt;/code&gt;するのではなく、後述のLaunchファイルからYAMLファイルでまとめて渡すのが一般的&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="namespaceremapping"&gt;Namespace・Remapping&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Namespaceは、ノード名やトピック名の前につける「名前空間」で、同じパッケージ・同じノードを複数のインスタンスとして区別して動かすときに使う
&lt;ul&gt;
&lt;li&gt;例: &lt;code&gt;robot1/cmd_vel&lt;/code&gt;、&lt;code&gt;robot2/cmd_vel&lt;/code&gt;のように、ロボットごとに名前空間を分ける&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Remappingは、ノードが元々使っているトピック名・サービス名などを、実行時に別の名前に付け替える仕組み
&lt;ul&gt;
&lt;li&gt;例: &lt;code&gt;ros2 run pkg node --ros-args -r cmd_vel:=robot1/cmd_vel&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;どちらも、コードを一切変更せずに、起動時のオプションやLaunchファイルの引数だけで名前を切り替えられるのがポイント&lt;/li&gt;
&lt;li&gt;複数台のロボットを同時に動かす場合や、他人が作ったパッケージをそのまま自分のシステムに組み込む場合に、ほぼ必須になる知識&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="launchファイル"&gt;Launchファイル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;複数のノードを、パラメータ付きでまとめて起動するための設定ファイル&lt;/li&gt;
&lt;li&gt;Python・XML・YAMLのいずれかで書ける（最近はPythonで書くことが多い）&lt;/li&gt;
&lt;li&gt;実際のロボットは複数のノードが同時に動いて成り立っているため、1つずつ&lt;code&gt;ros2 run&lt;/code&gt;するのではなく、launchファイルでまとめて立ち上げるのが基本的な運用になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ライフサイクルノードmanaged-nodes"&gt;ライフサイクルノード（Managed Nodes）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;通常のノードは起動したらすぐ全機能が有効になるが、ライフサイクルノードは明示的な状態管理を持つ
主な状態は以下の通り。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;状態&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unconfigured&lt;/td&gt;
&lt;td&gt;起動直後、まだ設定されていない状態&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inactive&lt;/td&gt;
&lt;td&gt;設定は終わっているが、まだ動いていない状態&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;実際に処理を行っている状態&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finalized&lt;/td&gt;
&lt;td&gt;終了処理が終わった状態&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;状態遷移は、&lt;code&gt;configure&lt;/code&gt;・&lt;code&gt;activate&lt;/code&gt;・&lt;code&gt;deactivate&lt;/code&gt;・&lt;code&gt;cleanup&lt;/code&gt;・&lt;code&gt;shutdown&lt;/code&gt;といったサービス呼び出しで制御する&lt;/li&gt;
&lt;li&gt;Nav2は、内部の各サーバー（Planner、Controllerなど）がこのライフサイクルノードとして作られていて、&lt;code&gt;lifecycle_manager&lt;/code&gt;というノードが、それらの状態をまとめて管理・遷移させている&lt;/li&gt;
&lt;li&gt;Nav2起動時に「なぜか動かない」場合、実はライフサイクルが&lt;code&gt;Active&lt;/code&gt;まで遷移していないだけ、ということもよくある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ロボット特有の周辺技術"&gt;ロボット特有の周辺技術&lt;/h2&gt;
&lt;h3 id="rosbag2"&gt;rosbag2&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;トピックに流れているデータを記録・再生するツール（ROS1の&lt;code&gt;rosbag&lt;/code&gt;のROS2版）&lt;/li&gt;
&lt;li&gt;実機やシミュレーションで流れたデータをファイルに記録しておき、後から同じデータを何度でも再生できる&lt;/li&gt;
&lt;li&gt;実機を毎回動かさなくても、記録済みのデータでノードの開発・デバッグを進められるのが大きな利点&lt;/li&gt;
&lt;li&gt;主なコマンド
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ros2 bag record -a&lt;/code&gt;: 全トピックを記録する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 bag record &amp;lt;topic1&amp;gt; &amp;lt;topic2&amp;gt;&lt;/code&gt;: 指定したトピックだけ記録する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 bag play &amp;lt;bagファイル&amp;gt;&lt;/code&gt;: 記録したデータを再生する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 bag info &amp;lt;bagファイル&amp;gt;&lt;/code&gt;: 記録内容（トピック・件数・期間など）を確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;保存形式は&lt;code&gt;sqlite3&lt;/code&gt;か&lt;code&gt;mcap&lt;/code&gt;が使われる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="urdfunified-robot-description-format"&gt;URDF（Unified Robot Description Format）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ロボットの物理的な構造（リンクとジョイント）を記述するXML形式&lt;/li&gt;
&lt;li&gt;リンク（Link）は剛体の部品（腕の一部、車体など）、ジョイント（Joint）はリンク同士をつなぐ関節（回転・スライドなど）を表す&lt;/li&gt;
&lt;li&gt;各リンクの見た目（形状・色）や、衝突判定用の形状、質量・慣性などの物理情報もここに書ける&lt;/li&gt;
&lt;li&gt;&lt;code&gt;robot_state_publisher&lt;/code&gt;というノードが、URDFとジョイントの角度情報から、後述のTF2の座標変換を自動的に計算・配信してくれる&lt;/li&gt;
&lt;li&gt;RVizでロボットの3Dモデルを表示したり、Gazeboでシミュレーションしたりする際の元データにもなる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="tf2座標変換"&gt;TF2（座標変換）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ロボットに関わる複数の座標系（フレーム）の関係を、時系列で管理する仕組み&lt;/li&gt;
&lt;li&gt;例えば「地図（map）」「ロボット本体（base_link）」「カメラ（camera_link）」は、それぞれ別の座標系を持っていて、TF2はこれらの間の相対位置・姿勢を管理する&lt;/li&gt;
&lt;li&gt;各フレームは木構造（ツリー）でつながっていて、&lt;code&gt;map -&amp;gt; odom -&amp;gt; base_link -&amp;gt; camera_link&lt;/code&gt;のように親子関係を辿ることで、任意の2点間の座標変換を計算できる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2 run rqt_tf_tree rqt_tf_tree&lt;/code&gt;で、今のフレーム構成をツリー図として確認できる&lt;/li&gt;
&lt;li&gt;Nav2のようなナビゲーションスタックは、TF2が正しく配信されていることが前提になっているため、ロボット開発で最初につまずきやすいポイントの1つ&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="slamsimultaneous-localization-and-mapping"&gt;SLAM（Simultaneous Localization and Mapping）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自己位置推定（Localization）と地図作成（Mapping）を同時に行う技術&lt;/li&gt;
&lt;li&gt;ロボットが未知の環境を動き回りながら、センサー情報をもとに「今どこにいるか」と「周囲の地図」を同時に構築していく&lt;/li&gt;
&lt;li&gt;前述のNav2は自己位置推定を行わない（AMCLなどと組み合わせる前提）ため、Nav2を使うには、事前にSLAMで地図を作っておくか、SLAMをリアルタイムで動かしながらナビゲーションする、という使い方になる&lt;/li&gt;
&lt;li&gt;ROS2では、2D LiDARを使ったSLAMの標準的な実装として&lt;code&gt;slam_toolbox&lt;/code&gt;というパッケージがよく使われる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="visual-slam"&gt;Visual SLAM&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LiDARなどの距離センサーではなく、カメラ映像を使って自己位置推定・地図作成を行うSLAM&lt;/li&gt;
&lt;li&gt;画像内の特徴点（際立った点）をフレーム間で追跡し、その動きからカメラ（ロボット）自身の移動量と、周囲の3次元構造を推定する&lt;/li&gt;
&lt;li&gt;LiDARより安価なセンサー（カメラ）で実現できる一方、照明条件の変化や、特徴点の少ない環境（真っ白な壁など）に弱いという弱点がある&lt;/li&gt;
&lt;li&gt;代表的な実装として、ORB-SLAMやRTAB-Map（ROS2にも対応）などがある&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cuvslam"&gt;cuVSLAM&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;NVIDIAが開発した、GPU（CUDA）で高速化されたVisual SLAMの実装&lt;/li&gt;
&lt;li&gt;Isaac ROS（NVIDIAが提供するROS2向けのGPUアクセラレーションパッケージ群）の一部として提供されている&lt;/li&gt;
&lt;li&gt;ステレオカメラの映像を使い、GPU上で並列処理することで、CPUベースのVisual SLAMより高速・低遅延に自己位置推定を行える&lt;/li&gt;
&lt;li&gt;Jetsonシリーズのようなエッジデバイス上でのリアルタイム動作を意識して設計されている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="nav2navigation2"&gt;Nav2（Navigation2）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2上で自律移動（ナビゲーション）を実現するための標準的なソフトウェアスタック&lt;/li&gt;
&lt;li&gt;地図上で目的地を指定すると、経路計画と障害物回避をしながら自律的に移動できるようにする
主な構成要素は以下の通り。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;構成要素&lt;/th&gt;
&lt;th&gt;役割&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Global Planner&lt;/td&gt;
&lt;td&gt;地図全体を使って、大まかな経路を計画する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Controller（Local Planner）&lt;/td&gt;
&lt;td&gt;直近の障害物やロボットの動特性を考慮して、実際の速度指令（前述の&lt;code&gt;cmd_vel&lt;/code&gt;）を計算する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Costmap&lt;/td&gt;
&lt;td&gt;障害物や走行コストを表現する地図。全体用のGlobal Costmapと、直近用のLocal Costmapの2種類がある&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Behavior Tree&lt;/td&gt;
&lt;td&gt;経路計画→移動→リカバリー動作といった、Nav2全体の動作フローを制御する仕組み&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery Behaviors&lt;/td&gt;
&lt;td&gt;経路が見つからない・スタックしたときに行う復帰動作（その場回転、後退など）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;Nav2自体は「自分が今どこにいるか」は推定しないため、AMCLなどの自己位置推定と組み合わせて使うのが前提&lt;/li&gt;
&lt;li&gt;launchファイルで各構成要素をまとめて立ち上げ、パラメータYAMLで細かい挙動をチューニングするのが基本的な使い方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="順運動学fkと逆運動学ik"&gt;順運動学（FK）と逆運動学（IK）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Nav2・SLAMが移動ロボット向けの話だったのに対し、ここからはロボットアーム（マニピュレータ）向けの基礎知識&lt;/li&gt;
&lt;li&gt;順運動学（Forward Kinematics, FK）: 各関節の角度が分かっているときに、アームの先端（エンドエフェクタ）がどの位置・姿勢にあるかを計算すること
&lt;ul&gt;
&lt;li&gt;「関節の角度 → 先端の位置」という向きの計算で、URDFのリンク・ジョイント情報から比較的簡単に求まる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;逆運動学（Inverse Kinematics, IK）: 逆に、アームの先端を「この位置・姿勢にしたい」と決めたときに、そのために必要な各関節の角度を計算すること
&lt;ul&gt;
&lt;li&gt;「先端の位置 → 関節の角度」という向きの計算で、同じ先端位置に対して関節角度の組み合わせが複数存在したり、そもそも解が存在しない（届かない位置）こともあり、FKより計算が難しい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dhパラメータとリンク長"&gt;DHパラメータとリンク長&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;FKを計算する際、隣り合う関節同士の座標系の関係を統一的に表現するための方法が、Denavit-Hartenberg（DH）パラメータ&lt;/li&gt;
&lt;li&gt;以下4つのパラメータの組み合わせで、隣り合う座標系同士の変換を表現する
&lt;ul&gt;
&lt;li&gt;リンク長$a_i$: $x_i$軸に沿って測った、$z_i$軸から$z_{i+1}$軸までの距離。そのリンク（関節と関節の間の剛体部分）の物理的な長さにあたる&lt;/li&gt;
&lt;li&gt;リンクのねじれ角$\alpha_i$: $x_i$軸まわりに測った、$z_i$軸から$z_{i+1}$軸までの角度&lt;/li&gt;
&lt;li&gt;リンクオフセット$d_i$: $z_i$軸に沿って測った、$x_{i-1}$軸から$x_i$軸までの距離&lt;/li&gt;
&lt;li&gt;関節角$\theta_i$: $z_i$軸まわりに測った、$x_{i-1}$軸から$x_i$軸までの角度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;回転関節の場合、可変なのは関節角$\theta_i$だけで、リンク長$a_i$を含む残り3つはロボットの機械構造によって決まる定数になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pid制御とpd制御"&gt;PID制御とPD制御&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;関節や車輪を目標値（角度・速度・位置など）に追従させるための、古典的で最も広く使われるフィードバック制御手法&lt;/li&gt;
&lt;li&gt;目標値と現在値の差（誤差）$e(t)$を使って、以下の3項を組み合わせて制御量$u(t)$を計算する&lt;/li&gt;
&lt;/ul&gt;
$$
u(t) = K_p e(t) + K_i \int_0^t e(\tau)\,d\tau + K_d \frac{de(t)}{dt}
$$&lt;ul&gt;
&lt;li&gt;比例項（P, Proportional）: 誤差の大きさに比例した制御量。誤差が大きいほど強く補正する&lt;/li&gt;
&lt;li&gt;積分項（I, Integral）: 誤差の累積に比例した制御量。比例項だけでは埋まらずにじわじわ残る誤差（定常偏差）を解消する&lt;/li&gt;
&lt;li&gt;微分項（D, Derivative）: 誤差の変化率に比例した制御量。急激な変化を抑え、目標値を行き過ぎるオーバーシュートを防ぐ&lt;/li&gt;
&lt;li&gt;PID制御: 上記3項全てを使う、最も一般的な構成&lt;/li&gt;
&lt;li&gt;PD制御: 積分項を使わず比例項と微分項だけを使う構成。積分項による巻き込み（積分ワインドアップ）を避けたい場合や、定常偏差が問題になりにくい速度制御などで使われる&lt;/li&gt;
&lt;li&gt;ROS2では、&lt;code&gt;ros2_control&lt;/code&gt;フレームワークの&lt;code&gt;control_toolbox&lt;/code&gt;パッケージにPID制御の実装があり、&lt;code&gt;ros2_controllers&lt;/code&gt;の&lt;code&gt;pid_controller&lt;/code&gt;から直接利用できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="クランプclamp"&gt;クランプ（Clamp）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;値を決められた上限・下限の範囲内に収まるように制限する処理のこと&lt;/li&gt;
&lt;li&gt;制御出力$u(t)$が、モーターの実際の駆動範囲を超えないように上限・下限で切り詰める、といった使い方をする&lt;/li&gt;
&lt;li&gt;積分ワインドアップへの対策の1つに、クランプ方式のアンチワインドアップ（Clamping Anti-Windup）がある
&lt;ul&gt;
&lt;li&gt;出力が上限・下限に達している間は、積分項の蓄積を止める（またはその値自体を制限する）ことで、誤差が解消された後に出力が行き過ぎるのを防ぐ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="command-interfaceとstate-interfaceactvel"&gt;Command InterfaceとState Interface（ActVel）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PID制御が誤差$e(t)$を計算するには、目標値だけでなく「今どうなっているか」という実測値が必要になる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ros2_control&lt;/code&gt;では、コントローラーからハードウェアへの指令をCommand Interface、ハードウェアからコントローラーへのフィードバックをState Interfaceとして抽象化している&lt;/li&gt;
&lt;li&gt;代表的な種類には&lt;code&gt;HW_IF_POSITION&lt;/code&gt;（位置）・&lt;code&gt;HW_IF_VELOCITY&lt;/code&gt;（速度）・&lt;code&gt;HW_IF_EFFORT&lt;/code&gt;（トルク・力）があり、同じ関節でもCommand用とState用で別々のインターフェースとして扱われる&lt;/li&gt;
&lt;li&gt;速度のState Interface（実測速度）は、しばしば「ActVel（Actual Velocity）」と呼ばれる。モータードライバの標準規格であるCiA402（CANopenのドライブ用プロファイル）でも、指令速度とは別に「Velocity actual value」というオブジェクトが定義されており、ActVelという略称はここに由来することが多い&lt;/li&gt;
&lt;li&gt;前述の&lt;code&gt;cmd_vel&lt;/code&gt;が、ナビゲーションスタックなど上位からロボット全体への速度指令であるのに対し、ActVelは個々の関節・モーターレベルでの実測値であり、抽象化のレイヤーが異なる点に注意&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="moveit"&gt;MoveIt&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ROS2上でロボットアームの動作計画（モーションプランニング）を行うための標準的なソフトウェアスタック&lt;/li&gt;
&lt;li&gt;Nav2が移動ロボット向けの標準スタックなのに対し、MoveItはアーム向けの標準スタックという位置づけ&lt;/li&gt;
&lt;li&gt;前述のIKを解いて目標姿勢までの関節角度を求めつつ、障害物を避けながらの経路計画や衝突検知も行う&lt;/li&gt;
&lt;li&gt;URDFで定義したロボットの構造をそのまま利用でき、Gazeboのようなシミュレータ上での動作確認にも対応している&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gazeboシミュレータ"&gt;Gazebo（シミュレータ）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ロボットの物理シミュレーションを行うためのソフトウェア&lt;/li&gt;
&lt;li&gt;前述のURDFで記述したロボットモデルを仮想空間に配置し、重力・摩擦・衝突などを考慮した動きをシミュレートできる&lt;/li&gt;
&lt;li&gt;実機がまだない、あるいは実機を壊すリスクがある動作を試したいときに、ROS2のノードをそのまま実機と同じように動かして検証できる&lt;/li&gt;
&lt;li&gt;カメラ・LiDARなどのセンサーのシミュレーションデータも出力できるので、Nav2のようなセンサー入力が前提のスタックのテストにもよく使われる&lt;/li&gt;
&lt;li&gt;最近は従来のGazebo Classicから、後継のGazebo（旧Ignition Gazebo）への移行が進んでいる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ROS2は、ロボットの各機能をノードという単位に分けて、通信でつなげて動かすためのフレームワーク&lt;/li&gt;
&lt;li&gt;インストールは、その時点の最新LTSディストリビューションを、対応するUbuntuのバージョンに入れるのが基本&lt;/li&gt;
&lt;li&gt;通信の基盤はDDSで、ROS1にあった中央サーバー（単一障害点）がない&lt;/li&gt;
&lt;li&gt;ノード間の通信は、Topic（非同期の流し込み）・Service（同期的な問い合わせ）・Action（進捗報告つきの長時間処理）の3種類を目的に応じて使い分ける。QoSはその通信の品質を細かく設定する仕組み&lt;/li&gt;
&lt;li&gt;実際のコードは、&lt;code&gt;Node&lt;/code&gt;を継承したクラスにPublisher/Subscriberやコールバックを持たせる形で書き、&lt;code&gt;rclpy.spin&lt;/code&gt;が内部のExecutorでコールバックを回す&lt;/li&gt;
&lt;li&gt;開発は、ワークスペースの中にパッケージを作り、rosdepで依存関係を解決してcolconでビルドし、setup.bashをsourceして使う、という流れが基本&lt;/li&gt;
&lt;li&gt;動作の調整はパラメータで行い、Namespace・Remappingで名前を実行時に切り替えられる。複数ノードとパラメータをまとめて起動するのがLaunchファイルの役割&lt;/li&gt;
&lt;li&gt;rosbag2でデータを記録・再生できるので、実機を毎回動かさなくても開発・デバッグを進められる&lt;/li&gt;
&lt;li&gt;URDFでロボットの構造を記述し、そこからTF2が座標変換を計算・配信する。この2つはNav2などの前提になる基礎的な仕組み&lt;/li&gt;
&lt;li&gt;SLAM（Visual SLAM・cuVSLAMも含む）で自己位置推定と地図作成を行い、その地図をもとにNav2が自律移動する、という役割分担になっている&lt;/li&gt;
&lt;li&gt;速度指令は&lt;code&gt;cmd_vel&lt;/code&gt;という標準的なトピック名でやり取りされ、ライフサイクルノードで状態管理されたNav2が、その&lt;code&gt;cmd_vel&lt;/code&gt;を出す自律移動用の標準スタック&lt;/li&gt;
&lt;li&gt;ロボットアームの場合は、関節角度から先端位置を求めるFK、先端位置から関節角度を求めるIKが基本になり、MoveItがそれを担うNav2の対になる標準スタック&lt;/li&gt;
&lt;li&gt;Gazeboを使えば、実機なしでもロボットのシミュレーションができる&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>