Cannot set Fixed Frame = map

By ihsumlee , 13 March 2026
content

讓 RViz2 的 Fixed Frame = map 不再出現

Frame [map] does not exist


Step 0:準備(每個 Terminal 都先 source)

每開一個新 terminal 先做:

source /opt/ros/jazzy/setup.bash
source ~/nav_class_ws/install/setup.bash

Step 1:啟動 Stage(提供 odom→base_link→laser 的 TF)

Terminal 1:

ros2 launch stage_ros2 demo.launch.py one_tf_tree:=true

✅ 檢查點 1:確認 TF 內有 robot_0/odom

ros2 topic echo /tf --once | head

你應該至少看到類似:

  • frame_id: robot_0/odom

  • child_frame_id: robot_0/base_link

沒看到 robot_0/odom 就代表 Stage 沒正常提供 TF,先別往下做。


Step 2:(可選)降低雷射頻率(避免 VM queue full)

Terminal 2:

ros2 run topic_tools throttle messages /robot_0/base_scan 10.0 /robot_0/base_scan_throttle

✅ 檢查點 2:確認 throttle topic 有資料

ros2 topic echo /robot_0/base_scan_throttle --once

Step 3:啟動 Nav2(map_server + amcl + controller)

Terminal 3:

重點:要加 autostart:=True(避免 lifecycle 卡住)

ros2 launch nav2_bringup bringup_launch.py \
  map:=/home/lee/nav_class_assets/maps/classroom_map_simple.yaml \
  params_file:=/home/lee/nav_class_assets/nav2/nav2_stage_robot0.yaml \
  use_sim_time:=True \
  autostart:=True

✅ 檢查點 3-1:確認 /map topic 存在且有資料

ros2 topic echo /map --once

要看到 frame_id: map,並印出 OccupancyGrid。

✅ 檢查點 3-2:確認 AMCL active + 允許 TF

ros2 lifecycle get /amcl
ros2 param get /amcl tf_broadcast

你要看到:

  • active [3]

  • Boolean value is: True


Step 4:關鍵步驟 —— 初始化 AMCL(讓 map frame 出現在 TF 裡)

你卡好幾天的根本原因就是:map frame 不是 map_server 給的,而是 AMCL 發的 map→odom TF。

AMCL 沒初始位姿時,map frame 不會出現。

你有兩種方式,建議兩種都會:


方法 A:用 RViz 點 2D Pose Estimate

  1. RViz → Global Options → Fixed Frame 先設 robot_0/odom(如果 map 還沒出現)

  2. 點上方工具列 2D Pose Estimate

  3. 在 map 上點一下位置 + 拖曳箭頭方向

  4. 等 2~5 秒

  5. 再把 Fixed Frame 改成 map


方法 B(救命用,完全不用 RViz):用指令發布 /initialpose

Terminal 4:

ros2 topic pub --once /initialpose geometry_msgs/PoseWithCovarianceStamped "
header:
  frame_id: map
pose:
  pose:
    position: {x: 0.0, y: 0.0, z: 0.0}
    orientation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}
  covariance: [0.25, 0, 0, 0, 0, 0,
               0, 0.25, 0, 0, 0, 0,
               0, 0, 0.0, 0, 0, 0,
               0, 0, 0, 0.0, 0, 0,
               0, 0, 0, 0, 0.0, 0,
               0, 0, 0, 0, 0, 0.0685]"
"

✅ 檢查點 4:確認 map→robot_0/odom TF 出現(最重要的驗證)

ros2 run tf2_ros tf2_echo map robot_0/odom
  • 若開始連續輸出 Translation/Rotation → ✅ map frame 真正存在了

  • 若還說 frame does not exist → AMCL frame 設定不匹配(下一節)


Step 5:RViz Fixed Frame 設為 map(應該要 OK)

現在回到 RViz:

  • Global Options → Fixed Frame = map

✅ 檢查點 5:左側顯示應該是

  • Global Status: Ok

  • Fixed Frame: Ok

如果 Step 4 做了仍然不行(最常見的設定錯誤)

請檢查 AMCL 的 frame 名稱是否 match Stage 的 TF:

ros2 param get /amcl odom_frame_id
ros2 param get /amcl base_frame_id

你應該要看到

  • robot_0/odom

  • robot_0/base_link

如果你看到 odombase_link(沒 robot_0/),就要改 nav2_stage_robot0.yaml


  • /map topic ≠ map frame

  • /map 是地圖資料;map frame 是 AMCL(或 SLAM)發布的 TF

  • 所以你必須 設定 initial pose,才能讓 map → robot_0/odom 出現,RViz Fixed Frame 才能用 map

 

 


 

如果你希望我把這份流程直接整理成你 Drupal 好貼的 Markdown(含標題、程式碼框、檢查點),我也可以直接輸出一份「可貼上 Drupal」版本。

Tags