2025年2月6日 星期四

ROS/ROS2 機器人開發、模擬與實作簡介

 主題總覽

#文件主要涵蓋了以下主題:

  • ROS/ROS2 機器人開發框架: 介紹了 ROS/ROS2 的概念、架構、工具以及它們在機器人開發中的應用。
  • Gazebo 模擬器: 介紹了 Gazebo 模擬器的使用,包括環境設定、模型建立、插件應用以及如何與 ROS/ROS2 整合進行機器人模擬。
  • TurtleBot3 (TB3): 提到TB3是一款受歡迎的ROS平台,用於教學、研究和開發。文件涵蓋了TB3的設定、基本操作、SLAM、導航和模擬。
  • 機器人定位、導航與 SLAM: 探討了機器人在環境中定位、建立地圖以及自主導航的相關理論和實踐方法。
  • 機器人控制: 介紹了機器人的運動控制方法,包括速度控制、PID 控制以及如何將 ROS 控制訊號轉換為馬達控制訊號。
  • 自動駕駛: 涵蓋了自動駕駛機器人的創建、感測器融合、卡爾曼濾波器以及數位孿生等概念。
  • 人機互動(HRI): 介紹了人機互動的基礎知識,包括HRI系統的設計和評估。

#重要概念與事實

  1. ROS/ROS2 框架
  • ROS 作為框架: 是一種分布式架構,可同時運行多個進程(節點),並提供它們相互通信的橋樑。
  • 「框架,就是ROS給你定好了一套規範。ROS采用了一种分布式架构,可以同时运行多个进程,每个进程能单独设计,然后放在一起组合起来。」
  • 節點 (Node): ROS 中的進程被稱為節點,每個節點負責特定的功能,例如機器人控制、感測器數據採集等。
  • 「在ROS里,进程有个名字,叫做节点—node。请记住这个词,节点node。」
  • ROS2 相較於 ROS1 的改進:
  • 支援多平台 (Ubuntu, OS X, Windows)。
  • 更廣泛運用 C++11/14 標準。
  • 支援 Python 3。
  • 使用中介軟體介面 (middleware interface) 來實現序列化、傳輸及發掘機制,例如 DDS。
  • 支援獨立編譯,每個 package 單獨編譯。
  • ament: ROS 2 使用 ament 作為其建構系統。
  • ROS2 也支援其他編譯系統。目前除CMake外, 編譯工具也支援單純的Python package。
  • Colcon: ROS 2 使用 colcon 進行編譯。
  • 「在 ROS 2 的世界中,進行編譯的重要工具就是 colcon
  • ROS2 初學者課程: 介紹了 ROS2 的操作、生命週期節點、執行器和元件等進階概念,並提供了實踐專案。
  • Action伺服器和客戶端: 提到生成並建立操作定義,寫一個完整的Action伺服器和客戶端。
  1. Gazebo 模擬器
  • 無頭模式 (Headless Mode): 可以不含 Gazebo 圖形用戶界面運行,節省資源。
  • 「您可能想在無頭模式(不含 Gazebo 圖形用户界面)下運行 Gazebo,因为它使用的资源较少,而且不依赖于您系统中支持 OpenGL 渲染的显卡。」
  • 世界 (World) 設定: 可以在特定世界中運行模擬,例如有風的世界。
  • 「通过将所需的世界与所需载具的名称连接,可以在特定世界中运行模拟。例如,要运行风世界的 x500 您可以指定载具」
  • Plugin: 動態加載的程式碼塊,用於物理模擬、用戶指令和場景顯示。
  • 「Plugin 是一個動態加載的程式碼塊(Dynamic load chunk of code),例:Physics plugin 對於動態模擬十分重要」
  • Gazebo 與 ROS/ROS2 整合: 可以透過 gazebo_ros_pkgs 這個 package 來和 ROS 或 ROS2 進行話題與服務的傳遞。
  • 「Gazebo雖然是獨立的機器人模擬軟體,非為ROS2而生,不過Gazebo能透過 Gazebo_ros_pkgs 這個package 來和ROS或ROS2的任何一個版本做話題與服務的傳遞。」
  • URDF: 使用 URDF (Unified Robot Description Format) 描述機器人的物理屬性,並使用 Xacro 工具改進 URDF 檔案。
  • ROS 控制 Gazebo 機器人:
  • 在 Xacro 檔案中加入插件 libgazebo_ros_control.so。
  • 建立 ros2_control.yaml 設定 PWM 速度控制。
  • 啟動 Gazebo 和 ros2_control,並使用 cmd_vel 測試輪子轉速。
  • Topics and Messages: 提到使用 gz topic 指令來發布 topic 訊息,以控制模擬介面中的模型車。
  • Lights: Light tag 指定了世界的光源,光源的 type 可以是 point(點光源)、directional(方向光源)、spot(聚光燈)。
  1. TurtleBot3 (TB3)
  • TB3 特點: 全世界最受歡迎的 ROS 平台,價格實惠、體積小、ROS 標準、可擴展性強。
  • 「全世界最受歡迎的 ROS 平台」、「實惠的價格」、「體積小」、「ROS 標準」、「可擴展性」
  • TB3 型號: 包括 Burger、Waffle 和 Waffle Pi。
  • TB3 主要組件: 單板電腦 (SBC)、感測器、內嵌控制板 (OpenCR)、智能馬達。
  • TB3 應用: 包括 SLAM、導航、自動駕駛和機器學習。
  • TB3 改裝: 提供多種改裝方案,如小車、機器手臂、賽格威等。
  • TB3 學習資源: 提供線上教學網站、Blockly、模擬課程和實體書。
  1. 機器人定位、導航與 SLAM
  • 定位方法: 2D 和 3D 定位的理論基礎,使用 tf 包進行幀之間的轉換和定位。
  • SLAM: 即時定位與地圖構建,使用 gmapping 包實現 SLAM 演算法。
  • 分層導航: 使用 global planner 和 local planner 進行路徑規劃,使用 costmap 進行障礙物標定。
  • AMCL: 使用 Adaptive Monte Carlo Localization 定位演算法,依據編碼器推斷出 odometry。
  • Navigation 2 (Nav2): 最終了解 ROS2 的 Nav2 堆棧 – SLAM、地圖、導航、Gazebo 模擬、Python 程式碼 – 一步一步地.
  1. 機器人控制
  • 速度控制: 使用 cmd_vel 控制機器人速度。
  • PID 控制: 加入 PID 控制來平滑加速與減速。
  • PWM 控制: 改變輸入電壓來影響馬達速度。
  • ros2_control: 使用 ros2_control 讓 cmd_vel 控制馬達。
  • 差動驅動 (DiffDrive): 使用 差動驅動 (DiffDrive) 控制。
  • RPM 反饋: 要把 PWM 訊號轉成 RPM 反饋回 ROS 2。
  • STM32 CAN Bus: 要讓 STM32 透過 CAN Bus 接收 cmd_vel。
  1. 自動駕駛
  • 自動駕駛機器人: 創建真正的自動駕駛機器人,並在 Gazebo 中進行模擬。
  • 感測器融合: 實施感測器融合演算法。
  • 卡爾曼濾波器: 了解使用卡爾曼濾波器的機器人定位和傳感器融合。
  • 數位孿生: 創建自動駕駛機器人的數位孿生。
  • 自主導航挑戰賽: 參與 TurtleBot3 AutoRace 自動駕駛挑戰賽。
  1. 人機互動(HRI)
  • HRI 基礎知識: 介紹了人機互動的基礎知識,包括HRI系統的設計和評估。
  • HRI 應用: 將 HRI 系統用於人類和機器人可以互動和合作的應用,以提高生產力和效率。

#重要指令和工具

  • 1>ros2 pkg create: 建立 ROS 2 專案。
  • ros2 pkg create --build-type ament_cmake <project_name> (C++ 專案)
  • ros2 pkg create --build-type ament_python <project_name> (Python 專案)
  • 2>colcon build: 編譯 ROS 2 專案。
  • colcon build --packages-select <certain project>: 指定要編譯某個專案。
  • colcon build --symlink-install: 使用 symbolic link 連結到 src 資料夾。
  • colcon build --parallel-workers n: 同時用 n 個 thread 進行編譯。
  • colcon build --merge-install: 不再用資料夾來歸類 install 資料夾下的 component。
  • colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release: 使用 release build。
  • 3>ros2 run: 執行 ROS 2 節點。
  • 4>ros2 launch: 執行 ROS 2 launch 檔案。
  • 5>vcs import: 從 .repos 檔案下載程式碼。
  • vcs import src < project.repos
  • 6>gz topic: 發布 topic 訊息。
  • gz topic -t "/cmd_vel" -m gz.msgs.Twist -p "linear: {x: 0.5}, angular: {z: 0.05}"
  • 7>ros2 topic pub: 測試 cmd_vel。

#結論

提供的文件涵蓋了廣泛的機器人開發主題,從 ROS/ROS2 框架和 Gazebo 模擬器的基礎知識,到定位、導航、SLAM 和自動駕駛等進階概念。 這些資源對於想要學習機器人技術和使用 ROS/ROS2 開發機器人應用程式的學生、工程師和研究人員來說非常有價值。 同時也介紹了如何使用TB3這款平台來實作上述概念。

希望這份簡報文件對您有所幫助!

 使用 Gazebo Model Editor 建立一個雙輪車模型。這個模型需要包含車身、兩個輪子和輪軸。

這個雙輪車模型具有以下特點:

  1. 主要組件:
    • 車身(chassis):紅色矩形底盤
    • 左輪(left_wheel):黑色圓柱形輪子
    • 右輪(right_wheel):黑色圓柱形輪子
  2. 尺寸設定:
    • 車身:長 40cm x 寬 20cm x 高 10cm
    • 輪子:半徑 10cm,寬度 5cm
  3. 物理屬性:
    • 車身質量:5.0 kg
    • 每個輪子質量:1.0 kg
    • 包含適當的慣性矩陣設定
  4. 關節設定:
    • 使用 revolute 型關節連接輪子和車身
    • 輪子可繞 Y 軸旋轉
    • 設定了適當的運動限制

要在 Gazebo 中使用這個模型,你需要:

  1. 將上述 SDF 代碼保存為 model.sdf 文件
  2. 放在 ~/.gazebo/models/differential_drive_robot/ 目錄下
  3. 在同一目錄創建 model.config 文件

你需要我為這個模型添加其他功能嗎?比如:

  • 添加輪子的材質貼圖
  • 調整物理參數
  • 添加傳感器

Differential Drive Robot SDF Model.xml


===============================
<?xml version="1.0" ?>
<sdf version="1.6">
  <model name="differential_drive_robot">
    <!-- Main chassis -->
    <link name="chassis">
      <pose>0 0 0.1 0 0 0</pose>
      <collision name="collision">
        <geometry>
          <box>
            <size>0.4 0.2 0.1</size>
          </box>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <box>
            <size>0.4 0.2 0.1</size>
          </box>
        </geometry>
        <material>
          <ambient>1 0 0 1</ambient>
          <diffuse>1 0 0 1</diffuse>
        </material>
      </visual>
      <inertial>
        <mass>5.0</mass>
        <inertia>
          <ixx>0.042</ixx>
          <iyy>0.071</iyy>
          <izz>0.104</izz>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyz>0</iyz>
        </inertia>
      </inertial>
    </link>

    <!-- Left wheel -->
    <link name="left_wheel">
      <pose>0 0.12 0.1 0 1.5707 1.5707</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>0.1</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.1</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.1 1</diffuse>
        </material>
      </visual>
      <inertial>
        <mass>1.0</mass>
        <inertia>
          <ixx>0.001</ixx>
          <iyy>0.001</iyy>
          <izz>0.001</izz>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyz>0</iyz>
        </inertia>
      </inertial>
    </link>

    <!-- Right wheel -->
    <link name="right_wheel">
      <pose>0 -0.12 0.1 0 1.5707 1.5707</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>0.1</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.1</radius>
            <length>0.05</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.1 1</diffuse>
        </material>
      </visual>
      <inertial>
        <mass>1.0</mass>
        <inertia>
          <ixx>0.001</ixx>
          <iyy>0.001</iyy>
          <izz>0.001</izz>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyz>0</iyz>
        </inertia>
      </inertial>
    </link>

    <!-- Left wheel joint -->
    <joint name="left_wheel_joint" type="revolute">
      <parent>chassis</parent>
      <child>left_wheel</child>
      <axis>
        <xyz>0 1 0</xyz>
        <limit>
          <effort>10</effort>
        </limit>
      </axis>
    </joint>

    <!-- Right wheel joint -->
    <joint name="right_wheel_joint" type="revolute">
      <parent>chassis</parent>
      <child>right_wheel</child>
      <axis>
        <xyz>0 1 0</xyz>
        <limit>
          <effort>10</effort>
        </limit>
      </axis>
    </joint>
  </model>
</sdf>

Gazebo Model Editor 編輯 RDF 文件的步驟

 我來說明如何使用 Gazebo Model Editor 編輯 RDF 文件的步驟:

  1. 首先打開終端機,輸入以下指令啟動 Gazebo Model Editor:
bash
gazebo --gui model_editor
  1. 在 Gazebo Model Editor 界面中:
    • 點擊左上角的 File -> New Model 建立新模型
    • 或是 File -> Open Model 開啟已有的模型
  2. 編輯 RDF 相關屬性:
    • 在左側 Model 面板中選擇要編輯的組件
    • 右側 Properties 面板會顯示該組件的各項屬性
    • 可以編輯 collision、visual、inertial 等屬性
    • 修改 link、joint 等模型結構
  3. 保存 RDF 文件:
    • File -> Save As 將模型存為 .sdf 格式
    • 默認會保存在 ~/.gazebo/models/ 目錄下
    • 也可以指定其他保存路徑
  4. 驗證模型:
    • 使用內建的模擬器預覽模型
    • 確認物理屬性和視覺效果是否正確

什麼是 SDF?

 SDF (Simulation Description Format) 是 Gazebo 模擬器使用的標準 XML 格式,用來描述 機器人、環境、傳感器、燈光、物理屬性等。相比 URDF (Unified Robot Description Format),SDF 支援更多 仿真相關的物理設定,例如摩擦、彈性、流體動力學等。


📖 1️⃣ SDF XML 基本結構

<sdf version="1.9"> <world name="default"> <include> <uri>model://ground_plane</uri> </include> <model name="myrobot"> <static>false</static> <link name="chassis"> <pose>0 0 0.1 0 0 0</pose> <inertial> <mass>10.0</mass> <inertia> <ixx>0.5</ixx> <iyy>1.0</iyy> <izz>0.1</izz> <ixy>0.0</ixy> <ixz>0.0</ixz> <iyz>0.0</iyz> </inertia> </inertial> <visual name="chassis_visual"> <geometry> <box> <size>0.4 0.2 0.1</size> </box> </geometry> <material> <ambient>0.8 0.8 0.8 1</ambient> </material> </visual> <collision name="chassis_collision"> <geometry> <box> <size>0.4 0.2 0.1</size> </box> </geometry> <surface> <friction> <ode> <mu>0.5</mu> <mu2>0.5</mu2> </ode> </friction> </surface> </collision> </link> </model> </world> </sdf>

📌 2️⃣ SDF XML 標籤說明

標籤作用範例
<sdf>SDF 主標籤,指定版本<sdf version="1.9">
<world>定義仿真世界<world name="default">
<include>引入模型<include><uri>model://ground_plane</uri></include>
<model>定義機器人或物體<model name="myrobot">
<static>設定模型是否固定<static>false</static>
<link>定義機器人組件<link name="chassis">
<pose>位置與姿態<pose>0 0 0.1 0 0 0</pose>
<inertial>定義質量與慣性<mass>10.0</mass>
<visual>設定外觀模型<visual name="chassis_visual">
<geometry>幾何形狀<box><size>0.4 0.2 0.1</size></box>
<material>設定材質<ambient>0.8 0.8 0.8 1</ambient>
<collision>設定碰撞體<collision name="chassis_collision">
<surface>設定物理屬性<friction><ode><mu>0.5</mu></ode></friction>

📌 3️⃣ SDF 設計與編寫工具流程

✅ 1. 選擇適合的編輯工具

工具用途
VS Code推薦,支援 SDF XML 語法高亮
Gazebo Model Editor內建 SDF 視覺化編輯
SDF Validator (sdf CLI)檢查 SDF 格式正確性
Blender + .dae/.stl建立 3D 模型,匯出至 SDF

✅ 2. 撰寫 SDF 文件

  1. 建立 SDF 檔案

    mkdir -p ~/gazebo_ws/models/myrobot cd ~/gazebo_ws/models/myrobot touch model.sdf touch model.config
  2. 撰寫 model.sdf

    <sdf version="1.9"> <model name="myrobot"> <static>false</static> <link name="base"> <pose>0 0 0 0 0 0</pose> <visual name="base_visual"> <geometry> <cylinder> <radius>0.2</radius> <length>0.1</length> </cylinder> </geometry> </visual> </link> </model> </sdf>
  3. 撰寫 model.config (用於 Gazebo 瀏覽模型)

    <model> <name>myrobot</name> <version>1.0</version> <sdf version="1.9">model.sdf</sdf> <author> <name>My Name</name> <email>myemail@example.com</email> </author> <description>Simple mobile robot</description> </model>

✅ 3. 測試 SDF 模型

  1. 檢查 SDF 格式是否正確

    sdf validate model.sdf

    如果沒有錯誤,則表示格式正確。

  2. 將模型加載到 Gazebo

    gazebo --verbose

    然後在 Gazebo 內:

    • Insertmyrobot拖曳進場景

📌 4️⃣ SDF vs. URDF (主要區別)

功能URDFSDF
支援 Gazebo❌ 需要 gazebo_ros 轉換✅ 原生支援
物理屬性🚫 限制較多✅ 更完整 (摩擦、彈性)
感測器🚫 需額外定義✅ 內建支援
燈光❌ 需手動添加✅ 內建 <light> 支援
流體動力學🚫 不支援✅ 支援

🛠 建議:

  • 要在 ROS 內控制機器人URDF + gazebo_ros_control
  • 要完整模擬物理世界SDF

✅ 結論

  1. SDF 是 Gazebo 的原生格式,支援完整的物理屬性。
  2. 可以用 VS Code / Gazebo Model Editor 來設計 SDF
  3. 使用 sdf validate 確保 SDF 格式正確
  4. model.config 讓 Gazebo 讀取你的模型

🚀 你還需要什麼額外的 SDF 設定,例如感測器 (sensor)、燈光 (light)、或馬達 (joint + actuator) 嗎?

機器人模型示例 use URDF

 一個具體的機器人模型示例,包含完整的文件結構和代碼:

1. 完整的文件結構

my_robot_pkg/ ├── CMakeLists.txt ├── package.xml ├── launch/ │ ├── display.launch │ └── gazebo.launch ├── urdf/ │ ├── my_robot.urdf │ ├── materials.xacro │ └── macros.xacro ├── meshes/ │ ├── visual/ │ │ ├── base.dae │ │ ├── arm.dae │ │ └── gripper.dae │ └── collision/ │ ├── base.stl │ ├── arm.stl │ └── gripper.stl └── config/ └── joint_controllers.yaml

2. URDF 示例代碼

xml
<?xml version="1.0"?> <robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro"> <!-- 材質定義 --> <material name="blue"> <color rgba="0 0 0.8 1"/> </material> <!-- 基座鏈接 --> <link name="base_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0"/> <geometry> <mesh filename="package://my_robot_pkg/meshes/visual/base.dae" scale="0.001 0.001 0.001"/> </geometry> <material name="blue"/> </visual> <collision> <origin xyz="0 0 0" rpy="0 0 0"/> <geometry> <mesh filename="package://my_robot_pkg/meshes/collision/base.stl"/> </geometry> </collision> <inertial> <mass value="5.0"/> <origin xyz="0 0 0" rpy="0 0 0"/> <inertia ixx="0.1" ixy="0" ixz="0" iyy="0.1" iyz="0" izz="0.1"/> </inertial> </link> <!-- 機械臂關節 --> <joint name="arm_joint" type="revolute"> <parent link="base_link"/> <child link="arm_link"/> <origin xyz="0 0 0.1" rpy="0 0 0"/> <axis xyz="0 0 1"/> <limit lower="-3.14" upper="3.14" effort="100" velocity="1.0"/> </joint> <!-- 機械臂鏈接 --> <link name="arm_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0"/> <geometry> <mesh filename="package://my_robot_pkg/meshes/visual/arm.dae" scale="0.001 0.001 0.001"/> </geometry> </visual> <collision> <origin xyz="0 0 0" rpy="0 0 0"/> <geometry> <mesh filename="package://my_robot_pkg/meshes/collision/arm.stl"/> </geometry> </collision> <inertial> <mass value="1.0"/> <origin xyz="0 0 0" rpy="0 0 0"/> <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/> </inertial> </link> </robot>

3. Launch 文件示例

xml
<!-- gazebo.launch --> <launch> <!-- 載入機器人描述參數 --> <param name="robot_description" command="$(find xacro)/xacro '$(find my_robot_pkg)/urdf/my_robot.urdf'"/> <!-- 啟動 Gazebo --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="paused" value="false"/> <arg name="use_sim_time" value="true"/> <arg name="gui" value="true"/> <arg name="debug" value="false"/> </include> <!-- 生成機器人模型 --> <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param robot_description -urdf -model my_robot"/> <!-- 啟動控制器 --> <rosparam command="load" file="$(find my_robot_pkg)/config/joint_controllers.yaml"/> <node name="controller_spawner" pkg="controller_manager" type="spawner" output="screen" args="joint_state_controller arm_controller"/> </launch>

4. 控制器配置示例

yaml
# joint_controllers.yaml joint_state_controller: type: joint_state_controller/JointStateController publish_rate: 50 arm_controller: type: position_controllers/JointPositionController joint: arm_joint pid: {p: 100.0, i: 0.01, d: 10.0}

5. Gazebo 相關插件配置

xml
<!-- 在 URDF 中添加 Gazebo 插件 --> <gazebo> <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so"> <robotNamespace>/my_robot</robotNamespace> <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType> </plugin> </gazebo> <!-- 為鏈接添加材質 --> <gazebo reference="base_link"> <material>Gazebo/Blue</material> </gazebo>

6. 運行和測試

  1. 編譯包:
bash
catkin_make
  1. 運行模擬:
bash
roslaunch my_robot_pkg gazebo.launch
  1. 發送控制命令:
bash
rostopic pub /my_robot/arm_controller/command std_msgs/Float64 "data: 1.57"

7. 調試技巧

  1. 檢查模型是否正確載入:
bash
rosrun tf_echo /base_link /arm_link
  1. 查看關節狀態:
bash
rostopic echo /joint_states
  1. 使用 RViz 可視化:
bash
rosrun rviz rviz -d `rospack find my_robot_pkg`/rviz/config.rviz

這個完整示例展示了如何:

  • 組織機器人描述文件
  • 配置 Gazebo 模擬
  • 設置控制器
  • 運行和測試模型

ROS/ROS2 機器人開發、模擬與實作簡介

  主題總覽 #文件主要涵蓋了以下主題: ROS/ROS2 機器人開發框架 : 介紹了 ROS/ROS2 的概念、架構、工具以及它們在機器人開發中的應用。 Gazebo 模擬器 : 介紹了 Gazebo 模擬器的使用,包括環境設定、模型建立、插件應用以及如何與 ROS/ROS2 ...