
    MZdR!                     X    d dl mZmZmZmZmZmZ d dlmZ d dl	m
Z
 dgZ G d de      Zy)    )Body
LagrangianKanesMethodLagrangesMethod	RigidBodyParticle)_Methods)MatrixJointsMethodc                       e Zd ZdZd Zed        Zed        Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zd Zd Zd Zd Zd Zd ZefdZddZy)r   a%  Method for formulating the equations of motion using a set of interconnected bodies with joints.

    Parameters
    ==========

    newtonion : Body or ReferenceFrame
        The newtonion(inertial) frame.
    *joints : Joint
        The joints in the system

    Attributes
    ==========

    q, u : iterable
        Iterable of the generalized coordinates and speeds
    bodies : iterable
        Iterable of Body objects in the system.
    loads : iterable
        Iterable of (Point, vector) or (ReferenceFrame, vector) tuples
        describing the forces on the system.
    mass_matrix : Matrix, shape(n, n)
        The system's mass matrix
    forcing : Matrix, shape(n, 1)
        The system's forcing vector
    mass_matrix_full : Matrix, shape(2*n, 2*n)
        The "mass matrix" for the u's and q's
    forcing_full : Matrix, shape(2*n, 1)
        The "forcing vector" for the u's and q's
    method : KanesMethod or Lagrange's method
        Method's object.
    kdes : iterable
        Iterable of kde in they system.

    Examples
    ========

    This is a simple example for a one degree of freedom translational
    spring-mass-damper.

    >>> from sympy import symbols
    >>> from sympy.physics.mechanics import Body, JointsMethod, PrismaticJoint
    >>> from sympy.physics.vector import dynamicsymbols
    >>> c, k = symbols('c k')
    >>> x, v = dynamicsymbols('x v')
    >>> wall = Body('W')
    >>> body = Body('B')
    >>> J = PrismaticJoint('J', wall, body, coordinates=x, speeds=v)
    >>> wall.apply_force(c*v*wall.x, reaction_body=body)
    >>> wall.apply_force(k*x*wall.x, reaction_body=body)
    >>> method = JointsMethod(wall, J)
    >>> method.form_eoms()
    Matrix([[-B_mass*Derivative(v(t), t) - c*v(t) - k*x(t)]])
    >>> M = method.mass_matrix_full
    >>> F = method.forcing_full
    >>> rhs = M.LUsolve(F)
    >>> rhs
    Matrix([
    [                     v(t)],
    [(-c*v(t) - k*x(t))/B_mass]])

    Notes
    =====

    ``JointsMethod`` currently only works with systems that do not have any
    configuration or motion constraints.

    c                 D   t        |t              r|j                  | _        n|| _        || _        | j	                         | _        | j                         | _        | j                         | _	        | j                         | _        | j                         | _        d | _        y N)
isinstancer   frame_joints_generate_bodylist_bodies_generate_loadlist_loads_generate_q_q_generate_u_u_generate_kdes_kdes_method)self	newtonionjointss      F/usr/lib/python3/dist-packages/sympy/physics/mechanics/jointsmethod.py__init__zJointsMethod.__init__N   s|    i&"DJ"DJ..0--/""$""$((*
    c                     | j                   S )zList of bodies in they system.)r   r   s    r    bodieszJointsMethod.bodies]        ||r"   c                     | j                   S )zList of loads on the system.)r   r$   s    r    loadszJointsMethod.loadsb   s     {{r"   c                     | j                   S z$List of the generalized coordinates.)r   r$   s    r    qzJointsMethod.qg        wwr"   c                     | j                   S )zList of the generalized speeds.)r   r$   s    r    uzJointsMethod.ul   r,   r"   c                     | j                   S r*   )r   r$   s    r    kdeszJointsMethod.kdesq   s     zzr"   c                 .    | j                   j                  S )z)The "forcing vector" for the u's and q's.)methodforcing_fullr$   s    r    r3   zJointsMethod.forcing_fullv   s     {{'''r"   c                 .    | j                   j                  S )z&The "mass matrix" for the u's and q's.)r2   mass_matrix_fullr$   s    r    r5   zJointsMethod.mass_matrix_full{   s     {{+++r"   c                 .    | j                   j                  S )zThe system's mass matrix.)r2   mass_matrixr$   s    r    r7   zJointsMethod.mass_matrix   s     {{&&&r"   c                 .    | j                   j                  S )zThe system's forcing vector.)r2   forcingr$   s    r    r9   zJointsMethod.forcing   s     {{"""r"   c                     | j                   S )z3Object of method used to form equations of systems.)r   r$   s    r    r2   zJointsMethod.method   r&   r"   c                     g }| j                   D ]U  }|j                  |vr|j                  |j                         |j                  |vs;|j                  |j                         W |S r   )r   childappendparent)r   r%   joints      r    r   zJointsMethod._generate_bodylist   sY    \\ 	,E{{&(ekk*||6)ell+		,
 r"   c                 b    g }| j                   D ]  }|j                  |j                          |S r   )r%   extendr(   )r   	load_listbodys      r    r   zJointsMethod._generate_loadlist   s2    	KK 	)DTZZ(	)r"   c                     g }| j                   D ]3  }|j                  D ]"  }||v rt        d      |j                  |       $ 5 t	        |      S )Nz'Coordinates of joints should be unique.)r   coordinates
ValueErrorr=   r
   )r   q_indr?   
coordinates       r    r   zJointsMethod._generate_q   s[    \\ 	)E#// )
&$%NOOZ()	)
 e}r"   c                     g }| j                   D ]3  }|j                  D ]"  }||v rt        d      |j                  |       $ 5 t	        |      S )Nz"Speeds of joints should be unique.)r   speedsrF   r=   r
   )r   u_indr?   speeds       r    r   zJointsMethod._generate_u   sX    \\ 	$E $E>$%IJJU#$	$
 e}r"   c                     t        ddg       j                  }| j                  D ]  }|j                  |j                        } |S )N   r   )r
   Tr   col_joinr0   )r   kd_indr?   s      r    r   zJointsMethod._generate_kdes   s@    1b!##\\ 	1E__UZZ0F	1r"   c           	         g }| j                   D ]  }|j                  rpt        |j                  |j                  |j
                  |j                  |j                  |j                  f      }|j                  |_        |j                  |       t        |j                  |j                  |j                        }|j                  |_        |j                  |        |S r   )r%   is_rigidbodyr   name
masscenterr   masscentral_inertiapotential_energyr=   r   )r   bodylistrC   rbparts        r    _convert_bodieszJointsMethod._convert_bodies   s    KK 		&D  tyy$//4::tyy))4??;=&*&;&;##		4??DIIF(,(=(=%%		& r"   c                    | j                         }t        |t              rFt        | j                  g| } ||| j
                  | j                  || j                        | _        nE || j                  | j
                  | j                  | j                  | j                  |      | _        | j                  j                         }|S )a7  Method to form system's equation of motions.

        Parameters
        ==========

        method : Class
            Class name of method.

        Returns
        ========

        Matrix
            Vector of equations of motions.

        Examples
        ========

        This is a simple example for a one degree of freedom translational
        spring-mass-damper.

        >>> from sympy import S, symbols
        >>> from sympy.physics.mechanics import LagrangesMethod, dynamicsymbols, Body
        >>> from sympy.physics.mechanics import PrismaticJoint, JointsMethod
        >>> q = dynamicsymbols('q')
        >>> qd = dynamicsymbols('q', 1)
        >>> m, k, b = symbols('m k b')
        >>> wall = Body('W')
        >>> part = Body('P', mass=m)
        >>> part.potential_energy = k * q**2 / S(2)
        >>> J = PrismaticJoint('J', wall, part, coordinates=q, speeds=qd)
        >>> wall.apply_force(b * qd * wall.x, reaction_body=part)
        >>> method = JointsMethod(wall, J)
        >>> method.form_eoms(LagrangesMethod)
        Matrix([[b*Derivative(q(t), t) + k*q(t) + m*Derivative(q(t), (t, 2))]])

        We can also solve for the states using the 'rhs' method.

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

        )rG   rK   kd_eqs	forcelistr%   )r\   
issubclassr   r   r   r+   r(   r   r.   r0   r2   
_form_eoms)r   r2   rY   Lsolns        r    	form_eomszJointsMethod.form_eoms   s    Z '')fo.4::11A!!TVVTZZ4::NDL!$**DFF$&&QUQZQZ.2jjKDL{{%%'r"   Nc                 :    | j                   j                  |      S )ax  Returns equations that can be solved numerically.

        Parameters
        ==========

        inv_method : str
            The specific sympy inverse matrix calculation method to use. For a
            list of valid methods, see
            :meth:`~sympy.matrices.matrices.MatrixBase.inv`

        Returns
        ========

        Matrix
            Numerically solvable equations.

        See Also
        ========

        sympy.physics.mechanics.kane.KanesMethod.rhs:
            KanesMethod's rhs function.
        sympy.physics.mechanics.lagrange.LagrangesMethod.rhs:
            LagrangesMethod's rhs function.

        )
inv_method)r2   rhs)r   rf   s     r    rg   zJointsMethod.rhs   s    6 {{*55r"   r   )__name__
__module____qualname____doc__r!   propertyr%   r(   r+   r.   r0   r3   r5   r7   r9   r2   r   r   r   r   r   r\   r   rd   rg    r"   r    r   r   	   s   BH           ( ( , , ' ' # #    + 5n6r"   N)sympy.physics.mechanicsr   r   r   r   r   r   sympy.physics.mechanics.methodr	   sympy.core.backendr
   __all__r   rm   r"   r    <module>rr      s+   9 9 3 %
N68 N6r"   