SymPy-1-13-中文文档-三十五-

106 阅读43分钟

SymPy 1.13 中文文档(三十五)

原文:docs.sympy.org/latest/index.html

系统(文档字符串)

原文:docs.sympy.org/latest/modules/physics/mechanics/api/system.html

class sympy.physics.mechanics.system.SymbolicSystem(coord_states, right_hand_side, speeds=None, mass_matrix=None, coordinate_derivatives=None, alg_con=None, output_eqns={}, coord_idxs=None, speed_idxs=None, bodies=None, loads=None)

SymbolicSystem 是一个类,其中包含系统的所有信息,以符号格式表示,如运动方程和系统中的主体和载荷。

对于符号系统,可以描述运动方程的三种方式:

[1] 显式形式,其中运动学和动力学结合在一起

x’ = F_1(x, t, r, p)

[2] 隐式形式,其中运动学和动力学结合在一起

M_2(x, p) x’ = F_2(x, t, r, p)

[3] 隐式形式,其中运动学和动力学分开

M_3(q, p) u’ = F_3(q, u, t, r, p) q’ = G(q, u, t, r, p)

其中

x:状态,例如[q, u] t:时间 r:指定的(外生的)输入 p:常数 q:广义坐标 u:广义速度 F_1:显式形式中联合方程的右手边 F_2:隐式形式中联合方程的右手边 F_3:隐式形式中动力学方程的右手边 M_2:隐式形式中联合方程的质量矩阵 M_3:隐式形式中动力学方程的质量矩阵 G:运动学微分方程的右手边

参数:

coord_states:时间函数的有序可迭代集合

此输入将根据是否提供速度而确定是系统的坐标还是状态集合。如果指定了速度,则假定此输入是坐标,否则假定此输入是状态。

right_hand_sideMatrix

此变量是任何形式的运动方程的右手边。具体形式将根据是否提供质量矩阵或坐标导数而假定。

speedsordered:时间函数的有序可迭代集合,可选

这是系统的广义速度集合。如果给定,则假定第一个参数(coord_states)将表示系统的广义坐标。

mass_matrixMatrix,可选

运动方程的隐式形式矩阵(形式[2]和[3])。形式的区别取决于是否传入坐标导数。如果给出坐标导数,则假定为形式[3],否则假定为形式[2]。

coordinate_derivativesMatrix,可选

显式形式的运动学方程的右手边。如果提供,则假定正在以[3]形式输入运动方程。

alg_conIterable,可选

运动方程中包含代数约束而不是微分方程的行的索引。如果方程以[3]形式输入,则假定这些索引引用质量矩阵/右手边组合而不是坐标导数。

output_eqnsDictionary,可选

任何希望跟踪的输出方程都存储在字典中,其中键对应于特定方程的名称,而值则是其在符号形式中的方程。

coord_idxs可迭代,可选

如果coord_states对应于状态而不是坐标,则此变量将告诉SymbolicSystem哪些状态的索引对应于广义坐标。

speed_idxs可迭代,可选

如果coord_states对应于状态而不是坐标,则此变量将告诉SymbolicSystem哪些状态的索引对应于广义速度。

bodies是 Body/Rigidbody 对象的可迭代集合,可选

可迭代对象,包含系统的物体

loads是负载实例的可迭代集合,可选

可迭代对象,包含系统的负载,其中力由(作用点,力矢量)给出,力矩由(作用参考框架,力矩矢量)给出。例如[(point, force), (ref_frame, torque)]

示例

作为简单示例,将简单摆的动态输入到SymbolicSystem对象中。首先需要一些导入,然后将为摆长(l)、摆尾部质量(m)和重力常数(g)设置符号。

>>> from sympy import Matrix, sin, symbols
>>> from sympy.physics.mechanics import dynamicsymbols, SymbolicSystem
>>> l, m, g = symbols('l m g') 

系统将由从垂直方向的角度θ和使用广义速度ω定义,其中ω = θ点。

>>> theta, omega = dynamicsymbols('theta omega') 

现在动力学方程已准备好形成,并传递给SymbolicSystem对象。

>>> kin_explicit_rhs = Matrix([omega])
>>> dyn_implicit_mat = Matrix([l**2 * m])
>>> dyn_implicit_rhs = Matrix([-g * l * m * sin(theta)])
>>> symsystem = SymbolicSystem([theta], dyn_implicit_rhs, [omega],
...                            dyn_implicit_mat) 

笔记

m:广义速度的数量 n:广义坐标的数量 o:状态的数量

属性

coordinates(Matrix, shape(n, 1)) 这是系统广义坐标的矩阵。
speeds(Matrix, shape(m, 1)) 这是系统广义速度的矩阵。
states(Matrix, shape(o, 1)) 这是系统状态变量的矩阵。
alg_con(List) 此列表包含组合运动方程中代数约束的索引。这些约束的存在要求使用 DAE 求解器而不是 ODE 求解器。如果系统以[3]形式给出,则alg_con变量将被调整,以便它表示组合运动方程的运动学和动力学,因此始终确保它与输入的质量矩阵匹配。
dyn_implicit_mat(Matrix, shape(m, m)) 这是运动方程[3]中隐式形式的 M 矩阵(质量矩阵或广义惯性矩阵)。
dyn_implicit_rhs(Matrix, shape(m, 1)) 这是运动方程[3]中隐式形式的右手边 F 向量。
comb_implicit_mat(矩阵,形状(o, o)) 这是运动方程[2]中的 M 矩阵。 该矩阵具有块对角结构,其中左上角块(第一行)表示运动方程运动学形式的矩阵,右下角块(最后几行)表示运动方程动力学形式的矩阵。
comb_implicit_rhs(矩阵,形状(o, 1)) 这是运动方程[2]中的 F 向量。 该向量的顶部部分表示运动方程运动学形式的右手边,向量的底部部分表示运动方程动力学形式的右手边。
comb_explicit_rhs(矩阵,形状(o, 1)) 此向量表示联合运动方程以显式形式表示的右手边(上述的形式[1])。
kin_explicit_rhs(矩阵,形状(m, 1)) 这是运动方程运动学形式的显式右手边,如形式[3](G 矩阵)中所示。
output_eqns(字典) 如果给定输出方程,则它们将存储在字典中,其中键对应于特定方程的名称,而值则是其符号形式的方程本身
bodies(元组) 如果系统中给出了主体,则它们将存储在一个元组中,以便将来访问
loads(元组) 如果系统中给出了载荷,则它们将存储在一个元组中,以便将来访问。 这包括力和扭矩,其中力由(施加点,力矢量)给出,扭矩由(作用参考框架,扭矩矢量)给出。
property alg_con

返回包含联合运动方程中代数约束行索引的列表

property bodies

返回系统中的主体

property comb_explicit_rhs

返回包含以显式形式表示的运动方程右手边 x’ = F 的列矩阵,其中包括运动方程的运动学方程

property comb_implicit_mat

返回与以隐式形式表示的运动方程(形式[2])M x’ = F 对应的矩阵 M,其中包括运动方程的运动学方程

property comb_implicit_rhs

返回与以隐式形式表示的运动方程(形式[2])M x’ = F 对应的列矩阵 F,其中包括运动方程的运动学方程

compute_explicit_form()

如果在初始化时提供了联合运动方程的显式右手边,则此方法将计算它。 这个计算可能需要一段时间来完成。

constant_symbols()

返回包含系统中所有不依赖于时间的符号的列矩阵

property coordinates

返回广义坐标的列矩阵

property dyn_implicit_mat

返回与动态方程对应的以隐式形式表示的矩阵 M,其中运动方程的运动学方程未包含

property dyn_implicit_rhs

返回与动态方程对应的以隐式形式表示的矩阵 M,其中不包括运动方程的运动学方程

dynamic_symbols()

返回包含系统中所有依赖于时间的符号的列矩阵

property kin_explicit_rhs

返回显式形式的运动学方程右手边,即 q’ = G

property loads

返回系统中的负载

property speeds

返回广义速度的列矩阵

property states

返回状态变量的列矩阵

class sympy.physics.mechanics.system.System(frame=None, fixed_point=None)

定义一个多体系统并形成其运动方程的类。

解释

System 实例存储与模型相关的不同对象,包括刚体、关节、约束和其他相关信息。通过定义各组件之间的关系,System 可以使用诸如 KanesMethod 等后端来形成运动方程。System 已经设计成与第三方库兼容,以增强灵活性和与其他工具的集成。

示例

在下面的示例中,创建了带有摆的小车。小车沿轨道的 x 轴移动,摆绕 z 轴旋转。摆的长度为 l,将摆表示为一个粒子。为了移动小车,对小车施加了时间相关的力 F

首先需要导入一些函数并创建一些变量。

>>> from sympy import symbols, simplify
>>> from sympy.physics.mechanics import (
...     mechanics_printing, dynamicsymbols, RigidBody, Particle,
...     ReferenceFrame, PrismaticJoint, PinJoint, System)
>>> mechanics_printing(pretty_print=False)
>>> g, l = symbols('g l')
>>> F = dynamicsymbols('F') 

下一步是创建刚体。还有必要为后来定位粒子与销关节相关的框架创建一个框架,因为粒子没有固定于刚体的框架。

>>> rail = RigidBody('rail')
>>> cart = RigidBody('cart')
>>> bob = Particle('bob')
>>> bob_frame = ReferenceFrame('bob_frame') 

初始化系统,以轨道作为牛顿参考。该体系也会自动添加到系统中。

>>> system = System.from_newtonian(rail)
>>> print(system.bodies[0])
rail 

创建关节,同时立即将它们添加到系统中。

>>> system.add_joints(
...     PrismaticJoint('slider', rail, cart, joint_axis=rail.x),
...     PinJoint('pin', cart, bob, joint_axis=cart.z,
...              child_interframe=bob_frame,
...              child_point=l * bob_frame.y)
... )
>>> system.joints
(PrismaticJoint: slider  parent: rail  child: cart,
PinJoint: pin  parent: cart  child: bob) 

添加关节时,还会将相关的广义坐标、广义速度、运动学微分方程和刚体一同加入系统。

>>> system.q
Matrix([
[q_slider],
[   q_pin]])
>>> system.u
Matrix([
[u_slider],
[   u_pin]])
>>> system.kdes
Matrix([
[u_slider - q_slider'],
[      u_pin - q_pin']])
>>> [body.name for body in system.bodies]
['rail', 'cart', 'bob'] 

确定了运动学后,我们现在可以应用重力和小车的力 F

>>> system.apply_uniform_gravity(-g * system.y)
>>> system.add_loads((cart.masscenter, F * rail.x))
>>> system.loads
((rail_masscenter, - g*rail_mass*rail_frame.y),
 (cart_masscenter, - cart_mass*g*rail_frame.y),
 (bob_masscenter, - bob_mass*g*rail_frame.y),
 (cart_masscenter, F*rail_frame.x)) 

定义完整系统后,我们现在可以形成运动方程。在形成运动方程之前,可以运行一些检查,试图识别一些常见错误。

>>> system.validate_system()
>>> system.form_eoms()
Matrix([
[bob_mass*l*u_pin**2*sin(q_pin) - bob_mass*l*cos(q_pin)*u_pin'
 - (bob_mass + cart_mass)*u_slider' + F],
[                   -bob_mass*g*l*sin(q_pin) - bob_mass*l**2*u_pin'
 - bob_mass*l*cos(q_pin)*u_slider']])
>>> simplify(system.mass_matrix)
Matrix([
[ bob_mass + cart_mass, bob_mass*l*cos(q_pin)],
[bob_mass*l*cos(q_pin),         bob_mass*l**2]])
>>> system.forcing
Matrix([
[bob_mass*l*u_pin**2*sin(q_pin) + F],
[          -bob_mass*g*l*sin(q_pin)]]) 

如果我们添加一个约束以防止粒子在水平(x)方向上移动,则上述示例的复杂性可以增加。可以通过添加一个完全约束来实现。之后,我们还应重新定义我们的(非)独立广义坐标和速度。

>>> system.add_holonomic_constraints(
...     bob.masscenter.pos_from(rail.masscenter).dot(system.x)
... )
>>> system.q_ind = system.get_joint('pin').coordinates
>>> system.q_dep = system.get_joint('slider').coordinates
>>> system.u_ind = system.get_joint('pin').speeds
>>> system.u_dep = system.get_joint('slider').speeds 

利用更新后的系统可以再次形成运动方程。

>>> system.validate_system()
>>> system.form_eoms()
Matrix([[-bob_mass*g*l*sin(q_pin)
 - bob_mass*l**2*u_pin'
 - bob_mass*l*cos(q_pin)*u_slider'
 - l*(bob_mass*l*u_pin**2*sin(q_pin)
 - bob_mass*l*cos(q_pin)*u_pin'
 - (bob_mass + cart_mass)*u_slider')*cos(q_pin)
 - l*F*cos(q_pin)]])
>>> simplify(system.mass_matrix)
Matrix([
[bob_mass*l**2*sin(q_pin)**2, -cart_mass*l*cos(q_pin)],
[               l*cos(q_pin),                       1]])
>>> simplify(system.forcing)
Matrix([
[-l*(bob_mass*g*sin(q_pin) + bob_mass*l*u_pin**2*sin(2*q_pin)/2
 + F*cos(q_pin))],
[
l*u_pin**2*sin(q_pin)]]) 

属性

frame(ReferenceFrame)系统的惯性参考系。
fixed_point(Point)惯性参考系中的固定点。
x(矢量)惯性参考系中固定的单位矢量。
y(矢量)惯性参考系中固定的单位矢量。
z(矢量)惯性参考系中固定的单位矢量。
q(ImmutableMatrix)所有广义坐标的矩阵,即独立广义坐标与依赖广义坐标叠加。
u(ImmutableMatrix)所有广义速度的矩阵,即独立广义速度与依赖广义速度叠加。
q_ind(ImmutableMatrix)独立广义坐标的矩阵。
q_dep(ImmutableMatrix) 依赖广义坐标的矩阵。
u_ind(ImmutableMatrix) 独立广义速度的矩阵。
u_dep(ImmutableMatrix) 依赖广义速度的矩阵。
u_aux(ImmutableMatrix) 辅助广义速度的矩阵。
kdes(ImmutableMatrix) 以表达式形式等于零矩阵的运动微分方程矩阵。
bodies(BodyBase 子类的元组) 构成系统的所有物体的元组。
joints(Joint 的元组) 连接系统中物体的所有关节的元组。
loads(LoadBase 子类的元组) 应用于系统的所有载荷的元组。
actuators(ActuatorBase 子类的元组) 系统中存在的所有执行器的元组。
holonomic_constraints(ImmutableMatrix) 以表达式形式等于零矩阵的完整约束矩阵。
nonholonomic_constraints(ImmutableMatrix) 以表达式形式等于零矩阵的非完整约束矩阵。
velocity_constraints(ImmutableMatrix) 以表达式形式等于零矩阵的速度约束矩阵。这些默认为由扩展非完整约束的时间导数导出的。
eom_method(KanesMethod 或 LagrangesMethod 的子类) 用于形成运动方程的后端。
property actuators

系统中存在的执行器的元组。

add_actuators(*actuators)

向系统添加执行器。

参数:

*执行器 :ActuatorBase 的子类

一个或多个执行器。

add_auxiliary_speeds(*speeds)

向系统添加辅助速度。

参数:

*速度 :dynamicsymbols

一个或多个要添加到系统中的辅助速度。

add_bodies(*bodies)

向系统添加物体。

参数:

物体 :Particle 或 RigidBody

一个或多个物体。

add_coordinates(*coordinates, independent=True)

向系统添加广义坐标。

参数:

*坐标 :dynamicsymbols

一个或多个要添加到系统中的广义坐标。

独立 :bool 或 bool 列表,可选

布尔值,表示坐标是依赖还是独立。默认值为 True,因此坐标默认情况下被添加为独立。

add_holonomic_constraints(*constraints)

向系统添加完整约束。

参数:

*约束 :Expr

一个或多个应该为零的完整约束表达式。

add_joints(*joints)

向系统添加关节。

参数:

*连接 :Joint 的子类

一个或多个关节。

Explanation

此方法向系统添加一个或多个关节,包括其相关的对象,即广义坐标、广义速度、运动微分方程和物体。

Notes

对于广义坐标、广义速度和物体,检查它们是否已被系统实例知晓。如果是,则不添加。然而,运动微分方程总是会被添加到系统中,所以你不需要手动提前添加它们。

add_kdes(*kdes)

向系统添加运动微分方程。

参数:

*kdes :Expr

一个或多个运动微分方程。

add_loads(*loads)

向系统添加载荷。

参数:

*loads : Force 或 Torque

一个或多个载荷。

add_nonholonomic_constraints(*constraints)

向系统添加非完整约束。

参数:

*constraints : Expr

一个或多个非完整约束,这些约束是应该为零的表达式。

add_speeds(*speeds, independent=True)

向系统添加广义速度。

参数:

*speeds : dynamicsymbols

要添加到系统中的一个或多个广义速度。

independent : bool 或者 bool 列表,可选

布尔值,指示速度是否是依赖的或独立的。默认为 True,因此速度默认情况下被添加为独立的。

apply_uniform_gravity(acceleration)

通过添加载荷向系统中的所有物体施加均匀重力。

参数:

acceleration : Vector

由于重力引起的加速度。

property bodies

添加到系统中的所有物体的元组。

property eom_method

用于形成运动方程的后端。

property fixed_point

惯性参考框架中的固定点。

property forcing

系统的强制向量。

property forcing_full

系统的强制向量,通过显式或隐式形式的运动微分方程进行扩展。

form_eoms(eom_method=<class 'sympy.physics.mechanics.kane.KanesMethod'>, **kwargs)

形成系统的运动方程。

参数:

eom_method : KanesMethod 或 LagrangesMethod 的子类

用于形成运动方程的后端类。默认为 KanesMethod

返回:

ImmutableMatrix

运动方程的向量。

示例

这是一个简单的示例,用于单自由度的弹簧-质量-阻尼器系统。

>>> from sympy import S, symbols
>>> from sympy.physics.mechanics import (
...     LagrangesMethod, dynamicsymbols, PrismaticJoint, Particle,
...     RigidBody, System)
>>> q = dynamicsymbols('q')
>>> qd = dynamicsymbols('q', 1)
>>> m, k, b = symbols('m k b')
>>> wall = RigidBody('W')
>>> system = System.from_newtonian(wall)
>>> bob = Particle('P', mass=m)
>>> bob.potential_energy = S.Half * k * q**2
>>> system.add_joints(PrismaticJoint('J', wall, bob, q, qd))
>>> system.add_loads((bob.masscenter, b * qd * system.x))
>>> system.form_eoms(LagrangesMethod)
Matrix([[-b*Derivative(q(t), t) + k*q(t) + m*Derivative(q(t), (t, 2))]]) 

我们还可以使用 'rhs' 方法来求解状态。

>>> system.rhs()
Matrix([
[               Derivative(q(t), t)],
[(b*Derivative(q(t), t) - k*q(t))/m]]) 
property frame

系统的惯性参考框架。

classmethod from_newtonian(newtonian)

通过添加载荷将系统构造为牛顿体系。

get_body(name)

通过名称从系统中检索物体。

参数:

name : str

要检索的物体的名称。

返回:

刚体或粒子

具有给定名称的物体,如果没有这样的物体则为 None。

get_joint(name)

通过名称从系统中检索关节。

参数:

name : str

要检索的关节的名称。

返回:

Joint 的子类

具有给定名称的关节,如果没有这样的关节则为 None。

property holonomic_constraints

具有等于零矩阵的完整性约束的矩阵表达式。

property joints

添加到系统中的所有关节的元组。

property kdes

作为表达式等于零矩阵的运动微分方程。这些方程描述了广义坐标和广义速度之间的耦合。

property loads

应用于系统的载荷的元组。

property mass_matrix

系统的质量矩阵。

解释

系统的质量矩阵 (M_d) 和强制向量 (f_d) 描述系统的动力学,如下方程所示:

[M_d \dot{u} = f_d]

其中 (\dot{u}) 是广义速度的时间导数。

property mass_matrix_full

系统的质量矩阵,通过显式或隐式形式的运动微分方程进行扩展。

解释

系统的完整质量矩阵 (M_m) 和完整强制向量 (f_m) 描述系统的动力学和运动学,如下方程所示:

[M_m \dot{x} = f_m]

其中 (x) 是状态向量,堆叠 (q) 和 (u)。

property nonholonomic_constraints

非完整约束作为表达式等于零矩阵的矩阵。

property q

所有广义坐标的矩阵,独立的堆叠在依赖上。

property q_dep

依赖广义坐标的矩阵。

property q_ind

独立广义坐标的矩阵。

rhs(inv_method=None)

计算显式形式的运动方程。

参数:

inv_method : 字符串

用于进行 sympy 逆矩阵计算的特定方法。有关有效方法的列表,请参阅 inv()

返回:

ImmutableMatrix

显式形式的运动方程。

另请参阅

sympy.physics.mechanics.kane.KanesMethod.rhs

KanesMethod 的 rhs 函数。

sympy.physics.mechanics.lagrange.LagrangesMethod.rhs

LagrangesMethod 的 rhs 函数。

property u

所有广义速度的矩阵,独立的堆叠在依赖上。

property u_aux

辅助广义速度的矩阵。

property u_dep

依赖广义速度的矩阵。

property u_ind

独立广义速度的矩阵。

validate_system(eom_method=<class 'sympy.physics.mechanics.kane.KanesMethod'>, check_duplicates=False)

使用一些基本检查验证系统。

参数:

eom_method : KanesMethod 或 LagrangesMethod 的子类

将用于形成运动方程的后端类。不同的后端有不同的检查。默认为 KanesMethod

check_duplicates : 布尔值

布尔值,指示是否应检查系统中是否存在重复定义。默认值为 False,因为在向系统添加对象时已经检查了重复性。

解释

此方法根据以下检查验证系统:

  • 依赖广义坐标数应等于完整约束数。

  • 系统还应知晓由关节定义的所有广义坐标。

  • 如果 KanesMethod 作为 eom_method 使用:

    • 系统还应知晓由关节定义的所有广义速度和运动微分方程。

    • 依赖广义速度数应等于速度约束数。

    • 广义坐标数应小于或等于广义速度数。

    • 广义坐标数应等于运动微分方程数。

  • 如果 LagrangesMethod 作为 eom_method 使用:

    • 不应有任何不是广义坐标的导数的广义速度(包括由关节定义的广义速度)。

注意事项

此方法不能保证向后兼容,因为它可能随时间改进。在某些领域,该方法可能会变得更加严格或更少严格。然而,一个定义良好的系统应该始终通过所有这些测试。

property velocity_constraints

以速度约束为表达式并等于零矩阵的矩阵。速度约束通常由完整约束和非完整约束衍生,除非显式设置。

property x

惯性参考系中固定的单位向量。

property y

惯性参考系中固定的单位向量。

property z

惯性参考系中固定的单位向量。

线性化(文档字符串)

原文链接:docs.sympy.org/latest/modules/physics/mechanics/api/linearize.html

class sympy.physics.mechanics.linearize.Linearizer(f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a, q, u, q_i=None, q_d=None, u_i=None, u_d=None, r=None, lams=None, linear_solver='LU')

此对象保存动态系统的一般模型形式。该模型用于计算系统的线性化形式,同时正确处理导致依赖坐标和速度的约束。符号和方法描述在[R739]中。

参考文献

[R739] (1,2)

D. L. Peterson, G. Gede, and M. Hubbard,“Symbolic linearization of equations of motion of constrained multibody systems”,Multibody Syst Dyn,vol. 33,no. 2,pp. 143-161,Feb. 2015,doi: 10.1007/s11044-014-9436-5。

属性

f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a(矩阵)包含一般系统形式的矩阵。
q, u, r(矩阵)包含广义坐标、速度和输入向量的矩阵。
q_i, u_i(矩阵)独立的广义坐标和速度的矩阵。
q_d, u_d(矩阵)依赖广义坐标和速度的矩阵。
perm_mat(矩阵)排列矩阵,使得[q_ind, u_ind]^T = perm_mat*[q, u]^T
__init__(f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a, q, u, q_i=None, q_d=None, u_i=None, u_d=None, r=None, lams=None, linear_solver='LU')

参数:

f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a:array_like

拥有一般系统形式的方程组。如果参数不存在,则提供空数组或矩阵。

q:array_like

广义坐标。

u:array_like

广义速度

q_i, u_i:array_like,可选

独立的广义坐标和速度。

q_d, u_d:array_like,可选

独立的广义坐标和速度。

r:array_like,可选

输入变量。

lams:array_like,可选

拉格朗日乘数

linear_solver:str,callable

用于解决线性化过程中形式为 A*x=b 的几个符号线性系统的方法。如果提供的是字符串,它应该是一个可以与 sympy.matrices.matrixbase.MatrixBase.solve() 一起使用的有效方法。如果提供的是可调用对象,它应具有格式 x = f(A, b),其中它解决方程并返回解决方案。默认值是 'LU',对应于 SymPy 的 A.LUsolve(b)LUsolve() 计算快速,但通常会导致除以零,从而导致 nan 结果。

linearize(op_point=None, A_and_B=False, simplify=False)

在操作点附近对系统进行线性化。注意 q_op、u_op、qd_op、ud_op 必须满足运动方程。这些可以是符号的或数值的。

参数:

op_point:字典或字典的可迭代对象,可选

字典或包含所有或部分广义坐标、广义速度及其时间导数的字典的可迭代对象。这些将在线性化完成之前替换到线性化系统中。如果希望操作点是任意符号的集合,则设置为None。请注意,任何符号的减少(无论是替换为数字还是具有公共参数的表达式)都将导致更快的运行时。

A_and_B : bool, optional

如果 A_and_B=False(默认),则返回(M, A, B),如果 A_and_B=True,则返回(A, B)。请参阅下文。

simplify : bool, optional

确定返回值在返回前是否被简化。对于大型表达式,这可能需要一些时间。默认为 False。

返回:

M, A, B : 矩阵, A_and_B=False

隐式形式的矩阵:

[M]*[q', u']^T = [A]*[q_ind, u_ind]^T + [B]*r

A, B : 矩阵, A_and_B=True

显式形式的矩阵:

[q_ind', u_ind']^T = [A]*[q_ind, u_ind]^T + [B]*r

注意

请注意,使用 A_and_B=True 进行求解在存在许多符号参数时计算密集。因此,可能更倾向于使用默认的 A_and_B=False,返回 M、A 和 B。稍后可以对这些矩阵进行更多值的替换。然后可以找到状态空间形式为 A = P.TM.LUsolve(A),B = P.TM.LUsolve(B),其中 P = Linearizer.perm_mat。

表达式操作(文档字符串)

原文:docs.sympy.org/latest/modules/physics/mechanics/api/expr_manip.html

sympy.physics.mechanics.msubs(expr, *sub_dicts, smart=False, **kwargs)

用于物理学衍生表达式的自定义 subs。

遍历一次表达式树,执行在 sub_dicts 中找到的 subs。忽略 Derivative 表达式内的项:

示例

>>> from sympy.physics.mechanics import dynamicsymbols, msubs
>>> x = dynamicsymbols('x')
>>> msubs(x.diff() + x, {x: 1})
Derivative(x(t), t) + 1 

注意 sub_dicts 可以是单个字典,也可以是多个字典:

>>> x, y, z = dynamicsymbols('x, y, z')
>>> sub1 = {x: 1, y: 2}
>>> sub2 = {z: 3, x.diff(): 4}
>>> msubs(x.diff() + x + y + z, sub1, sub2)
10 

如果 smart=True(默认为 False),还会检查可能导致 nan 的条件,但如果简化后会得到有效表达式。例如:

>>> from sympy import sin, tan
>>> (sin(x)/tan(x)).subs(x, 0)
nan
>>> msubs(sin(x)/tan(x), {x: 0}, smart=True)
1 

首先用 sin/cos 替换所有 tan。然后遍历每个节点。如果节点是分数,则首先对分母进行 subs。如果结果为 0,则尝试简化整个分数。使用这种选择性简化,只针对结果为 1/0 的子表达式,从而实现更快的性能。

sympy.physics.mechanics.find_dynamicsymbols(expression, exclude=None, reference_frame=None)

找到表达式中的所有动态符号。

参数:

expression:SymPy 表达式

exclude:动态符号的可迭代对象,可选

reference_frame:ReferenceFrame,可选

确定给定向量的动态符号的框架。

解释

如果使用了可选的 exclude 关键字参数,则只返回不在可迭代对象 exclude 中的动态符号。如果我们打算将此函数应用于向量,则还需使用可选的 reference_frame 来指示与给定向量的动态符号相关联的相应参考框架。

示例

>>> from sympy.physics.mechanics import dynamicsymbols, find_dynamicsymbols
>>> from sympy.physics.mechanics import ReferenceFrame
>>> x, y = dynamicsymbols('x, y')
>>> expr = x + x.diff()*y
>>> find_dynamicsymbols(expr)
{x(t), y(t), Derivative(x(t), t)}
>>> find_dynamicsymbols(expr, exclude=[x, y])
{Derivative(x(t), t)}
>>> a, b, c = dynamicsymbols('a, b, c')
>>> A = ReferenceFrame('A')
>>> v = a * A.x + b * A.y + c * A.z
>>> find_dynamicsymbols(v, reference_frame=A)
{a(t), b(t), c(t)} 

打印(文档字符串)

原文链接:docs.sympy.org/latest/modules/physics/mechanics/api/printing.html

mechanics_printing

此函数与sympy.physics.vector.printing.init_vprinting相同。

mprint

此函数与sympy.physics.vector.printing.vprint相同。

mpprint

此函数与sympy.physics.vector.printing.vpprint相同。

mlatex

此函数与sympy.physics.vector.printing.vlatex相同。

路径(文档字符串)

原文:docs.sympy.org/latest/modules/physics/mechanics/api/pathway.html

实现执行器使用的路径。

class sympy.physics.mechanics.pathway.LinearPathway(*attachments)

一对附件点之间的线性路径。

参数:

attachments:tuple[Point, Point]

两个Point对象,线性路径跨越的两个点。构造函数期望传递两个点,例如LinearPathway(Point('pA'), Point('pB'))。传递更多或更少的点将导致错误抛出。

解释

线性路径形成两点之间的直线段,是可以形成的最简单的路径。它不会与系统中的任何其他对象交互,即LinearPathway将与其他对象相交,以确保其两端(其附件)之间的路径是最短可能的。

线性路径由可以相对移动的两个点和作用于这些点的一对相等且反向的力组成。如果定义了两点之间的正时间变化欧几里得距离,则“伸展速度”是该距离的时间导数。当两点相互远离时,伸展速度为正;当相互靠近时,为负。对于作用于任一点的力的方向,由构造从另一点指向该点的单位向量来确定。这建立了一个符号约定,使得正力大小倾向于推动点分离。以下图示显示了正力方向和点之间的距离:

P           Q
o<--- F --->o
|           |
|<--l(t)--->| 

示例

>>> from sympy.physics.mechanics import LinearPathway 

要构建路径,需要将两个点作为attachments参数传递为一个tuple

>>> from sympy.physics.mechanics import Point
>>> pA, pB = Point('pA'), Point('pB')
>>> linear_pathway = LinearPathway(pA, pB)
>>> linear_pathway
LinearPathway(pA, pB) 

在未描述其附件点的位置和速度的情况下,上述创建的路径并不特别有趣。没有这些信息,无法描述路径的运动,即其长度或其伸展速度。

>>> from sympy.physics.mechanics import ReferenceFrame
>>> from sympy.physics.vector import dynamicsymbols
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> pB.set_pos(pA, q*N.x)
>>> pB.pos_from(pA)
q(t)*N.x 

可通过其length属性访问路径的长度。

>>> linear_pathway.length
sqrt(q(t)**2) 

注意返回的看似过于复杂的表达式实际上是必需的,因为它确保了路径的长度始终为正。

类似地,可以通过其extension_velocity属性访问路径的伸展速度。

>>> linear_pathway.extension_velocity
sqrt(q(t)**2)*Derivative(q(t), t)/q(t) 
property extension_velocity

路径伸展速度的精确分析表达式。

property length

路径长度的精确分析表达式。

to_loads(force)

方程运动方法类所需的负载。

参数:

force:Expr

沿路径长度作用的力的大小。根据路径长度、路径伸展速度和点对力的符号约定,如果此Expr为正,则力将作用于将一对点推开(它是伸展的)。

解释

当构建运动方程时,KanesMethod需要将Point-Vector元组列表传递给其kanes_equations方法的loads参数。此方法充当实用程序,用于生成所需的正确结构的点和向量对,以便这些可以轻松地与负载列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些负载也以正确的形式传递给其他运动方程方法类,例如LagrangesMethod

示例

下面的示例显示了如何生成线性执行器中产生的扩展力F的负载。首先,在全局框架Nx方向上的坐标q之间创建两点之间的线性执行器。

>>> from sympy.physics.mechanics import (LinearPathway, Point,
...     ReferenceFrame)
>>> from sympy.physics.vector import dynamicsymbols
>>> q = dynamicsymbols('q')
>>> N = ReferenceFrame('N')
>>> pA, pB = Point('pA'), Point('pB')
>>> pB.set_pos(pA, q*N.x)
>>> linear_pathway = LinearPathway(pA, pB) 

现在创建一个符号F来描述将沿路径产生的(可扩展的)力的大小。调用路径的to_loads方法,并将F作为唯一参数传递,即可生成KanesMethod所需的负载列表。

>>> from sympy import symbols
>>> F = symbols('F')
>>> linear_pathway.to_loads(F)
[(pA, - F*q(t)/sqrt(q(t)**2)*N.x), (pB, F*q(t)/sqrt(q(t)**2)*N.x)] 
class sympy.physics.mechanics.pathway.ObstacleSetPathway(*attachments)

一组附着点之间的障碍集路径。

参数:

attachments:tuple[Point, Point]

定义分段障碍集路径的Point对象集合。

说明

障碍集路径形成一系列直线段,连接一组点中的相邻点。它类似于多条线性路径端到端连接。它不会与系统中的任何其他对象交互,即ObstacleSetPathway将保证其附着点(其连接点)之间的路径是可能的最短路径。

示例

要构建障碍集路径,需要将三个或更多点作为tuple传递给attachments参数。

>>> from sympy.physics.mechanics import ObstacleSetPathway, Point
>>> pA, pB, pC, pD = Point('pA'), Point('pB'), Point('pC'), Point('pD')
>>> obstacle_set_pathway = ObstacleSetPathway(pA, pB, pC, pD)
>>> obstacle_set_pathway
ObstacleSetPathway(pA, pB, pC, pD) 

上述创建的路径如果未描述其附着点的位置和速度,则并不十分有趣。没有这些信息,无法描述路径的运动方式,即其长度或伸展速度。

>>> from sympy import cos, sin
>>> from sympy.physics.mechanics import ReferenceFrame
>>> from sympy.physics.vector import dynamicsymbols
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> pO = Point('pO')
>>> pA.set_pos(pO, N.y)
>>> pB.set_pos(pO, -N.x)
>>> pC.set_pos(pA, cos(q) * N.x - (sin(q) + 1) * N.y)
>>> pD.set_pos(pA, sin(q) * N.x + (cos(q) - 1) * N.y)
>>> pB.pos_from(pA)
- N.x - N.y
>>> pC.pos_from(pA)
cos(q(t))*N.x + (-sin(q(t)) - 1)*N.y
>>> pD.pos_from(pA)
sin(q(t))*N.x + (cos(q(t)) - 1)*N.y 

可通过其length属性访问路径的长度。

>>> obstacle_set_pathway.length.simplify()
sqrt(2)*(sqrt(cos(q(t)) + 1) + 2) 

类似地,可通过其extension_velocity属性访问路径的伸展速度。

>>> obstacle_set_pathway.extension_velocity.simplify()
-sqrt(2)*sin(q(t))*Derivative(q(t), t)/(2*sqrt(cos(q(t)) + 1)) 
property attachments

定义路径分段路径的点集合。

property extension_velocity

路径伸展速度的精确解析表达式。

property length

路径长度的精确解析表达式。

to_loads(force)

运动方程方法类所需的负载。

参数:

:Expr

沿路径长度作用的力。假设这个Expr代表一个扩展力。

说明

KanesMethod在构建运动方程时,需要将Point-Vector元组列表传递给其kanes_equations方法的loads参数。此方法充当实用程序,用于生成所需的正确结构的点和矢量对,以便这些可以轻松地与负载列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些负载也以正确的形式传递给其他运动方程方法类,例如LagrangesMethod

示例

下面的示例展示了如何在遵循四点之间障碍物设置路径的执行器中生成产生膨胀力F的负载。首先,在参考框架AB中创建一对参考框架,在这些框架中,四个点pApBpCpD将被定位。前两个点在框架A中,后两个点在框架B中。框架B也将被定向,以使其通过全局框架中N.z轴的旋转qA相关联(N.zA.zB.z是平行的)。

>>> from sympy.physics.mechanics import (ObstacleSetPathway, Point,
...     ReferenceFrame)
>>> from sympy.physics.vector import dynamicsymbols
>>> q = dynamicsymbols('q')
>>> N = ReferenceFrame('N')
>>> N = ReferenceFrame('N')
>>> A = N.orientnew('A', 'axis', (0, N.x))
>>> B = A.orientnew('B', 'axis', (q, N.z))
>>> pO = Point('pO')
>>> pA, pB, pC, pD = Point('pA'), Point('pB'), Point('pC'), Point('pD')
>>> pA.set_pos(pO, A.x)
>>> pB.set_pos(pO, -A.y)
>>> pC.set_pos(pO, B.y)
>>> pD.set_pos(pO, B.x)
>>> obstacle_set_pathway = ObstacleSetPathway(pA, pB, pC, pD) 

现在创建一个符号F来描述沿路径产生的(膨胀的)力的大小。通过调用路径的to_loads方法,并将F作为唯一参数传递,可以生成KanesMethod所需的负载列表。

>>> from sympy import Symbol
>>> F = Symbol('F')
>>> obstacle_set_pathway.to_loads(F)
[(pA, sqrt(2)*F/2*A.x + sqrt(2)*F/2*A.y),
 (pB, - sqrt(2)*F/2*A.x - sqrt(2)*F/2*A.y),
 (pB, - F/sqrt(2*cos(q(t)) + 2)*A.y - F/sqrt(2*cos(q(t)) + 2)*B.y),
 (pC, F/sqrt(2*cos(q(t)) + 2)*A.y + F/sqrt(2*cos(q(t)) + 2)*B.y),
 (pC, - sqrt(2)*F/2*B.x + sqrt(2)*F/2*B.y),
 (pD, sqrt(2)*F/2*B.x - sqrt(2)*F/2*B.y)] 
class sympy.physics.mechanics.pathway.PathwayBase(*attachments)

所有路径类继承的抽象基类。

注意事项

此类的实例不能直接由用户实例化。然而,可以通过子类化来创建自定义路径类型。

property attachments

定义路径末端的一对点。

abstract property extension_velocity

表示路径扩展速度的表达式。

abstract property length

表示路径长度的表达式。

abstract to_loads(force)

运动方程方法类所需的负载。

解释

KanesMethod在构建运动方程时,需要将Point-Vector元组列表传递给其kanes_equations方法的loads参数。此方法充当实用程序,用于生成所需的正确结构的点和矢量对,以便这些可以轻松地与负载列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些负载也以正确的形式传递给其他运动方程方法类,例如LagrangesMethod

class sympy.physics.mechanics.pathway.WrappingPathway(attachment_1, attachment_2, geometry)

包裹几何对象的路径。

参数:

附件 _1:Point

两个Point对象中的第一个,路径跨度的表达式。

附件 _2:Point

两个Point对象中的第二个,路径跨度的对象对。

几何:WrappingGeometryBase

包裹路径的几何形状。

解释

一个包裹路径与几何对象相互作用并形成沿其表面平滑包裹的路径。沿着几何对象的包裹路径将是几何对象根据两点定义的测地线。它不会与系统中的任何其他对象相互作用,即WrappingPathway会与其他对象相交,以确保其两端(其附件)之间的路径是可能的最短路径。

为了解释用于路径长度、扩展速度和应用力方向的符号约定,我们可以忽略包裹路径所与之互动的几何体。包裹路径由可以相对移动的两点组成,并且作用于这些点的一对大小相等且方向相反的力。如果定义了两点之间的正时间变化的欧几里得距离,则“扩展速度”是该距离的时间导数。当两点彼此远离时,扩展速度为正,当彼此靠近时为负。作用于任一点的力的方向由构造的单位向量确定,该单位向量指向另一点到此点。这建立了一种符号约定,使得正力大小倾向于推动点之间的距离。下图显示了正力的方向和点之间的距离:

P           Q
o<--- F --->o
|           |
|<--l(t)--->| 

示例

>>> from sympy.physics.mechanics import WrappingPathway 

要构建一个包裹路径,与其他路径一样,必须传递一对点,后跟一个包裹几何类的实例作为关键字参数。我们将使用一个半径为r且轴平行于N.x且通过点pO的圆柱体。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import Point, ReferenceFrame, WrappingCylinder
>>> r = symbols('r')
>>> N = ReferenceFrame('N')
>>> pA, pB, pO = Point('pA'), Point('pB'), Point('pO')
>>> cylinder = WrappingCylinder(r, pO, N.x)
>>> wrapping_pathway = WrappingPathway(pA, pB, cylinder)
>>> wrapping_pathway
WrappingPathway(pA, pB, geometry=WrappingCylinder(radius=r, point=pO,
 axis=N.x)) 
property extension_velocity

路径扩展速度的精确解析表达式。

property geometry

包裹路径所包裹的几何形状。

property length

路径长度的精确解析表达式。

to_loads(force)

动力学方法类所需的负载。

参数:

:Expr

沿着路径长度作用的力的大小。假定这个Expr代表一个扩展力。

解释

当构建运动方程时,KanesMethod要求在其kanes_equations方法的loads参数中传递一个Point-Vector元组列表。这种方法充当一个实用程序,以生成所需的正确结构化的点和向量对,以便这些可以轻松地与列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些负载也以正确的形式传递给其他动力学方法类,例如LagrangesMethod

示例

下面的示例显示了如何在包裹在圆柱体周围的执行器中生成产生的负载F。首先,创建一个半径为r且轴平行于全局框架NN.z方向,并且也通过点pO的圆柱体。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import (Point, ReferenceFrame,
...     WrappingCylinder)
>>> N = ReferenceFrame('N')
>>> r = symbols('r', positive=True)
>>> pO = Point('pO')
>>> cylinder = WrappingCylinder(r, pO, N.z) 

使用 WrappingPathway 类创建执行器的路径,该类定义为跨越两点 pApB。这两个点位于圆柱体表面,点 pB 的位置相对于点 pA 是由动力学符号 q 定义的。

>>> from sympy import cos, sin
>>> from sympy.physics.mechanics import WrappingPathway, dynamicsymbols
>>> q = dynamicsymbols('q')
>>> pA = Point('pA')
>>> pB = Point('pB')
>>> pA.set_pos(pO, r*N.x)
>>> pB.set_pos(pO, r*(cos(q)*N.x + sin(q)*N.y))
>>> pB.pos_from(pA)
(r*cos(q(t)) - r)*N.x + r*sin(q(t))*N.y
>>> pathway = WrappingPathway(pA, pB, cylinder) 

现在创建一个符号 F 来描述(膨胀)力的大小,该力将沿着路径产生。KanesMethod 需要的负载列表可以通过调用路径的 to_loads 方法,并传递 F 作为唯一参数来生成。

>>> F = symbols('F')
>>> loads = pathway.to_loads(F)
>>> [load.__class__(load.location, load.vector.simplify()) for load in loads]
[(pA, F*N.y), (pB, F*sin(q(t))*N.x - F*cos(q(t))*N.y),
 (pO, - F*sin(q(t))*N.x + F*(cos(q(t)) - 1)*N.y)] 

执行器(文档字符串)

原文链接:docs.sympy.org/latest/modules/physics/mechanics/api/actuator.html

实现用于链接力和扭矩应用的执行器。

class sympy.physics.mechanics.actuator.ActuatorBase

所有执行器类继承的抽象基类。

注释

该类的实例不能直接由用户实例化。但是,可以通过子类化来创建自定义的执行器类型。

abstract to_loads()

方程运动方法类所需的负载。

说明

KanesMethod在构建运动方程时需要将Point-Vector元组列表传递给其kanes_equations方法的loads参数。此方法充当实用程序,以生成所需的正确结构化的点和矢量对,以便这些可以轻松地与负载列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些负载也以正确的形式传递给其他运动方程方法类,例如LagrangesMethod

class sympy.physics.mechanics.actuator.DuffingSpring(linear_stiffness, nonlinear_stiffness, pathway, equilibrium_length=0)

基于 Duffing 方程的非线性弹簧。

参数:

linear_stiffness:Expr

线性刚度系数(beta)。

nonlinear_stiffness:Expr

非线性刚度系数(alpha)。

pathway:PathwayBase

执行器所遵循的路径。

equilibrium_length:Expr,可选

弹簧处于平衡状态的长度(x)。

说明

在这里,DuffingSpring表示基于 Duffing 方程的非线性弹簧施加的力:F = -betax-alphax**3,其中 x 是从平衡位置偏移,beta 是线性弹簧常数,alpha 是非线性立方项的系数。

property force

Duffing 弹簧产生的力。

class sympy.physics.mechanics.actuator.ForceActuator(force, pathway)

产生力的执行器。

参数:

force:Expr

定义执行器产生的(扩张性)力的标量表达式。

pathway:PathwayBase

执行器所遵循的路径。这必须是PathwayBase的具体子类的实例,例如LinearPathway

说明

ForceActuator是一种沿其长度产生(扩张性)力的执行器。

力致动器使用路径实例来确定其施加在系统上的力的方向和数量。考虑最简单的情况,即使用LinearPathway实例。该路径由两个可以相对移动的点组成,并导致作用在端点上的一对相等且相反的力。如果定义了两点之间的正时变欧氏距离,则“伸展速度”是该距离的时间导数。当两点彼此远离时,伸展速度为正,当彼此靠近时为负。决定作用于任一点的力的方向是通过构建从另一点指向该点的单位向量来确定的。这建立了一个符号约定,使得正力大小倾向于推动点分开,这是这种情况下“扩展性”的含义。以下图表显示了正力方向和点之间的距离:

P           Q
o<--- F --->o
|           |
|<--l(t)--->| 

示例

要构建一个致动器,必须提供一个表达式(或符号)来表示它可以产生的力,以及指定其作用线的路径。让我们还创建一个全局参考框架,并在其中固定一个点,同时设置另一个点的位置,以便它可以在该框架的x方向上自由移动,由坐标q指定。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import (ForceActuator, LinearPathway,
...     Point, ReferenceFrame)
>>> from sympy.physics.vector import dynamicsymbols
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> force = symbols('F')
>>> pA, pB = Point('pA'), Point('pB')
>>> pA.set_vel(N, 0)
>>> pB.set_pos(pA, q*N.x)
>>> pB.pos_from(pA)
q(t)*N.x
>>> linear_pathway = LinearPathway(pA, pB)
>>> actuator = ForceActuator(force, linear_pathway)
>>> actuator
ForceActuator(F, LinearPathway(pA, pB)) 
property force

致动器产生的力的大小。

property pathway

Pathway定义致动器作用线路。

to_loads()

运动方程方法类所需的加载。

解释

KanesMethod在构建运动方程时,需要将Point-Vector元组列表传递给其loads参数的kanes_equations方法。该方法作为一个实用工具,用于生成所需的正确结构的点和向量对,这样可以轻松地与加载列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些加载也符合其他运动方程方法类的正确形式,例如LagrangesMethod

示例

下面的示例展示了如何生成由线性路径跟随的力致动器产生的加载。在本例中,假设力致动器用于模拟简单的线性弹簧。首先,在全局参考框架Nx方向上由坐标q分隔的两点之间创建一个线性路径。

>>> from sympy.physics.mechanics import (LinearPathway, Point,
...     ReferenceFrame)
>>> from sympy.physics.vector import dynamicsymbols
>>> q = dynamicsymbols('q')
>>> N = ReferenceFrame('N')
>>> pA, pB = Point('pA'), Point('pB')
>>> pB.set_pos(pA, q*N.x)
>>> pathway = LinearPathway(pA, pB) 

现在创建一个符号k来描述弹簧的刚度,并实例化一个力致动器,该致动器产生与弹簧的刚度和路径长度成比例的(收缩性)力。请注意,致动器类使用的符号约定是扩展力为正,因此为了使弹簧产生收缩力,需要将弹簧力计算为其刚度乘以长度的负值。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import ForceActuator
>>> stiffness = symbols('k')
>>> spring_force = -stiffness*pathway.length
>>> spring = ForceActuator(spring_force, pathway) 

弹簧产生的力可以通过调用to_loads方法在KanesMethod(和其他运动方程方法)需要的负载列表形式中生成。

>>> spring.to_loads()
[(pA, k*q(t)*N.x), (pB, - k*q(t)*N.x)] 

一个简单的线性阻尼器可以以类似的方式建模。创建另一个符号c来描述阻尼器的阻尼系数。这次实例化一个力作用器,该力与阻尼器的阻尼系数和路径的延伸速度成比例。请注意,阻尼力是负的,因为它作用于阻尼器长度变化的相反方向。

>>> damping_coefficient = symbols('c')
>>> damping_force = -damping_coefficient*pathway.extension_velocity
>>> damper = ForceActuator(damping_force, pathway) 

再次,阻尼器产生的力可以通过调用to_loads方法生成。

>>> damper.to_loads()
[(pA, c*Derivative(q(t), t)*N.x), (pB, - c*Derivative(q(t), t)*N.x)] 
class sympy.physics.mechanics.actuator.LinearDamper(damping, pathway)

阻尼器的力是其延伸速度的线性函数。

参数:

阻尼:Expr

阻尼常数。

路径:PathwayBase

执行器遵循的路径。这必须是PathwayBase的具体子类的实例,例如LinearPathway

解释

请注意,LinearDamper名称中的“线性”指的是阻尼力是阻尼器长度变化率的线性函数。即对于阻尼系数为c和延伸速度为v的线性阻尼器,阻尼力将为-c*v,这是v的线性函数。要创建一个沿线性或直线路径在两端之间的阻尼器,需要将一个LinearPathway实例传递给pathway参数。

LinearDamperForceActuator的子类,因此遵循相同的长度、延伸速度和施加在物体附着点上的力的符号约定。力方向的约定是,当一个线性阻尼器以LinearPathway实例作为其路径实例化时,它们作用于推动阻尼器两端分开的方向。因为阻尼器产生的力与长度变化方向相反,所以当延伸速度为正时,在两端施加的力的标量部分为负,以便在转换为矢量数量时翻转端点力的符号。当延伸速度为负时(即阻尼器缩短时),施加的力的标量部分也为负,以使符号取消,在路径端点的力方向与端点的力的正符号约定相同(即它们作用于推动路径端点分离)。以下图显示了正力感知和点之间的距离:

P           Q
o<--- F --->o
|           |
|<--l(t)--->| 

示例

要构建线性阻尼器,必须提供一个表达式(或符号),用来表示阻尼器的阻尼系数(我们将使用符号c),并指定其作用路径。让我们还创建一个全局参考框架,并在其中固定一个点的空间位置,同时设置另一个点的位置,使其可以在框架的 x 方向上自由移动,由坐标q指定。两点彼此移动的速度可以由坐标u来指定,其中uq(t)的第一阶时间导数(即u = Derivative(q(t), t))。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import (LinearDamper, LinearPathway,
...     Point, ReferenceFrame)
>>> from sympy.physics.vector import dynamicsymbols
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> damping = symbols('c')
>>> pA, pB = Point('pA'), Point('pB')
>>> pA.set_vel(N, 0)
>>> pB.set_pos(pA, q*N.x)
>>> pB.pos_from(pA)
q(t)*N.x
>>> pB.vel(N)
Derivative(q(t), t)*N.x
>>> linear_pathway = LinearPathway(pA, pB)
>>> damper = LinearDamper(damping, linear_pathway)
>>> damper
LinearDamper(c, LinearPathway(pA, pB)) 

此阻尼器将产生一个力,其与其阻尼系数和路径的延伸长度成比例。请注意,这个力是负的,因为 SymPy 对执行器的符号约定是负力是收缩性的,而阻尼器的阻尼力将与长度变化的方向相反。

>>> damper.force
-c*sqrt(q(t)**2)*Derivative(q(t), t)/q(t) 

另请参见

力执行器

产生力的执行器(LinearDamper的超类)。

线性路径

一对点之间的直线路径。

property damping

线性阻尼器的阻尼常数。

property force

线性阻尼器产生的阻尼力。

class sympy.physics.mechanics.actuator.LinearSpring(stiffness, pathway, equilibrium_length=0)

其长度的弹簧力为其长度的线性函数。

参数:

刚度 : Expr

弹簧常数。

路径 : PathwayBase

执行器遵循的路径。这必须是PathwayBase的一个具体子类的实例,例如LinearPathway

平衡长度 : Expr,可选

弹簧处于平衡状态时的长度,即它不产生任何力。默认值为 0,即弹簧力是路径长度的线性函数,没有常量偏移量。

解释

请注意LinearSpring名称中的“线性”指的是弹簧力是弹簧长度的线性函数的事实。即对于具有刚度k、其两端距离为x,且平衡长度为0的线性弹簧,弹簧力将为-k*x,这是x的线性函数。要创建一个遵循线性或直线路径的弹簧,需要将LinearPathway实例传递给pathway参数。

LinearSpringForceActuator 的子类,因此遵循相同的长度、延伸速度和作用于其连接到身体上的点的力的方向的符号约定。力的方向约定是,当线性弹簧实例化为具有 LinearPathway 实例作为其路径时,它们作用于弹簧两端,使它们彼此远离。因为弹簧产生收缩力并在拉伸时拉动两端朝向平衡长度,所以力端点的标量部分为负,以便在转换为矢量量时翻转端点上的力的符号。以下图示显示了正力感知和点之间的距离:

P           Q
o<--- F --->o
|           |
|<--l(t)--->| 

示例

要构造线性弹簧,必须提供一个表达弹簧刚度(弹簧常数)的表达式(或符号),以及指定其作用线的路径。让我们还创建一个全局参考框架,并在其中空间固定其中一个点,同时设置另一个点位于可以自由在框架的 x 方向上移动的坐标 q 指定的位置。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import (LinearPathway, LinearSpring,
...     Point, ReferenceFrame)
>>> from sympy.physics.vector import dynamicsymbols
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> stiffness = symbols('k')
>>> pA, pB = Point('pA'), Point('pB')
>>> pA.set_vel(N, 0)
>>> pB.set_pos(pA, q*N.x)
>>> pB.pos_from(pA)
q(t)*N.x
>>> linear_pathway = LinearPathway(pA, pB)
>>> spring = LinearSpring(stiffness, linear_pathway)
>>> spring
LinearSpring(k, LinearPathway(pA, pB)) 

此弹簧将产生与其刚度和路径长度成比例的力。请注意,由于 SymPy 对执行器的符号约定是负力是收缩的,因此此力为负。

>>> spring.force
-k*sqrt(q(t)**2) 

要创建具有非零平衡长度的线性弹簧,可以在 LinearSpring 实例的 equilibrium_length 参数上传递一个表达式(或符号)。让我们创建一个符号 l 以表示非零平衡长度,并创建另一个线性弹簧。

>>> l = symbols('l')
>>> spring = LinearSpring(stiffness, linear_pathway, equilibrium_length=l)
>>> spring
LinearSpring(k, LinearPathway(pA, pB), equilibrium_length=l) 

这个新弹簧的弹簧力再次与其刚度和路径长度成正比。然而,当 q(t) 等于 l 时,弹簧不会产生任何力。请注意,当 q(t) 小于 l 时,力会变得扩张,正如预期的那样。

>>> spring.force
-k*(-l + sqrt(q(t)**2)) 

另请参阅

ForceActuator

产生力的执行器(LinearSpring 的超类)。

LinearPathway

一对点之间的直线路径。

property equilibrium_length

弹簧在其不产生力的长度。

property force

线性弹簧产生的弹簧力。

property stiffness

线性弹簧的弹簧常数。

class sympy.physics.mechanics.actuator.TorqueActuator(torque, axis, target_frame, reaction_frame=None)

产生扭矩的执行器。

参数:

扭矩:表达式

定义执行器产生的扭矩的标量表达式。

:向量

执行器施加扭矩的轴。

目标框架:参考框架 | 刚体

执行器将施加扭矩的主要框架。

反作用框架:参考框架 | 刚体 | 无

执行器将施加扭矩的次要框架。请注意,(相等和相反的)反作用扭矩应用于该框架。

说明

TorqueActuator是在一对身体上产生相等且相反扭矩的执行器。

示例

要构建扭矩执行器,必须提供一个表示其可以产生的扭矩的表达式(或符号),以及指定扭矩作用轴线的向量,并且指定扭矩将作用的一对框架。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import (ReferenceFrame, RigidBody,
...     TorqueActuator)
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> torque = symbols('T')
>>> axis = N.z
>>> parent = RigidBody('parent', frame=N)
>>> child = RigidBody('child', frame=A)
>>> bodies = (child, parent)
>>> actuator = TorqueActuator(torque, axis, *bodies)
>>> actuator
TorqueActuator(T, axis=N.z, target_frame=A, reaction_frame=N) 

注意,因为扭矩实际上作用于框架而不是物体,当传递RigidBody而不是ReferenceFrame时,TorqueActuator将提取与之关联的框架。

classmethod at_pin_joint(torque, pin_joint)

PinJoint实例化的替代构造方法。

参数:

torque:Expr

定义执行器产生的扭矩的标量表达式。

pin_joint:PinJoint

销钉关节及其关联的父体和子体,扭矩执行器将作用于其上。扭矩执行器作用于销钉关节的父体和子体,子体作为反作用体。销钉关节的轴线被用作扭矩执行器施加扭矩的轴线。

示例

要创建销钉关节,需要向PinJoint类的构造函数传递名称、父体和子体。还可以使用joint_axis关键字参数来控制关节轴线。在这个例子中,让我们使用父体参考框架的 z 轴作为关节轴线。

>>> from sympy.physics.mechanics import (PinJoint, ReferenceFrame,
...     RigidBody, TorqueActuator)
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> parent = RigidBody('parent', frame=N)
>>> child = RigidBody('child', frame=A)
>>> pin_joint = PinJoint(
...     'pin',
...     parent,
...     child,
...     joint_axis=N.z,
... ) 

让我们还创建一个符号T,用来表示扭矩执行器施加的扭矩。

>>> from sympy import symbols
>>> torque = symbols('T') 

要从先前实例化的torquepin_joint变量创建扭矩执行器,可以将它们传递给TorqueActuator类的替代构造类方法at_pin_joint。应注意,正扭矩将导致关节坐标的正位移或者扭矩施加在子体上,产生在父体上的反作用力。

>>> actuator = TorqueActuator.at_pin_joint(torque, pin_joint)
>>> actuator
TorqueActuator(T, axis=N.z, target_frame=A, reaction_frame=N) 
property axis

扭矩作用的轴线。

property reaction_frame

扭矩将作用的主要参考框架。

property target_frame

扭矩将作用的主要参考框架。

to_loads()

运动方程方法类所需的负载。

解释

在构造运动方程时,KanesMethod需要传递到其kanes_equations方法的loads参数的Point-Vector元组列表。此方法作为一个实用程序,用于生成所需的正确结构化的点和向量对,以便可以轻松地将它们与负载列表中的其他项目连接,并传递给KanesMethod.kanes_equations。这些负载也以正确的形式传递给其他运动方程方法类,例如LagrangesMethod

示例

下面的示例展示了如何生成作用于由销钉关节连接的一对身体上的扭矩执行器产生的负载。

>>> from sympy import symbols
>>> from sympy.physics.mechanics import (PinJoint, ReferenceFrame,
...     RigidBody, TorqueActuator)
>>> torque = symbols('T')
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> parent = RigidBody('parent', frame=N)
>>> child = RigidBody('child', frame=A)
>>> pin_joint = PinJoint(
...     'pin',
...     parent,
...     child,
...     joint_axis=N.z,
... )
>>> actuator = TorqueActuator.at_pin_joint(torque, pin_joint) 

通过调用to_loads方法可以生成阻尼器产生的力。

>>> actuator.to_loads()
[(A, T*N.z), (N, - T*N.z)] 

或者,如果扭矩执行器创建时没有反作用框架,则to_loads方法返回的负载将仅包含作用在目标框架上的单个负载。

>>> actuator = TorqueActuator(torque, N.z, N)
>>> actuator.to_loads()
[(N, T*N.z)] 
property torque

执行器产生的扭矩大小。