手动定义动力学 custom_dynamics.py
很多时候,能够轻松实现自定义动力学对研究可能有用。为此,我们为 HovingAUV 创建了控制器,这些控制器接收线性和角加速度,并将其集成以实现自定义动力学。除了碰撞,模拟器中没有对车辆施加其他加速度,从而允许在python中实现完全自定义的动力学。这种可能性是无限的,包括复杂的流体力学、水流等。
此外,动力学传感器 DynamicsSensor 旨在提供计算动力学所需的所有必要当前状态信息,包括加速度、速度和当前姿态信息。
以下是一个实际应用示例,其中手动实现了重力、浮力和阻尼。

import numpy as np
import holoocean
from holoocean.agents import HoveringAUV
from scipy.spatial.transform import Rotation
scenario = {
"name": "hovering_dynamics",
"package_name": "Ocean",
"world": "SimpleUnderwater",
"main_agent": "auv0",
"agents": [
{
"agent_name": "auv0",
"agent_type": "HoveringAUV",
"sensors": [
{
"sensor_type": "DynamicsSensor",
"configuration":{
"UseRPY": False # 使用四元数
}
},
],
"control_scheme": 2, # 这是 Custom Dynamics 的控制方案。
"location": [0,0,-10],
"rotation": [20,20,90]
}
]
}
g = 9.81 # 重力
b = 3 # 线性阻尼
c = 2 # 角阻尼
# HoveringAUV.mass += 1 # 或者让它下沉
def f(x):
# 从状态中提取所有信息
a = x[:3]
v = x[3:6]
p = x[6:9]
alpha = x[9:12]
omega = x[12:15]
quat = x[15:19]
R = Rotation.from_quat(quat).as_matrix()
# 对所有力求和
force = np.zeros(3)
force[2] += -HoveringAUV.mass * g # 重力
force[2] += HoveringAUV.water_density * g * HoveringAUV.volume # 浮力
force -= v*b # 阻尼
# 对所有力矩求和
torque = np.zeros(3)
buoy_force = HoveringAUV.water_density*g*HoveringAUV.volume*np.array([0,0,1]) # 在全局坐标系中
cob = R@HoveringAUV.cob # 将浮心移动至全局坐标系
torque += np.cross(cob, buoy_force) # 浮力产生的力矩
torque -= omega*c # 阻尼
# 将力和力矩转换为加速度
lin_accel = force / HoveringAUV.mass
ang_accel = np.linalg.inv(HoveringAUV.I)@torque
return np.append(lin_accel, ang_accel)
u = np.zeros(6)
# 构建环境
with holoocean.make(scenario_cfg=scenario) as env:
for i in range(500):
# 步进仿真
state = env.step(u)
# 获取要传递给 HoloOcean 的加速度数据
u = f(state["DynamicsSensor"])