この回から、まとめ課題に入ります。前の回で読んだ scan_avoid は、/scan を読むところから速度指令を出すところまでを 1 つのノードでやっていました。まとめ課題では、同じ働きを知覚・判断・行動の 3 つに分けて設計します。
3 つのうち、自分で作るのは知覚ノード(/scan から前方の距離を出す)と判断ノード(距離から進む・曲がるを決めて /cmd_vel に出す)の 2 つです。行動は、ロボットの中ですでに動いています。/cmd_vel を受け取り、cmd_vel_guard で速さの上限と途切れを見張ってから脚を動かす部分です(#08 で確かめました)。つまり、判断ノードが /cmd_vel に出したところから先が行動です。
分ける理由は、見た目を整えるためではありません。分けておくと、ロボットが無くても 1 つずつ確かめられるからです。この回で、その効き目を確かめます。
- 課題を 1 つ選ぶ
- グラフを先に描く(ノード・トピック・型・QoS・周期・パラメータ)
- ノードごとに設計シートを書く。判断ノードには止まる条件を必ず書く
- 設計シートを交換し、相手の「止まる条件」の抜けを 1 つ指摘し合う
- 知覚ノードだけ AI に作らせ、記録データで検証する
5 では、できた知覚ノードを記録データで動かします。動かす前に、次のことを予想してノートに書いてください。結果の画面と説明は「結果を見る」をクリックすると開きます。予想を書き、自分で実行してから開いてください。
| 確かめること | 予想すること | 手がかり |
|---|---|---|
| 周期 | ros2 topic hz /front_distance が何 Hz 前後になるか | #10 の scan_monitor で見た /scan の周期と、自分のノードが「/scan が来るたびに出す」のか「タイマーで出す」のか |
| 値 | 記録の中で箱が近づいた場面で、/front_distance がいくつくらいになるか | #10 の scan_monitor の「前」の値 |
| 異常時 | 再生を一時停止したとき、/front_distance はどうなるか | 自分の設計シートの「止まる条件・異常時の決まり」に書いたこと |
予想は外れてかまいません。大事なのは、外れたときに「なぜ違ったか」を考えることです。分からないときも空欄にせず、「分からない」と書いて、手がかりにしたことを 1 つ書きます。
授業で受ける人は、この回の記録を実習レポート(Word)の「第 10 回」のシートに書きます。スクリーンショットは、シートの中の「画面:」の欄(実験や記録の表のすぐ下)に貼ります。ひとりで学ぶ人も、予想と結果を同じ形でノートに残しておくと、あとで見返せます。
この回で撮っておく画面
動画は撮りません。そのかわり、下の画面を撮って残します。授業で受ける人は、実習レポートの「第 10 回」の、それぞれの「画面:」の欄に貼ります。ひとりで学ぶ人も、同じ画面を残しておくと、あとで値を見直せます。最初の 1 枚は、実習を始める前に端末で TZ=Asia/Tokyo date と打ち、日付と時刻が出た画面です。授業の日に実習したことの記録になります。講義用の環境の時計は世界標準時(UTC)なので、TZ=Asia/Tokyo を付けて日本時間で出します。
TZ=Asia/Tokyo dateの画面- 設計のグラフ(手描きでよい。写真)
- 交換して書き込みが入った設計シート(写真)
- 記録を再生しながらの
ros2 topic hz /front_distance ros2 topic info -v /front_distance(設計シートの型と見比べる)- 箱を動かした場面の
ros2 topic echo /front_distance
この回で使うもの
| もの | 使うところ |
|---|---|
| 講義用の環境 | すべて |
#10 で記録した room_scan | 知覚ノードの検証 |
| 設計シート(#04 から使っているもの) | すべて |
| ロボット | この回では使いません(次の回で使います) |
1 課題を選ぶ
次の 4 つから 1 つを選び、選んだ課題をレポートに書きます。どれを選んでも、知覚ノードと判断ノードの 2 つを作ります。
| 課題 | 知覚ノードが出すもの | 判断ノードがすること |
|---|---|---|
| A. 壁に沿って歩く | 右側の壁までの距離 | 距離を一定に保つよう、旋回の速さを決める |
| B. 近づいたら止まり、離れたらついていく | 前方でいちばん近い物体までの距離 | 距離に応じて前進・停止・後退を切り替える |
| C. 正方形の角をセンサーで決める | 前方の壁までの距離 | 時間ではなく、壁までの距離で曲がる |
| D. 自由課題 | 先生と相談して決める | 先生と相談して決める |
C は #08 で歩かせた square_walker の作り直しです。あのときは「3 秒進んで 90° 回る」と時間で決めていたので、床がすべると形が崩れました。壁までの距離で曲がるようにすると、何が変わるかを確かめる課題です。
迷ったら B を選んでください。このあとの例(front_distance と判断ノード)は B の形で書いてあるので、そのまま手本にできます。D を選ぶ人は、知覚・判断・行動に分けられる課題か(自分で作るのは知覚と判断の 2 つ)を、先生と相談してから決めます。選んだ課題は、レポートの第 10 回の「まとめ課題」の欄に書きます。
2 グラフを先に描く
コードより先に、紙かホワイトボードに描きます。先に描くのは、つながりを決めるのは AI ではなく自分だからです(#04 で設計シートを先に書いたのと同じ理由です)。描くのは次の 5 つです。
- ノード(丸)とその名前
- トピック(四角)とその名前
- メッセージの型(
std_msgs/msg/Float32など) - QoS(
/scanを受けるところは sensor_data。自分で作るトピックは既定のままでよい) - 周期(1 秒に何回出すか)とパラメータ
sensor_data は、センサーのためにあらかじめ用意されている QoS の組み合わせの名前です。中身は best effort、つまり「届かなくても送り直さない」設定になっています。#09 の実験 2 で見たとおり、この LiDAR の /scan は RELIABLE で送られてきますが、受ける側は best effort(sensor_data)にしておきます。理由は次の「QoS をもう少しくわしく」で説明します。
QoS をもう少しくわしく
QoS(Quality of Service)は、トピックの「届け方の約束」です。いちばん大事なのは Reliability(信頼性)の 2 種類です(#09 の実験 1 で試しました)。
| Reliability | 届け方 | 向いているもの |
|---|---|---|
| reliable | 届かなかったら送り直す。確実に届くが、送り直す分だけ遅れることがある | 速度指令・設定など、1 つも落としたくないもの(自分で作るトピックの既定) |
| best effort | 送りっぱなし。届かなかったものは捨てる | LiDAR・カメラなど、次々に新しい値が来るので古い値を送り直しても意味がないもの |
組み合わせの決まりは、#09 の実験 1 の A〜D のとおりです。
| 送る側 | 受ける側 | 届くか | |
|---|---|---|---|
| A | best effort | reliable | 届かない |
| B | best effort | best effort | 届く |
| C | reliable | best effort | 届く |
| D | reliable | reliable | 届く |
届かないのは A だけです。受ける側が「送り直してでも確実に届けてほしい」と求めても、送る側がその約束をしていないからです。表を縦に見ると、受ける側を best effort にしておけば、送る側がどちらでも届く(B と C)ことが分かります。今の LiDAR は reliable で送っていますが、LiDAR を別の機種に替えたり、送る側の設定が変わったりしても、best effort で受けるノードはそのまま動きます。センサーを受けるときに sensor_data を使うのは、このためです。
A の組み合わせで困るのは、つながらなくてもエラーで止まらないことです。ノードは起動したまま、コールバックが 1 回も呼ばれません。#09 で見たように黄色の警告は出ますが、ほかの表示に流されて見落としやすいものです。「起動したのに何も出ない」ときは、QoS を疑ってください。
コードでは、購読をつくるときの最後の引数で決めます。10 と書くと「reliable で、10 個までためる」という意味になります。今の /scan は reliable で送られてくるので 10 でも届きますが(D)、送る側が best effort に変わると届かなくなります(A)。/scan を受けるときは、rclpy.qos に用意されている qos_profile_sensor_data を渡します。
from rclpy.qos import qos_profile_sensor_data
from sensor_msgs.msg import LaserScan
from std_msgs.msg import Float32
# /scan を受ける(best effort)。送る側がどちらでも届く
self.create_subscription(LaserScan, 'scan', self.on_scan, qos_profile_sensor_data)
# 自分で作るトピックを出す(既定の reliable でよい)
self.pub = self.create_publisher(Float32, 'front_distance', 10)
自分のノードがどちらで受けているかは、ノードを動かしたままコマンドで確かめられます。
ros2 topic info -v /scan
出てきた一覧は、送る側(Publisher count の下)と受ける側(Subscription count の下)に分かれています。受ける側の中から自分のノードの名前(Node name: の行)を探し、その数行下の QoS profile: の中にある Reliability: が BEST_EFFORT になっていれば、設計どおりです。
トピックの型は自分で選びます。距離 1 つなら std_msgs/msg/Float32 で足ります。迷ったら、ros2 interface show で中身を見てから決めてください(#03・#05 で使いました)。
ros2 interface show std_msgs/msg/Float32
ros2 interface show sensor_msgs/msg/LaserScan | sed -n '1,16p'
2 行目は、入力の /scan の型です。説明の行が長く続くので、sed -n '1,16p' で最初の 16 行だけを出しています。
周期は、入力より速くしても意味がありません。/scan は 1 秒に約 5 回です(#10 の scan_monitor の右端に出ていた 5 Hz)。知覚ノードは /scan が来るたびに 1 回出すのがいちばん素直です。パラメータは、コードを書き換えずに起動のときに変えたい値です(#04 の rate・start と同じ)。止まる距離や速さのように、試しながら決め直しそうな値をパラメータにしておきます。
名前の付け方
ロボットが実際に聞いているのは /cmd_vel です(#08 で確かめました)。設計の段階では、判断ノードの出口を /cmd_vel と書いておき、試すときに -r cmd_vel:=/cmd_vel_test でつなぎ替えます。こうしておくと、コードを変えずに「ロボットに出す・出さない」を切り替えられます。
3 設計シートを書く
ノードごとに 1 枚書きます。AI に渡すのはこのシートです。この節では、次の順に進めます。
- 書き方の例(課題 B の知覚ノード
front_distance)を、欄ごとに読む - 自分の課題のノードごとにシートを書く
- 判断ノードの「止まる条件」は、AI に質問役をしてもらいながら自分で決める
書き方の例:front_distance(前方の距離を出す知覚ノード)
#04 の設計シートと同じ欄を、短くまとめて書いた例です(「受け取るもの」を「入力」、「出すもの」を「出力」と書いています)。
ノード名:front_distance
役割:/scan から、前方 ±30° でいちばん近い物体までの距離を出す
入力:/scan(sensor_msgs/msg/LaserScan、QoS は sensor_data(best effort)で受ける、約 5 Hz)
出力:/front_distance(std_msgs/msg/Float32、5 Hz)
パラメータ:front_angle_deg(既定 0.0)、half_width_deg(既定 30.0)
止まる条件・異常時の決まり:
- 有効な点が 1 つも無いときは inf を出す(0.0 は出さない。近いと誤解されるため)
- /scan が 1 秒来なければ、何も出さない(判断ノード側が途絶えに気づけるように)
検証の方法:
1. ros2 bag play room_scan --loop で再生し、ros2 topic hz /front_distance が約 5 Hz か
2. 箱を動かした場面で、値が実際に変わるか(scan_monitor の「前」と比べる)
それぞれの欄に何を書いたか、なぜそう決めたかは次のとおりです。
| 欄 | この例で書いたこと | 何を書くか・なぜそう決めたか |
|---|---|---|
| ノード名 | front_distance | ros2 node list に出る名前です。仕事が分かる短い英語にします。 |
| 役割 | 前方 ±30° でいちばん近い物体までの距離を出す | 1 文で書きます。#10 の課題で作ったノードとほぼ同じ仕事で、「表示する」のかわりに「トピックに出す」にしています。判断ノードに渡すためです。 |
| 入力 | /scan・LaserScan・sensor_data・約 5 Hz | LiDAR が出しているトピックです。型は ros2 topic info /scan で見られます。QoS は、受ける側を sensor_data(best effort)にします。送る側が reliable でも best effort でも届くからです(#09 の実験 1 の B・C)。周期は #10 で見た 5 Hz です。 |
| 出力 | /front_distance・Float32・5 Hz | 距離 1 つなので Float32 で足ります。/scan が来るたびに 1 回出すので、周期は入力と同じ 5 Hz です。トピック名は、判断ノードの「入力」と一字一句同じにします。 |
| パラメータ | front_angle_deg(0.0)・half_width_deg(30.0) | 正面の向きと、左右に何度まで見るかです。#09 の実験 5 で LiDAR の 0° が正面からずれていたら、front_angle_deg をコードを変えずに直せます。 |
| 止まる条件・異常時の決まり | 有効な点が無ければ inf//scan が来なければ何も出さない | 知覚ノードは速度指令を出さないので「止まる」ことはありませんが、困った場面で何を出すかは決めておきます。0.0 を出すと「すぐ前に物がある」と読まれてしまうので、測れないときは inf(無限大)にします。入力が来ないときに古い値を出し続けると、判断ノードが途絶えに気づけないので、何も出しません。 |
| 検証の方法 | hz で周期、箱の場面で値 | できたノードをどのコマンドで確かめるかを、作る前に決めておきます。ここに書いたことを、5 で実際に確かめます。 |
シートの最後には、#04 と同じく「使った AI とプロンプト」の欄も付けておきます。
自分のシートを書く
選んだ課題のノードを、1 ノード 1 枚で書きます。知覚ノードは上の例を手本にし、自分の課題に合わせて変えます(課題 A なら「右側」、課題 C なら「前方の壁」までの距離です)。判断ノードは、入力が知覚ノードの出力で、出力が速度指令(/cmd_vel、型は geometry_msgs/msg/Twist。#08 で見た型)です。
判断ノードの「止まる条件」
判断ノードのシートには、止まる条件を必ず書きます。次の 3 つは最低限です。
| 起きること | どうするか |
|---|---|
| 入力のトピックが一定時間届かない | 速度 0 を送り続ける(何も送らない、ではない) |
距離が取れない(inf や nan) | 前が空いていると解釈しない。止まる側に倒す |
| 値が想定の範囲を外れている | 範囲に収める、または止まる。どちらにするかを書く |
#11 の scan_avoid が持っていたのは、1 つめ(入力が途絶えたら止まる)だけです。前方に有効な点が 1 つも無いと、前方の距離は inf になり、scan_avoid はそれを「空いている」と読んで前進します。範囲の外の値は捨てるだけで、止まりはしません。自分のノードでは、3 つとも答えておく必要があります。「一定時間」を何秒にするか、範囲の外をどこからにするかは、課題によって違うので自分で決めて、数字で書きます。
この欄を AI に「書いて」と頼んではいけません。止まる条件は、ロボットをぶつけないための約束です。自分で決めていないと、床で試すときにどこを見ればよいか分かりません。迷うときは、#04 と同じように AI に質問役をしてもらいます。次のプロンプトに、書きかけのシートを貼って渡します。
ROS 2 のまとめ課題で、判断ノードの設計シートを書いています。「止まる条件」の欄を埋めたいので、手伝ってください。
次のルールを守ってください。
・答えを先に書かないでください。場面を 1 つずつ取り上げて、「そのとき、このノードは何を出すべきか」を私に質問してください。
・少なくとも次の 3 つの場面は必ず聞いてください。入力のトピックが一定時間届かないとき。距離が inf や nan のとき。値が想定の範囲を外れているとき。
・私が「分からない」と答えたら、その場面で何が起きるかを高校生にも分かる言葉で説明し、選ぶための手がかりを出してから、もう一度聞いてください。
・私の答えが危ないと思ったら(ロボットが動き続けてしまう、など)、どこが危ないかを言って聞き返してください。
・全部の場面が決まったら、私が決めたことを場面ごとに箇条書きで並べ直してください。欄には私が自分で書きます。
作るノード:(ここに、判断ノードの仕事を 1 文で書く)
受け取るもの:(ここに、知覚ノードの設計シートの「出力」を貼る)
私が書いたところまでの設計シート:
(ここに書きかけのシートを貼る)
進め方は #04 の「分からない欄は、AI に聞き返してもらう」と同じです。AI の質問に自分の言葉で答え、分からないときは「分からない」と言います。最後に AI が並べ直した箇条書きを見ながら、欄は自分で書きます。書いた欄は、上の 3 つの場面がすべて入っているか、どれも「動き続ける」側になっていないかを、自分で読んで確かめます。使ったプロンプトと、聞き返されて決めたことは、シートの「使った AI とプロンプト」の欄に書いておきます。
4 設計シートを交換する
隣の人とシートを交換し、相手の設計について次の 2 つを探します。見つけたら、口で言うのではなく相手のシートに書き込みます。
- 止まる条件の抜け(上の表の 3 つが書いてあるか)
- つながらないところ(出す型と受ける型、トピック名、周期が合っているか)
この指摘は、#03 の実験 4 で「型が合っていないと、エラーも出ずに届かない」ことを確かめたのと同じ話です。違うのは、動かす前に紙の上で見つける点です。
書き込むときは「おかしい」とだけ書かず、どの欄の、どの場面が抜けているかを書きます(例:「判断ノード・止まる条件:/front_distance が届かなくなったときに何を出すかが書いていない」)。抜けが見つからないときも、3 つの場面を 1 つずつ確かめたことが分かるように、確かめた場面に印を付けて返します。
シートが戻ってきたら、書き込みが入った状態で写真を撮ってから、指摘されたところを直します。指摘されたことと、それをどう直したか、自分が相手に指摘したことは、レポートの第 10 回の「設計シートの交換」の表に書きます。
5 知覚ノードを AI に作らせ、記録で検証する
設計シートをそのまま AI に渡し、知覚ノードだけを作らせます。判断ノードは次の回です。できたら、ロボットにはつながずに、#10 の記録で確かめます。この節の流れは次のとおりです。
- パッケージ
my_taskを作る - AI に知覚ノードを作らせ、設計シートと突き合わせてから保存する
- ビルドし、記録を再生しながら動かす
- 表の 5 項目を、コマンドで 1 つずつ確かめる
5-1 パッケージを作る
まとめ課題のノードは、すべて 1 つのパッケージ my_task に入れます。次の回の launch ファイルの例も、この名前で書いてあります。作り方は #04 の「2. パッケージを作る」と同じです。/scan の型を使うので、--dependencies に sensor_msgs を足します。
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python --node-name front_distance my_task --dependencies rclpy std_msgs sensor_msgs
--node-name front_distance を付けたので、ひな形の my_task/front_distance.py ができ、setup.py にも登録されています。自分の課題で知覚ノードの名前を変えた人は、ここも自分の名前にします。
5-2 AI に作らせ、シートと突き合わせる
次のプロンプトに、知覚ノードの設計シートを貼って AI に渡します。
次の設計シートどおりに、ROS 2 Humble で動く Python(rclpy)のノードを書いてください。
パッケージ名は my_task、ファイルは my_task/front_distance.py です。
設計シートにないトピックやパラメータは足さないでください。
(ここに知覚ノードの設計シートを貼る)
返ってきたコードは、保存する前に設計シートと突き合わせます。見るのは、#04 の「3-2. 設計シートと突き合わせる」と同じく、トピック名・型・QoS(/scan の購読に qos_profile_sensor_data が渡されているか。10 になっていたら、今は届いても送る側が変わると届かなくなる)・パラメータの名前と初期値、それから止まる条件・異常時の決まり(有効な点が無いときに何を出すか)です。違っていたら、直すのはシートではなくコードです。AI に「設計シートの○○と違う」と伝えて直させます。
突き合わせたら、ひな形のファイルを開いて、中身を AI のコードに置き換えて Ctrl+S で保存します。
codium ~/ros2_ws/src/my_task/my_task/front_distance.py
5-3 ビルドして、記録で動かす
cd ~/ros2_ws && colcon build --symlink-install && source install/setup.bash
前の回からロボットにつないだままの人は、先に robot-disconnect で切り離します。実物の /scan と記録の /scan が混ざらないようにするためです(#10・#11 と同じです)。
端末を 3 つ使います。新しく開いた端末では、ros2 run の前に source ~/ros2_ws/install/setup.bash が要ることがあります(「Package 'my_task' not found」と出たときです)。
# 端末 1:記録を再生する
cd ~/bags
ros2 bag play room_scan --loop
# 端末 2:自分の知覚ノードを動かす
ros2 run my_task front_distance
# 端末 3:出ているか、何 Hz かを見る
ros2 topic hz /front_distance
はじめに立てた予想(周期)と比べてから、結果を開いてください。
結果を見る(予想を書き、自分で実行してから開く)

ros2 topic hz。設計シートに書いた 5 Hz で出ている。真ん中のノードは画面に何も出さないが、それでよい(この画面ではパッケージ名が my_robot になっている)知覚ノードは /scan が来るたびに 1 回出しているので、周期は /scan と同じ 5 Hz 前後になります。
つながりも見ておきます。rqt_graph の使い方は #03 の実験 1 と同じで、表示を「Nodes/Topics (active)」にして更新ボタンを押します。
rqt_graph
5-4 設計どおりかを確かめる
次の表の 5 項目を、上から順に確かめます。「合格の目安」の値は、自分の設計シートに書いたものです。
| 確かめること | 使うもの | 合格の目安 |
|---|---|---|
| 出ているか | ros2 topic list | 自分で決めた名前で出ている |
| 型が設計どおりか | ros2 topic info -v | シートに書いた型と同じ |
| 周期が設計どおりか | ros2 topic hz | シートに書いた周期に近い |
| 値が正しいか | scan_monitor の「前」と並べる | 同じ場面で近い値になる |
| 異常時 | 記録の再生を一時停止する | シートに書いたとおりの動きになる |
ros2 topic list
ros2 topic info -v /front_distance
ros2 topic echo /front_distance
scan_monitor と並べるときは、もう 1 つ端末を開いて ros2 run sakigake_samples scan_monitor を動かします(#10 の「サンプルと比べる」)。記録を一時停止するには、端末 1 をクリックしてスペースキーを押します。もう一度押すと続きから再生します(#10 の実験 3)。一時停止したら、端末 3 の ros2 topic echo がどうなるかを見ます。
結果を見る(予想を書き、自分で実行してから開く)
一時停止したときに何が起きたかは、自分の設計シートの「止まる条件・異常時の決まり」と比べて判定します。シートと違う動きをしていたら、直すのはコードです。
判断ノードは、まだ作っていなくても試せる
知覚ノードの出力と同じ型・同じ名前のトピックを、手で送れます。次の回で使う方法です。
# 判断ノードに、知覚ノードの代わりの値を手で送る
ros2 topic pub --rate 5 /front_distance std_msgs/msg/Float32 "{data: 0.3}"
# 別の端末で、出てきた速度指令を見る
ros2 topic echo /cmd_vel_test
これができるのは、判断ノードが「距離という数字」だけを見ていて、LiDAR そのものを見ていないからです。知覚と判断を分けた効き目が、ここに出ます。
本質の問い
授業の最後に、次の 2 つに答えてください。
- 知覚・判断・行動を分けたことで、今日、ロボットなしで確かめられたことは何か。分けずに 1 つのノードにしていたら、どこで困ったか。
- 自分の判断ノードが「止まる」のは、どんなときか。3 つ挙げ、それぞれ、その場面をロボットなしで作る方法を書く。
考え方の例(答えを書いてから開く)
1 つめ:知覚ノードの値が正しいかどうかを、記録の再生だけで確かめられた。1 つにまとめていたら、距離の計算を直すたびにロボットを起こして箱を並べ直すことになる。また、速度指令を出す部分が同居していると、確かめている最中に脚が動く危険がある。
2 つめの例:①入力が 1 秒届かない(再生を一時停止すれば作れる)、②距離が inf(LiDAR の届かない広い場所の記録、または手で inf を送る)、③値が近すぎる(ros2 topic pub で 0.05 を送る)。
つまずきやすい点
| 症状 | 見るところ |
|---|---|
ros2 topic hz が何も出さない | ノードが出していないか、名前が違う。ros2 topic list で実際の名前を見る |
| 再生しているのに値が変わらない | 記録に /scan が入っているか(ros2 bag info)。ロボットにつながったままになっていないか |
| AI が設計シートと違う型で作った | ros2 topic info -v で型を見て、シートと突き合わせる。直すのはシートではなくコード |
| 周期が設計より速い・遅い | タイマーの間隔か、/scan が来るたびに出しているか。どちらにするかをシートに書いておく |
値が scan_monitor と大きく違う | 角度の単位(度とラジアン)と、正面の向き(front_angle_deg) |
まとめ
| やったこと | わかったこと |
|---|---|
| 課題を選ぶ | どの課題も、知覚・判断・行動に分けられる |
| グラフを先に描く | 名前・型・QoS・周期を決めておくと、AI に渡す材料がそろう |
| 設計シート | 止まる条件は、動かす前に決めておく項目である |
| 交換して指摘 | つながらないところは、紙の上で見つけられる |
| 記録で検証 | 知覚ノードは、ロボットが無くても合否を判定できる |
次の回は、残りのノードを作って 1 つの launch ファイルにまとめ、記録データ・机の上での確認・床の順に試験します。





