2025年8月28日 星期四

Ubuntu 24.04 install ros2_humble , gazebo_classic ,rviz2 範例

 這是一份在 Ubuntu 24.04 上安裝 ROS 2 HumbleGazebo ClassicRviz2 的範例說明。

由於 ROS 2 Humble 的官方支援版本是 Ubuntu 22.04 (Jammy),

因此在 Ubuntu 24.04 (Noble) 上安裝需要一些額外步驟。

1. 系統設定與 ROS 2 套件庫設定

首先,請確保您的系統是最新的,並設定 ROS 2 的套件庫。


1.1 更新系統與安裝基本工具

開啟終端機,執行以下指令:

sudo apt update
sudo apt upgrade
sudo apt install software-properties-common
sudo add-apt-repository universe

1.2 設定 ROS 2 套件庫

設定 GPG 金鑰以驗證套件,並將 ROS 2 套件庫加入您的來源清單:


sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo jammy) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

注意: 這裡我們將 ROS 2 的來源指定為 jammy,因為 Humble 是為 Ubuntu 22.04 (Jammy) 編譯的。這是在 Ubuntu 24.04 上安裝的關鍵步驟。


2. 安裝 ROS 2 Humble

現在可以開始安裝 ROS 2 Humble 的桌面完整版(Desktop Full)。

sudo apt update
sudo apt install ros-humble-desktop-full

這個指令會自動安裝包括 Rviz2 在內的所有核心套件。


3. 環境設定

安裝完成後,您需要將 ROS 2 的環境變數加入您的 shell 設定檔中,以便每次開啟終端機都能直接使用 ROS 2 指令。


echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

為了確保可以自動完成 ROS 2 指令,您也可以安裝 argcomplete

sudo apt install python3-argcomplete

然後在您的 ~/.bashrc 中加入這行:

eval "$(register-python-argcomplete3 ros2)"

4. 安裝 Gazebo Classic

ROS 2 Humble 官方支援的是 Gazebo garden,但許多舊專案仍使用 Gazebo Classic (版本 11)。這裡提供 Gazebo Classic 的安裝步驟。

4.1 設定 Gazebo 套件庫

sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" > /etc/apt/sources.list.d/gazebo-stable.list'
wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -

注意: 由於 apt-key 已過時,這個步驟可能會顯示警告。在 Ubuntu 24.04 上,更現代的方式是使用 curl

替代的現代方法:


sudo curl -sSL http://packages.osrfoundation.org/gazebo.key | sudo gpg --dearmor -o /usr/share/keyrings/osrf-stable-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/osrf-stable-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null

4.2 安裝 Gazebo Classic

sudo apt update
sudo apt install gazebo11
sudo apt install libgazebo11-dev

4.3 安裝 Gazebo 與 ROS 2 的整合套件

這部分是讓 ROS 2 能與 Gazebo Classic 溝通的關鍵:

sudo apt install ros-humble-gazebo-ros-pkgs

5. 測試安裝結果

5.1 測試 ROS 2

開啟兩個終端機。

  • 在第一個終端機:

    Bash
    ros2 run demo_nodes_cpp talker
    
  • 在第二個終端機:

    Bash
    ros2 run demo_nodes_py listener
    

如果看到 talker 發送訊息,listener 接收到,表示 ROS 2 核心安裝成功。

5.2 測試 Rviz2

在終端機輸入:

Bash
rviz2

Rviz2 視窗應該會成功開啟。

5.3 測試 Gazebo Classic

在終端機輸入:

Bash
gazebo

Gazebo 視窗應該會成功開啟。

恭喜! 現在您已經在 Ubuntu 24.04 上成功安裝了 ROS 2 Humble、Rviz2 和 Gazebo Classic。您可以開始進行您的機器人專案了。

2025年8月27日 星期三

Rviz2 for Twowheel

 要在 RViz2 裡觀察你兩輪車(twowheel_amr)的狀態與感測器資料,可以走這個最小流程:


1️⃣ 準備工作

先確定三個東西都在跑:

  1. gzserver(Gazebo Classic 伺服器,載入了 libgazebo_ros_factory.so

  2. spawn_entity.py(已把 twowheel_amr 放進 Gazebo)

  3. robot_state_publisher(用 robot_description 廣播 TF,讓 RViz2 看得到機器結構)

你可以用下面這個最小 Launch File(display.launch.py)幫你啟 robot_state_publisher:

from launch import LaunchDescription from launch.substitutions import Command, LaunchConfiguration from launch.actions import DeclareLaunchArgument from launch_ros.actions import Node def generate_launch_description(): urdf_file = LaunchConfiguration('urdf_file') return LaunchDescription([ DeclareLaunchArgument( 'urdf_file', default_value='/absolute/path/to/twowheel.fixed.urdf.xacro', description='URDF Xacro file' ), Node( package='robot_state_publisher', executable='robot_state_publisher', parameters=[{'robot_description': Command(['xacro ', urdf_file])}], output='screen' ), Node( package='joint_state_publisher_gui', executable='joint_state_publisher_gui' ) ])

啟動:

ros2 launch twowheel_bot display.launch.py urdf_file:=/absolute/path/to/twowheel.fixed.urdf.xacro




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


2️⃣ 開啟 RViz2

在另一個終端執行:

rviz2

3️⃣ RViz2 裡的設定

  1. 左下角 Add → 選擇 RobotModel → 你應該會看到 twowheel_amr 的 URDF。

    • Description Source 設為 robot_description

    • 參考座標框(Fixed Frame)設為 odombase_footprint

  2. Add → 選擇 LaserScan

    • Topic 設為 /twowheel_amr/scan(如果你用我幫你改的 <output_type>LaserScan</output_type>

    • Style 建議設為 PointsFlat Squares

  3. Add → 選擇 Imu

    • Topic 設為 /twowheel_amr/imu/data

    • 可以勾選「Axes」或「Imu」顯示方向。

  4. 如果需要 odometry,AddOdometry,topic 設為 /odom


4️⃣ 驗證

  • 在 RViz2 應該可以看到你的兩輪車模型。

  • LaserScan 會顯示一圈雷射點。

  • IMU 可以看到方向箭頭隨 Gazebo 車體晃動而改變。

  • 你也可以用指令確認:

    ros2 topic list | egrep "scan|imu|odom" ros2 topic echo /twowheel_amr/scan --once ros2 topic echo /twowheel_amr/imu/data --once

要不要我幫你直接寫一個 整合版 twowheel_rviz.launch.py

(同時跑 robot_state_publisher + rviz2,

並且自動載入一個配置好的 RViz2 設定檔 .rviz,直接打開就能看到車體+雷射+IMU)?


2025年8月26日 星期二

雷射(LiDAR) ,IMU for Gazebo URDF

 依照你前面在 Gazebo log 裡看到的兩個問題:

  1. Laser(ray sensor)缺 <output_type> → Gazebo 預設成 PointCloud2,RViz2 看起來不直覺。

  2. IMU sensor 缺 noise 配置 → 導致 Get noise index not valid

我幫你把這兩個部分補齊,直接整合進 xacro 版本。


修正版片段

雷射(LiDAR)

<gazebo reference="lidar_link"> <sensor name="lidar" type="ray"> <pose>0 0 0 0 0 0</pose> <visualize>true</visualize> <update_rate>30</update_rate> <ray> <scan> <horizontal> <samples>720</samples> <resolution>1</resolution> <min_angle>-1.5708</min_angle> <max_angle>1.5708</max_angle> </horizontal> </scan> <range> <min>0.12</min> <max>3.5</max> <resolution>0.01</resolution> </range> </ray> <!-- ROS 2 插件 --> <plugin name="gazebo_ros_laser" filename="libgazebo_ros_ray_sensor.so"> <ros> <namespace>/twowheel_amr</namespace> <remapping>~/out:=scan</remapping> </ros> <output_type>sensor_msgs/LaserScan</output_type> <!-- 新增 --> <frame_name>lidar_link</frame_name> </plugin> </sensor> </gazebo>

IMU

<gazebo reference="imu_link"> <sensor name="imu_sensor" type="imu"> <update_rate>200</update_rate> <always_on>true</always_on> <visualize>false</visualize> <imu> <angular_velocity> <x> <noise type="gaussian"> <mean>0.0</mean> <stddev>0.0002</stddev> <bias_mean>0.0</bias_mean> <bias_stddev>0.00001</bias_stddev> </noise> </x> <y><noise type="gaussian"><mean>0</mean><stddev>0.0002</stddev><bias_mean>0</bias_mean><bias_stddev>0.00001</bias_stddev></noise></y> <z><noise type="gaussian"><mean>0</mean><stddev>0.0002</stddev><bias_mean>0</bias_mean><bias_stddev>0.00001</bias_stddev></noise></z> </angular_velocity> <linear_acceleration> <x><noise type="gaussian"><mean>0</mean><stddev>0.02</stddev><bias_mean>0</bias_mean><bias_stddev>0.001</bias_stddev></noise></x> <y><noise type="gaussian"><mean>0</mean><stddev>0.02</stddev><bias_mean>0</bias_mean><bias_stddev>0.001</bias_stddev></noise></y> <z><noise type="gaussian"><mean>0</mean><stddev>0.02</stddev><bias_mean>0</bias_mean><bias_stddev>0.001</bias_stddev></noise></z> </linear_acceleration> </imu> <!-- ROS 2 插件 --> <plugin name="gazebo_ros_imu" filename="libgazebo_ros_imu_sensor.so"> <ros> <namespace>/twowheel_amr</namespace> <remapping>~/out:=imu/data</remapping> </ros> <initial_orientation_as_reference>false</initial_orientation_as_reference> <frame_name>imu_link</frame_name> </plugin> </sensor> </gazebo>

測試方法

  1. 重新轉換:

xacro twowheel.urdf.xacro -o /tmp/twowheel.urdf
  1. 再 spawn 進 Gazebo:

ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -file /tmp/twowheel.urdf
  1. 檢查 ROS2 topic:

ros2 topic list | egrep "scan|imu" ros2 topic echo /twowheel_amr/scan --once ros2 topic echo /twowheel_amr/imu/data --once


[建議測試]

# 轉成 URDF

xacro /path/to/twowheel.fixed.urdf.xacro -o /tmp/twowheel.urdf


#(可選)檢查

check_urdf /tmp/twowheel.urdf



/spawn_entity 不存在=你的 gzserver 沒跑,或沒載入 libgazebo_ros_factory.so,或終端的 GAZEBO_MASTER_URI 不一致。照下面最短路徑做就會好:

1) 在「終端A」起 gzserver(一定要帶 factory)

source /opt/ros/humble/setup.bash export ALSOFT_DRIVERS=null export LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe LIBGL_DRI3_DISABLE=1 #(可選)統一埠,兩個終端都要設同一值 export GAZEBO_MASTER_URI=http://127.0.0.1:11345 gzserver --verbose /usr/share/gazebo-11/worlds/empty.world \ -s libgazebo_ros_init.so \ -s libgazebo_ros_factory.so \ -s libgazebo_ros_force_system.so

別關掉這個終端;保持 gzserver 在跑。

# 先起 gzserver(建議 headless、靜音、軟體渲染)


# 另開終端 spawn(用檔案最穩)load urdf to gzserver world 

ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -file /tmp/twowheel.urdf


#gzclient is show GUI 

gzclient 


# 驗證感測器

ros2 topic list | egrep "scan|imu"

ros2 topic echo /twowheel_amr/scan --once

ros2 topic echo /twowheel_amr/imu/data --once


gazebo restart and load urdf

 sudo lsof -i :11345 正是要找出誰佔住 Gazebo Master 的 11345 連接埠

接下來的動作分兩步:


1. 看輸出結果

通常會出現類似:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gzserver 1234 ubuntu ... TCP *:11345 (LISTEN)

gzclient 5678 ubuntu ... TCP *:11345 (LISTEN)

重點是 COMMANDPID


2. 終止佔用者

假設輸出顯示:

  • gzserver 1234 → 就是之前殘留的模擬伺服器。

  • gzclient 5678 → GUI 端也可能卡住。

終止方法:

# 溫和 kill kill 1234 kill 5678 # 如果還不死,再強制 kill -9 sudo kill -9 1234

確認是否釋放:

sudo lsof -i :11345

沒有任何輸出就表示 11345 已經空出來。


3. 重新啟 Gazebo

export ALSOFT_DRIVERS=null export LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe LIBGL_DRI3_DISABLE=1 gzserver --verbose empty.world \ -s libgazebo_ros_init.so \ -s libgazebo_ros_factory.so \ -s libgazebo_ros_force_system.so


4 另開終端再跑 spawn:

load urdf to gzserver 

ros2 run gazebo_ros spawn_entity.py -entity twowheel_amr -file /path/to/twowheel.urdf


ros2 run gazebo_ros spawn_entity.py 執行詳細說明

spawn_entity.py 腳本是 ROS2 與 Gazebo 交互的核心工具之一,它的主要作用是將機器人模型(URDF 或 SDF 格式)動態地載入到正在運行的 Gazebo 模擬環境中。

指令分解

  • ros2 run:這是 ROS2 的標準指令,用於運行一個套件中的可執行腳本。

  • gazebo_ros:指定要運行腳本的套件名稱。

  • spawn_entity.py:要運行的 Python 腳本。

腳本參數

  • -entity twowheel_amr

    • -entity:指定要在 Gazebo 中生成的實體名稱。

    • twowheel_amr:這是你給機器人實體起的名字。這個名字在 Gazebo 模擬世界中是唯一的。

  • -file twowheel.urdf

    • -file:指定要載入的機器人描述檔案的完整路徑。

    • twowheel.urdf:這通常是你的 URDF 或 XACRO 檔案經過處理後生成的 URDF 格式。

執行過程

  1. 客戶端節點啟動ros2 run 指令啟動 spawn_entity.py 腳本,它會作為一個 ROS2 節點。

  2. 讀取模型檔案:腳本讀取 -file 參數指定的 twowheel.urdf 檔案內容。

  3. 尋找服務:腳本嘗試連接到 gzserver 提供的 ROS 服務 /spawn_entity

  4. 發送服務請求:如果成功連接到服務,腳本會將機器人實體的名稱(twowheel_amr)和 URDF 檔案的內容作為數據包,通過服務請求發送給 gzserver

  5. Gazebo 載入模型gzserver 接收到請求後,會解析 URDF 檔案,在模擬世界中創建機器人的所有連結、關節、視覺、碰撞模型,並初始化所有 Gazebo 插件。

  6. 結果回饋gzserver 返回一個服務響應,告訴 spawn_entity.py 腳本模型是否成功生成。

為何使用 spawn_entity.py

  • 動態載入:它允許你在 Gazebo 運行時動態地添加或移除機器人模型,而不需要每次都重新啟動整個 Gazebo 伺服器。

  • 與 ROS2 整合:它是一個標準的 ROS2 節點,可以直接在 launch 檔案中使用,方便自動化啟動整個模擬環境。



ROS2 launch (gzserver , gzclient )

 要將 gzservergzclient 協同啟動,最常見且最方便的方法是使用一個 launch 檔案。但如果你需要手動操作,可以按照以下兩個步驟來進行。

1. 啟動 Gazebo 伺服器 (gzserver)

首先,在一個終端機中啟動 Gazebo 伺服器,並載入你的世界檔案(例如 empty.world)。這個指令會啟動 Gazebo 的後端,但不會顯示任何圖形介面。

# 確保 Gazebo 已被正確安裝
gzserver empty.world
  • 參數說明

    • empty.world:指定 Gazebo 要載入的世界檔案。這個檔案定義了環境、光線和任何靜態物體。

2. 啟動 Gazebo 客戶端 (gzclient)

在另一個終端機中,啟動 Gazebo 客戶端。gzclient 會自動尋找並連接到正在運行的 gzserver

gzclient
  • 自動連接gzclient 預設會嘗試連接到本地主機的 Gazebo 伺服器。

  • 一旦連接成功,你就會看到 Gazebo 的圖形介面,顯示 gzserver 中正在運行的世界。

使用 launch 檔案自動化啟動 (推薦)

為了避免手動啟動兩個終端機,並確保所有設定都正確載入,強烈建議使用 ROS2 的 launch 檔案。我們之前建立的 gazebo.launch.py 就已經包含了這個邏輯。

這個 launch 檔案使用 IncludeLaunchDescription 來啟動 Gazebo,它會自動處理 gzservergzclient 的啟動。

[Python]
# 這是我們之前建立的 launch 檔案中的一部分
# This is a part of the launch file we created before
gazebo_ros_dir = get_package_share_directory('gazebo_ros')

gazebo_node = IncludeLaunchDescription(
    PythonLaunchDescriptionSource(
        os.path.join(gazebo_ros_dir, 'launch', 'gazebo.launch.py')
    ),
    launch_arguments={'world': 'empty.world'}.items()
)

這個指令會自動

  1. 啟動 gzserver:在背景運行 Gazebo 的伺服器。

  2. 啟動 gzclient:在前景啟動 Gazebo 的圖形介面。

總結: 雖然你可以手動啟動 gzservergzclient

但使用 ros2 launch 是更標準、更推薦的做法,

它可以將整個模擬環境的啟動過程自動化,

並確保所有 ROS2 節點和 Gazebo 插件都能正確載入。



2025年8月25日 星期一

ros2 run gazebo_ros spawn_entity.py 執行詳細說明

 

2. ros2 run gazebo_ros spawn_entity.py 執行詳細說明

spawn_entity.py 腳本是 ROS2 與 Gazebo 交互的核心工具之一,它的主要作用是將機器人模型(URDF 或 SDF 格式)動態地載入到正在運行的 Gazebo 模擬環境中。

指令分解

  • ros2 run:這是 ROS2 的標準指令,用於運行一個套件中的可執行腳本。

  • gazebo_ros:指定要運行腳本的套件名稱。

  • spawn_entity.py:要運行的 Python 腳本。

腳本參數

  • -entity twowheel_amr

    • -entity:指定要在 Gazebo 中生成的實體名稱。

    • twowheel_amr:這是你給機器人實體起的名字。這個名字在 Gazebo 模擬世界中是唯一的。

  • -file twowheel.urdf

    • -file:指定要載入的機器人描述檔案的完整路徑。

    • twowheel.urdf:這通常是你的 URDF 或 XACRO 檔案經過處理後生成的 URDF 格式。

執行過程

  1. 客戶端節點啟動ros2 run 指令啟動 spawn_entity.py 腳本,它會作為一個 ROS2 節點。

  2. 讀取模型檔案:腳本讀取 -file 參數指定的 twowheel.urdf 檔案內容。

  3. 尋找服務:腳本嘗試連接到 gzserver 提供的 ROS 服務 /spawn_entity

  4. 發送服務請求:如果成功連接到服務,腳本會將機器人實體的名稱(twowheel_amr)和 URDF 檔案的內容作為數據包,通過服務請求發送給 gzserver

  5. Gazebo 載入模型gzserver 接收到請求後,會解析 URDF 檔案,在模擬世界中創建機器人的所有連結、關節、視覺、碰撞模型,並初始化所有 Gazebo 插件。

  6. 結果回饋gzserver 返回一個服務響應,告訴 spawn_entity.py 腳本模型是否成功生成。

為何使用 spawn_entity.py

  • 動態載入:它允許你在 Gazebo 運行時動態地添加或移除機器人模型,而不需要每次都重新啟動整個 Gazebo 伺服器。

  • 與 ROS2 整合:它是一個標準的 ROS2 節點,可以直接在 launch 檔案中使用,方便自動化啟動整個模擬環境。

gazebo debug notex2

 你的系統少了常用的連接埠檢查工具(sslsof)。先安裝,

然後清掉殘留的 Gazebo,再重新啟動。

1) 安裝工具

sudo apt-get update sudo apt-get install -y iproute2 lsof net-tools psmisc # iproute2 提供 ss;net-tools 提供 netstat;psmisc 提供 killall

2) 查誰占用 11345(任選一種)

# 方法 A(建議):ss sudo ss -lptn 'sport = :11345' # 方法 B:lsof sudo lsof -i :11345 # 方法 C:netstat(備用) sudo netstat -lptn | grep 11345

看輸出中的 COMMAND/PID,通常是 gzservergzclient

3) 關掉殘留的 Gazebo

# 溫和地殺掉 killall gzserver gzclient 2>/dev/null || true # 若還活著,強制殺(用第2步查到的 PID) sudo kill -9 <PID1> <PID2>

4) 直接重新啟 gzserver(先把環境設乾淨)

(無頭、靜音、軟體渲染——最穩定)

source /opt/ros/humble/setup.bash export ALSOFT_DRIVERS=null export LIBGL_ALWAYS_SOFTWARE=1 export GALLIUM_DRIVER=llvmpipe export LIBGL_DRI3_DISABLE=1 gzserver --verbose empty.world \ -s libgazebo_ros_init.so \ -s libgazebo_ros_factory.so \ -s libgazebo_ros_force_system.so

這個終端請保持開著,表示 gzserver 正在跑。

5) 另一個終端再 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

6)(多人或重複實例)改用別的連接埠

如果你常常遇到「Address already in use」:

# 在所有相關終端一致設定(包含 gzserver / gzclient / spawn_entity / ros2 launch) export GAZEBO_MASTER_URI=http://127.0.0.1:11445


======

單獨啟動 gzserver

gzserver --verbose /usr/share/gazebo-11/worlds/empty.world \ -s libgazebo_ros_init.so -s libgazebo_ros_factory.so -s libgazebo_ros_force_system.so

1. Gzserver 和 Gzclient 的互動關係

在 Gazebo 模擬環境中,gzservergzclient 扮演著不同的角色,它們的協同工作模式是 ROS 模擬的核心。

  • gzserver (Gazebo Server)

    • 角色:模擬器後端,負責所有物理計算和感測器數據生成。

    • 主要職責

      1. 物理模擬:載入世界檔案(.world),處理所有物體之間的物理交互,例如重力、摩擦力、碰撞等。

      2. 感測器數據生成:根據 URDF 中定義的 Gazebo 插件(如 LiDAR、IMU、相機),生成並發佈虛擬的感測器數據。

      3. ROS 橋接:作為 ROS 的服務器,提供 spawn_entityset_model_state 等服務,以及發佈感測器數據和機器人里程計等 ROS 主題。

  • gzclient (Gazebo Client)

    • 角色:模擬器前端,負責所有圖形介面(GUI)的顯示。

    • 主要職責

      1. 視覺化:從 gzserver 接收模擬世界的渲染數據,並將其顯示在螢幕上。

      2. 使用者交互:提供使用者介面,允許使用者通過滑鼠或鍵盤在 3D 世界中移動視角、選擇物體、暫停或重啟模擬。

互動關係

  • gzserver 是核心,即使沒有 gzclient,它也可以在無頭(headless)模式下運行,持續進行模擬和發佈數據。

  • 這對於自動化測試和機器人訓練非常有用。

  • gzclient 是一個可選的 GUI 介面,它連接到 gzserver,以便使用者能夠可視化地觀察模擬過程。

  • 如果 gzserver 崩潰,gzclient 也會因為失去連接而結束。





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 的最後幾行貼上來,

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