welcom ! Handel home

2025年6月24日 星期二

ros_maze_house.stl 模型 load by ros2 gazebo x11

ros_maze_house.stl 模型

markdown
ros_maze_house/ └── meshes/ └── ros_maze_house.stl

接下來提供如何在 ROS 2 + Gazebo 11(Focal, Foxy 適用) 的 Docker 環境中,將該 STL 模型載入 Gazebo,並建立 ROS 套件的完整流程。


✅ 一、建立 ROS 2 套件 ros_maze_house_world

1. 建議結構

bash
ros2_ws/ └── src/ └── ros_maze_house_world/ ├── launch/ │ └── maze_world.launch.py ├── models/ │ └── maze_house/ │ ├── model.config │ ├── model.sdf │ └── meshes/ │ └── ros_maze_house.stl └── worlds/ └── maze_house.world

✅ 二、編寫模型 SDF 檔案 model.sdf

xml
<!-- models/maze_house/model.sdf --> <sdf version="1.6"> <model name="maze_house"> <static>true</static> <link name="maze_link"> <visual name="visual"> <geometry> <mesh> <uri>model://maze_house/meshes/ros_maze_house.stl</uri> <scale>1 1 1</scale> </mesh> </geometry> </visual> <collision name="collision"> <geometry> <mesh> <uri>model://maze_house/meshes/ros_maze_house.stl</uri> <scale>1 1 1</scale> </mesh> </geometry> </collision> </link> </model> </sdf>

✅ 三、建立 model.config

xml
<model> <name>maze_house</name> <version>1.0</version> <sdf version="1.6">model.sdf</sdf> <author> <name>ros-user</name> <email>ros@example.com</email> </author> <description>A STL-based maze model</description> </model>

✅ 四、建立 Gazebo 世界檔 maze_house.world

xml
<sdf version="1.6"> <world name="default"> <include> <uri>model://sun</uri> </include> <include> <uri>model://ground_plane</uri> </include> <include> <uri>model://maze_house</uri> </include> </world> </sdf>

✅ 五、建立 ROS 2 Launch 檔 maze_world.launch.py

python
from launch import LaunchDescription from launch.actions import ExecuteProcess from ament_index_python.packages import get_package_share_directory import os def generate_launch_description(): pkg_path = get_package_share_directory('ros_maze_house_world') world_path = os.path.join(pkg_path, 'worlds', 'maze_house.world') return LaunchDescription([ ExecuteProcess( cmd=[ 'gazebo', '--verbose', world_path, '-s', 'libgazebo_ros_factory.so' ], output='screen' ) ])

✅ 六、使用 Docker 建立 ROS 2 + Gazebo 環境

bash
docker run -it --rm \ --name ros2_gazebo_maze \ --env="DISPLAY" \ --env="QT_X11_NO_MITSHM=1" \ --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ --volume="$HOME/.Xauthority:/root/.Xauthority:rw" \ --volume="$HOME/ros2_ws:/root/ros2_ws:rw" \ --net=host \ osrf/ros:foxy-desktop

⚠️ 若用 ROS 2 Humble 請使用 osrf/ros:humble-desktop,Gazebo 版本需切換為 Fortress。


✅ 七、Docker 容器中執行步驟

bash
cd /root/ros2_ws source /opt/ros/foxy/setup.bash colcon build --packages-select ros_maze_house_world source install/setup.bash ros2 launch ros_maze_house_world maze_world.launch.py

✅ 八、設定 GAZEBO_MODEL_PATH(避免模型找不到)

bash
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/root/ros2_ws/install/ros_maze_house_world/share/ros_maze_house_world/models


2025年6月23日 星期一

ROS2 build the new package for maze world 建立迷宮套件

 


ros2 pkg create --build-type ament_cmake my_maze_world 這個命令是 ROS 2 中用來創建一個新的 ROS 2 套件 (package) 的指令。讓我來為您詳細解釋這個命令的每個部分及其用途:


命令拆解與說明

  • ros2 pkg create

    • 這是基礎命令,用於創建 ROS 2 套件。在 ROS 2 中,所有的程式碼、配置檔案、模型、啟動檔案等都被組織在套件中。這有助於模組化、重用和管理您的機器人專案。
  • --build-type ament_cmake

    • 這個參數指定了您要創建的套件的建構系統類型
    • 在 ROS 2 中,主要的建構系統有兩種:
      • ament_cmake: 這是基於 CMake 的建構系統,主要用於編譯 C++ 程式碼。它也支援處理 Python 模組、設定檔等。對於包含 C++ 節點、模型檔案、啟動檔案等,這是最常用的建構類型。
      • ament_python: 這是專為純 Python 套件設計的建構系統。如果您只打算用 Python 編寫程式碼且沒有任何 C++ 部分,可以使用這個。
    • 對於您打算在其中放置 Gazebo 模型、世界檔案和 ROS 2 啟動檔案的套件,ament_cmake正確且推薦的選擇,因為它提供了更廣泛的靈活性來管理這些資源。
  • my_maze_world

    • 這是您要創建的新套件的名稱。您可以將其替換為任何您喜歡的、有意義的名稱。
    • 命名慣例通常建議使用小寫字母和下劃線 (snake_case)。

執行這個命令會發生什麼?

當您在您的 ROS 2 工作空間的 src 目錄中執行這個命令時(例如,在 ~/ros2_ws/src),ros2 pkg create --build-type ament_cmake my_maze_world 將會:

  1. 創建一個新的目錄:在當前目錄下創建一個名為 my_maze_world 的新資料夾。
  2. 生成套件結構:在這個新資料夾內自動生成一個基本的套件結構,包括:
    • CMakeLists.txt:CMake 建構系統的主要配置檔案,用於定義如何編譯和安裝套件中的內容。
    • package.xml:套件的元資料檔案,包含套件的名稱、版本、描述、作者、維護者、以及最重要的依賴關係。ROS 2 使用這個檔案來了解套件所需的所有其他套件。
    • src/:一個空的目錄,通常用於放置 C++ 原始碼檔案。
    • include/:一個空的目錄,通常用於放置 C++ 頭檔案。
  3. 預設配置CMakeLists.txtpackage.xml 會被預先填充一些基礎的配置,讓您可以直接開始添加自己的程式碼和資源。

為什麼要創建這個套件?

創建像 my_maze_world 這樣的套件有以下幾個主要目的:

  1. 組織與管理:它提供了一個結構化的方式來組織所有與您的迷宮環境相關的檔案,例如:
    • 3D 模型檔案 (STL)。
    • Gazebo 模型描述檔案 (SDF)。
    • Gazebo 世界檔案 (World)。
    • ROS 2 啟動檔案 (Launch)。
    • 任何未來可能與迷宮互動的自定義 ROS 2 節點(例如,用於生成目標點或監控迷宮狀態的 Python/C++ 節點)。
  2. 依賴性管理:透過 package.xml,您可以明確定義您的迷宮套件所依賴的其他 ROS 2 套件(例如 gazebo_rosrclpyxacro 等)。這使得其他人在使用您的套件時,可以更容易地安裝所有必要的依賴項。
  3. 可重用性與分享:將迷宮相關的資源封裝在一個套件中,使得您可以輕鬆地在不同的專案中重用它,或與其他人分享您的迷宮環境。
  4. 建構系統集成ament_cmake 確保您的套件能夠被 colcon build 正確地編譯和安裝,從而將所有資源放置到 ROS 2 的安裝目錄中,方便被其他 ROS 2 節點或工具找到和使用。

簡而言之,my_maze_world 這個套件將成為您在 ROS 2 Humble 中管理和啟動迷宮模擬環境的中心。

ROS 2 (Humble) 中建置「迷宮環境(Maze)」模擬場景 的完整說明

關於 ROS 2 (Humble) 中建置「迷宮環境(Maze)」模擬場景 的完整說明,

包含如何使用 .STL 格式建模物件、載入到 Gazebo 中,

以及整合 ROS 2 模組(如地圖、定位、導航)。


🔷 一、什麼是 STL 格式(Stereolithography)

  • .STL 是一種表示三角形網格的 3D 模型格式,常用於機構建模、3D 列印。

  • 特點:

    • 僅描述幾何形狀(不包含顏色 / 材質 / 質感)

    • 可匯入到 Gazebo 作為靜態碰撞體或視覺模型

STL 在 Gazebo 中會透過 <mesh> 標籤載入成 visualcollision 組件。


🔷 二、建立迷宮 STL 並匯入 Gazebo

1️⃣ 建模(你可使用以下任一工具)

  • Blender:免費強大的 3D 建模軟體(可輸出 .stl

  • Fusion 360 / FreeCAD:適合精密機械建模

  • TinkerCAD:簡易建模(教育用途)

匯出時請注意單位(cm / m),Gazebo 使用公尺為單位。


2️⃣ STL 模型放置到資源資料夾

建議結構如下(符合 ROS package):

bash
my_maze_world/ ├── meshes/ │ └── maze_model.stl ├── models/ │ └── maze/ │ ├── model.config │ └── model.sdf ├── launch/ │ └── maze_world.launch.py ├── worlds/ │ └── maze.world

3️⃣ 建立 model.sdf(用於 Gazebo 載入 STL)

xml
<!-- models/maze/model.sdf --> <sdf version="1.6"> <model name="maze"> <static>true</static> <link name="maze_link"> <visual name="maze_visual"> <geometry> <mesh> <uri>model://maze/meshes/maze_model.stl</uri> <scale>1 1 1</scale> </mesh> </geometry> </visual> <collision name="maze_collision"> <geometry> <mesh> <uri>model://maze/meshes/maze_model.stl</uri> <scale>1 1 1</scale> </mesh> </geometry> </collision> </link> </model> </sdf>

4️⃣ 建立 model.config

xml
<!-- models/maze/model.config --> <model> <name>maze</name> <version>1.0</version> <sdf version="1.6">model.sdf</sdf> <author> <name>Handel</name> <email>you@example.com</email> </author> <description>Maze simulation model</description> </model>

🔷 三、建立 Gazebo 世界檔(maze.world)

xml
<!-- worlds/maze.world --> <sdf version="1.6"> <world name="default"> <include> <uri>model://sun</uri> </include> <include> <uri>model://ground_plane</uri> </include> <include> <uri>model://maze</uri> </include> </world> </sdf>

🔷 四、ROS 2 Humble 中整合 Gazebo

1️⃣ 安裝 ROS 2 Gazebo 套件(如尚未安裝)

bash
sudo apt install ros-humble-gazebo-ros-pkgs ros-humble-gazebo-ros2-control

2️⃣ 建立 launch file

python
# launch/maze_world.launch.py from launch import LaunchDescription from launch_ros.actions import Node from launch.actions import ExecuteProcess def generate_launch_description(): return LaunchDescription([ ExecuteProcess( cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_factory.so', './worlds/maze.world'], cwd='<YOUR_PACKAGE_PATH>', output='screen' ) ])

或使用 gazebo_ros 提供的 gazebo.launch.py,只需指定世界檔。


🔷 五、啟動迷宮模擬環境

bash
cd ~/ros2_ws colcon build source install/setup.bash ros2 launch my_maze_world maze_world.launch.py

🔷 六、常見延伸整合

功能使用方式
導入 SLAM 地圖建構加入 SLAM node + SLAM toolbox (slam_toolbox)
AMCL 定位使用 nav2_bringup,載入 .pgm + .yaml 地圖並配置初始位姿
自走導航使用 Nav2 的 lifecycle bringup、設定路徑、goal pose
加入自走車模型使用 URDF 或 XACRO 匯入機器人模型,搭配差速控制與 sensor plugin
使用 Rviz2 配合觀察ros2 run rviz2 rviz2,載入機器人與地圖顯示,設定 Frame = map/base_link

✅ 小結

模組任務
.stl建立迷宮模型
model.sdf將 STL 載入 Gazebo 物件模型
maze.world定義整個模擬場景
launch.py啟動 Gazebo + 模型
Nav2導航與避障
RViz2觀察 SLAM / AMCL / 路徑等結果

如需:

  • 範例 STL 模型 + SDF + 世界地圖

  • 輸出 .pgm/.yaml 地圖給 Nav2 用

  • 加入機器人模型與差速控制器

我可以幫你整理完整的 ROS 2 專案架構與腳本,是否需要一份 zip 專案樣板或 Docker 化模擬環境?

ROS2 建立 my_maze_world 迷宮模型的 package

以下是你要建立 my_maze_world 這個 ROS 2 Humble 套件的完整流程與建議放置位置,包含:

  1. 建立 ROS 2 package

  2. 放置 STL 模型、SDF 檔、world 檔、launch 檔

  3. 編譯與啟動


✅ 1. 推薦放置目錄

請在你的 ROS 2 開發空間(通常是 ~/ros2_ws)中操作:

bash
cd ~/ros2_ws/src ros2 pkg create --build-type ament_cmake my_maze_world

這會產生以下目錄結構:

css
ros2_ws/ └── src/ └── my_maze_world/ ├── CMakeLists.txt ├── package.xml

✅ 2. 加入 STL / SDF / world / launch 等資源檔案

建議加入以下資料夾結構:

lua
my_maze_world/ ├── CMakeLists.txt ├── package.xml ├── launch/ │ └── maze_world.launch.py ├── meshes/ │ └── maze_model.stl ├── models/ │ └── maze/ │ ├── model.config │ └── model.sdf ├── worlds/ │ └── maze.world ├── resource/ │ └── ...

✅ 3. 修改 CMakeLists.txt(加入安裝設定)

請在 CMakeLists.txt 加入:

cmake
install(DIRECTORY launch models meshes worlds DESTINATION share/${PROJECT_NAME} )

✅ 4. 修改 package.xml(加入依賴)

加入 gazebo 相關依賴(必要時):

xml
<exec_depend>gazebo_ros</exec_depend>

✅ 5. 編譯套件

bash
cd ~/ros2_ws colcon build --packages-select my_maze_world source install/setup.bash

✅ 6. 啟動模擬環境

bash
ros2 launch my_maze_world maze_world.launch.py

確保你有正確安裝 Gazebo 並設好環境變數(如:GAZEBO_MODEL_PATH


✅ 7. 設定 GAZEBO_MODEL_PATH(讓 Gazebo 找到模型)

bash
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/ros2_ws/install/my_maze_world/share/my_maze_world/models

建議你可以加入 .bashrc

bash
echo 'export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:$HOME/ros2_ws/install/my_maze_world/share/my_maze_world/models' >> ~/.bashrc source ~/.bashrc

✅ 範例專案完成後執行畫面

成功後你會看到:

  • Gazebo 啟動,載入 ground_plane、sun、maze.stl 迷宮模型

  • 可手動放入機器人進行 SLAM、Nav2 等應用


如果你需要我幫你建立這個 ROS 2 my_maze_world package 的初始專案 zip 包,包含:

  • STL 測試模型

  • Gazebo 世界檔

  • SDF 模型定義

  • 含啟動 launch 的完整專案

也可以提供,請告訴我你要的格式。

2025年6月11日 星期三

ROS 2 Gazebo 並整合控制與感測器

將模型放入 ROS 2 Gazebo 並整合控制與感測器

將模型放入 ROS 2 Gazebo 並整合控制與感測器

本指南將詳細說明如何將您的 URDF 模型整合到 ROS 2 Gazebo 環境中,並加入控制插件、感測器模擬以及 RViz 可視化配置。內容基於您提供的資訊進行組織。

關於檔案名稱的注意事項: 您提供的 zip 檔案包含一個資料夾 ROS小車URDF-02,其中有一個 .urdf 檔案和多個 .stl 檔案(機構模型),命名中有中文亂碼(例如 Φ╗èΘ½ö_IMU.stl),這可能是編碼問題造成的。在實際操作中,建議將這些檔案重新命名為英文或純數字名稱,以避免潛在問題。本指南中的範例會使用簡化的英文名稱。

✅ 一、前置需求

請確保您已安裝以下軟體:

  • ROS 2(如 Humble / Iron)
  • Gazebo(通常是 Gazebo Classic,非 Ignition)
  • ros_ign_gazebo(如果您使用的是 Ignition 版本)
  • gazebo_ros_pkgs
✅ 二、解壓模型檔案

假設您有一個 ROS 2 workspace 位於 ~/ros2_ws。請使用以下指令將壓縮包解壓到您的 ROS 2 工作區:

bash 已複製!
cd ~/ros2_ws/src
unzip /mnt/data/ROS小車URDF-02.zip -d urdf_car

這會將內容解壓到 ~/ros2_ws/src/urdf_car 資料夾中。

✅ 三、檢查模型目錄結構

解壓後,請確保目錄內包含類似以下結構(請根據實際情況調整檔案名稱):

swift 已複製!
urdf_car/
├── CMakeLists.txt
├── package.xml
├── launch/
│   └── gazebo.launch.py
├── urdf/
│   └── car.urdf.xacro  或 car.urdf (根據您提供的檔案應為 .urdf)
├── meshes/
│   └── *.dae / *.stl
└── world/
    └── your_world.world (optional)

如果檔案是 .xacro 格式,您需要在啟動前轉換成 URDF 格式。由於您提供的檔案是 .urdf,通常不需要額外轉換,但請檢查內容是否完整。

✅ 四、建立 launch 檔來載入模型至 Gazebo

這是一個典型的 gazebo.launch.py 範例,可以用來載入車模到 Gazebo。請將此內容儲存到 urdf_car/launch/gazebo.launch.py。確保 arguments=['urdf/car.urdf'] 中的檔案名稱與您的模型實際名稱一致。

python 已複製!
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess

def generate_launch_description():
    return LaunchDescription([
        # 啟動 Gazebo 模擬器 
        ExecuteProcess(
            cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_factory.so'],
            output='screen'),

        # 載入車輛模型
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            name='robot_state_publisher',
            output='screen', 
            parameters=[{'use_sim_time': True}],
            arguments=['urdf/car.urdf']  # 根據實際檔名修改,例如 'urdf/ROS小車URDF-02.urdf'
        ),

        # Spawn Model 到 Gazebo 中
        Node(
            package='gazebo_ros',
            executable='spawn_entity.py',
            arguments=['-entity', 'urdf_car', '-file', 'urdf/car.urdf', '-x', '0', '-y', '0', '-z', '0.2'], 
            output='screen'
        )
    ])
✅ 五、編譯並啟動
  1. 回到工作區根目錄並編譯您的 package:
  2. bash 已複製!
    cd ~/ros2_ws
    colcon build --packages-select urdf_car
    source install/setup.bash
  3. 啟動模擬:
  4. bash 已複製!
    ros2 launch urdf_car gazebo.launch.py
✅ 六、建議補充(選用)

以下是進一步增強您的模型與模擬環境的建議:

  • 加入控制插件(如 diff_drive_controller)
  • 加入感測器模擬(如 lidar、camera、IMU)
  • 撰寫控制節點與 RViz 可視化配置

接下來的步驟

以下將說明如何加入控制器、感測器模擬、RViz 可視化設定及控制節點。

① 修改 URDF:加入 Plugin 和 Sensor 模組

請將以下範例片段加入到您的 URDF 檔案中。通常這些 <gazebo> 標籤會放在 </robot> 標籤之前,或者與對應的 <link> 標籤在相同的 <robot> 範圍內。請確保連接 (reference) 的 link name 正確。

✅ 加入 Diff Drive Controller Plugin
xml 已複製!
<gazebo>
  <plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
    <ros>
      <namespace>/</namespace> 
    </ros>
    <update_rate>50</update_rate>
    <left_wheel>left_wheel_joint</left_wheel>
    <right_wheel>right_wheel_joint</right_wheel>
    <wheel_separation>0.5</wheel_separation>
    <wheel_diameter>0.15</wheel_diameter>
    <command_topic>cmd_vel</command_topic>
    <odometry_topic>odom</odometry_topic>
    <odometry_frame>odom</odometry_frame>
    <robot_base_frame>base_link</robot_base_frame>
    <publish_tf>true</publish_tf>
  </plugin>
</gazebo>

注意: 請將 left_wheel_jointright_wheel_joint 替換為您 URDF 中實際定義的左右輪關節名稱。

✅ 加入 IMU 感測器模擬
xml 已複製!
<link name="imu_link">
  <inertial>
    <mass value="0.01"/>
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001"/>
  </inertial>
</link>

<gazebo reference="imu_link">
  <sensor name="imu_sensor" type="imu">
    <always_on>true</always_on>
    <update_rate>50</update_rate>
    <imu> 
      <angular_velocity />
      <linear_acceleration />
    </imu>
    <plugin name="imu_plugin" filename="libgazebo_ros_imu_sensor.so"/>
  </sensor>
</gazebo>

注意: 您需要在 URDF 中定義一個名為 imu_link 的連結,並將其放置在模型中 IMU 實際位置。如果您的模型中已有名為 Φ╗èΘ½ö_IMU.stl 的 mesh,則可能需要創建一個對應的 linkjoint,並將此 <gazebo reference="imu_link"> 部分與其關聯。

✅ 加入相機模擬(RGB Camera)
xml 已複製!
<gazebo reference="camera_link">
  <sensor name="camera_sensor" type="camera">
    <camera>
      <horizontal_fov>1.39626</horizontal_fov>
      <image>
        <width>640</width>
        <height>480</height>
        <format>R8G8B8</format>
      </image>
      <clip>
        <near>0.1</near>
        <far>100</far> 
      </clip>
    </camera>
    <plugin name="camera_controller" filename="libgazebo_ros_camera.so">
      <camera_name>camera</camera_name>
      <image_topic_name>image_raw</image_topic_name>
      <camera_info_topic_name>camera_info</camera_info_topic_name>
    </plugin>
  </sensor>
</gazebo>

注意: 您需要在 URDF 中定義一個名為 camera_link 的連結,並將其放置在模型中相機實際位置。

✅ 加入 LiDAR 模擬(單線雷達)
xml 已複製!
<gazebo reference="lidar_link">
  <sensor name="lidar_sensor" type="ray">
    <ray>
      <scan>
        <horizontal>
          <samples>720</samples>
          <resolution>1</resolution>
          <min_angle>-1.57</min_angle>
          <max_angle>1.57</max_angle> 
        </horizontal>
      </scan>
      <range>
        <min>0.1</min>
        <max>10.0</max>
        <resolution>0.01</resolution>
      </range>
    </ray>
    <plugin name="gazebo_ros_laser" filename="libgazebo_ros_ray_sensor.so"/>
  </sensor>
</gazebo>

注意: 您需要在 URDF 中定義一個名為 lidar_link 的連結,並將其放置在模型中 LiDAR 實際位置。

② RViz 可視化設定

在您的 urdf_car package 中新增一個 rviz 資料夾,並在其中創建一個 car_config.rviz 檔案。將以下內容複製到該檔案中。這是一個簡化示意,您可以根據需要添加更多顯示項。

ini 已複製!
Visualization Manager:
  Class: ""
  Displays:
    - Name: RobotModel
      Enabled: true
      Robot Description: robot_description 
    - Name: TF
      Enabled: true
    - Name: Odometry
      Topic: /odom
      Enabled: true
    - Name: LaserScan
      Topic: /scan
      Enabled: true

③ 控制節點(Teleop 範例)

要透過鍵盤控制車輛,您可以安裝 teleop_twist_keyboard package。

  1. 安裝:
  2. bash 已複製!
    sudo apt install ros-humble-teleop-twist-keyboard
  3. 執行:
  4. bash 已複製!
    ros2 run teleop_twist_keyboard teleop_twist_keyboard

    這會發布 /cmd_vel 主題,用於控制車子移動。

④ 啟動 Launch 檔整合

您可以建立一個新的 bringup.launch.py 檔案(例如在 urdf_car/launch/ 中)來一次性啟動 Gazebo、模型和 RViz。

python 已複製!
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
import os
from ament_index_python.packages import get_package_share_directory # 需要添加此行以獲取包路徑

def generate_launch_description():
    pkg_share = get_package_share_directory('urdf_car') # 獲取 urdf_car 包的安裝路徑

    return LaunchDescription([
        # 啟動 Gazebo + 模型 
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(pkg_share, 'launch', 'gazebo.launch.py'))
        ),

        # 啟動 RViz
        Node(
            package='rviz2',
            executable='rviz2',
            name='rviz2',
            arguments=['-d', os.path.join(pkg_share, 'rviz', 'car_config.rviz')], 
            output='screen'
        ),
    ])

注意: 您可能需要手動編輯 urdf_car/CMakeLists.txtpackage.xml,以確保這些新的 launchrviz 檔案會被安裝到 package 的 share 目錄中。例如,在 CMakeLists.txt 中加入類似以下行:

cmake 已複製!
install(
    DIRECTORY launch rviz
    DESTINATION share/${PROJECT_NAME}
)
install(
    FILES urdf/car.urdf # 如果您的urdf在urdf/下,請確保安裝
    DESTINATION share/${PROJECT_NAME}/urdf
)
install(
    DIRECTORY meshes # 如果您有 meshes 資料夾,請確保安裝
    DESTINATION share/${PROJECT_NAME}/meshes
)

並在 package.xml 中確認所有依賴都已聲明,例如 gazebo_ros, robot_state_publisher, rviz2 等。

✅ 總結

完成這些步驟後,您現在將擁有一個更完整的 ROS 2 Gazebo 模擬環境:

  • URDF 中加入了輪控器、IMU、雷達、相機模擬。
  • RViz 可視化:可顯示模型、雷達、IMU 等。
  • 控制節點:可用鍵盤控制車輛。
  • 啟動腳本:自動載入模型與視覺化環境。

若您需要實際修改您的 URDF 檔案並產出完整的工作範例,或者需要協助產生 package.xmlCMakeLists.txt 等,我可以進一步提供協助。

ROS2_Gazebo_URDF build and Load

將模型放入 ROS 2 Gazebo 並整合控制與感測器

將模型放入 ROS 2 Gazebo 並整合控制與感測器

本指南將詳細說明如何將您的 URDF 模型整合到 ROS 2 Gazebo 環境中,並加入控制插件、感測器模擬以及 RViz 可視化配置。內容基於您提供的資訊進行組織。

關於檔案名稱的注意事項: 您提供的 zip 檔案包含一個資料夾 ROS小車URDF-02,其中有一個 .urdf 檔案和多個 .stl 檔案(機構模型),命名中有中文亂碼(例如 Φ╗èΘ½ö_IMU.stl),這可能是編碼問題造成的。在實際操作中,建議將這些檔案重新命名為英文或純數字名稱,以避免潛在問題。本指南中的範例會使用簡化的英文名稱。

✅ 一、前置需求

請確保您已安裝以下軟體:

  • ROS 2(如 Humble / Iron)
  • Gazebo(通常是 Gazebo Classic,非 Ignition)
  • ros_ign_gazebo(如果您使用的是 Ignition 版本)
  • gazebo_ros_pkgs
✅ 二、解壓模型檔案

假設您有一個 ROS 2 workspace 位於 ~/ros2_ws。請使用以下指令將壓縮包解壓到您的 ROS 2 工作區:

bash 已複製!
cd ~/ros2_ws/src
unzip /mnt/data/ROS小車URDF-02.zip -d urdf_car

這會將內容解壓到 ~/ros2_ws/src/urdf_car 資料夾中。

✅ 三、檢查模型目錄結構

解壓後,請確保目錄內包含類似以下結構(請根據實際情況調整檔案名稱):

swift 已複製!
urdf_car/
├── CMakeLists.txt
├── package.xml
├── launch/
│   └── gazebo.launch.py
├── urdf/
│   └── car.urdf.xacro  或 car.urdf (根據您提供的檔案應為 .urdf)
├── meshes/
│   └── *.dae / *.stl
└── world/
    └── your_world.world (optional)

如果檔案是 .xacro 格式,您需要在啟動前轉換成 URDF 格式。由於您提供的檔案是 .urdf,通常不需要額外轉換,但請檢查內容是否完整。

✅ 四、建立 launch 檔來載入模型至 Gazebo

這是一個典型的 gazebo.launch.py 範例,可以用來載入車模到 Gazebo。請將此內容儲存到 urdf_car/launch/gazebo.launch.py。確保 arguments=['urdf/car.urdf'] 中的檔案名稱與您的模型實際名稱一致。

python 已複製!
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess

def generate_launch_description():
    return LaunchDescription([
        # 啟動 Gazebo 模擬器 
        ExecuteProcess(
            cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_factory.so'],
            output='screen'),

        # 載入車輛模型
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            name='robot_state_publisher',
            output='screen', 
            parameters=[{'use_sim_time': True}],
            arguments=['urdf/car.urdf']  # 根據實際檔名修改,例如 'urdf/ROS小車URDF-02.urdf'
        ),

        # Spawn Model 到 Gazebo 中
        Node(
            package='gazebo_ros',
            executable='spawn_entity.py',
            arguments=['-entity', 'urdf_car', '-file', 'urdf/car.urdf', '-x', '0', '-y', '0', '-z', '0.2'], 
            output='screen'
        )
    ])
✅ 五、編譯並啟動
  1. 回到工作區根目錄並編譯您的 package:
  2. bash 已複製!
    cd ~/ros2_ws
    colcon build --packages-select urdf_car
    source install/setup.bash
  3. 啟動模擬:
  4. bash 已複製!
    ros2 launch urdf_car gazebo.launch.py
✅ 六、建議補充(選用)

以下是進一步增強您的模型與模擬環境的建議:

  • 加入控制插件(如 diff_drive_controller)
  • 加入感測器模擬(如 lidar、camera、IMU)
  • 撰寫控制節點與 RViz 可視化配置

接下來的步驟

以下將說明如何加入控制器、感測器模擬、RViz 可視化設定及控制節點。

① 修改 URDF:加入 Plugin 和 Sensor 模組

請將以下範例片段加入到您的 URDF 檔案中。通常這些 <gazebo> 標籤會放在 </robot> 標籤之前,或者與對應的 <link> 標籤在相同的 <robot> 範圍內。請確保連接 (reference) 的 link name 正確。

✅ 加入 Diff Drive Controller Plugin
xml 已複製!
<gazebo>
  <plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
    <ros>
      <namespace>/</namespace> 
    </ros>
    <update_rate>50</update_rate>
    <left_wheel>left_wheel_joint</left_wheel>
    <right_wheel>right_wheel_joint</right_wheel>
    <wheel_separation>0.5</wheel_separation>
    <wheel_diameter>0.15</wheel_diameter>
    <command_topic>cmd_vel</command_topic>
    <odometry_topic>odom</odometry_topic>
    <odometry_frame>odom</odometry_frame>
    <robot_base_frame>base_link</robot_base_frame>
    <publish_tf>true</publish_tf>
  </plugin>
</gazebo>

注意: 請將 left_wheel_jointright_wheel_joint 替換為您 URDF 中實際定義的左右輪關節名稱。

✅ 加入 IMU 感測器模擬
xml 已複製!
<link name="imu_link">
  <inertial>
    <mass value="0.01"/>
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001"/>
  </inertial>
</link>

<gazebo reference="imu_link">
  <sensor name="imu_sensor" type="imu">
    <always_on>true</always_on>
    <update_rate>50</update_rate>
    <imu> 
      <angular_velocity />
      <linear_acceleration />
    </imu>
    <plugin name="imu_plugin" filename="libgazebo_ros_imu_sensor.so"/>
  </sensor>
</gazebo>

注意: 您需要在 URDF 中定義一個名為 imu_link 的連結,並將其放置在模型中 IMU 實際位置。如果您的模型中已有名為 Φ╗èΘ½ö_IMU.stl 的 mesh,則可能需要創建一個對應的 linkjoint,並將此 <gazebo reference="imu_link"> 部分與其關聯。

✅ 加入相機模擬(RGB Camera)
xml 已複製!
<gazebo reference="camera_link">
  <sensor name="camera_sensor" type="camera">
    <camera>
      <horizontal_fov>1.39626</horizontal_fov>
      <image>
        <width>640</width>
        <height>480</height>
        <format>R8G8B8</format>
      </image>
      <clip>
        <near>0.1</near>
        <far>100</far> 
      </clip>
    </camera>
    <plugin name="camera_controller" filename="libgazebo_ros_camera.so">
      <camera_name>camera</camera_name>
      <image_topic_name>image_raw</image_topic_name>
      <camera_info_topic_name>camera_info</camera_info_topic_name>
    </plugin>
  </sensor>
</gazebo>

注意: 您需要在 URDF 中定義一個名為 camera_link 的連結,並將其放置在模型中相機實際位置。

✅ 加入 LiDAR 模擬(單線雷達)
xml 已複製!
<gazebo reference="lidar_link">
  <sensor name="lidar_sensor" type="ray">
    <ray>
      <scan>
        <horizontal>
          <samples>720</samples>
          <resolution>1</resolution>
          <min_angle>-1.57</min_angle>
          <max_angle>1.57</max_angle> 
        </horizontal>
      </scan>
      <range>
        <min>0.1</min>
        <max>10.0</max>
        <resolution>0.01</resolution>
      </range>
    </ray>
    <plugin name="gazebo_ros_laser" filename="libgazebo_ros_ray_sensor.so"/>
  </sensor>
</gazebo>

注意: 您需要在 URDF 中定義一個名為 lidar_link 的連結,並將其放置在模型中 LiDAR 實際位置。

② RViz 可視化設定

在您的 urdf_car package 中新增一個 rviz 資料夾,並在其中創建一個 car_config.rviz 檔案。將以下內容複製到該檔案中。這是一個簡化示意,您可以根據需要添加更多顯示項。

ini 已複製!
Visualization Manager:
  Class: ""
  Displays:
    - Name: RobotModel
      Enabled: true
      Robot Description: robot_description 
    - Name: TF
      Enabled: true
    - Name: Odometry
      Topic: /odom
      Enabled: true
    - Name: LaserScan
      Topic: /scan
      Enabled: true

③ 控制節點(Teleop 範例)

要透過鍵盤控制車輛,您可以安裝 teleop_twist_keyboard package。

  1. 安裝:
  2. bash 已複製!
    sudo apt install ros-humble-teleop-twist-keyboard
  3. 執行:
  4. bash 已複製!
    ros2 run teleop_twist_keyboard teleop_twist_keyboard

    這會發布 /cmd_vel 主題,用於控制車子移動。

④ 啟動 Launch 檔整合

您可以建立一個新的 bringup.launch.py 檔案(例如在 urdf_car/launch/ 中)來一次性啟動 Gazebo、模型和 RViz。

python 已複製!
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
import os
from ament_index_python.packages import get_package_share_directory # 需要添加此行以獲取包路徑

def generate_launch_description():
    pkg_share = get_package_share_directory('urdf_car') # 獲取 urdf_car 包的安裝路徑

    return LaunchDescription([
        # 啟動 Gazebo + 模型 
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(pkg_share, 'launch', 'gazebo.launch.py'))
        ),

        # 啟動 RViz
        Node(
            package='rviz2',
            executable='rviz2',
            name='rviz2',
            arguments=['-d', os.path.join(pkg_share, 'rviz', 'car_config.rviz')], 
            output='screen'
        ),
    ])

注意: 您可能需要手動編輯 urdf_car/CMakeLists.txtpackage.xml,以確保這些新的 launchrviz 檔案會被安裝到 package 的 share 目錄中。例如,在 CMakeLists.txt 中加入類似以下行:

cmake 已複製!
install(
    DIRECTORY launch rviz
    DESTINATION share/${PROJECT_NAME}
)
install(
    FILES urdf/car.urdf # 如果您的urdf在urdf/下,請確保安裝
    DESTINATION share/${PROJECT_NAME}/urdf
)
install(
    DIRECTORY meshes # 如果您有 meshes 資料夾,請確保安裝
    DESTINATION share/${PROJECT_NAME}/meshes
)

並在 package.xml 中確認所有依賴都已聲明,例如 gazebo_ros, robot_state_publisher, rviz2 等。

✅ 總結

完成這些步驟後,您現在將擁有一個更完整的 ROS 2 Gazebo 模擬環境:

  • URDF 中加入了輪控器、IMU、雷達、相機模擬。
  • RViz 可視化:可顯示模型、雷達、IMU 等。
  • 控制節點:可用鍵盤控制車輛。
  • 啟動腳本:自動載入模型與視覺化環境。

若您需要實際修改您的 URDF 檔案並產出完整的工作範例,或者需要協助產生 package.xmlCMakeLists.txt 等,我可以進一步提供協助。

2025年4月18日 星期五

成功安裝了 micro-ROS / ROS 2 ESP32 開發環境

 已經成功安裝了 micro-ROS / ROS 2 ESP32 開發環境所需的 Python 套件與 colcon 工具鏈,其中包括:

  • colcon 相關核心與擴充

  • empy(ROS2 build template 使用)

  • pytest(unit test 支援)

  • catkin_pkg(老式 ROS1 兼容用)

  • PyYAML 等支援性工具

這表示你的 Python 環境、虛擬環境與 micro-ROS toolchain 現在都已經準備好,可以進行後續的韌體建構、燒錄與 agent 通訊測試。


🔜 建議你下一步可以做的事:

✅ 建構韌體

bash
ros2 run micro_ros_setup build_firmware.sh

這會編譯 ESP32 韌體(FreeRTOS + micro-ROS)並輸出至 firmware/build/ 目錄。


✅ 確認 USB 串口後燒錄(ESP32 預設為 /dev/ttyUSB0

bash
export MICROROS_FIRMWARE_SERIAL_DEVICE=/dev/ttyUSB0 ros2 run micro_ros_setup flash_firmware.sh

✅ 執行 micro-ROS Agent(在主機端,連接到 ESP32)

bash
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0

你應該會看到 micro-ROS agent 開始通訊、顯示 INFO micro_ros_agent 類似的日誌輸出。


✅ 測試 ROS 2 通訊(主機)

bash
ros2 topic list ros2 topic echo /<你的 topic 名稱>

🛠 若你還沒寫 app.c 內容

你可以用預設範本:

bash
ros2 run micro_ros_setup configure_firmware.sh int32_publisher -t serial -d /dev/ttyUSB0

會建立一個簡單的 ROS publisher,固定頻率送 std_msgs/msg/Int32/int32_publisher topic。


如果你之後想改成自訂的 topic、subscriber、timer、executor 範本,我可以幫你快速產一份乾淨的 app.c 模板。

是否需要我幫你生成一份 ESP32 專用的 micro-ROS 範例 app.c?或整個專案初始化腳本?




目前 firmware/ 裡沒有 esp-idf/ 資料夾,這代表 micro-ROS 的 ESP32 韌體環境建立雖然成功,但 ESP-IDF SDK 尚未下載或安裝完成,所以還不能開始 build。


🔍 為什麼沒有 esp-idf/

這是因為 ESP-IDF 套件通常是在執行以下指令時才會被自動下載安裝:

bash
ros2 run micro_ros_setup build_firmware.sh

該指令會觸發:

  • 建立 esp-idf/ 資料夾

  • 執行 esp-idf/install.sh

  • 設定 Python 虛擬環境

  • 初始化環境變數(例如 . ./export.sh


✅ 解法步驟

請你接下來執行這步驟:

bash
ros2 run micro_ros_setup build_firmware.sh

這會自動觸發以下操作:

  • Clone ESP-IDF(通常為 v4.4 版,根據 micro-ROS 設定)

  • 安裝 Python 套件到 virtualenv

  • 設定 toolchain 與編譯配置

  • 準備 build tree 與 sdkconfig


🛠 若你遇到失敗(例如 proxy 或 pip 問題)

你也可以手動做:

bash
cd firmware/ git clone -b v4.4 --recursive https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh

完成後:

bash
. ./export.sh

然後再回去執行:

bash
ros2 run micro_ros_setup build_firmware.sh

📂 正常情況下的 firmware/ 應為:

lua
firmware/ ├── COLCON_IGNORE ├── PLATFORM ├── dev_ws/ ├── freertos_apps/ ├── mcu_ws/ ├── toolchain/ └── esp-idf/ <-- ⚠️ 你現在缺少的這個

需要我幫你自動建立一套包含 ESP-IDF 的 micro-ROS ESP32 Docker 或 bash 安裝環境嗎?

可大幅簡化以上流程並支援 S3/C3 多板子切換。

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

🧨 問題摘要:

  1. ESP-IDF 工具鏈版本警告(非致命)

    vbnet
    WARNING: using an unsupported version of tool xtensa-esp32-elf...

    ➤ 表示你環境中有不符合 micro-ROS 預期版本的工具,但不會直接中斷 build。

  2. 真正的錯誤來自 app 沒選好或目錄不存在:

    bash
    head: cannot open '/home/ubuntu/data/firmware_esp32_ws/firmware/APP' pushd: .../microros_esp32_extensions/build: No such file or directory

✅ 根本原因

你使用的是:

bash
ros2 run micro_ros_setup build_firmware.sh

但沒有先 設定 app 程式,micro-ROS build script 預設會讀取:

firmware/APP

這個檔案告訴 script 要從哪個 app 資料夾編譯。


✅ 解法步驟:正確設定 ESP32 範例 App

請執行下列指令設定一個官方提供的範例 App:

bash
ros2 run micro_ros_setup configure_firmware.sh int32_publisher -t serial -d /dev/ttyUSB0

這會:

  • firmware/freertos_apps/apps/int32_publisher/ 放一份範例 app.c

  • 寫入 firmware/APP 檔案

  • 設定好 ESP32 用的 serial 參數

接著再執行 build:

bash
ros2 run micro_ros_setup build_firmware.sh

🧪 驗證你是否成功設定 app

檢查這個檔案是否存在:

bash
cat firmware/APP # 應該輸出類似: # freertos_apps/apps/int32_publisher

確認這個資料夾有:

bash
ls firmware/freertos_apps/apps/int32_publisher/ # 應該包含 app.c

⚠️ 補充:toolchain warning 的處理建議

建議讓 micro-ROS 自動使用它內建的 toolchain,不要把 host 環境中其他版本插入 $PATH,避免以下狀況:

bash
WARNING: using an unsupported version...

若你不放心,可以把 host 中的 xtensa-esp32 toolchain 暫時移除 PATH 或用 Docker 隔離。


✅ 小結

動作指令
設定 Appros2 run micro_ros_setup configure_firmware.sh int32_publisher -t serial -d /dev/ttyUSB0
編譯韌體ros2 run micro_ros_setup build_firmware.sh
燒錄 ESP32ros2 run micro_ros_setup flash_firmware.sh
啟動 Agentros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0


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

[100%] Built target app

代表你的 ESP32 micro-ROS 專案中的 app.c 已經 成功編譯完成,目前狀態:


✅ app 目標已正確被 CMake 和 make 編譯出來

✅ 所有依賴(如 rclc、std_msgs、freertos)都已連結成功

✅ 沒有出現 undefined reference 或 linking 錯誤


📦 下一步建議

如果你是透過 micro-ROS 官方工具鏈建立的 firmware(

也就是用:

bash

ros2 run micro_ros_setup configure_firmware.sh ...

)那麼接下來只要 燒錄 ESP32 即可:


🔥 燒錄韌體至 ESP32

bash

export MICROROS_FIRMWARE_SERIAL_DEVICE=/dev/ttyUSB0

ros2 run micro_ros_setup flash_firmware.sh

⚠ 若使用 ESP32-S3 開發板,請記得加:


bash

export IDF_TARGET=esp32s3


🧠 啟動 micro-ROS agent(主機端,串接 ROS2)

bash

ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0


📡 測試 ROS2 Topic(如果你用的是 Int32 publisher 範本)

bash

ros2 topic list

ros2 topic echo /int_topic


🔧 想加功能?(下一步建議)

如果你已經成功編譯並燒錄,接下來你可以考慮擴展功能,例如:


加上 subscriber 處理主機命令

加上 timer 結合感測器(如 GPIO, ADC, I2C)

整合 IMU、溫濕度、GPS 等外接模組

使用 micro-ROS parameter 動態修改頻率或 topic 名稱

支援 OTA 或 BLE 傳輸


如果你想,我可以幫你生成:

subscriber + publisher 雙向通訊範例

ADC / GPIO 讀取整合進 timer callback

micro-ROS + FreeRTOS task 結合架構

micro-ROS + ESP-NOW 或 WiFi UDP 範例整合

需要我幫你生成哪一種?或你有特定硬體想整合?