You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将速度-距离图转换为加速度图(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:04:54