2025年8月25日 星期一

ROS2 by Gaezbo (gzserver . gzclient) Notex1

Service /spawn_entity unavailable. Was Gazebo started with GazeboRosFactory?

= 你在執行 spawn_entity.py 時,gzserver 沒有在跑,或是 沒載入 libgazebo_ros_factory.so 外掛。先把伺服器(Gazebo Classic)正確起來,再執行 spawn 就會成功。

下面給你最穩、最短的檢查與啟動步驟(ROS 2 + Gazebo Classic 基礎):


1) 先確認環境

在每個新終端先做:

source /opt/ros/humble/setup.bash # 若有工作區,還要: # source ~/data/ros2_ws4/install/setup.bash

檢查外掛有沒有安裝:

dpkg -l | grep ros-humble-gazebo-ros-pkgs || sudo apt-get install -y ros-humble-gazebo-ros-pkgs

2) 正確啟動 gzserver(必須帶 Factory 外掛)

開「終端 A」:

# 若在伺服器/VM,建議軟體渲染 + 關聲音,避免 GL/ALSA 鬧事(可選但穩) export LIBGL_ALWAYS_SOFTWARE=1 export GALLIUM_DRIVER=llvmpipe export LIBGL_DRI3_DISABLE=1 export ALSOFT_DRIVERS=null # 僅啟動伺服器(不開 GUI),最穩: gzserver --verbose empty.world \ -s libgazebo_ros_init.so \ -s libgazebo_ros_factory.so \ -s libgazebo_ros_force_system.so

看到 Gazebo multi-robot simulator...[Msg] Waiting for master. 等訊息並持續跑著,就代表 OK。

若這一步立刻崩潰(exit code ≠ 0),把終端最後 30 行貼給我;通常是 GL/音效或外掛載不到。


3) 另開終端做 spawn(用檔案最穩)

開「終端 B」:

source /opt/ros/humble/setup.bash # source ~/data/ros2_ws4/install/setup.bash # 如需 # 你的檔案目前位於: cd ~/data/ros2_ws4/install/twowheel_bot/share/twowheel_bot/urdf # 直接用檔案(不用 topic)spawn: ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -file twowheel.urdf

成功會顯示:

[spawn_entity]: Spawn Entity started ... [INFO] SpawnEntity: Successfully spawned entity [twowheel_amr]

4)(可選)用 robot_description 方式

如果你想走 topic 方式,要robot_state_publisher 發佈 robot_description

「終端 C」:

source /opt/ros/humble/setup.bash # source ~/data/ros2_ws4/install/setup.bash ros2 run robot_state_publisher robot_state_publisher \ --ros-args -p robot_description:="$(xacro twowheel.urdf.xacro)"

「終端 B」再執行:

ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -topic robot_description

5) 快速排錯清單

  • ros2 topic list | grep spawn 不會看到 /spawn_entity(它是服務,不是 topic),要看 服務

    ros2 service list | grep spawn_entity

    只有在 gzserver + libgazebo_ros_factory.so 正常時才會出現 /spawn_entity

  • ps aux | grep gzserver 應該看到一個常駐的 gzserver 行程。

  • 盡量不要用 root跑 Gazebo/ROS 2;root 環境變數常不完整(若一定要 root,務必也 source 對應 setup.bash)。

  • 還是報 ALSA/GLX 錯誤→ 保持上面那些 export(軟體渲染 + 靜音)最穩。


一條龍(同一個終端)示範(先起 server,再 spawn)

# 1) 起 server(前景跑) source /opt/ros/humble/setup.bash export LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe LIBGL_DRI3_DISABLE=1 ALSOFT_DRIVERS=null gzserver --verbose empty.world -s libgazebo_ros_init.so -s libgazebo_ros_factory.so -s libgazebo_ros_force_system.so

另開終端:

# 2) spawn source /opt/ros/humble/setup.bash cd ~/data/ros2_ws4/install/twowheel_bot/share/twowheel_bot/urdf ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -file twowheel.urdf

照這樣跑,/spawn_entity 不存在的錯誤就會消失。若仍有狀況,把 gzserver --verbose 的錯誤訊息貼來,我幫你對症處理。


====================================


這個錯誤表示 Gazebo Master 連接埠被占用(預設是 11345)。

通常是之前的 gzserver/gzclient 還在背景跑,或你同時用 root/ubuntu 兩個帳號各啟了一個 Gazebo。


下面給你最穩、最快的解法(擇一或依序做):


A) 找到並關掉佔用者(建議先做)

# 找出誰占用 11345 sudo ss -lptn 'sport = :11345' # 或 sudo lsof -i :11345 # 殺掉殘留的 gzserver/gzclient(溫和) pkill -f gzserver pkill -f gzclient # 再確認一次 ps aux | egrep 'gzserver|gzclient|gazebo' | grep -v egrep

若還是無法釋放,用:

sudo kill -9 <PID> # 對 ss/lsof 找到的 PID

小提醒:避免混用 root 與 ubuntu 啟動 Gazebo。兩邊都會搶同一個 11345。


B) 改用另一個連接埠(多人/多實例同機時最穩)

在所有要用的終端(包含要跑 gzserverspawn_entity.pygzclient、以及 ros2 launch 的終端)一致設定:

export GAZEBO_MASTER_URI=http://127.0.0.1:11445

然後啟動:

gzserver --verbose empty.world \ -s libgazebo_ros_init.so \ -s libgazebo_ros_factory.so \ -s libgazebo_ros_force_system.so

另開終端(同樣先 export GAZEBO_MASTER_URI=http://127.0.0.1:11445)再執行:

ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -file /path/to/twowheel.urdf # 或需要 GUI 時 gzclient

C) 清理暫存(偶爾有用)

# 清除可能殘留的 lock / ipc 目錄(依你的使用者名稱) rm -rf /tmp/gazebo-*-$USER

D) 常見地雷避免

  • 同一台機器上每個使用者或每個專案都用不同的 GAZEBO_MASTER_URI 連接埠(例如 11445、11446…),避免互相干擾。

  • 若用 tmux/screen 或遠端斷線,背景可能還有 gzserver 留著;用 ps 檢查。

  • source /opt/ros/humble/setup.bash(以及你的工作區 install/setup.bash),再啟動 Gazebo/ROS 節點,避免外掛路徑錯。

  • 如果之前還有 OpenGL/ALSA 鬧事,啟動前可以加:

    export LIBGL_ALWAYS_SOFTWARE=1 export GALLIUM_DRIVER=llvmpipe export LIBGL_DRI3_DISABLE=1 export ALSOFT_DRIVERS=null

照 A 清掉佔用者或 B 改用新連接埠後,再啟 gzserverspawn_entity.py 就能過了。

若仍卡住,把你 ss -lptn 'sport = :11345'gzserver --verbose 的最後幾行貼上來,

我幫你精準判斷是哪個程序卡著。








沒有留言:

張貼留言