图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

275 lines
9.1 KiB

from sympy.core.backend import Symbol, symbols, sin, cos, Matrix
from sympy.physics.vector import Point, ReferenceFrame, dynamicsymbols
from sympy.physics.mechanics import inertia, Body
from sympy.testing.pytest import raises
def test_default():
body = Body('body')
assert body.name == 'body'
assert body.loads == []
point = Point('body_masscenter')
point.set_vel(body.frame, 0)
com = body.masscenter
frame = body.frame
assert com.vel(frame) == point.vel(frame)
assert body.mass == Symbol('body_mass')
ixx, iyy, izz = symbols('body_ixx body_iyy body_izz')
ixy, iyz, izx = symbols('body_ixy body_iyz body_izx')
assert body.inertia == (inertia(body.frame, ixx, iyy, izz, ixy, iyz, izx),
body.masscenter)
def test_custom_rigid_body():
# Body with RigidBody.
rigidbody_masscenter = Point('rigidbody_masscenter')
rigidbody_mass = Symbol('rigidbody_mass')
rigidbody_frame = ReferenceFrame('rigidbody_frame')
body_inertia = inertia(rigidbody_frame, 1, 0, 0)
rigid_body = Body('rigidbody_body', rigidbody_masscenter, rigidbody_mass,
rigidbody_frame, body_inertia)
com = rigid_body.masscenter
frame = rigid_body.frame
rigidbody_masscenter.set_vel(rigidbody_frame, 0)
assert com.vel(frame) == rigidbody_masscenter.vel(frame)
assert com.pos_from(com) == rigidbody_masscenter.pos_from(com)
assert rigid_body.mass == rigidbody_mass
assert rigid_body.inertia == (body_inertia, rigidbody_masscenter)
assert rigid_body.is_rigidbody
assert hasattr(rigid_body, 'masscenter')
assert hasattr(rigid_body, 'mass')
assert hasattr(rigid_body, 'frame')
assert hasattr(rigid_body, 'inertia')
def test_particle_body():
# Body with Particle
particle_masscenter = Point('particle_masscenter')
particle_mass = Symbol('particle_mass')
particle_frame = ReferenceFrame('particle_frame')
particle_body = Body('particle_body', particle_masscenter, particle_mass,
particle_frame)
com = particle_body.masscenter
frame = particle_body.frame
particle_masscenter.set_vel(particle_frame, 0)
assert com.vel(frame) == particle_masscenter.vel(frame)
assert com.pos_from(com) == particle_masscenter.pos_from(com)
assert particle_body.mass == particle_mass
assert not hasattr(particle_body, "_inertia")
assert hasattr(particle_body, 'frame')
assert hasattr(particle_body, 'masscenter')
assert hasattr(particle_body, 'mass')
assert not particle_body.is_rigidbody
def test_particle_body_add_force():
# Body with Particle
particle_masscenter = Point('particle_masscenter')
particle_mass = Symbol('particle_mass')
particle_frame = ReferenceFrame('particle_frame')
particle_body = Body('particle_body', particle_masscenter, particle_mass,
particle_frame)
a = Symbol('a')
force_vector = a * particle_body.frame.x
particle_body.apply_force(force_vector, particle_body.masscenter)
assert len(particle_body.loads) == 1
point = particle_body.masscenter.locatenew(
particle_body._name + '_point0', 0)
point.set_vel(particle_body.frame, 0)
force_point = particle_body.loads[0][0]
frame = particle_body.frame
assert force_point.vel(frame) == point.vel(frame)
assert force_point.pos_from(force_point) == point.pos_from(force_point)
assert particle_body.loads[0][1] == force_vector
def test_body_add_force():
# Body with RigidBody.
rigidbody_masscenter = Point('rigidbody_masscenter')
rigidbody_mass = Symbol('rigidbody_mass')
rigidbody_frame = ReferenceFrame('rigidbody_frame')
body_inertia = inertia(rigidbody_frame, 1, 0, 0)
rigid_body = Body('rigidbody_body', rigidbody_masscenter, rigidbody_mass,
rigidbody_frame, body_inertia)
l = Symbol('l')
Fa = Symbol('Fa')
point = rigid_body.masscenter.locatenew(
'rigidbody_body_point0',
l * rigid_body.frame.x)
point.set_vel(rigid_body.frame, 0)
force_vector = Fa * rigid_body.frame.z
# apply_force with point
rigid_body.apply_force(force_vector, point)
assert len(rigid_body.loads) == 1
force_point = rigid_body.loads[0][0]
frame = rigid_body.frame
assert force_point.vel(frame) == point.vel(frame)
assert force_point.pos_from(force_point) == point.pos_from(force_point)
assert rigid_body.loads[0][1] == force_vector
# apply_force without point
rigid_body.apply_force(force_vector)
assert len(rigid_body.loads) == 2
assert rigid_body.loads[1][1] == force_vector
# passing something else than point
raises(TypeError, lambda: rigid_body.apply_force(force_vector, 0))
raises(TypeError, lambda: rigid_body.apply_force(0))
def test_body_add_torque():
body = Body('body')
torque_vector = body.frame.x
body.apply_torque(torque_vector)
assert len(body.loads) == 1
assert body.loads[0] == (body.frame, torque_vector)
raises(TypeError, lambda: body.apply_torque(0))
def test_body_masscenter_vel():
A = Body('A')
N = ReferenceFrame('N')
B = Body('B', frame=N)
A.masscenter.set_vel(N, N.z)
assert A.masscenter_vel(B) == N.z
assert A.masscenter_vel(N) == N.z
def test_body_ang_vel():
A = Body('A')
N = ReferenceFrame('N')
B = Body('B', frame=N)
A.frame.set_ang_vel(N, N.y)
assert A.ang_vel_in(B) == N.y
assert B.ang_vel_in(A) == -N.y
assert A.ang_vel_in(N) == N.y
def test_body_dcm():
A = Body('A')
B = Body('B')
A.frame.orient_axis(B.frame, B.frame.z, 10)
assert A.dcm(B) == Matrix([[cos(10), sin(10), 0], [-sin(10), cos(10), 0], [0, 0, 1]])
assert A.dcm(B.frame) == Matrix([[cos(10), sin(10), 0], [-sin(10), cos(10), 0], [0, 0, 1]])
def test_body_axis():
N = ReferenceFrame('N')
B = Body('B', frame=N)
assert B.x == N.x
assert B.y == N.y
assert B.z == N.z
def test_apply_force_multiple_one_point():
a, b = symbols('a b')
P = Point('P')
B = Body('B')
f1 = a*B.x
f2 = b*B.y
B.apply_force(f1, P)
assert B.loads == [(P, f1)]
B.apply_force(f2, P)
assert B.loads == [(P, f1+f2)]
def test_apply_force():
f, g = symbols('f g')
q, x, v1, v2 = dynamicsymbols('q x v1 v2')
P1 = Point('P1')
P2 = Point('P2')
B1 = Body('B1')
B2 = Body('B2')
N = ReferenceFrame('N')
P1.set_vel(B1.frame, v1*B1.x)
P2.set_vel(B2.frame, v2*B2.x)
force = f*q*N.z # time varying force
B1.apply_force(force, P1, B2, P2) #applying equal and opposite force on moving points
assert B1.loads == [(P1, force)]
assert B2.loads == [(P2, -force)]
g1 = B1.mass*g*N.y
g2 = B2.mass*g*N.y
B1.apply_force(g1) #applying gravity on B1 masscenter
B2.apply_force(g2) #applying gravity on B2 masscenter
assert B1.loads == [(P1,force), (B1.masscenter, g1)]
assert B2.loads == [(P2, -force), (B2.masscenter, g2)]
force2 = x*N.x
B1.apply_force(force2, reaction_body=B2) #Applying time varying force on masscenter
assert B1.loads == [(P1, force), (B1.masscenter, force2+g1)]
assert B2.loads == [(P2, -force), (B2.masscenter, -force2+g2)]
def test_apply_torque():
t = symbols('t')
q = dynamicsymbols('q')
B1 = Body('B1')
B2 = Body('B2')
N = ReferenceFrame('N')
torque = t*q*N.x
B1.apply_torque(torque, B2) #Applying equal and opposite torque
assert B1.loads == [(B1.frame, torque)]
assert B2.loads == [(B2.frame, -torque)]
torque2 = t*N.y
B1.apply_torque(torque2)
assert B1.loads == [(B1.frame, torque+torque2)]
def test_clear_load():
a = symbols('a')
P = Point('P')
B = Body('B')
force = a*B.z
B.apply_force(force, P)
assert B.loads == [(P, force)]
B.clear_loads()
assert B.loads == []
def test_remove_load():
P1 = Point('P1')
P2 = Point('P2')
B = Body('B')
f1 = B.x
f2 = B.y
B.apply_force(f1, P1)
B.apply_force(f2, P2)
assert B.loads == [(P1, f1), (P2, f2)]
B.remove_load(P2)
assert B.loads == [(P1, f1)]
B.apply_torque(f1.cross(f2))
assert B.loads == [(P1, f1), (B.frame, f1.cross(f2))]
B.remove_load()
assert B.loads == [(P1, f1)]
def test_apply_loads_on_multi_degree_freedom_holonomic_system():
"""Example based on: https://pydy.readthedocs.io/en/latest/examples/multidof-holonomic.html"""
W = Body('W') #Wall
B = Body('B') #Block
P = Body('P') #Pendulum
b = Body('b') #bob
q1, q2 = dynamicsymbols('q1 q2') #generalized coordinates
k, c, g, kT = symbols('k c g kT') #constants
F, T = dynamicsymbols('F T') #Specified forces
#Applying forces
B.apply_force(F*W.x)
W.apply_force(k*q1*W.x, reaction_body=B) #Spring force
W.apply_force(c*q1.diff()*W.x, reaction_body=B) #dampner
P.apply_force(P.mass*g*W.y)
b.apply_force(b.mass*g*W.y)
#Applying torques
P.apply_torque(kT*q2*W.z, reaction_body=b)
P.apply_torque(T*W.z)
assert B.loads == [(B.masscenter, (F - k*q1 - c*q1.diff())*W.x)]
assert P.loads == [(P.masscenter, P.mass*g*W.y), (P.frame, (T + kT*q2)*W.z)]
assert b.loads == [(b.masscenter, b.mass*g*W.y), (b.frame, -kT*q2*W.z)]
assert W.loads == [(W.masscenter, (c*q1.diff() + k*q1)*W.x)]