test_rigidbody.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. from sympy.physics.mechanics import Point, ReferenceFrame, Dyadic, RigidBody
  2. from sympy.physics.mechanics import dynamicsymbols, outer, inertia, Inertia
  3. from sympy.physics.mechanics import inertia_of_point_mass
  4. from sympy import expand, zeros, simplify, symbols
  5. from sympy.testing.pytest import raises, warns_deprecated_sympy
  6. def test_rigidbody_default():
  7. # Test default
  8. b = RigidBody('B')
  9. I = inertia(b.frame, *symbols('B_ixx B_iyy B_izz B_ixy B_iyz B_izx'))
  10. assert b.name == 'B'
  11. assert b.mass == symbols('B_mass')
  12. assert b.masscenter.name == 'B_masscenter'
  13. assert b.inertia == (I, b.masscenter)
  14. assert b.central_inertia == I
  15. assert b.frame.name == 'B_frame'
  16. assert b.__str__() == 'B'
  17. assert b.__repr__() == (
  18. "RigidBody('B', masscenter=B_masscenter, frame=B_frame, mass=B_mass, "
  19. "inertia=Inertia(dyadic=B_ixx*(B_frame.x|B_frame.x) + "
  20. "B_ixy*(B_frame.x|B_frame.y) + B_izx*(B_frame.x|B_frame.z) + "
  21. "B_ixy*(B_frame.y|B_frame.x) + B_iyy*(B_frame.y|B_frame.y) + "
  22. "B_iyz*(B_frame.y|B_frame.z) + B_izx*(B_frame.z|B_frame.x) + "
  23. "B_iyz*(B_frame.z|B_frame.y) + B_izz*(B_frame.z|B_frame.z), "
  24. "point=B_masscenter))")
  25. def test_rigidbody():
  26. m, m2, v1, v2, v3, omega = symbols('m m2 v1 v2 v3 omega')
  27. A = ReferenceFrame('A')
  28. A2 = ReferenceFrame('A2')
  29. P = Point('P')
  30. P2 = Point('P2')
  31. I = Dyadic(0)
  32. I2 = Dyadic(0)
  33. B = RigidBody('B', P, A, m, (I, P))
  34. assert B.mass == m
  35. assert B.frame == A
  36. assert B.masscenter == P
  37. assert B.inertia == (I, B.masscenter)
  38. B.mass = m2
  39. B.frame = A2
  40. B.masscenter = P2
  41. B.inertia = (I2, B.masscenter)
  42. raises(TypeError, lambda: RigidBody(P, P, A, m, (I, P)))
  43. raises(TypeError, lambda: RigidBody('B', P, P, m, (I, P)))
  44. raises(TypeError, lambda: RigidBody('B', P, A, m, (P, P)))
  45. raises(TypeError, lambda: RigidBody('B', P, A, m, (I, I)))
  46. assert B.__str__() == 'B'
  47. assert B.mass == m2
  48. assert B.frame == A2
  49. assert B.masscenter == P2
  50. assert B.inertia == (I2, B.masscenter)
  51. assert isinstance(B.inertia, Inertia)
  52. # Testing linear momentum function assuming A2 is the inertial frame
  53. N = ReferenceFrame('N')
  54. P2.set_vel(N, v1 * N.x + v2 * N.y + v3 * N.z)
  55. assert B.linear_momentum(N) == m2 * (v1 * N.x + v2 * N.y + v3 * N.z)
  56. def test_rigidbody2():
  57. M, v, r, omega, g, h = dynamicsymbols('M v r omega g h')
  58. N = ReferenceFrame('N')
  59. b = ReferenceFrame('b')
  60. b.set_ang_vel(N, omega * b.x)
  61. P = Point('P')
  62. I = outer(b.x, b.x)
  63. Inertia_tuple = (I, P)
  64. B = RigidBody('B', P, b, M, Inertia_tuple)
  65. P.set_vel(N, v * b.x)
  66. assert B.angular_momentum(P, N) == omega * b.x
  67. O = Point('O')
  68. O.set_vel(N, v * b.x)
  69. P.set_pos(O, r * b.y)
  70. assert B.angular_momentum(O, N) == omega * b.x - M*v*r*b.z
  71. B.potential_energy = M * g * h
  72. assert B.potential_energy == M * g * h
  73. assert expand(2 * B.kinetic_energy(N)) == omega**2 + M * v**2
  74. def test_rigidbody3():
  75. q1, q2, q3, q4 = dynamicsymbols('q1:5')
  76. p1, p2, p3 = symbols('p1:4')
  77. m = symbols('m')
  78. A = ReferenceFrame('A')
  79. B = A.orientnew('B', 'axis', [q1, A.x])
  80. O = Point('O')
  81. O.set_vel(A, q2*A.x + q3*A.y + q4*A.z)
  82. P = O.locatenew('P', p1*B.x + p2*B.y + p3*B.z)
  83. P.v2pt_theory(O, A, B)
  84. I = outer(B.x, B.x)
  85. rb1 = RigidBody('rb1', P, B, m, (I, P))
  86. # I_S/O = I_S/S* + I_S*/O
  87. rb2 = RigidBody('rb2', P, B, m,
  88. (I + inertia_of_point_mass(m, P.pos_from(O), B), O))
  89. assert rb1.central_inertia == rb2.central_inertia
  90. assert rb1.angular_momentum(O, A) == rb2.angular_momentum(O, A)
  91. def test_pendulum_angular_momentum():
  92. """Consider a pendulum of length OA = 2a, of mass m as a rigid body of
  93. center of mass G (OG = a) which turn around (O,z). The angle between the
  94. reference frame R and the rod is q. The inertia of the body is I =
  95. (G,0,ma^2/3,ma^2/3). """
  96. m, a = symbols('m, a')
  97. q = dynamicsymbols('q')
  98. R = ReferenceFrame('R')
  99. R1 = R.orientnew('R1', 'Axis', [q, R.z])
  100. R1.set_ang_vel(R, q.diff() * R.z)
  101. I = inertia(R1, 0, m * a**2 / 3, m * a**2 / 3)
  102. O = Point('O')
  103. A = O.locatenew('A', 2*a * R1.x)
  104. G = O.locatenew('G', a * R1.x)
  105. S = RigidBody('S', G, R1, m, (I, G))
  106. O.set_vel(R, 0)
  107. A.v2pt_theory(O, R, R1)
  108. G.v2pt_theory(O, R, R1)
  109. assert (4 * m * a**2 / 3 * q.diff() * R.z -
  110. S.angular_momentum(O, R).express(R)) == 0
  111. def test_rigidbody_inertia():
  112. N = ReferenceFrame('N')
  113. m, Ix, Iy, Iz, a, b = symbols('m, I_x, I_y, I_z, a, b')
  114. Io = inertia(N, Ix, Iy, Iz)
  115. o = Point('o')
  116. p = o.locatenew('p', a * N.x + b * N.y)
  117. R = RigidBody('R', o, N, m, (Io, p))
  118. I_check = inertia(N, Ix - b ** 2 * m, Iy - a ** 2 * m,
  119. Iz - m * (a ** 2 + b ** 2), m * a * b)
  120. assert isinstance(R.inertia, Inertia)
  121. assert R.inertia == (Io, p)
  122. assert R.central_inertia == I_check
  123. R.central_inertia = Io
  124. assert R.inertia == (Io, o)
  125. assert R.central_inertia == Io
  126. R.inertia = (Io, p)
  127. assert R.inertia == (Io, p)
  128. assert R.central_inertia == I_check
  129. # parse Inertia object
  130. R.inertia = Inertia(Io, o)
  131. assert R.inertia == (Io, o)
  132. def test_parallel_axis():
  133. N = ReferenceFrame('N')
  134. m, Ix, Iy, Iz, a, b = symbols('m, I_x, I_y, I_z, a, b')
  135. Io = inertia(N, Ix, Iy, Iz)
  136. o = Point('o')
  137. p = o.locatenew('p', a * N.x + b * N.y)
  138. R = RigidBody('R', o, N, m, (Io, o))
  139. Ip = R.parallel_axis(p)
  140. Ip_expected = inertia(N, Ix + m * b**2, Iy + m * a**2,
  141. Iz + m * (a**2 + b**2), ixy=-m * a * b)
  142. assert Ip == Ip_expected
  143. # Reference frame from which the parallel axis is viewed should not matter
  144. A = ReferenceFrame('A')
  145. A.orient_axis(N, N.z, 1)
  146. assert simplify(
  147. (R.parallel_axis(p, A) - Ip_expected).to_matrix(A)) == zeros(3, 3)
  148. def test_deprecated_set_potential_energy():
  149. m, g, h = symbols('m g h')
  150. A = ReferenceFrame('A')
  151. P = Point('P')
  152. I = Dyadic(0)
  153. B = RigidBody('B', P, A, m, (I, P))
  154. with warns_deprecated_sympy():
  155. B.set_potential_energy(m*g*h)