2. 路面输入模型构建
任务说明
本案例构建悬架系统仿真所需的路面激励输入模型,包含两种典型工况:随机路面(描述连续不平路面)与凸起路面(描述减速带或障碍物)。模型输出为路面垂向位移随时间变化的序列,可直接作为后续悬架动力学仿真的激励源。
路面模型原理
随机路面采用滤波白噪声法生成,其核心是将白噪声通过一阶成形滤波器,得到与路面功率谱密度(PSD)等级对应的时域位移信号。路面空间频率PSD满足:
Gq(n) = Gq(n0)·(n/n0)-W
其中n0=0.1 m-1为参考空间频率,Gq(n0)为路面不平度系数(按ISO 8608标准,B级路面取64×10-6 m³),W≈2为频率指数。转换为时域后,采用一阶滤波器近似:
Gq(f) = Gq(n0)·u/(f²·(2π)²)
其中u为车速,f为时间频率。对应的成形滤波器传递函数为:
H(s) = 2π·n0·√(Gq(n0)·u) / (s + 2π·nc·u)
式中nc=0.01 m-1为下限截止空间频率,用于避免低频发散。凸起路面采用半正弦脉冲描述,模拟车辆通过减速带时的路面位移输入。
代码实现
以下Python代码实现两类路面模型,并输出可保存为CSV的时域数据:
import numpy as np
import matplotlib.pyplot as plt
def random_road(duration=10.0, fs=1000.0, velocity=20.0,
Gq_n0=64e-6, n0=0.1, nc=0.01):
"""
滤波白噪声法生成随机路面时域模型
参数:
duration: 仿真时长(s)
fs: 采样频率(Hz)
velocity: 车速(m/s)
Gq_n0: 路面不平度系数(m^3), B级路面默认64e-6
返回:
t: 时间数组(s)
z: 路面垂向位移(m)
"""
dt = 1.0 / fs
n_samples = int(duration * fs)
t = np.arange(n_samples) * dt
# 白噪声序列(标准差为1)
w = np.random.randn(n_samples)
# 成形滤波器系数(双线性变换离散化)
# 连续域: H(s) = K / (s + a)
K = 2 * np.pi * n0 * np.sqrt(Gq_n0 * velocity)
a = 2 * np.pi * nc * velocity
# 双线性变换: s = (2/dt)*(z-1)/(z+1)
# 离散传递函数: H(z) = b0 + b1*z^-1 / (1 + a1*z^-1)
T = dt
b0 = K * T / (2 + a * T)
b1 = b0
a1 = (a * T - 2) / (a * T + 2)
# 滤波
z_road = np.zeros(n_samples)
for i in range(1, n_samples):
z_road[i] = b0 * w[i] + b1 * w[i-1] - a1 * z_road[i-1]
return t, z_road
def bump_road(duration=5.0, fs=1000.0, velocity=10.0,
bump_height=0.05, bump_length=0.4, bump_start=1.0):
"""
凸起路面(半正弦脉冲)时域模型
参数:
duration: 仿真时长(s)
fs: 采样频率(Hz)
velocity: 车速(m/s)
bump_height: 凸起高度(m)
bump_length: 凸起长度(m)
bump_start: 凸起起始时间(s)
返回:
t: 时间数组(s)
z: 路面垂向位移(m)
"""
dt = 1.0 / fs
n_samples = int(duration * fs)
t = np.arange(n_samples) * dt
# 凸起持续时间
bump_duration = bump_length / velocity
z = np.zeros(n_samples)
# 半正弦脉冲
mask = (t >= bump_start) & (t <= bump_start + bump_duration)
z[mask] = bump_height * np.sin(np.pi * (t[mask] - bump_start) / bump_duration)
return t, z
if __name__ == "__main__":
# 生成随机路面(B级, 车速20m/s, 时长10s)
t1, z1 = random_road(duration=10.0, fs=1000.0, velocity=20.0)
np.savetxt("random_road.csv", np.column_stack((t1, z1)),
delimiter=",", header="time_s,displacement_m", comments="")
# 生成凸起路面(高度5cm, 长度0.4m, 车速10m/s)
t2, z2 = bump_road(duration=5.0, fs=1000.0, velocity=10.0,
bump_height=0.05, bump_length=0.4, bump_start=1.0)
np.savetxt("bump_road.csv", np.column_stack((t2, z2)),
delimiter=",", header="time_s,displacement_m", comments="")
# 绘图对比
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
ax1.plot(t1, z1, linewidth=0.5)
ax1.set_xlabel("Time (s)")
ax1.set_ylabel("Displacement (m)")
ax1.set_title("Random Road (ISO Class B, v=20m/s)")
ax1.grid(True)
ax2.plot(t2, z2, linewidth=1.5)
ax2.set_xlabel("Time (s)")
ax2.set_ylabel("Displacement (m)")
ax2.set_title("Bump Road (h=5cm, L=0.4m, v=10m/s)")
ax2.grid(True)
plt.tight_layout()
plt.savefig("road_profiles.png", dpi=150)
plt.show()
关键实现说明
随机路面生成中,滤波器系数通过双线性变换从连续域映射到离散域,保证数值稳定性。白噪声序列使用np.random.randn生成标准正态分布随机数。凸起路面采用半正弦函数描述,其数学表达式为:
z(t) = h·sin(π·(t-t₀)/T_b), t₀ ≤ t ≤ t₀+T_b
其中T_b = L/v为通过凸起的时间,h为凸起高度,L为凸起长度。该模型可模拟车辆单次通过减速带时的路面激励。
落地与验证
运行方式:将代码保存为road_model.py,在Python环境中执行python road_model.py。需要安装numpy和matplotlib库。
输出文件:运行后生成两个CSV文件(random_road.csv和bump_road.csv),以及一张对比图road_profiles.png。
验证方法:
- 检查
random_road.csv中位移数据:均方根值(RMS)应在0.005~0.02 m范围内(B级路面典型值),且信号无明显趋势项; - 检查
bump_road.csv:在t=1.0s附近应出现一个单峰脉冲,峰值接近0.05m,脉冲宽度约0.04s(0.4m/10m/s); - 观察生成的
road_profiles.png:随机路面曲线应呈现高频小幅波动,凸起路面为光滑单脉冲形状。
判定标准:若随机路面位移RMS在合理范围且凸起路面峰值与设定值偏差小于5%,则模型构建正确,可作为悬架MILSIL仿真的路面激励输入。