ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

SymPy 多体系统运动方程建模:Kane 方法与 Lagrange 方法 API 完全指南

SymPy 多体系统运动方程建模:Kane 方法与 Lagrange 方法 API 完全指南 SymPy 多体系统运动方程建模Kane 方法与 Lagrange 方法 API 完全指南【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy导读本文是 Mechanics API Reference 中Kanes Method 与 Lagranges Method两个核心 API 的深入技术指南对应文档源文件为 kane_lagrange.rst。SymPy 的sympy.physics.mechanics模块使用纯 Python 符号计算为多刚体系统建立运动方程Equations of Motion, EOM而KanesMethod与LagrangesMethod正是其中两套并列的建模引擎。读完本文你将掌握两种方法各自的适用场景与参数语义、如何从自由度与约束出发构造完整的系统模型、如何提取质量矩阵/力向量并直接喂给 ODE 求解器以及如何借助Linearizer完成符号线性化与 Lagrange 乘子求解。文中的每个结论都有当前仓库源码作为依据。一、两种方法在 SymPy 中的定位kane_lagrange.rst通过两个automodule指令把 kane.py 与 lagrange.py 的完整 docstring 注入到 API 文档中这两个文件分别导出KanesMethod与LagrangesMethod见两文件的__all__定义。Mechanics 模块的文档明确说明该模块实现了两种经典的运动方程生成方法——Kane 方法与 Lagrange 方法。两者的目标一致把多体系统的动力学信息组合为可交给通用 ODE 求解器积分的形式即前向动力学问题求解流程中的第 4、5 步应用牛顿第二定律组合信息、把方程组织成可积形式。维度KanesMethodLagrangesMethod核心输入惯性参考系、广义坐标、广义速度、运动微分方程拉格朗日量 L、广义坐标动力学校核Fr Fr* 0广义主动力 广义惯性力d/dt(∂L/∂q̇) - ∂L/∂q Q约束处理配置约束、速度约束、加速度约束分层给出完整/非完整约束 自动生成的拉格朗日乘子 λ是否显式使用广义速度 u是u 与 q̇ 通过 kd 方程线性关联否直接使用 q̇ 与 q̈关键产出mass_matrix/forcing、mass_matrix_full/forcing_fulleom、mass_matrix/forcing、lam_vec从源码结构看两个类都继承自 method.py 中的MethodBase共享rhs()、linearize()、to_linearizer()等公共接口因此对使用者而言两者的下游用法高度一致。二、KanesMethod从广义速度到 Kane 方程2.1 理论基础Kane 的动力学微分方程写作F_r F_r* 0 r 1, ..., pp 为独立广义速度个数其中F_r为广义主动力、F_r*为广义惯性力。当把线性质量矩阵显式分离出来时可以写成矩阵形式M · u̇ F这正是KanesMethod内部把结果整理为质量矩阵 × 广义速度导数 力向量的理论来源。2.2 构造函数参数全景KanesMethod.__init__kane.py的完整签名如下参数类型/默认值含义frameReferenceFrame系统的惯性参考系必须传入否则抛出TypeErrorq_inddynamicsymbols 可迭代对象独立广义坐标u_inddynamicsymbols 可迭代对象独立广义速度kd_eqsExpr 可迭代对象默认 None运动微分方程线性关联广义速度与广义坐标的时间导数q_dependentdynamicsymbols 可迭代对象相关广义坐标configuration_constraintsExpr 可迭代对象完整约束构型约束残差u_dependentdynamicsymbols 可迭代对象相关广义速度velocity_constraintsExpr 可迭代对象速度约束残差非完整约束 完整约束的时间导数acceleration_constraintsExpr 可迭代对象加速度约束残差默认取速度约束的时间导数u_auxiliarydynamicsymbols 可迭代对象辅助广义速度用于引出非做功约束力bodiesParticle/RigidBody 可迭代对象系统中的质点与刚体forcelist(Point/ReferenceFrame, Vector) 可迭代对象施加在系统上的力与力矩explicit_kinematicsbool默认 True运动学质量矩阵/力向量是否用显式形式kd_eqs_solverstr/callable默认LU求解运动微分方程线性系统的方法constraint_solverstr/callable默认LU求解速度约束线性系统的方法nonholonomic_constraintsExpr 可迭代对象默认 None纯非完整约束残差可与velocity_constraints二选一几点值得注意的源码级细节约束数量校验_initialize_constraint_matrices中会强制相关坐标数 配置约束数相关速度数 速度约束数不满足直接抛出ValueErrorkane.py。nonholonomic_constraints与velocity_constraints互斥两者同时传入会触发ValueErrorkane.py若只给前者速度约束会自动由完整约束时间导数 非完整约束拼接而成。动力学符号校验_initialize_vectors之后调用_validate_coordinates确保 q、u 都是时间的函数。2.3 一个可直接运行的最小示例弹簧-质量-阻尼器文档 docstring 中给出的一自由度平动弹簧-质量-阻尼器示例是理解完整工作流的最佳起点kane.pyfrom sympy import symbols from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame from sympy.physics.mechanics import Point, Particle, KanesMethod q, u dynamicsymbols(q u) qd, ud dynamicsymbols(q u, 1) m, c, k symbols(m c k) N ReferenceFrame(N) P Point(P) P.set_vel(N, u * N.x) # 1) 运动微分方程q u kd [qd - u] # 2) 力列表(作用点, 力矢量) FL [(P, (-k * q - c * u) * N.x)] # 3) 体列表至少包含一个 Particle 或 RigidBody pa Particle(pa, P, m) BL [pa] # 4) 构造 KanesMethod 并形成 Fr Fr* 0 KM KanesMethod(N, q_ind[q], u_ind[u], kd_eqskd) (fr, frstar) KM.kanes_equations(BL, FL) # 5) 提取质量矩阵与力向量得到 M·udot forcing MM KM.mass_matrix forcing KM.forcing rhs MM.inv() * forcing # Matrix([[-c*u(t) - k*q(t))/m]]) # 6) 直接线性化得到状态矩阵 KM.linearize(A_and_BTrue)[0]该示例对应的仓库测试用例见 test_kane.py测试中不仅校验了rhs的两个分量与手算一致还验证了显式运动学下mass_matrix_kin eye(2)。2.4 显式与隐式运动学explicit_kinematics控制运动学矩阵的表示形式。默认显式形式下运动学质量矩阵k_kq̇ I单位阵将其置为False后k_kq̇不再必须是单位阵对于非平凡的运动学如某些齿轮、连杆关系可以得到更紧凑的方程。源码实现中kane.py运动微分方程先被整理为k_ku(q,t)·u k_kq̇(q,t)·q̇ f_k(q,t) 0_initialize_kindiffeq_matrices会提取系数矩阵k_ku、k_kq̇与常数项f_k并检查方程对 q̇ 与 u 是否线性——若非线性的方程出现在系数矩阵中会直接抛出ValueError测试用例 test_kane.py 用[q1d - u1**2, sin(q2d) - cos(u2)]验证了这一错误路径。显式形式下还会用线性求解器把 q̇ 解出得到qdot_u_map而隐式形式保留原始系数矩阵_k_kqdot_implicit等。从测试test_kane.py可知无论explicit_kinematics取 True 还是 FalseKM.rhs()与mass_matrix_full.LUsolve(forcing_full)的结果都必须一致——两者只是表达方式不同物理内容等价。2.5 线性求解器LU、CRAMER 与自定义 callablekd_eqs_solver与constraint_solver解决两类线性系统Ax rhs运动微分方程与速度约束。源码 Noteskane.py给出的选择建议默认LU运算量相对较低但可能产生除零错误CRAMER使用克莱默法则运算更慢、符号更冗长但解向量每个分量默认只做一次除法可规避部分除零问题自定义 callable格式为f(A, rhs)。例如用简化器包装 LU 求解lambda A, b: simplify(Matrix.LUsolve(A, b))或用linsolvelambda A, b: tuple(linsolve((A, b)))[0]系统应只有唯一解。2.6 约束系统相关坐标、相关速度与Ars矩阵当系统含约束时Kane 方法把速度约束整理为B·u C 0再将B分成独立列与相关列Ars -B_dep⁻¹·B_ind从而用独立速度表达相关速度。_initialize_constraint_matriceskane.py在求解Ars时如果遇到奇异矩阵会抛出带提示信息的NonInvertibleMatrixError可能是相关速度选择不当请换一组相关速度。如果传入相关速度与速度约束_form_fr与_form_frstar会通过Ars.T把相关部分折叠进独立的 Kane 方程kane.py、kane.py。这就是消去相关速度后 p 个独立方程的实现方式。2.7 辅助广义速度与auxiliary_eqs辅助广义速度u_auxiliary用于把非做功约束力引入显式表达。调用kanes_equations时如果存在辅助速度源码会再创建一个内部KanesMethod实例专门计算辅助方程kane.py最终返回的(Fr, Fr*)长度为o - m so 个广义速度、m 个运动约束、s 个辅助速度其中前o - m个是受约束的 Kane 方程后 s 个是辅助 Kane 方程可通过auxiliary_eqs属性访问kane.py。三、LagrangesMethod从拉格朗日量到运动方程3.1 两步式工作流LagrangesMethod 采用两步流程生成运动方程lagrange.py用拉格朗日量 广义坐标最少输入初始化对象若有约束以关键字参数传入系统会自动生成与约束方程数量相等的拉格朗日乘子非保守力以可迭代对象形式连同ReferenceFrame一并传入。3.2 构造函数参数参数类型/默认值含义LagrangianSympifyable标量拉格朗日量系统动能与势能之差是 q 与 q̇ 的函数qs时间函数可迭代对象广义坐标 qhol_coneqsExpr 可迭代对象完整约束残差nonhol_coneqsExpr 可迭代对象非完整约束残差forcelist可迭代对象(Point, Vector) 或 (ReferenceFrame, Vector) 元组只应包含非保守力/力矩保守力已在 L 中bodies可迭代对象Particle、RigidBody 或 Body 对象frameReferenceFrame惯性参考系仅当提供forcelist时需要3.3 最小示例弹簧-质量-阻尼器的拉格朗日版本文档 docstring 的示例lagrange.py展示了与 Kane 版本平行的完整流程from sympy.physics.mechanics import LagrangesMethod, Lagrangian from sympy.physics.mechanics import ReferenceFrame, Particle, Point from sympy.physics.mechanics import dynamicsymbols from sympy import symbols q dynamicsymbols(q) qd dynamicsymbols(q, 1) m, k, b symbols(m k b) N ReferenceFrame(N) P Point(P) P.set_vel(N, qd * N.x) # 1) 构造 Particle并设定势能 Pa Particle(Pa, P, m) Pa.potential_energy k * q**2 / 2 # 2) 用 Lagrangian() 组合动能与势能 L Lagrangian(N, Pa) # 3) 非保守力列表本例为阻尼力 fl [(P, -b * qd * N.x)] # 4) 生成拉格朗日方程 0 l LagrangesMethod(L, [q], forcelistfl, frameN) print(l.form_lagranges_equations()) # Matrix([[b*Derivative(q(t), t) k*q(t) m*Derivative(q(t), (t, 2))]]) # 5) 用 rhs() 得到一阶形式 print(l.rhs()) # Matrix([[Derivative(q(t), t)], [(-b*Derivative(q(t), t) - k*q(t))/m]])对应的仓库测试用例见 test_lagrange.py单摆与 test_lagrange.py斜面滚轮。3.4form_lagranges_equations的内部结构form_lagranges_equationslagrange.py把拉格朗日方程拆成四个项组合EOM term1 - term2 - term3 - term4 0其中term1 d/dt(∂L/∂q̇)对L求 q̇ 的 Jacobian 后再对时间求导term2 ∂L/∂qterm3约束力项。存在约束时自动生成lam1:lam(m1)乘子列向量lam_veclam_coeffs linear_eq_to_matrix(-coneqs, q̇)即约束 Jacobian的负值term3 lam_coeffsᵀ · lam_vecterm4非保守广义力通过sum(v.diff(qd, N).dot(f))由偏速度点乘力得到。最终把不含量 λ 的部分整理为M_d·q̈ F_d从而得到质量矩阵mass_matrix与力向量forcingeom则是完整方程含约束力。有无约束时方程的标准形式docstring 中的权威表述无约束: f_d(q, q, q, r, t) M_d·q g_d(q, q, r, t) 0 有约束: f_d(q, λ, q, q, r, t) M_d·q Cᵀ·λ g_d(q, q, r, t) 0其中C来自速度约束f_v(q, q, t) C·q g_v(q, t) 0的 Jacobian。3.5 完整形式矩阵与乘子求解mass_matrix_full给出含状态[q, q, λ]的一阶形式分块矩阵lagrange.py有约束时: [I 0 0 ] [q] [q ] [0 M_d -Cᵀ] [q] [F_d] [0 C 0 ] [λ ] [F_c]solve_multipliers(op_point, sol_type)lagrange.py可在指定工作点op_point为{symbol: value}字典或字典的可迭代对象上符号求解乘子返回dict默认{λ: value}或Matrix有序列矩阵。测试 test_lagrange.py 用一个带完整约束q1²q2²-L²0的非最小坐标摆验证了乘子解析解与solve_multipliers结果一致。四、共享能力rhs、线性化与工作流4.1rhs()一阶形式的数值积分接口两个类都继承MethodBase.rhs()。Kane 版本kane.py把结果整理成x [q] : f(q, u, r, p, t) [u]默认用mass_matrix.LUsolve(forcing)求解也可以通过inv_method指定其他求逆方法。这正是数值 ODE 积分器如scipy.integrate.solve_ivp需要的右端函数形式。4.2 线性化to_linearizer与linearizeto_linearizer(linear_solverLU)把运动方程数据打包进Linearizer实例。相比一次性linearize复用Linearizer对象可以在多个工作点上更高效地重复线性化。linearize(**kwargs)默认A_and_BFalse返回(M, A, B, r)满足M·[q, u]ᵀ A·[q_ind, u_ind]ᵀ B·rA_and_BTrue时直接返回状态空间形式dx A·x B·r。文档建议当符号参数很多时先取M, A, B并代入数值再通过A Pᵀ·M⁻¹·A组装状态矩阵可避免大规模符号求逆。工作点通过op_point关键字传入{symbol: value}字典或字典可迭代对象提前指定的工作点越多计算越快。输出r是方程中所有不属于 q、u、q̇、u̇ 的动力学符号如随时间变化的参数按规范顺序排序。LagrangesMethod 的linearize还需显式传入独立/相关坐标与速度的划分q_ind, qd_ind, q_dep, qd_dep划分不完整或不匹配会抛出ValueErrorlagrange.py。4.3 典型端到端工作流综合两个类的公共接口一套完整的建模-求解流水线通常是运动学描述用ReferenceFrame、Point、dynamicsymbols建立几何与速度关系Kane 还需给出 kd 方程Lagrange 则给出 L建模构造KanesMethod/LagrangesMethod传入坐标、速度/拉格朗日量、约束与载荷生成方程kanes_equations()或form_lagranges_equations()整理矩阵读取mass_matrix(_full)、forcing(_full)数值求解用rhs()生成右端函数交给 ODE 积分器可选分析用linearize()做符号线性化或用solve_multipliers()Lagrange求约束力。五、易错点与最佳实践小结场景建议忘记传kd_eqs给KanesMethodkanes_equations/kindiffdict会抛出AttributeErrorkd 是 Kane 方法的必填核心kd 方程对 q̇、u 非线性构造时直接ValueError务必保持 kd 线性相关坐标数 ≠ 配置约束数、相关速度数 ≠ 速度约束数构造时ValueError提示建模前先数清自由度velocity_constraints与nonholonomic_constraints同时给抛ValueError二选一LU 求解出现除零/nan换constraint_solverCRAMER或自定义 callable如 simplify 包装的 LU、linsolveArs奇异错误信息建议更换相关速度组合Lagrange 模型漏掉非保守力非保守力只能进forcelist保守力请放入拉格朗日量如potential_energy属性需要约束力数值用solve_multipliers(op_point)op_point越完整计算越快频繁多工作点线性化优先to_linearizer()复用对象而非反复linearize()六、进一步阅读API 总览与模块定位Mechanics API Reference源码实现kane.py、lagrange.py测试用例test_kane.py、test_lagrange.py线性化基础设施linearize.rst其他建模工具质点/刚体 API part_bod.rst、关节 joint.rst、系统级封装 system.rstKane 方法适合需要显式广义速度、或包含非完整约束与相关坐标的机器人/航天器建模Lagrange 方法以能量视角入手、自动引入乘子适合约束力需要显式求解的场景。两者产出的mass_matrix/forcing语义一致都可以无缝衔接rhs()与Linearizer这使 SymPy 成为从符号建模到数值仿真的统一工作台。【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表