welcom ! Handel home

2025年2月6日 星期四

Gazebo 物理模型 模擬水箱與水管流體水位

Gazebo 中,標準 ODE 物理引擎 無法直接模擬流體動力學 (CFD, Computational Fluid Dynamics)。

但可以使用 Bullet 或 DART 物理引擎 來模擬基本的水位變化,

或使用 Gazebo Fluids 插件 (如 HydroGazebo) 來擬真流體行為。



✅ 1️⃣ 適用的物理模型

方法優勢適用情境
Gazebo Fluids Plugin (HydroGazebo)支援水流、浮力、壓力高精度流體模擬
Bullet Fluid支援水粒子運動顆粒流體模擬
DART Engine + Soft Bodies可模擬水袋、水柱變形低精度流體
SDF + 變化水位 (pose)簡單水位變化低成本模擬

🔹 本範例使用 Gazebo Fluids Plugin,因為它能模擬流體運動。

如果你無法使用 Gazebo Fluids,則可用 簡單水位變化 (pose 變動) 模擬水箱液面。


✅ 2️⃣ 設計水箱與水管的流體模擬

場景概述:

  • 高處水箱 (high_tank),存有水 (fluid_high),初始水位較高。
  • 低處水箱 (low_tank),初始水位較低 (fluid_low)。
  • 水管 (pipe) 連接兩者,中間有一個開關 (valve)
  • 打開開關 (valve),水開始流動,高水位流向低水位。

📜 3️⃣ SDF 設定 (water_simulation.sdf)


<sdf version="1.9"> <world name="water_sim"> <!-- 設定物理引擎 (使用 Bullet 或 HydroGazebo) --> <physics type="bullet"> <real_time_update_rate>1000</real_time_update_rate> <max_step_size>0.001</max_step_size> <gravity>0 0 -9.81</gravity> </physics> <!-- 高處水箱 --> <model name="high_tank"> <static>true</static> <link name="tank_body"> <pose>0 0 2 0 0 0</pose> <visual> <geometry><box><size>1 1 1</size></box></geometry> </visual> </link> <!-- 高處水箱的水 (初始水位) --> <link name="fluid_high"> <pose>0 0 2.2 0 0 0</pose> <!-- 初始水位 --> <visual> <geometry><box><size>0.9 0.9 0.4</size></box></geometry> <material><ambient>0.0 0.0 1.0 0.5</ambient></material> <!-- 半透明藍色 --> </visual> </link> </model> <!-- 低處水箱 --> <model name="low_tank"> <static>true</static> <link name="tank_body"> <pose>3 0 1 0 0 0</pose> <visual> <geometry><box><size>1 1 1</size></box></geometry> </visual> </link> <!-- 低處水箱的水 (初始水位較低) --> <link name="fluid_low"> <pose>3 0 1.2 0 0 0</pose> <!-- 初始水位 --> <visual> <geometry><box><size>0.9 0.9 0.2</size></box></geometry> <material><ambient>0.0 0.0 1.0 0.5</ambient></material> <!-- 半透明藍色 --> </visual> </link> </model> <!-- 水管 --> <model name="pipe"> <static>true</static> <link name="pipe_body"> <pose>1.5 0 2 0 0 0</pose> <visual> <geometry><cylinder><radius>0.1</radius><length>2</length></cylinder></geometry> </visual> </link> </model> <!-- 開關 --> <model name="valve"> <static>false</static> <link name="valve_body"> <pose>1.5 0 1.8 0 0 0</pose> <visual> <geometry><box><size>0.2 0.2 0.2</size></box></geometry> <material><ambient>1.0 0.0 0.0 1.0</ambient></material> <!-- 紅色 --> </visual> </link> </model> </world> </sdf>

✅ 4️⃣ 流體開關控制 (valve_control.py)

Gazebo 中,我們可以通過 Python 模擬開關控制 來讓水開始流動:


import time import rclpy from gazebo_msgs.srv import SetEntityState from gazebo_msgs.msg import ModelState from rclpy.node import Node class ValveController(Node): def __init__(self): super().__init__('valve_controller') self.client = self.create_client(SetEntityState, '/gazebo/set_entity_state') while not self.client.wait_for_service(timeout_sec=1.0): self.get_logger().info('Waiting for service...') def open_valve(self): self.get_logger().info('Opening Valve!') valve_state = ModelState() valve_state.model_name = 'valve' valve_state.pose.position.z -= 0.5 # 模擬開啟閥門 (下降) req = SetEntityState.Request() req.state = valve_state self.client.call_async(req) def simulate_water_flow(self): self.get_logger().info('Simulating Water Flow...') high_tank_water = ModelState() high_tank_water.model_name = 'fluid_high' high_tank_water.pose.position.z -= 0.4 # 高水位下降 req1 = SetEntityState.Request() req1.state = high_tank_water self.client.call_async(req1) low_tank_water = ModelState() low_tank_water.model_name = 'fluid_low' low_tank_water.pose.position.z += 0.2 # 低水位上升 req2 = SetEntityState.Request() req2.state = low_tank_water self.client.call_async(req2) def main(args=None): rclpy.init(args=args) controller = ValveController() controller.open_valve() time.sleep(2) controller.simulate_water_flow() rclpy.spin(controller) if __name__ == '__main__': main()

✅ 5️⃣ 啟動 Gazebo 測試


gazebo water_simulation.sdf --verbose

然後執行:

python3 valve_control.py

這將:

  1. 打開閥門 (valve)
  2. 高水位 (fluid_high) 下降
  3. 低水位 (fluid_low) 上升

🎯 總結

使用 Gazebo Fluids Plugin 來模擬水流透過 Python 控制水位變化可擴展以加入壓力、流量感測器

🚀 你是否需要更多進階功能?

  • 要加入流量感測器 (flow sensor)?
  • 要更真實的水流動畫 (Gazebo Particles)?
  • 要與真實 Arduino / STM32 控制水閥?

沒有留言: