3D双摆Python仿真运行超时问题求助
3D双摆Python仿真运行超时问题求助
我太懂你这种卡到天荒地老的感受了——3D双摆的拉格朗日方程本身就是一堆高度耦合的非线性式子,SymPy直接用smp.solve硬啃解析解,大概率会陷入无限的化简循环,毕竟这玩意儿可能根本没有简洁的解析形式,自然会跑半小时都没动静。
给你几个针对性的解决思路,亲测有效:
1. 改用线性方程组求解器(最推荐)
拉格朗日方程最终整理后,其实是关于the1_dd, the2_dd, phi1_dd, phi2_dd的线性方程组,没必要用通用的solve,换成SymPy专门的linsolve速度会快到飞起。把你代码里的求解部分改成这样:
from sympy import linsolve # 用linsolve求解线性方程组 sols = linsolve([LE1, LE2, LE3, LE4], (the1_dd, the2_dd, phi1_dd, phi2_dd)) # 转换成字典格式方便后续调用 sols = dict(zip((the1_dd, the2_dd, phi1_dd, phi2_dd), list(sols)[0]))
linsolve会跳过通用求解器里很多无用的尝试,专门处理线性问题,计算效率能提升好几个数量级。
2. 先代入数值再求解
如果你不需要保留符号形式的解,可以先把m1、m2、L1、L2、g这些数值代入拉格朗日方程,再求二阶导数。这样SymPy的计算量会直接砍半:
# 先定义数值参数 num_params = {g:9.81, m1:2, m2:1, L1:2, L2:1} # 代入拉格朗日方程并化简 LE1_num = LE1.subs(num_params).simplify() LE2_num = LE2.subs(num_params).simplify() LE3_num = LE3.subs(num_params).simplify() LE4_num = LE4.subs(num_params).simplify() # 求解 sols = smp.solve([LE1_num, LE2_num, LE3_num, LE4_num], (the1_dd, the2_dd, phi1_dd, phi2_dd))
这样得到的解是绑定了数值的表达式,后续转成数值函数也会更快。
3. 跳过解析解,直接数值求解微分方程
另一种思路是不硬求解析解,把拉格朗日方程转换成一阶微分方程组后,用SciPy的solve_ivp(比odeint更现代)结合符号微分直接数值求解。简单来说就是在每个积分步里,用数值方法解出当前的二阶导数,不用提前推导全局解析式。
另外提个小细节:你代码里dSdt函数的返回列表最后一行多了个空格,虽然不影响运行,但看着有点别扭,顺手改了更舒服。
按照上面的方法调整后,应该能在几分钟内完成符号计算,顺利进入动画渲染环节。
备注:内容来源于stack exchange,提问作者Andrej Horehleď
相关产品推荐
相关产品推荐

