welcom ! Handel home

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 範例整合

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


在 ESP32 上使用 FreeRTOS 運行 micro-ROS 的操作步驟

 在 ESP32 上使用 FreeRTOS 運行 micro-ROS 的操作步驟

前置條件
  • 作業系統:Ubuntu 20.04 或 22.04(建議搭配 ROS 2 Humble)。
  • ROS 2:已安裝 ROS 2 Humble,並可透過 /opt/ros/humble/setup.bash 啟用。
  • ESP32 工具:已安裝 ESP-IDF(建議版本 v4.4 或更新,與 micro-ROS 相容)。
  • 依賴套件:已安裝 colconrosdepflex 等必要工具。
  • 硬體:ESP32 或 ESP32-S3,具備 USB 轉串口連線。

步驟 1:建立並編譯 ROS 2 工作空間
創建一個用於 micro-ROS 設置的工作空間,並編譯相關套件。
bash
mkdir -p ~/firmware_esp32_ws/src
cd ~/firmware_esp32_ws
git clone https://github.com/micro-ROS/micro_ros_setup src/micro_ros_setup
rosdep update
sudo apt install flex
rosdep install --from-path src --ignore-src -y
source /opt/ros/humble/setup.bash
colcon build
source install/local_setup.bash
說明與檢查
  • 這個步驟會下載 micro-ROS 的設置工具並編譯。
  • 確保 colcon build 執行無誤,無錯誤訊息。
  • 執行 source install/local_setup.bash 後,確認環境變數正確設置,可用 echo $ROS_DISTRO 檢查(應顯示 humble)。

步驟 2:建立 FreeRTOS 韌體工作空間
為 ESP32 創建基於 FreeRTOS 的 micro-ROS 韌體工作空間。
bash
ros2 run micro_ros_setup create_firmware_ws.sh freertos esp32
輸出結果
  • 執行後會在當前目錄下生成 firmware/ 資料夾,結構如下:
    firmware/
    ├── apps/
    ├── esp-idf/
    ├── mcu_ws/
    │   ├── src/
    │   └── install/
    ├── CMakeLists.txt
    ├── sdkconfig
  • 這裡明確指定 freertos 作為作業系統,esp32 作為目標平台(其他支援平台包括 nucleo_f446recrazyflie21 等)。
ESP32-S3 注意事項: 若使用 ESP32-S3,需在創建工作空間前設置以下環境變數:
bash
export IDF_TARGET=esp32s3
  • 這確保生成的工作空間適用於 ESP32-S3 的硬體配置。

步驟 3:編譯韌體
編譯針對 ESP32 的 micro-ROS 韌體。
bash
ros2 run micro_ros_setup build_firmware.sh
說明與檢查
  • 該指令會自動載入 ESP-IDF 環境並編譯韌體。
  • 編譯過程應無錯誤,否則檢查 ESP-IDF 版本或依賴套件。
  • 對於 ESP32-S3,確認 IDF_TARGET=esp32s3 已設置,並檢查 sdkconfig 檔案中的 UART 和快閃記憶體大小設置是否正確。
進階配置(選擇性): 若需調整 UART 引腳或快閃記憶體大小,可使用以下指令開啟配置介面:
bash
ros2 run micro_ros_setup configure_firmware.sh menuconfig
  • menuconfig 中調整相關參數(例如 UART 引腳、快閃記憶體大小),特別適用於 ESP32-S3。

步驟 4:燒錄韌體到 ESP32
將編譯好的韌體燒錄到 ESP32 硬體。
bash
export MICROROS_FIRMWARE_SERIAL_DEVICE=/dev/ttyUSB0
ros2 run micro_ros_setup flash_firmware.sh
說明與檢查
  • /dev/ttyUSB0 替換為實際的 USB 串口(可用 ls /dev/tty* 檢查)。
  • 確保 ESP32 已正確連接到電腦,且有寫入權限(可能需 sudo chmod 666 /dev/ttyUSB0)。
  • 燒錄完成後,檢查是否有錯誤訊息。

步驟 5:啟動 micro-ROS Agent
啟動 micro-ROS Agent 以與 ESP32 上的 micro-ROS 應用程式通訊。
bash
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
說明與檢查
  • 確保串口與燒錄時一致(例如 /dev/ttyUSB0)。
  • Agent 啟動後應顯示連線訊息,表示與 ESP32 的 micro-ROS 節點成功通訊。
  • 若無反應,檢查 ESP32 是否正確燒錄,或確認 UART 設置是否正確。

ESP32-S3 特別注意事項
若使用 ESP32-S3,請額外注意以下事項:
  1. 設置 IDF 目標
    bash
    export IDF_TARGET=esp32s3
    • 在創建韌體工作空間前執行,確保生成正確的配置。
  2. 檢查 UART 和快閃記憶體
    • ESP32-S3 的 UART 引腳和快閃記憶體大小可能與標準 ESP32 不同。
    • 使用 menuconfig 檢查並調整 sdkconfig 中的設置:
      bash
      ros2 run micro_ros_setup configure_firmware.sh menuconfig
    • 常見調整包括 UART 引腳分配和快閃記憶體大小(例如 4MB 或 8MB)。
  3. 燒錄問題
    • ESP32-S3 的燒錄可能需要額外驅動程式,確保 USB 驅動(如 cp2102ch340)已安裝。
    • 確認燒錄工具(如 esptool)與 ESP-IDF 版本相容。

常見問題與解決方法
  1. 編譯失敗
    • 確認 ESP-IDF 版本與 micro-ROS 相容(建議 v4.4 或更新)。
    • 檢查是否遺漏依賴套件,可重跑 rosdep install
  2. 燒錄失敗
    • 確認串口正確(/dev/ttyUSB0 或其他)。
    • 檢查 ESP32 是否進入燒錄模式(可能需按住 BOOT 按鈕)。
  3. Agent 無法連線
    • 確認 UART 設置與 Agent 的串口一致。
    • 檢查韌體是否正確燒錄,可透過串口監控工具(如 minicom)查看 ESP32 輸出。

總結
以上步驟涵蓋了從建立 ROS 2 工作空間到在 ESP32 上運行 micro-ROS 的完整流程。對於 ESP32-S3,需特別注意 IDF_TARGET 設置和 sdkconfig 配置。完成後,你將能夠在 ESP32 上運行 micro-ROS 節點,並透過 micro-ROS Agent 與 ROS 2 系統通訊。
若有進一步問題或需要範例程式碼(如 micro-ROS 節點程式),請提供更多細節,我可協助補充!


以下是為 ESP32 + micro-ROS + FreeRTOS 平台設計的一份簡單但完整的 app.c 範例程式,它會:

  • 初始化 micro-ROS 節點(rclc_node

  • 建立一個 publisher,發佈 std_msgs/msg/Int32 訊息到 /int_topic

  • 每 500ms 發送一筆遞增的數字

  • 使用 rclc_executor 管理 timer callback


firmware/apps/microros_esp32_extensions/app.c

c
#include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #include <rclc/rclc.h> #include <rclc/executor.h> #include <std_msgs/msg/int32.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> rcl_publisher_t publisher; std_msgs__msg__Int32 msg; int32_t count = 0; void timer_callback(rcl_timer_t * timer, int64_t last_call_time) { RCLC_UNUSED(last_call_time); if (timer != NULL) { msg.data = count++; rcl_publish(&publisher, &msg, NULL); } } void appMain(void * arg) { // === micro-ROS 初始化 === rcl_allocator_t allocator = rcl_get_default_allocator(); rclc_support_t support; rclc_support_init(&support, 0, NULL, &allocator); rcl_node_t node; rclc_node_init_default(&node, "esp32_node", "", &support); rclc_publisher_init_default( &publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "int_topic" ); // === Timer 500ms === rcl_timer_t timer; rclc_timer_init_default( &timer, &support, RCL_MS_TO_NS(500), timer_callback ); // === Executor === rclc_executor_t executor; rclc_executor_init(&executor, &support.context, 1, &allocator); rclc_executor_add_timer(&executor, &timer); // === 主循環 === while (1) { rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)); vTaskDelay(pdMS_TO_TICKS(100)); } // 不會執行到這裡,但若需清理可加上: // rcl_publisher_fini(&publisher, &node); // rcl_node_fini(&node); }

📦 配套資訊

這份程式預設的 Topic 是:

bash
Topic: /int_topic Type: std_msgs/msg/Int32

你可以在主機端使用:

bash
ros2 topic echo /int_topic

來觀察資料。


🧩 接下來怎麼用這份 app.c?

  1. 把上面的內容存進你的 firmware app 目錄,例如:

    bash
    firmware/apps/microros_esp32_extensions/app.c
  2. 重新 build:

    bash
    ros2 run micro_ros_setup build_firmware.sh
  3. 確保 ESP32 連接 USB,燒錄:

    bash
    export MICROROS_FIRMWARE_SERIAL_DEVICE=/dev/ttyUSB0 ros2 run micro_ros_setup flash_firmware.sh
  4. 啟動 Agent:

    bash
    ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
  5. 查看 ROS 2 topic:

    bash
    ros2 topic list ros2 topic echo /int_topic

如果你希望加上 subscriberparameterIMU / UART 傳感器整合,我可以幫你擴展這個 template。是否需要我也加上一個 subscriber 範例?