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

摩托车圈速模拟器g-g图绘制:Python求根代码正确性验证问询

摩托车g-g图绘制:求根代码验证与曲线补全解决方案

问题概述

我正在为摩托车圈速模拟器绘制g-g图(x轴为横向加速度ay,y轴为纵向加速度ax)。已知除ax外的所有参数,参考视频编写了求根代码,但绘图结果不符合预期。当前完整代码仅能展示ax正负区间的分段曲线,需要补全正负部分的连接,同时验证求根代码的正确性。

求根代码问题分析

原求根代码存在两个核心问题:

  • 参数传递逻辑错误:函数fxn1定义中ax是待求解变量,但调用时将ax数组作为第一个参数传入,同时固定ay为单一值,与g-g图需要遍历不同ay求解对应ax的逻辑完全相反。
  • 函数用途误解:当前代码是绘制fxn1随ax变化的曲线,而非求解fxn1(ax)=0的根——这才是获取每个ay对应极限ax的正确方式。

曲线补全问题分析

原完整代码仅分开计算了加速段(Wheelie_Min)和减速段(Deceleration_Max),但未整合轮胎摩擦力椭圆约束与抬头/翘尾的物理边界,导致曲线无法完整闭合。需要对每个ay值,同时计算可行的最大加速ax和最小减速ax,并确保所有约束(功率、抬头、翘尾、轮胎摩擦力)都被应用。

修正后的完整实现

以下代码整合了求根逻辑与所有物理约束,生成完整的g-g曲线:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import root_scalar

# 物理参数
g = 9.81       # 重力加速度
pa = 1.2       # 空气密度
m = 250        # 摩托车质量
h = 0.69       # 质心高度
ha = 0.69      # 压力中心高度
w = 1.5        # 轴距
b = 0.73       # 质心到前轴的纵向距离
CdA = 0.2      # 风阻系数×迎风面积
PMax = 180000  # 最大功率
ux = 1.2       # 纵向摩擦系数
uy = 1.44      # 横向摩擦系数
V = 20         # 基准速度

# 预计算参数
Fd = 0.5 * pa * CdA * V**2  # 空气阻力
Ap = ((PMax / (m * V)) - (Fd / m)) / g  # 无横向加速度时的最大加速(功率限制)

# 定义求根函数:对于给定ay,求解满足轮胎摩擦力约束的ax
def fxn1(ax, ay):
    term1 = ((w * (m*ax + Fd) * np.sqrt(ay**2 + g**2)) / 
             (g * ((w - b)*m*np.sqrt(ay**2 + g**2) + m*ax*h + Fd*ha))) ** 2 / ux**2
    term2 = (ay / g)**2 / uy**2
    return term1 + term2 - 1

# 生成ay的遍历范围
yw = np.linspace(-uy, uy, 200)  # 覆盖横向加速度的正负区间

# 初始化加速段和减速段的ax数组
ax_accel = np.zeros_like(yw)
ax_decel = np.zeros_like(yw)

for i, ay in enumerate(yw):
    # 求解加速状态下的ax(正ax)
    try:
        sol_accel = root_scalar(fxn1, args=(ay,), method='brentq', bracket=[0, Ap])
        ax_accel[i] = sol_accel.root
    except:
        # 当超出抬头约束时,使用抬头极限值
        Aw = ((b * np.sqrt((ay*g)**2 + g**2)) / h - (Fd*ha)/(m*h)) / g
        ax_accel[i] = min(Ap, Aw)
    
    # 求解减速状态下的ax(负ax)
    try:
        sol_decel = root_scalar(fxn1, args=(ay,), method='brentq', bracket=[-5, 0])
        ax_decel[i] = sol_decel.root
    except:
        # 当超出翘尾约束时,使用翘尾极限值
        As = (((w - b) * np.sqrt((ay*g)**2 + g**2)) / h - (Fd*ha)/(m*h)) / (-g)
        # 同时考虑轮胎摩擦力约束的减速极限
        Ad = (-g * ux * np.sqrt(1 - (ay/g)**2 / uy**2) - Fd/m) / g
        ax_decel[i] = max(As, Ad)

# 整合抬头和翘尾约束,修正加速/减速段的极限值
Aw = ((b * np.sqrt((yw*g)**2 + g**2)) / h - (Fd*ha)/(m*h)) / g
ax_accel = np.minimum(ax_accel, Aw, Ap)
As = (((w - b) * np.sqrt((yw*g)**2 + g**2)) / h - (Fd*ha)/(m*h)) / (-g)
Ad = (-g * ux * np.sqrt(1 - (yw/g)**2 / uy**2) - Fd/m) / g
ax_decel = np.maximum(ax_decel, As, Ad)

# 绘制完整的g-g图
plt.figure(dpi=120)
plt.plot(yw, ax_accel, 'r', label='极限加速')
plt.plot(yw, ax_decel, 'r', label='极限减速')
plt.fill_between(yw, ax_decel, ax_accel, color='red', alpha=0.1)
plt.xlabel('横向加速度 ay (g)')
plt.ylabel('纵向加速度 ax (g)')
plt.title('摩托车g-g图 (基准速度20m/s)')
plt.grid(True)
plt.axis('equal')
plt.legend()
plt.show()

代码说明

  1. 求根逻辑修正:使用scipy.optimize.root_scalar对每个ay值求解fxn1(ax)=0的根,得到满足轮胎摩擦力椭圆约束的极限ax。
  2. 约束整合:对每个ay,同时计算功率限制、抬头限制、翘尾限制和轮胎摩擦力限制,取最严格的约束作为最终极限值。
  3. 曲线补全:遍历正负ay区间,分别计算加速和减速段的ax值,最终绘制完整的闭合曲线,并填充可行区域。

内容的提问来源于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.28 11:43:19