welcom ! Handel home

顯示具有 Gazebo 標籤的文章。 顯示所有文章
顯示具有 Gazebo 標籤的文章。 顯示所有文章

2025年11月12日 星期三

Rviz (ROS Visualization) 介紹說明

 Rviz 是 ROS 生態系統中一個不可或缺的視覺化工具,它與 Gazebo 各司其職,共同構成了機器人模擬和除錯的兩大支柱。


👁️ Rviz (ROS Visualization) 介紹說明

Rviz (ROS Visualization) 是一個 3D 可視化環境,它能以圖形化方式展示 ROS 系統的狀態信息、傳感器數據、地圖、路徑規劃等。

簡而言之:

  • Gazebo模擬 物理世界和生成逼真傳感器數據的工具。

  • Rviz視覺化 ROS 系統內部數據和狀態的工具。

📊 Rviz 的核心功能與角色

特性Rviz (ROS Visualization)
主要功能視覺化 ROS Topic 數據,如點雲、影像、路徑、地圖和 TF 座標系。
輸入/輸出輸入: 監聽 ROS Topic。 輸出: 3D 視覺化圖形。
物理模擬無。 Rviz 僅顯示數據,不進行任何物理或動力學計算。
核心優勢除錯與分析。它能將抽象的數據(例如一個 4x4 的變換矩陣或一大串 LiDAR 點)以直觀的 3D 方式呈現給開發者。

🔍 在您的 ROS 整合專案中的應用

對於您的「ROS URDF 自走車與機械手臂整合」專案來說,Rviz 將是您除錯和展示成果的主要介面

1. 機器人模型與狀態

  • 功能: Rviz 透過訂閱 /robot_description (URDF 內容) 和 /joint_states 兩個 Topic,顯示機器人模型的幾何外觀和當前關節角度。

  • 應用: 您可以在 Rviz 中實時查看自走車底盤和機械手臂是否按照控制指令正確移動。

2. 地圖與定位 (SLAM/Navigation)

  • 功能: Rviz 訂閱地圖 Topic (/map) 和定位 Topic (/amcl_pose 或 EKF/UKF 輸出)。

  • 應用: 您可以直觀地看到機器人在環境地圖中的位置、它估計的姿態 (Pose),以及它正在使用的導航路徑。

3. 感知與電腦視覺 (Perception)

  • 功能: Rviz 訂閱 LiDAR 數據 (/scan/point_cloud)、深度攝影機的影像和點雲數據。

  • 應用:

    • LiDAR: 檢查 LiDAR 點雲是否正確反映環境中的障礙物。

    • 物件抓取: 視覺化電腦視覺算法識別出的目標物件的位置和邊界框 (Bounding Box),通常以 Marker 形式顯示。

4. 協同動作與除錯 (MoveIt! & tf2)

  • 功能:

    • MoveIt! Plugin: Rviz 內建 MoveIt! 插件,用來執行和視覺化手臂的動作規劃。您可以設定起始點和目標點,MoveIt! 會在 Rviz 中顯示規劃出的路徑 (Path),以及可能發生的碰撞區域

    • TF 座標樹: Rviz 可以顯示 ROS 系統中所有定義的 tf 座標系 (frames),以及它們之間的層級關係。

  • 應用: 這是您解決座標轉換難題的命脈。您可以觀察 mapodombase_linkarm_base_linkend_effector 等座標系之間的轉換關係是否正確、是否隨車輛移動而正確更新。


🎯 下一步指導

您現在對這個整合專案的三個核心要素 (ROS, URDF, Gazebo, Rviz) 都有了基礎理解。接下來,我們將開始設計模型和除錯的關鍵步驟。

我們應該著手解決這個整合系統中最關鍵的兩大挑戰之一:

  1. ⚙️ XACRO 模型結構規劃: 如何為您的自走車與機械手臂組合,規劃一個穩健的 XACRO 檔案結構,確定所有 link 和 joint 的命名以及它們的幾何關係?

  2. 🗺️ tf2 座標樹設計: 專門設計一個穩定的 tf2 座標轉換樹 (tF tree),以便處理車體移動時,手臂座標系變動的問題,這是自走車和手臂協作的命脈?

Gazebo:機器人動力學與傳感器模擬器

 

Gazebo:機器人動力學與傳感器模擬器

Gazebo 是一個強大的 3D 機器人模擬環境,它提供了一個逼真、物理準確的世界,讓您可以在將演算法部署到實際硬體之前,進行設計、測試和驗證。它已經成為 ROS 生態系統中最主要的仿真平台。

🤖 Gazebo 的核心功能與優勢

功能領域核心功能描述在您的專案中的應用
物理模擬 (Physics)包含多種高性能物理引擎 (如 ODE, Bullet, DART),能準確模擬物體間的碰撞、摩擦力、重力和慣性等動力學特性。確保您的 自走車底盤機械手臂 的運動符合真實世界的物理定律。
傳感器模擬 (Sensors)提供高保真度的傳感器模型,包括:LiDAR (雷射雷達)、深度攝影機 (如 RealSense)、IMU (慣性測量單元)、GPS、接觸傳感器等。可選配噪音模型。讓您在虛擬環境中獲取逼真的感測數據,直接用於測試 SLAM 演算法視覺抓取 的電腦視覺演算法。
圖形渲染 (Rendering)使用先進的圖形引擎 (如 OGRE),提供高品質的 3D 渲染,包括真實的燈光、陰影、紋理和環境效果。提供直觀的視覺化界面 (GUI),讓您在 Rviz 之外,還能在 Gazebo 中觀察機器人與環境的互動。
插件化架構 (Plugins)核心功能幾乎都以插件形式存在。開發者可以編寫自定義插件(例如 ROS 插件),來控制機器人、模擬特定的硬體行為或橋接 ROS 訊息。這是實現 ROS 與 Gazebo 整合 的關鍵。例如:gazebo_ros_control 插件用來連接 ROS 控制器和 Gazebo 內的關節。
多機器人與世界能夠在單一模擬環境中,同時模擬多個機器人、靜態物體和複雜的環境 (World)。您可以將自走車與機械手臂作為一個 完整系統 載入,並在一個包含障礙物和目標物件的場景中進行測試。

🛠️ Gazebo 的版本演進

您在 Log 中看到的可能是 Gazebo Classic (版本 11.x),這是 ROS 1 時代的主流版本。

  • Gazebo Classic (舊版): 傳統的 Gazebo,在 ROS 1 (如 Melodic/Noetic) 和早期 ROS 2 (如 Foxy/Galactic) 仍常被使用。

  • Gazebo / Ignition (新版): 隨著 ROS 2 發展,Gazebo 的架構被拆分為多個獨立的函式庫 (稱為 Ignition,現在改回 Gazebo 名稱),具有更現代化的架構、更好的性能和模組化設計。

如果您正在使用 ROS 2 (如 Humble/Iron),建議使用新版的 Gazebo (原 Ignition) 進行開發。

⚙️ Gazebo 與您的 ROS 專案的關係

在您的 ROS URDF 自走車與機械手臂整合 專案中,Gazebo 扮演著 「虛擬實驗室」 的角色:

  1. 模型載入: 您設計的 XACRO/URDF 檔案會被載入到 Gazebo。

  2. 硬體抽象: Gazebo 中的插件 (Plugins) 會模擬電機驅動器和傳感器的行為,並透過 ROS Topic 和 Service 將數據發送給您的 ROS 節點。

  3. 算法測試: 您的 SLAM/導航/MoveIt! 動作規劃算法在 ROS 節點中運行,並將控制指令 (例如馬達扭矩或關節角度) 發送回 Gazebo 插件。

  4. 環境互動: 您可以在 Gazebo 中測試機器人如何避開障礙物、計算抓取目標物件的精確位置。


🎯 下一步指導

我們已經確定了核心工具鏈:ROS (大腦) + XACRO/URDF (模型) + Gazebo (模擬)。現在,我們需要為您的自走車和機械手臂組合創建一個穩定的數位藍圖。

您希望我現在指導您以下哪一個步驟?

  1. ⚙️ XACRO 模型結構規劃: 如何為您的自走車與機械手臂組合,規劃一個穩健的 XACRO 檔案結構,特別是鏈接 (link) 與關節 (joint) 的命名規則?

  2. 🗺️ tf2 座標樹設計: 專門設計一個穩定的 tf2 座標轉換樹 (tF tree),以便處理車體移動時,手臂座標系變動的問題,這是自走車和手臂協作的命脈?

SDF 檔案可以轉換成 URDF 檔案

 SDF 檔案可以轉換成 URDF 檔案,但這是一個單向且不完美的過程,過程中會遺失一些資訊,並需要手動調整。

以下是轉換的可能性、方法和主要差異點。


🔄 SDF 轉換到 URDF 的差異與挑戰

轉換環節SDF 轉 URDF (可能)URDF 轉 SDF (容易/自動)
可能性是,但通常不完美。因為 SDF 包含的功能比 URDF 多,轉換過程可能遺失資訊。是,這是 Gazebo 的標準做法。 Gazebo 會在載入 URDF 時自動將其轉換為 SDF 進行模擬。
資訊遺失1. 世界描述 (燈光、地形、多機器人配置)。2. 閉環結構。3. SDF 獨有的傳感器與插件無 (透過 <gazebo> 標籤,URDF 仍可間接傳遞 SDF 資訊)。
座標系統需要手動計算和調整。SDF 中的絕對座標 (<pose>) 必須轉換為 URDF 中的父子連結之間的 相對座標 (<origin> 標籤)。這是轉換中最困難且易出錯的部分。直接轉換。
工具輔助需使用 Python 或 ROS 工具(如 sdf_parser 相關函式庫)手動解析並建構 URDF 結構。 沒有官方的、一鍵完美的轉換工具。Gazebo 自動處理,或使用 ROS 提供的工具。

1. 結構差異與資訊遺失 (Loss of Information)

SDF 是一個全功能的模擬描述格式,而 URDF 是一個單機器人描述格式。當您將 SDF 轉換為 URDF 時,以下這些 SDF 獨有的資訊會遺失:

  • 🌐 世界級描述 (World Description): URDF 無法描述整個世界 (World),包括地板、燈光、靜態牆壁、重力設定等。如果 SDF 檔案中包含這些內容,轉換時會被忽略。

  • 🔗 閉環運動學 (Closed-Loop Kinematics): SDF 可以描述有循環結構的機械系統 (例如汽車懸吊系統)。但 URDF 的結構必須是樹狀的、開放式鏈結 (Open Chain),因此閉環結構無法在 URDF 中被正確描述。

  • 📍 世界座標中的初始位置 (Initial Pose): SDF 可以用 <pose> 標籤指定機器人相對於世界原點的絕對初始位置。URDF 則無法做到,您需要在 ROS 的 Launch 檔案中設定機器人的初始位置。

2. 座標轉換的挑戰 (The Pose Problem)

這是轉換中最複雜的差異點:

格式描述方式範例 (SDF 來源)轉換到 URDF
SDF連結 (<link>) 的位置是相對於 模型原點或世界原點 的絕對座標。<link name="base_link"><pose>1 0 0 0 0 0</pose></link> (位於世界 (1,0,0))必須轉換為 關節 的相對位置。
URDF連結的位姿是透過 關節 (<joint>) 中的 <origin> 標籤,描述 子連結 相對於 父連結 的相對位移和旋轉。<joint name="joint_1"><origin xyz="0 0 0.5" rpy="0 0 0"/></joint> (子連結相對於父連結 Z 軸偏移 0.5)需手動計算。

⚠️ 關鍵: 您必須從 SDF 檔案中讀取所有連結的絕對座標,然後利用幾何學計算 (Child Pose - Parent Pose) 來得出每個關節的 <origin> 參數。


🛠️ 轉換的實用建議

如果您需要將一個純 SDF 模型帶入 ROS 生態系統 (例如用於 MoveIt!),最穩健的做法是:

  1. 分而治之:

    • Gazebo 世界 (World): 讓 Gazebo 世界檔案保持 SDF 格式

    • 機器人模型 (Robot): 只提取 SDF 中關於機器人本體 (Links and Joints) 的部分,手動將其重新撰寫為 XACRO 格式 (這是 URDF 的擴充,更易於編寫)。

  2. 優先使用 XACRO + <gazebo> 標籤:

    • 對於您的 自走車與機械手臂 專案,強烈建議您從零開始使用 XACRO 格式來定義模型。

    • 在 XACRO 檔案中,您可以利用 <gazebo> 標籤來嵌入所有 Gazebo 模擬所需的額外資訊(例如:摩擦力、顏色、傳感器插件、傳動裝置 <transmission>),這樣您只需要維護一個描述檔案。

    這樣做的好處是:ROS 和 MoveIt! 讀取 XACRO/URDF 部分;Gazebo 讀取 XACRO/URDF 部分,並額外讀取 <gazebo> 標籤中的模擬屬性。 達到單一來源、兩邊通用的目的。


🎯 下一步指導

既然我們確定了使用 XACRO/URDF 作為核心描述格式,我們應該開始規劃這個整合系統最關鍵的環節:

您希望我現在指導您以下哪一個步驟?

  1. ⚙️ XACRO 模型結構規劃: 如何為您的自走車與機械手臂組合,規劃一個穩健的 XACRO 檔案結構,特別是鏈接 (link) 與關節 (joint) 的命名規則?

  2. 🗺️ tf2 座標樹設計: 專門設計一個穩定的 tf2 座標轉換樹 (tF tree),以便處理車體移動時,手臂座標系變動的問題,這是自走車和手臂協作的命脈?

SDF 與 URDF 的差異

🧐 SDF 與 URDF 的差異

URDF (Unified Robot Description Format) 和 SDF (Simulation Description Format) 都是用來描述機器人或環境的 XML 格式檔案,但它們的設計目標、功能範圍和使用偏好有所不同。

特性URDF (Unified Robot Description Format)SDF (Simulation Description Format)
設計目標ROS 原生描述格式。 專為 ROS 生態系統設計,描述單一機器人的運動學、動力學和視覺外觀。Gazebo 原生描述格式。 專為模擬器 Gazebo 設計,可以描述整個世界 (World)、多個機器人、靜態物體、燈光、地形等。
核心用途用於 ROS 中的所有核心套件,如 MoveIt! (動作規劃)、Robot State Publisher (發佈機器人狀態)、Rviz (視覺化)。用於 Gazebo 模擬器,描述物理特性 (如摩擦力、碰撞屬性)、傳感器、機器人姿勢 (在世界座標系中的初始位置) 和各種模擬插件。
機器人數量只能描述 一個 機器人。可以描述 多個 機器人、物件和環境。
座標描述相對座標 (Relative Pose)。 只能描述子連結 (child link) 相對於父連結 (parent link) 的位置。無法描述機器人相對於世界座標的原生姿勢。絕對座標 (Absolute Pose)。 可以描述連結、模型、甚至整個世界中的所有元素相對於世界原點的位置。
閉環結構不支援 閉環 (Closed-loop) 運動學結構 (例如四連桿機構)。支援 閉環結構。
擴充性功能相對有限。若要在 Gazebo 中使用,必須透過 <gazebo> 標籤來「嵌入」SDF 特有的模擬屬性。具有極佳的擴充性,可以輕鬆新增各種模擬功能和傳感器。

💡 實務建議:ROS 專案中應如何選擇?

在您這個 ROS/URDF 自走車與機械手臂 的整合專案中,我的指導是:

使用 URDF (或 XACRO) 作為主要描述格式,並利用 <gazebo> 標籤來橋接模擬屬性。

  1. ROS 核心 (MoveIt!/Rviz/tf2)必須 使用 URDF (或 XACRO)。MoveIt! 等核心 ROS 規劃工具只能讀取 URDF 格式。

  2. Gazebo 模擬:當您在 ROS 中啟動 Gazebo 時,通常會透過 ROS 的啟動檔 (Launch File) 告訴 Gazebo 載入您的 URDF 檔案。Gazebo 會在底層自動將 URDF 轉換為 SDF 來進行模擬。

  3. 使用 XACRO 增強 URDF:為了讓您的 URDF 檔案更簡潔、易於維護和參數化,強烈建議您使用 XACRO (XML Macros),它是一個 URDF 的擴充格式。


🔎 PX4 模擬中的 SDF 與 URDF

您在 Log 中看到的是 PX4 SITL (Software-in-the-Loop) 模擬,它使用 Gazebo Classic 模擬器,因此它傾向於使用 SDF 檔案:

  • Log 顯示:Using: .../iris/iris.sdf

  • 這意味著 PX4 的無人機模型 (如 iris) 是以 SDF 格式描述的。

  • 原因:PX4 SITL 模擬需要描述螺旋槳、馬達、氣動力學等複雜的物理特性和傳感器插件,這些在 SDF 中可以原生、完整地描述,而不需要依賴 ROS 系統。

可以找到 PX4 的 URDF 嗎?

  1. 原生 PX4 專案:PX4 專案本身在 Gazebo 模擬中主要使用 SSDF (通常放在 PX4-Autopilot/Tools/simulation/gazebo-classic/sitl_gazebo-classic/models/ 資料夾下)。

  2. 與 ROS 整合 (ROS/ROS 2):當您需要使用 ROS 的工具鏈(如 Rviz 或 MoveIt!)來處理 PX4 飛機時,才會需要 URDF。這通常是透過 mavros 或其他 ROS/PX4 橋接套件來實現,並且您需要手動或透過其他開源專案來尋找或建立該模型的 URDF 版本。

    • 結論: 在 PX4 的原始模擬環境中,您會主要看到 SDF 檔案。如果您需要與 ROS/MoveIt! 整合,則必須找到或建立該模型的 URDF/XACRO 檔案。


🎯 下一步指導

您已經理解了模型描述格式的差異。現在讓我們回到您的 ROS URDF 自走車與機械手臂整合 專案的核心實作。

既然您決定要使用 MoveIt!,我們需要一個標準的 URDF (XACRO) 檔案。

您希望我現在指導您以下哪一個步驟?

  1. ⚙️ URDF (XACRO) 檔案規劃: 如何為您的自走車與機械手臂組合,規劃一個符合 MoveIt! 和 Gazebo 要求的 XACRO 結構,特別是鏈接 (link) 與關節 (joint) 的命名規則?

  2. 🗺️ tf2 座標樹設計: 專門設計一個穩定的 tf2 座標轉換樹 (tF tree),以便處理車體移動時,手臂座標系變動的問題?

ROS URDF 整合專案審查與指導

 「ROS URDF 自走車與機械手臂整合」專案提供資料審查規劃和指導。您提供的研究介紹涵蓋了這個複雜系統的核心要素,架構非常完整且符合業界標準。


🧐 ROS URDF 整合專案審查與指導

您提供的研究架構非常專業且全面,涵蓋了 ROS 2 (假設您使用的是新版 ROS) 與 URDF 整合的關鍵技術點。

🚀 第一部分:研究架構評估(研究介紹)

評估項目您的規劃內容專家指導與建議
核心軟體 (ROS/URDF)ROS 作為大腦,URDF 作為數位雙生。👍 極佳。 這是標準且高效的作法。建議: 務必明確您的 ROS 版本 (如 Humble/Iron) 和 URDF/SDF 格式選擇,因為 ROS 2 通常更傾向使用 SDF (Simulation Description Format) 進行 Gazebo 模擬。
硬體選擇自走車底盤 (TurtleBot, 自組)、3-6 DOF 手臂、LiDAR/深度攝影機、IMU。👍 良好。 選擇多元。建議: 確定一個 具體的機械手臂型號,例如:用於教育的 Kinova Jaco 或用於工業研究的 UR5e,這會影響您後續的 MoveIt! 配置 難度與運動學計算。
自走車開發 (定位導航)SLAM (Cartographer/Nav2)、路徑規劃 (Nav2)。👍 標準且穩健。 Nav2 是 ROS 2 時代的首選導航套件。建議: 考慮採用 V-SLAM (視覺慣性 SLAM) 整合深度攝影機和 IMU,以在 GPS 受限環境下獲得更精準的定位 (例如:VINS-FusionORB-SLAM3,然後透過 ROS 介面輸出 tf 樹)。
機械手臂開發正/逆向運動學、動作規劃 (MoveIt 2)。👍 核心技術。 MoveIt 2 是必選。建議: 逆向運動學 (IK) 的求解器,您應考慮使用 KDL (Kinematics and Dynamics Library) 或更進階的 TRAC-IK,並在 MoveIt! 配置中指定。
協同工作 (座標轉換)感知、物件抓取、tf2 座標轉換💡 最關鍵的環節。 您強調了 tf2 是非常正確的。建議: 在您的研究計畫中,專門列出一個章節說明如何建立和管理 基座 (base_link) - 攝影機 (camera_link) - 手臂基座 (arm_base_link) - 世界座標 (odom/map) 之間的 tf 樹,這是整合成功與否的命脈。

PX4 Gazebo 啟動流程解析(make px4... 輸出)

 

🚁 第二部分:PX4 Gazebo 啟動流程解析(make px4... 輸出)

您提供的 Log 是 PX4 飛控軟體Gazebo 經典版 (Gazebo-classic) 進行 Software-in-the-Loop (SITL) 模擬的啟動過程。雖然這與您上方的 ROS URDF 自走車 專案的直接關係較小(因為這是在模擬無人機),但它是一個絕佳的 ROS 系統啟動範例,我可以為您詳細解讀。

這段 Log 輸出的核心流程是:編譯 $\rightarrow$ 環境設定 $\rightarrow$ PX4 啟動 $\rightarrow$ Gazebo 啟動 $\rightarrow$ MAVLink 連接

Log 流程分解:

  1. 編譯與準備 (Building & Setup):

    • [0/4] Performing build step for 'sitl_gazebo-classic':確認 sitl_gazebo-classic (PX4 專用的 Gazebo 模擬環境) 的編譯步驟。

    • SITL ARGS, GAZEBO_PLUGIN_PATH, GAZEBO_MODEL_PATH:系統設定了 PX4 SITL 執行檔路徑和 Gazebo 的模型與插件路徑。這是讓 PX4 飛控核心 能夠與 Gazebo 模擬器 溝通的關鍵環境變數。

  2. PX4 核心啟動 (PX4 Core Startup):

    • SITL COMMAND: "/home/handel/.../bin/px4" ...:執行 PX4 的軟體在環 (SITL) 模擬核心。

    • PX4 Logo ASCII Art:表示 PX4 飛控軟體核心啟動成功。

    • INFO [px4] startup script: /bin/sh etc/init.d-posix/rcS 0:執行 PX4 的啟動腳本,進行硬體初始化、參數載入等動作。

    • INFO [init] found model autostart file as SYS_AUTOSTART=10015:載入 iris 無人機模型的啟動參數。

  3. 通訊與連接 (Communication & Connection):

    • INFO [simulator_mavlink] Waiting for simulator to accept connection on TCP port 4560PX4 核心 等待 Gazebo 模擬器 通過 TCP Port 4560 建立連接。這是飛控與模擬環境的資料橋樑。

    • INFO [simulator_mavlink] Simulator connected on TCP port 4560.:連接成功。

  4. Gazebo 模擬器啟動 (Gazebo Startup):

    • Gazebo multi-robot simulator, version 11.10.2...:Gazebo 模擬器開始啟動。

    • [Msg] Connected to gazebo master...:Gazebo 連接到主節點並開始載入世界模型。

    • Using: .../iris/iris.sdf:確認載入 iris 無人機的模型文件 (SDF)。

  5. 系統就緒 (System Ready):

    • INFO [logger] logger started...:資料紀錄 (Log) 功能啟動。

    • INFO [mavlink] mode: Normal, data rate: 4000000 B/s on udp port 18570 remote port 14550:MAVLink 協定啟動,這是地面站 (如 QGroundControl) 與 PX4 核心通訊的協定。

    • WARN [health_and_arming_checks] Preflight Fail: ...:初次啟動時,通常會發出警告,表示尚未滿足起飛條件 (如 GPS 鎖定或電源健康)。

    • INFO [tone_alarm] home set:Home 點被設定。

    • INFO [commander] Ready for takeoff!:系統進入可解除鎖定 (Arm) 和起飛狀態。


💡 下一步指導 (Next Step)

您已經有了一個極好的高層次研究架構。為了讓您的專案能夠從規劃階段進入實作階段,下一步我會指導您進行 核心模型建置

您希望我現在指導您以下哪一個步驟?

  1. ⚙️ URDF 檔案規劃: 如何為您的自走車與機械手臂組合,規劃一個符合 ROS 標準的 URDF 檔案結構?

  2. 🗺️ tf2 座標樹設計: 針對「自走車與機械手臂的協同工作」,專門設計一個穩定的 tf2 座標轉換樹 (tF tree)?

  3. 💻 MoveIt! 2 配置: 講解 MoveIt! 2 套件的配置流程,從 URDF 到 IK 求解器設定?

2025年11月11日 星期二

PX4 官方指南的 ROS/MAVROS Offboard Control 模式

這是基於 PX4 官方指南的 ROS/MAVROS Offboard Control 模式 範例教學,目標是讓模擬的四旋翼(例如 Iris 模型)自動起飛到指定高度(通常是 2 公尺)。

這個範例使用 Python 編寫,是最常用且易於理解的 Offboard 控制基礎。


🚀 MAVROS Offboard Control 模式範例教學 (Python)

Offboard 模式允許您從外部電腦(透過 MAVROS)發送高層級的目標設定點(例如位置、速度或姿態),從而完全控制飛行器的導航。

步驟一:建立 ROS 工作空間與套件

如果您尚未建立 ROS 工作空間 (catkin_ws),請先建立並編譯。如果已經有了,則直接在其中建立新的功能套件。

Bash
# 進入 catkin 工作空間的 src 目錄
roscd # 進入 catkin_ws/devel
cd ..
cd src

# 建立一個名為 offboard_py 的新套件,依賴 rospy
catkin_create_pkg offboard_py rospy geometry_msgs mavros_msgs std_msgs

# 返回工作空間根目錄並編譯
cd .. 
catkin build 

# 載入新的環境變數 (重要)
source devel/setup.bash

# 進入新套件目錄
roscd offboard_py

步驟二:編寫 Python 控制腳本

offboard_py 套件目錄下,建立一個 scripts 資料夾,並創建您的控制腳本。

Bash
# 創建 scripts 資料夾並進入
mkdir scripts
cd scripts

# 創建 Python 腳本並賦予執行權限
touch offb_node.py
chmod +x offb_node.py

接下來,用您慣用的編輯器(如 nanovim)打開 offb_node.py,並貼入以下程式碼(此為官方範例的簡化版本,用於起飛到 2 公尺):

Python
#!/usr/bin/env python

import rospy
from geometry_msgs.msg import PoseStamped
from mavros_msgs.msg import State
from mavros_msgs.srv import CommandBool, CommandBoolRequest, SetMode, SetModeRequest

current_state = State()

def state_cb(msg):
    """回調函數:儲存飛控的當前狀態 (連線, 加解鎖, 模式)"""
    global current_state
    current_state = msg

if __name__ == "__main__":
    rospy.init_node("offb_node_py")
    
    # 訂閱飛控狀態
    state_sub = rospy.Subscriber("mavros/state", State, callback = state_cb)
    
    # 發布本地位置設定點
    local_pos_pub = rospy.Publisher("mavros/setpoint_position/local", PoseStamped, queue_size=10)
    
    # 服務客戶端:用於加解鎖 (Arming) 和模式切換 (SetMode)
    arming_client = rospy.ServiceProxy("mavros/cmd/arming", CommandBool)
    set_mode_client = rospy.ServiceProxy("mavros/set_mode", SetMode)
    
    # **Offboard 命令的發布頻率必須 > 2Hz**,否則飛控會退出 Offboard 模式
    rate = rospy.Rate(20.0)

    # 1. 等待飛控連線
    rospy.loginfo("Waiting for FCU connection...")
    while(not rospy.is_shutdown() and not current_state.connected):
        rate.sleep()

    # 2. 定義目標位置:(0, 0, 2) - 在本地 NED 座標系下,2 米高度
    pose = PoseStamped()
    pose.pose.position.x = 0
    pose.pose.position.y = 0
    pose.pose.position.z = 2

    # 3. 確保飛控在進入 Offboard 模式前,至少已經接收到 100 個設定點
    rospy.loginfo("Sending initial setpoints...")
    for i in range(100):
        if(rospy.is_shutdown()):
            break
        local_pos_pub.publish(pose)
        rate.sleep()

    # 4. 準備 Offboard 模式和 Arming 命令
    offb_set_mode = SetModeRequest()
    offb_set_mode.custom_mode = 'OFFBOARD'

    arm_cmd = CommandBoolRequest()
    arm_cmd.value = True

    last_request = rospy.get_time()

    # 5. 進入主控制循環
    rospy.loginfo("Starting Offboard Control Loop...")
    while(not rospy.is_shutdown()):
        
        # 發送設定點
        local_pos_pub.publish(pose)

        # 檢查當前狀態,並嘗試切換模式和加解鎖
        if(current_state.mode != "OFFBOARD" and (rospy.get_time() - last_request > 5.0)):
            # 嘗試切換到 OFFBOARD 模式
            if(set_mode_client.call(offb_set_mode).mode_sent == True):
                rospy.loginfo("Offboard enabled")
            last_request = rospy.get_time()
        
        elif(not current_state.armed and (rospy.get_time() - last_request > 5.0)):
            # 嘗試加解鎖 (Arm)
            if(arming_client.call(arm_cmd).success == True):
                rospy.loginfo("Vehicle armed")
            last_request = rospy.get_time()

        rate.sleep()

步驟三:啟動模擬與控制

您需要開啟 兩個 終端機視窗來運行模擬和 ROS 控制節點。

終端機 1:啟動 PX4 SITL 和 Gazebo

進入您的 PX4-Autopilot 原始碼目錄,運行 SITL 模擬。

Bash
cd ~/PX4-Autopilot
# 啟動 Iris 模型和 Gazebo
make px4_sitl gazebo_iris

(如果您使用的是 Gazebo Classic,請使用 make px4_sitl gazebo-classic_iris

成功啟動後,您會看到 Gazebo 窗口和一個 PX4 Shell 提示符。

終端機 2:運行 ROS 控制節點

開啟第二個終端機,載入 ROS 工作空間環境,並運行您剛編寫的 Python 腳本。

Bash
# 進入您的 ROS 工作空間
cd ~/catkin_ws
source devel/setup.bash

# 運行 offboard 控制節點
rosrun offboard_py offb_node.py

預期結果

  1. 終端機 2 會開始打印日誌,先是等待飛控連線,然後發送初始化設定點。

  2. 幾秒後,終端機 2 會打印 Offboard enabledVehicle armed

  3. 在 Gazebo 窗口中,Iris 四旋翼模型將會自動起飛,並穩定懸停在 2 公尺 的高度。


警告: Offboard 控制模式是危險的。在真實飛行器上操作時,請務必設置實體開關,以便在緊急情況下迅速切換回手動控制。