如何将速度-距离图转换为加速度图(Python圈速模拟器)
圈速模拟器加速度曲线生成问题
我编写了一段圈速模拟器的Python代码,生成了速度随距离变化的曲线(如下方速度曲线所示),现在需要将其转换为加速度曲线。尝试将Wheelie_Min和Deceleration_Max存入数组绘制,但结果始终全正或全负,不符合速度下降时加速度为负的物理逻辑。考虑过对曲线微分,但不知如何实现,希望得到帮助。
速度-距离曲线

模拟器代码
import numpy as np import matplotlib.pyplot as plt T8_Angle = 180 T8_Radius = 80.5352283/2 T8_Length = T8_Radius * (T8_Angle*(np.pi/180)) T8_Velo = np.sqrt(uy*g*T8_Radius) St1Length = 400 dsa1 = 1 vela1 = [T8_Velo] sa1 = [0.] while sa1[-1] < St1Length: Fd = 0.5 * pa * CdA * vela1[-1]**2 Ap = ((PMax / ((m * vela1[-1]) + 1e-9)) - (Fd / m)) / g yw = 0 Aw = (((b * np.sqrt((yw)**2 + g**2)) / h) - ((Fd * ha) / (m * h))) / g Wheelie_Min = np.minimum(Ap, Aw) vela1_new = np.sqrt(vela1[-1]**2 + 2*Wheelie_Min*dsa1*g) vela1.append(vela1_new) sa1_new = sa1[-1] + dsa1 sa1.append(sa1_new) T1_Angle = 90 T1_Length = 315 T1_Radius = T1_Length/(2*np.pi*(T1_Angle/360)) T1_Velo = np.sqrt(uy*g*T1_Radius) dsd1 = 1 veld1 = [T1_Velo] sd1 = [St1Length] while sd1[-1] > 0: Fd = 0.5 * pa * CdA * veld1[-1]**2 yw = 0 Ad = (((g * ux * (np.sqrt(1 - (((yw)/ g)**2) * (1 / uy**2))) + (Fd / m))) * -1) / g As = ((((w-b) * np.sqrt((yw)**2 + g**2)) / h) + ((Fd * ha) / (m *h))) / (g *-1) Deceleration_Max = np.maximum(Ad, As) veld1_new = np.sqrt(veld1[-1]**2 - 2*Deceleration_Max*g*dsd1) veld1.append(veld1_new) sd1_new = sd1[-1] - dsd1 sd1.append(sd1_new) min_vel1 = [] for i in range(len(sa1)): s1 = sa1[i] v1_1 = vela1[i] v2_1 = veld1[-i-1] min_v1 = min(v1_1, v2_1) min_vel1.append(min_v1) St1Last = sa1[-1] St1T1 = St1Last+T1_Length fig, lv = plt.subplots() lv.plot(sa1, min_vel1, 'b') lv.hlines(T1_Velo, St1Last, St1T1, 'b') St2Length = 900 St2_Total = St2Length + St1T1 dsa2 = 1 vela2 = [T1_Velo] sa2 = [St1T1] while sa2[-1] < St2_Total: Fd = 0.5 * pa * CdA * vela2[-1]**2 Ap = ((PMax / ((m * vela2[-1]) + 1e-9)) - (Fd / m)) / g yw = 0 Aw = (((b * np.sqrt((yw)**2 + g**2)) / h) - ((Fd * ha) / (m * h))) / g Wheelie_Min = np.minimum(Ap, Aw) vela2_new = np.sqrt(vela2[-1]**2 + 2*Wheelie_Min*dsa2*g) vela2.append(vela2_new) sa2_new = sa2[-1] + dsa2 sa2.append(sa2_new) T2_Angle = 180 T2_Radius = 180 T2_Length = T2_Radius * (T2_Angle*(np.pi/180)) T2_Velo = np.sqrt(uy*g*T2_Radius) dsd2 = 1 veld2 = [T2_Velo] sd2 = [St2Length] while sd2[-1] > 0: Fd = 0.5 * pa * CdA * veld2[-1]**2 yw = 0 Ad = (((g * ux * (np.sqrt(1 - (((yw)/ g)**2) * (1 / uy**2))) + (Fd / m))) * -1) / g As = ((((w-b) * np.sqrt((yw)**2 + g**2)) / h) + ((Fd * ha) / (m *h))) / (g *-1) Deceleration_Max = np.maximum(Ad, As) veld2_new = np.sqrt(veld2[-1]**2 - 2*Deceleration_Max*g*dsd2) veld2.append(veld2_new) sd2_new = sd2[-1] - dsd2 sd2.append(sd2_new) min_vel2 = [] for i in range(len(sa2)): s2 = sa2[i] v1_2 = vela2[i] v2_2 = veld2[-i-1] min_v2 = min(v1_2, v2_2) min_vel2.append(min_v2) St2Last = sa2[-1] St2T2 = St2Last+T2_Length lv.plot(sa2, min_vel2, 'b') lv.hlines(T2_Velo, St2Last, St2T2, 'b') plt.xlabel('Distance (m)') plt.ylabel('Velocity (m/s)')
解决方案
1. 修正加速度存储的符号逻辑
原来的Deceleration_Max是正的减速比例,需要转换为负的加速度才符合物理规则。同时要对应min_vel的取值逻辑,匹配每个距离点的实际加速度:
# 在加速阶段新增数组存储加速度(正数值,单位m/s²) accel_st1 = [] while sa1[-1] < St1Length: # ... 原有代码 ... Wheelie_Min = np.minimum(Ap, Aw) accel_st1.append(Wheelie_Min * g) # ... 原有代码 ... # 在减速阶段新增数组存储加速度(负数值,单位m/s²) decel_st1 = [] while sd1[-1] > 0: # ... 原有代码 ... Deceleration_Max = np.maximum(Ad, As) decel_st1.append(-Deceleration_Max * g) # ... 原有代码 ... # 匹配min_vel的加速度数组 accel_st1_full = [] for i in range(len(sa1)): v1_1 = vela1[i] v2_1 = veld1[-i-1] if v1_1 <= v2_1: accel_st1_full.append(accel_st1[i] if i < len(accel_st1) else 0) else: accel_st1_full.append(decel_st1[-i-1] if (-i-1) >=0 else 0) # St2阶段同理添加加速度存储和匹配逻辑 # ... # 绘制加速度曲线 fig2, ax2 = plt.subplots() all_s = np.concatenate([sa1, np.linspace(St1Last, St1T1, 10), sa2, np.linspace(St2Last, St2T2, 10)]) all_accel = np.concatenate([accel_st1_full, [0]*10, accel_st2_full, [0]*10]) ax2.plot(all_s, all_accel, 'r') ax2.set_xlabel('Distance (m)') ax2.set_ylabel('Acceleration (m/s²)') plt.show()
2. 对速度曲线数值微分
利用物理公式a = v * dv/ds(加速度=速度×速度对距离的导数),用numpy的gradient函数直接计算:
# 合并所有距离和速度数据 all_s = np.concatenate([sa1, np.linspace(St1Last, St1T1, 10), sa2, np.linspace(St2Last, St2T2, 10)]) all_v = np.concatenate([min_vel1, [T1_Velo]*10, min_vel2, [T2_Velo]*10]) # 计算加速度 dv_ds = np.gradient(all_v, all_s) acceleration = all_v * dv_ds # 绘制曲线 fig, ax = plt.subplots() ax.plot(all_s, acceleration, 'r') ax.set_xlabel('Distance (m)') ax.set_ylabel('Acceleration (m/s²)') plt.show()
这种方法不依赖原有加速度计算逻辑,直接从最终速度曲线生成,结果更贴合实际速度变化。
内容的提问来源于stack exchange,提问作者Karl Burnett
相关产品推荐
相关产品推荐

