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

115 lines
4.6 KiB

  1. from sympy.core.backend import (cos, sin, Matrix, symbols)
  2. from sympy.physics.mechanics import (dynamicsymbols, ReferenceFrame, Point,
  3. KanesMethod, Particle)
  4. def test_replace_qdots_in_force():
  5. # Test PR 16700 "Replaces qdots with us in force-list in kanes.py"
  6. # The new functionality allows one to specify forces in qdots which will
  7. # automatically be replaced with u:s which are defined by the kde supplied
  8. # to KanesMethod. The test case is the double pendulum with interacting
  9. # forces in the example of chapter 4.7 "CONTRIBUTING INTERACTION FORCES"
  10. # in Ref. [1]. Reference list at end test function.
  11. q1, q2 = dynamicsymbols('q1, q2')
  12. qd1, qd2 = dynamicsymbols('q1, q2', level=1)
  13. u1, u2 = dynamicsymbols('u1, u2')
  14. l, m = symbols('l, m')
  15. N = ReferenceFrame('N') # Inertial frame
  16. A = N.orientnew('A', 'Axis', (q1, N.z)) # Rod A frame
  17. B = A.orientnew('B', 'Axis', (q2, N.z)) # Rod B frame
  18. O = Point('O') # Origo
  19. O.set_vel(N, 0)
  20. P = O.locatenew('P', ( l * A.x )) # Point @ end of rod A
  21. P.v2pt_theory(O, N, A)
  22. Q = P.locatenew('Q', ( l * B.x )) # Point @ end of rod B
  23. Q.v2pt_theory(P, N, B)
  24. Ap = Particle('Ap', P, m)
  25. Bp = Particle('Bp', Q, m)
  26. # The forces are specified below. sigma is the torsional spring stiffness
  27. # and delta is the viscous damping coefficient acting between the two
  28. # bodies. Here, we specify the viscous damper as function of qdots prior
  29. # forming the kde. In more complex systems it not might be obvious which
  30. # kde is most efficient, why it is convenient to specify viscous forces in
  31. # qdots independently of the kde.
  32. sig, delta = symbols('sigma, delta')
  33. Ta = (sig * q2 + delta * qd2) * N.z
  34. forces = [(A, Ta), (B, -Ta)]
  35. # Try different kdes.
  36. kde1 = [u1 - qd1, u2 - qd2]
  37. kde2 = [u1 - qd1, u2 - (qd1 + qd2)]
  38. KM1 = KanesMethod(N, [q1, q2], [u1, u2], kd_eqs=kde1)
  39. fr1, fstar1 = KM1.kanes_equations([Ap, Bp], forces)
  40. KM2 = KanesMethod(N, [q1, q2], [u1, u2], kd_eqs=kde2)
  41. fr2, fstar2 = KM2.kanes_equations([Ap, Bp], forces)
  42. # Check EOM for KM2:
  43. # Mass and force matrix from p.6 in Ref. [2] with added forces from
  44. # example of chapter 4.7 in [1] and without gravity.
  45. forcing_matrix_expected = Matrix( [ [ m * l**2 * sin(q2) * u2**2 + sig * q2
  46. + delta * (u2 - u1)],
  47. [ m * l**2 * sin(q2) * -u1**2 - sig * q2
  48. - delta * (u2 - u1)] ] )
  49. mass_matrix_expected = Matrix( [ [ 2 * m * l**2, m * l**2 * cos(q2) ],
  50. [ m * l**2 * cos(q2), m * l**2 ] ] )
  51. assert (KM2.mass_matrix.expand() == mass_matrix_expected.expand())
  52. assert (KM2.forcing.expand() == forcing_matrix_expected.expand())
  53. # Check fr1 with reference fr_expected from [1] with u:s instead of qdots.
  54. fr1_expected = Matrix([ 0, -(sig*q2 + delta * u2) ])
  55. assert fr1.expand() == fr1_expected.expand()
  56. # Check fr2
  57. fr2_expected = Matrix([sig * q2 + delta * (u2 - u1),
  58. - sig * q2 - delta * (u2 - u1)])
  59. assert fr2.expand() == fr2_expected.expand()
  60. # Specifying forces in u:s should stay the same:
  61. Ta = (sig * q2 + delta * u2) * N.z
  62. forces = [(A, Ta), (B, -Ta)]
  63. KM1 = KanesMethod(N, [q1, q2], [u1, u2], kd_eqs=kde1)
  64. fr1, fstar1 = KM1.kanes_equations([Ap, Bp], forces)
  65. assert fr1.expand() == fr1_expected.expand()
  66. Ta = (sig * q2 + delta * (u2-u1)) * N.z
  67. forces = [(A, Ta), (B, -Ta)]
  68. KM2 = KanesMethod(N, [q1, q2], [u1, u2], kd_eqs=kde2)
  69. fr2, fstar2 = KM2.kanes_equations([Ap, Bp], forces)
  70. assert fr2.expand() == fr2_expected.expand()
  71. # Test if we have a qubic qdot force:
  72. Ta = (sig * q2 + delta * qd2**3) * N.z
  73. forces = [(A, Ta), (B, -Ta)]
  74. KM1 = KanesMethod(N, [q1, q2], [u1, u2], kd_eqs=kde1)
  75. fr1, fstar1 = KM1.kanes_equations([Ap, Bp], forces)
  76. fr1_cubic_expected = Matrix([ 0, -(sig*q2 + delta * u2**3) ])
  77. assert fr1.expand() == fr1_cubic_expected.expand()
  78. KM2 = KanesMethod(N, [q1, q2], [u1, u2], kd_eqs=kde2)
  79. fr2, fstar2 = KM2.kanes_equations([Ap, Bp], forces)
  80. fr2_cubic_expected = Matrix([sig * q2 + delta * (u2 - u1)**3,
  81. - sig * q2 - delta * (u2 - u1)**3])
  82. assert fr2.expand() == fr2_cubic_expected.expand()
  83. # References:
  84. # [1] T.R. Kane, D. a Levinson, Dynamics Theory and Applications, 2005.
  85. # [2] Arun K Banerjee, Flexible Multibody Dynamics:Efficient Formulations
  86. # and Applications, John Wiley and Sons, Ltd, 2016.
  87. # doi:http://dx.doi.org/10.1002/9781119015635.