尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SymPy 矢量运动学完全指南:Point 类、运动学方程与运动参数求解

SymPy 矢量运动学完全指南:Point 类、运动学方程与运动参数求解 SymPy 矢量运动学完全指南Point 类、运动学方程与运动参数求解【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy本指南以 doc/src/modules/physics/vector/api/kinematics.rst 为核心骨架系统讲解sympy.physics.vector模块中的运动学Kinematics工具Point类的全部 API、三个运动学函数kinematic_equations、partial_velocity与get_motion_params。读完本文你将能够用 SymPy 描述多体系统中点的位置、速度、加速度建立广义速度与广义坐标之间的运动学微分方程并自动推导运动参数为后续动力学分析如sympy.physics.mechanics打下基础。一、概述运动学在 SymPy 矢量模块中的位置SymPy 的sympy.physics.vector是一个面向三维矢量运算与多体运动学、动力学分析的符号计算模块。它以时间相关的矢量函数为基础提供ReferenceFrame参考系、Vector矢量、Dyadic并矢等底层构件而Point点与运动学函数则是连接几何描述与运动描述的关键层。官方 API 文档 doc/src/modules/physics/vector/api/kinematics.rst 把运动学相关的公开接口划分为两部分sympy.physics.vector.point模块自动生成全部成员文档即Point类负责存储并计算点的位置、速度、加速度sympy.physics.vector.functions模块中的三个函数kinematic_equations运动学微分方程、partial_velocity偏速度、get_motion_params由已知运动量反推其余运动参数。整个physics/vector的 API 索引见 doc/src/modules/physics/vector/api/index.rst其中classes.rst覆盖CoordinateSym、ReferenceFrame、Vector、Dyadickinematics.rst即本文主题。在动手前先准备环境并导入常用符号from sympy.physics.vector import Point, ReferenceFrame, dynamicsymbols from sympy.physics.vector import init_vprinting init_vprinting(pretty_printFalse)init_vprinting让交互环境中的矢量输出更接近教科书写法如q表示对时间的一阶导数它定义于 sympy/physics/vector/functions.py。二、Point 类点的运动学描述Point定义于 sympy/physics/vector/point.pyThis object represents a point in a dynamic system内部用三个字典存储运动信息_pos_dict点之间的相对位置矢量_vel_dict点在各参考系中的速度_acc_dict点在各参考系中的加速度。构造点只需传入名字O Point(O)。也可以用symbols(..., clsPoint)一次性创建多个点from sympy import symbols A, B symbols(A B, clsPoint) # 同时创建两个 Point type(A) # class sympy.physics.vector.point.Point下文按位置—速度—加速度—理论公式的顺序介绍 Point 的全部公开方法。2.1 位置set_pos / pos_from / locatenewset_pos(otherpoint, value)设置本点相对另一点的位置矢量并自动在otherpoint中登记反向位置N ReferenceFrame(N) p1 Point(p1) p2 Point(p2) p1.set_pos(p2, 10 * N.x) p1.pos_from(p2) # 10*N.xpos_from(otherpoint)返回从otherpoint指向本点的位置矢量。它内部调用_pdict_list(other, 0)在位置树_pos_dict上做广度优先搜索找出连接两点的最短路径再沿路径累加得到矢量见 sympy/physics/vector/point.py。若两点间没有连接路径会抛出ValueError(No Connecting Path found ...)。locatenew(name, value)是基于现有点创建新点的便捷方法以本点为父点新点位于相对矢量value处且双向登记位置关系P O.locatenew(P, q * B.x q2 * B.y)locatenew内部等价于p.set_pos(self, value)加上self.set_pos(p, -value)见 sympy/physics/vector/point.py因此新建点会立即与父点构成位置连通路径。2.2 速度set_vel / velset_vel(frame, value)为点在指定参考系中设定速度u1, u2, u3 dynamicsymbols(u1 u2 u3) O.set_vel(N, u1 * N.x u2 * N.y u3 * N.z)vel(frame)返回点在参考系frame中的速度。其实现sympy/physics/vector/point.py值得注意若速度已在该系中显式定义直接返回否则从本点出发做 BFS 广度优先遍历位置树找到最近的已在目标系中定义速度的邻居点利用pos_from(neighbor).dt(frame) neighbor_velocity自动推算本点速度若发现位置关系构成闭环会给出 Kinematic loops are defined among the positions of points 的警告若存在多个可推算来源会提示这些来源给出的速度可能不一致若既未定义也无可推算路径抛出ValueError提示该点在该参考系中的速度未定义。这意味着你只需定义部分点的速度其余点可以通过位置关系自动求导得到p Point(p) q dynamicsymbols(q) p.set_vel(N, 10 * N.x) p2 Point(p2) p2.set_pos(p, q*N.x) p2.vel(N) # (Derivative(q(t), t) 10)*N.x2.3 加速度set_acc / accset_acc(frame, value)设定加速度acc(frame)返回加速度。acc的自动推导逻辑sympy/physics/vector/point.py是若该系下没有显式加速度但已定义速度则对速度做该系下的时间导数(self._vel_dict[frame]).dt(frame)否则返回零矢量。2.4 一点理论1-point theoryv1pt_theory / a1pt_theory当动点 P 在中间系 B 中运动而 B 相对惯性系 N 转动时适用一点理论。其速度与加速度公式分别为^N v^P ^B v^P ^N v^O ^N omega^B x r^OP ^N a^P ^B a^P ^N a^O ^N alpha^B x r^OP ^N omega^B x (^N omega^B x r^OP) 2 ^N omega^B x ^B v^P其中 O 是固定在 B 中的点P 是在 B 中运动的点。文档与源码示例sympy/physics/vector/point.pyq, q2 dynamicsymbols(q q2) qd, q2d dynamicsymbols(q q2, 1) N ReferenceFrame(N) B ReferenceFrame(B) B.set_ang_vel(N, 5 * B.y) O Point(O) P O.locatenew(P, q * B.x q2 * B.y) P.set_vel(B, qd * B.x q2d * B.y) O.set_vel(N, 0) P.v1pt_theory(O, N, B) # q*B.x q2*B.y - 5*q*B.z P.a1pt_theory(O, N, B) # (-25*q q)*B.x q2*B.y - 10*q*B.z注意a1pt_theory的输出里出现了科氏加速度项2 * omega.cross(v)见 sympy/physics/vector/point.py这与上面公式中的2 ^N omega^B x ^B v^P一一对应。2.5 二点理论2-point theoryv2pt_theory / a2pt_theory当 P 与 O 都固定在同一个系 B中、B 相对 N 转动时适用二点理论^N v^P ^N v^O ^N omega^B x r^OP ^N a^P ^N a^O ^N alpha^B x r^OP ^N omega^B x (^N omega^B x r^OP)示例转轴沿 N.z 的刚体旋转q dynamicsymbols(q) qd dynamicsymbols(q, 1) N ReferenceFrame(N) B N.orientnew(B, Axis, [q, N.z]) O Point(O) P O.locatenew(P, 10 * B.x) O.set_vel(N, 5 * N.x) P.v2pt_theory(O, N, B) # 5*N.x 10*q*B.y P.a2pt_theory(O, N, B) # - 10*q**2*B.x 10*q*B.y输出中-10*q**2*B.x是向心加速度omega x (omega x r)10*q*B.y是切向加速度alpha x r5*N.x来自 O 点的牵连加速度与公式严格一致。四个理论方法的参数约定完全相同otherpoint是基准点、outframe是期望输出的参考系、interframe/fixedframe是中间固定系它们内部都会先做参数校验_check_frame、_check_point再调用set_vel/set_acc写入结果。2.6 偏速度Point.partial_velocityPoint.partial_velocity(frame, *gen_speeds)返回该点线速度矢量对给定广义速度的偏导数偏速度。例如A ReferenceFrame(A) p Point(p) u1, u2 dynamicsymbols(u1, u2) p.set_vel(N, u1 * N.x u2 * A.y) p.partial_velocity(N, u1) # N.x p.partial_velocity(N, u1, u2) # (N.x, A.y)该方法在底层委托给functions.partial_velocity见 sympy/physics/vector/point.py。偏速度是 Kane 方法构建系统运动方程的核心中间量sympy.physics.mechanics中的KanesMethod会大量使用它。三、kinematic_equations建立广义速度与广义坐标的关系kinematic_equations(speeds, coords, rot_type, rot_order)位于 sympy/physics/vector/functions.py其作用是给定体固定body-fixed广义速度u [u1, u2, u3]与描述姿态的广义坐标q返回一组形如qdot - f(u, q) 0的运动学微分方程右端全部归零便于直接代入微分方程求解器。3.1 参数说明参数类型说明speedslist长度 3体固定角速度的度量数即 B 相对 A 的角速度形如u1*B.x u2*B.y u3*B.zcoordslist长度 3 或 4定义两参考系姿态的广义坐标body/space 需 3 个quaternion 需 4 个rot_typestrbody、space或quaternion大小写不敏感rot_orderstr 或 int转动顺序如313、123quaternion 模式必须为空rot_order的合法取值在源码中硬编码为(123, 231, 312, 132, 213, 321, 121, 131, 212, 232, 313, 323, 1, 2, 3, )sympy/physics/vector/functions.py。输入会先做规范化rot_order中的字母X/Y/Z会被自动翻译为1/2/3rot_type转小写。非法组合会抛出ValueError如 body/space 模式下坐标个数不为 3、quaternion 模式带转动顺序、rot_order不在白名单内speeds/coords非 list 或长度不对则抛TypeError。3.2 body 与 space 模式Body内旋与 space外旋两种模式都要求 3 个广义坐标两者的差异在于转轴解释顺序不同。示例body 313 转序from sympy.physics.vector import dynamicsymbols, kinematic_equations, vprint u1, u2, u3 dynamicsymbols(u1 u2 u3) q1, q2, q3 dynamicsymbols(q1 q2 q3) vprint(kinematic_equations([u1,u2,u3], [q1,q2,q3], body, 313), orderNone) # [-(u1*sin(q3) u2*cos(q3))/sin(q2) q1, # -u1*cos(q3) u2*sin(q3) q2, # (u1*sin(q3) u2*cos(q3))*cos(q2)/sin(q2) - u3 q3]源码针对 body/space 的 12 种转序分别硬编码了推导好的解析式sympy/physics/vector/functions.py因此该函数是即取即用的无需运行时符号推导。注意当q2对应的角度使sin(q2)或cos(q2)为零时会出现分母奇异这是欧拉角描述的固有缺陷对应姿态表示的奇异点。若三个角速度全为零函数直接返回[S.Zero]*3。3.3 quaternion 模式quaternion 模式用 4 个坐标[e0, e1, e2, e3]描述姿态不存在奇异点。源码中用欧拉参数矩阵构造运动学关系sympy/physics/vector/functions.pyE Matrix([[e0, -e3, e2, e1], [e3, e0, -e1, e2], [-e2, e1, e0, e3], [-e1, -e2, -e3, e0]]) edots Matrix([diff(i, t) for i in [e1, e2, e3, e0]]) return list(edots.T - 0.5 * w.T * E.T) # w [u1, u2, u3, 0]测试用例sympy/physics/vector/tests/test_functions.py验证了 quaternion 模式返回的四条方程并覆盖了各类非法输入quaternion 搭配坐标个数不为 4、quaternion 带转序、非法rot_type、speeds/coords非序列等均按预期抛出ValueError或TypeError。四、get_motion_params由已知运动量反推其余参数get_motion_params(frame, **kwargs)sympy/physics/vector/functions.py返回三元组(加速度, 速度, 位置)。其工作模式由传入的最高阶运动量决定传入acceleration→ 模式 2对加速度积分求速度再对速度积分求位置只传velocity→ 模式 1对速度积分求位置只传position→ 模式 0对位置求导得速度与加速度。**kwargs支持的键acceleration、velocity、position、timevalue1位置边界条件对应时刻、timevalue2速度边界条件对应时刻。边界条件velocity、position缺省为零矢量时刻缺省为零若边界条件是时间的函数会先把时间符号替换成对应时刻值再当常数使用见 sympy/physics/vector/functions.py 的_process_vector_differential辅助函数它用integrate配合定积分上下限实现带初值的积分。4.1 只给位置R ReferenceFrame(R) v1, v2, v3 dynamicsymbols(v1 v2 v3) v v1*R.x v2*R.y v3*R.z get_motion_params(R, positionv) # (v1*R.x v2*R.y v3*R.z, # v1*R.x v2*R.y v3*R.z, # v1*R.x v2*R.y v3*R.z)模式 0 直接对位置矢量做时间导数注意输出的是关于时间t的函数dynamicsymbols而非常数符号。4.2 只给速度from sympy import symbols a, b, c symbols(a b c) v a*R.x b*R.y c*R.z get_motion_params(R, velocityv) # (0, a*R.x b*R.y c*R.z, a*t*R.x b*t*R.y c*t*R.z)这里a, b, c是常数符号因此加速度为零、位置 v * t。4.3 给加速度含边界条件parameters get_motion_params(R, accelerationv) # v a*R.x b*R.y c*R.z parameters[1] # 速度a*t*R.x b*t*R.y c*t*R.z parameters[2] # 位置a*t**2/2*R.x b*t**2/2*R.y c*t**2/2*R.z若同时提供初速与初始位置边界条件可以指定不同时刻get_motion_params(N, accelerationv1, velocityv0, positionv2, timevalue1t1, timevalue2t2)测试sympy/physics/vector/tests/test_functions.py覆盖了位置/速度/加速度三种模式的全部组合验证了常数边界条件与时间函数边界条件下的结果包括Integral形式的解析解可作为自定义验证的参考。五、partial_velocity批量的偏速度计算模块级函数partial_velocity(vel_vecs, gen_speeds, frame)sympy/physics/vector/functions.py一次性计算多个速度矢量对多个广义速度的偏导数返回列表的列表外层对应每个速度矢量内层是该速度对每个广义速度的偏速度。参数vel_vecs速度矢量迭代器可为线速度或角速度、gen_speeds广义速度迭代器、frame求偏导所在的参考系。vel_vecs或gen_speeds非可迭代对象时抛TypeError。from sympy.physics.vector import Point, ReferenceFrame, partial_velocity u dynamicsymbols(u) N ReferenceFrame(N) P Point(P) P.set_vel(N, u * N.x) partial_velocity([P.vel(N)], [u], N) # [[N.x]]底层实现利用linear_eq_to_matrix提取每个广义速度的线性系数sympy/physics/vector/functions.py因此速度矢量必须是广义速度的线性表达式——这正是 Kane 方法KanesMethod对广义速度定义的要求。综合测试示例sympy/physics/vector/tests/test_functions.py展示了包含三个参考系、多个点的多体系统先用locatenew定义点位置、用v2pt_theory推算速度再对线速度与角速度混合列表求偏速度并断言结果与解析期望一致同时验证了两系间未定义姿态关系时偏速度仍可计算因为偏导只依赖系数线性提取。ReferenceFrame上的partial_velocity方法sympy/physics/vector/tests/test_frame.py返回单系角速度的偏速度其符号约定为A.partial_velocity(N, u1)即A相对N角速度对u1的偏导。六、实战串联一个完整的运动学建模流程将上述工具串联可快速完成一个典型多体系统的运动学建模from sympy.physics.vector import (Point, ReferenceFrame, dynamicsymbols, kinematic_equations, get_motion_params, partial_velocity, init_vprinting) init_vprinting(pretty_printFalse) # 1. 定义参考系、广义坐标与广义速度 N ReferenceFrame(N) # 惯性系 q1, q2 dynamicsymbols(q1 q2) # 广义坐标 u1, u2 dynamicsymbols(u1 u2) # 广义速度 # 2. 建立姿态与点的位置关系 B N.orientnew(B, Axis, [q1, N.z]) # B 相对 N 绕 z 轴转 q1 O Point(O) O.set_vel(N, 0) P O.locatenew(P, q2 * B.x) # P 沿 B.x 滑动 # 3. 用一点理论求速度/加速度 P.set_vel(B, u2 * B.x) # 滑动速度 B.set_ang_vel(N, u1 * B.z) # 转动速度 P.v1pt_theory(O, N, B) # P 在 N 中的速度 P.a1pt_theory(O, N, B) # P 在 N 中的加速度 # 4. 运动学微分方程将 u1, u2 与 q1, q2 关联 ke kinematic_equations([u1, 0, u2], [q1, q2, 0], body, 3) # 5. 偏速度供动力学方程使用 P.partial_velocity(N, u1, u2)这套流程与sympy.physics.mechanics中Particle/KanesMethod的建模思路一致先描述几何与姿态再用理论公式自动完成求导最后生成可供数值求解器或进一步动力学分析使用的方程。七、总结与延伸阅读doc/src/modules/physics/vector/api/kinematics.rst所覆盖的内容构成了 SymPy 运动学分析的最小完整工具集Pointsympy/physics/vector/point.py以位置树 速度/加速度字典组织数据通过set_pos/set_vel/set_acc写入、pos_from/vel/acc读取并以locatenew便捷建点、以一点/二点理论处理动点与刚体固定点kinematic_equations针对 body/space/quaternion 三种姿态描述直接给出qdot与u之间的解析运动学方程get_motion_params按已知高阶量求低阶量、低阶量作边界条件的规则通过符号积分反推完整的 (加速度, 速度, 位置)partial_velocity通过线性系数提取批量计算偏速度是 Kane 方法的关键输入。进一步学习可参考同目录下的 classes.rstReferenceFrame、Vector、Dyadic等基础类、functions.rstdynamicsymbols、express、time_derivative等函数以及sympy.physics.mechanics模块的动力学 API测试文件 sympy/physics/vector/tests/test_functions.py 与 sympy/physics/vector/tests/test_frame.py 中包含了大量可复现的用例是理解边界行为的最佳参考。【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表