图片解析应用
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

  1. from sympy.core.backend import Symbol, symbols, sin, cos, Matrix
  2. from sympy.physics.vector import Point, ReferenceFrame, dynamicsymbols
  3. from sympy.physics.mechanics import inertia, Body
  4. from sympy.testing.pytest import raises
  5. def test_default():
  6. body = Body('body')
  7. assert body.name == 'body'
  8. assert body.loads == []
  9. point = Point('body_masscenter')
  10. point.set_vel(body.frame, 0)
  11. com = body.masscenter
  12. frame = body.frame
  13. assert com.vel(frame) == point.vel(frame)
  14. assert body.mass == Symbol('body_mass')
  15. ixx, iyy, izz = symbols('body_ixx body_iyy body_izz')
  16. ixy, iyz, izx = symbols('body_ixy body_iyz body_izx')
  17. assert body.inertia == (inertia(body.frame, ixx, iyy, izz, ixy, iyz, izx),
  18. body.masscenter)
  19. def test_custom_rigid_body():
  20. # Body with RigidBody.
  21. rigidbody_masscenter = Point('rigidbody_masscenter')
  22. rigidbody_mass = Symbol('rigidbody_mass')
  23. rigidbody_frame = ReferenceFrame('rigidbody_frame')
  24. body_inertia = inertia(rigidbody_frame, 1, 0, 0)
  25. rigid_body = Body('rigidbody_body', rigidbody_masscenter, rigidbody_mass,
  26. rigidbody_frame, body_inertia)
  27. com = rigid_body.masscenter
  28. frame = rigid_body.frame
  29. rigidbody_masscenter.set_vel(rigidbody_frame, 0)
  30. assert com.vel(frame) == rigidbody_masscenter.vel(frame)
  31. assert com.pos_from(com) == rigidbody_masscenter.pos_from(com)
  32. assert rigid_body.mass == rigidbody_mass
  33. assert rigid_body.inertia == (body_inertia, rigidbody_masscenter)
  34. assert rigid_body.is_rigidbody
  35. assert hasattr(rigid_body, 'masscenter')
  36. assert hasattr(rigid_body, 'mass')
  37. assert hasattr(rigid_body, 'frame')
  38. assert hasattr(rigid_body, 'inertia')
  39. def test_particle_body():
  40. # Body with Particle
  41. particle_masscenter = Point('particle_masscenter')
  42. particle_mass = Symbol('particle_mass')
  43. particle_frame = ReferenceFrame('particle_frame')
  44. particle_body = Body('particle_body', particle_masscenter, particle_mass,
  45. particle_frame)
  46. com = particle_body.masscenter
  47. frame = particle_body.frame
  48. particle_masscenter.set_vel(particle_frame, 0)
  49. assert com.vel(frame) == particle_masscenter.vel(frame)
  50. assert com.pos_from(com) == particle_masscenter.pos_from(com)
  51. assert particle_body.mass == particle_mass
  52. assert not hasattr(particle_body, "_inertia")
  53. assert hasattr(particle_body, 'frame')
  54. assert hasattr(particle_body, 'masscenter')
  55. assert hasattr(particle_body, 'mass')
  56. assert not particle_body.is_rigidbody
  57. def test_particle_body_add_force():
  58. # Body with Particle
  59. particle_masscenter = Point('particle_masscenter')
  60. particle_mass = Symbol('particle_mass')
  61. particle_frame = ReferenceFrame('particle_frame')
  62. particle_body = Body('particle_body', particle_masscenter, particle_mass,
  63. particle_frame)
  64. a = Symbol('a')
  65. force_vector = a * particle_body.frame.x
  66. particle_body.apply_force(force_vector, particle_body.masscenter)
  67. assert len(particle_body.loads) == 1
  68. point = particle_body.masscenter.locatenew(
  69. particle_body._name + '_point0', 0)
  70. point.set_vel(particle_body.frame, 0)
  71. force_point = particle_body.loads[0][0]
  72. frame = particle_body.frame
  73. assert force_point.vel(frame) == point.vel(frame)
  74. assert force_point.pos_from(force_point) == point.pos_from(force_point)
  75. assert particle_body.loads[0][1] == force_vector
  76. def test_body_add_force():
  77. # Body with RigidBody.
  78. rigidbody_masscenter = Point('rigidbody_masscenter')
  79. rigidbody_mass = Symbol('rigidbody_mass')
  80. rigidbody_frame = ReferenceFrame('rigidbody_frame')
  81. body_inertia = inertia(rigidbody_frame, 1, 0, 0)
  82. rigid_body = Body('rigidbody_body', rigidbody_masscenter, rigidbody_mass,
  83. rigidbody_frame, body_inertia)
  84. l = Symbol('l')
  85. Fa = Symbol('Fa')
  86. point = rigid_body.masscenter.locatenew(
  87. 'rigidbody_body_point0',
  88. l * rigid_body.frame.x)
  89. point.set_vel(rigid_body.frame, 0)
  90. force_vector = Fa * rigid_body.frame.z
  91. # apply_force with point
  92. rigid_body.apply_force(force_vector, point)
  93. assert len(rigid_body.loads) == 1
  94. force_point = rigid_body.loads[0][0]
  95. frame = rigid_body.frame
  96. assert force_point.vel(frame) == point.vel(frame)
  97. assert force_point.pos_from(force_point) == point.pos_from(force_point)
  98. assert rigid_body.loads[0][1] == force_vector
  99. # apply_force without point
  100. rigid_body.apply_force(force_vector)
  101. assert len(rigid_body.loads) == 2
  102. assert rigid_body.loads[1][1] == force_vector
  103. # passing something else than point
  104. raises(TypeError, lambda: rigid_body.apply_force(force_vector, 0))
  105. raises(TypeError, lambda: rigid_body.apply_force(0))
  106. def test_body_add_torque():
  107. body = Body('body')
  108. torque_vector = body.frame.x
  109. body.apply_torque(torque_vector)
  110. assert len(body.loads) == 1
  111. assert body.loads[0] == (body.frame, torque_vector)
  112. raises(TypeError, lambda: body.apply_torque(0))
  113. def test_body_masscenter_vel():
  114. A = Body('A')
  115. N = ReferenceFrame('N')
  116. B = Body('B', frame=N)
  117. A.masscenter.set_vel(N, N.z)
  118. assert A.masscenter_vel(B) == N.z
  119. assert A.masscenter_vel(N) == N.z
  120. def test_body_ang_vel():
  121. A = Body('A')
  122. N = ReferenceFrame('N')
  123. B = Body('B', frame=N)
  124. A.frame.set_ang_vel(N, N.y)
  125. assert A.ang_vel_in(B) == N.y
  126. assert B.ang_vel_in(A) == -N.y
  127. assert A.ang_vel_in(N) == N.y
  128. def test_body_dcm():
  129. A = Body('A')
  130. B = Body('B')
  131. A.frame.orient_axis(B.frame, B.frame.z, 10)
  132. assert A.dcm(B) == Matrix([[cos(10), sin(10), 0], [-sin(10), cos(10), 0], [0, 0, 1]])
  133. assert A.dcm(B.frame) == Matrix([[cos(10), sin(10), 0], [-sin(10), cos(10), 0], [0, 0, 1]])
  134. def test_body_axis():
  135. N = ReferenceFrame('N')
  136. B = Body('B', frame=N)
  137. assert B.x == N.x
  138. assert B.y == N.y
  139. assert B.z == N.z
  140. def test_apply_force_multiple_one_point():
  141. a, b = symbols('a b')
  142. P = Point('P')
  143. B = Body('B')
  144. f1 = a*B.x
  145. f2 = b*B.y
  146. B.apply_force(f1, P)
  147. assert B.loads == [(P, f1)]
  148. B.apply_force(f2, P)
  149. assert B.loads == [(P, f1+f2)]
  150. def test_apply_force():
  151. f, g = symbols('f g')
  152. q, x, v1, v2 = dynamicsymbols('q x v1 v2')
  153. P1 = Point('P1')
  154. P2 = Point('P2')
  155. B1 = Body('B1')
  156. B2 = Body('B2')
  157. N = ReferenceFrame('N')
  158. P1.set_vel(B1.frame, v1*B1.x)
  159. P2.set_vel(B2.frame, v2*B2.x)
  160. force = f*q*N.z # time varying force
  161. B1.apply_force(force, P1, B2, P2) #applying equal and opposite force on moving points
  162. assert B1.loads == [(P1, force)]
  163. assert B2.loads == [(P2, -force)]
  164. g1 = B1.mass*g*N.y
  165. g2 = B2.mass*g*N.y
  166. B1.apply_force(g1) #applying gravity on B1 masscenter
  167. B2.apply_force(g2) #applying gravity on B2 masscenter
  168. assert B1.loads == [(P1,force), (B1.masscenter, g1)]
  169. assert B2.loads == [(P2, -force), (B2.masscenter, g2)]
  170. force2 = x*N.x
  171. B1.apply_force(force2, reaction_body=B2) #Applying time varying force on masscenter
  172. assert B1.loads == [(P1, force), (B1.masscenter, force2+g1)]
  173. assert B2.loads == [(P2, -force), (B2.masscenter, -force2+g2)]
  174. def test_apply_torque():
  175. t = symbols('t')
  176. q = dynamicsymbols('q')
  177. B1 = Body('B1')
  178. B2 = Body('B2')
  179. N = ReferenceFrame('N')
  180. torque = t*q*N.x
  181. B1.apply_torque(torque, B2) #Applying equal and opposite torque
  182. assert B1.loads == [(B1.frame, torque)]
  183. assert B2.loads == [(B2.frame, -torque)]
  184. torque2 = t*N.y
  185. B1.apply_torque(torque2)
  186. assert B1.loads == [(B1.frame, torque+torque2)]
  187. def test_clear_load():
  188. a = symbols('a')
  189. P = Point('P')
  190. B = Body('B')
  191. force = a*B.z
  192. B.apply_force(force, P)
  193. assert B.loads == [(P, force)]
  194. B.clear_loads()
  195. assert B.loads == []
  196. def test_remove_load():
  197. P1 = Point('P1')
  198. P2 = Point('P2')
  199. B = Body('B')
  200. f1 = B.x
  201. f2 = B.y
  202. B.apply_force(f1, P1)
  203. B.apply_force(f2, P2)
  204. assert B.loads == [(P1, f1), (P2, f2)]
  205. B.remove_load(P2)
  206. assert B.loads == [(P1, f1)]
  207. B.apply_torque(f1.cross(f2))
  208. assert B.loads == [(P1, f1), (B.frame, f1.cross(f2))]
  209. B.remove_load()
  210. assert B.loads == [(P1, f1)]
  211. def test_apply_loads_on_multi_degree_freedom_holonomic_system():
  212. """Example based on: https://pydy.readthedocs.io/en/latest/examples/multidof-holonomic.html"""
  213. W = Body('W') #Wall
  214. B = Body('B') #Block
  215. P = Body('P') #Pendulum
  216. b = Body('b') #bob
  217. q1, q2 = dynamicsymbols('q1 q2') #generalized coordinates
  218. k, c, g, kT = symbols('k c g kT') #constants
  219. F, T = dynamicsymbols('F T') #Specified forces
  220. #Applying forces
  221. B.apply_force(F*W.x)
  222. W.apply_force(k*q1*W.x, reaction_body=B) #Spring force
  223. W.apply_force(c*q1.diff()*W.x, reaction_body=B) #dampner
  224. P.apply_force(P.mass*g*W.y)
  225. b.apply_force(b.mass*g*W.y)
  226. #Applying torques
  227. P.apply_torque(kT*q2*W.z, reaction_body=b)
  228. P.apply_torque(T*W.z)
  229. assert B.loads == [(B.masscenter, (F - k*q1 - c*q1.diff())*W.x)]
  230. assert P.loads == [(P.masscenter, P.mass*g*W.y), (P.frame, (T + kT*q2)*W.z)]
  231. assert b.loads == [(b.masscenter, b.mass*g*W.y), (b.frame, -kT*q2*W.z)]
  232. assert W.loads == [(W.masscenter, (c*q1.diff() + k*q1)*W.x)]