o
    oh3                     @   s   d dl mZmZmZmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZ d dl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
 d
eZdS )    )zerosMatrixdiffeye)default_sort_key)ReferenceFramedynamicsymbolspartial_velocity)_Methods)Particle)	RigidBody)msubsfind_dynamicsymbols_f_list_parser_validate_coordinates_parse_linear_solver)
Linearizer)iterableKanesMethodc                   @   s,  e Zd ZdZ						d8ddZdd Zd9d	d
Zd9ddZdd Zdd Z	d9ddZ
dddddZd:ddZdd Zd;ddZdd Zedd Zed d! Zed"d# Zed$d% Zed&d' Zed(d) Zed*d+ Zed,d- Zed.d/ Zed0d1 Zed2d3 Zed4d5 Zed6d7 ZdS )<r   a"  Kane's method object.

    Explanation
    ===========

    This object is used to do the "book-keeping" as you go through and form
    equations of motion in the way Kane presents in:
    Kane, T., Levinson, D. Dynamics Theory and Applications. 1985 McGraw-Hill

    The attributes are for equations in the form [M] udot = forcing.

    Attributes
    ==========

    q, u : Matrix
        Matrices of the generalized coordinates and speeds
    bodies : iterable
        Iterable of Particle and RigidBody objects in the system.
    loads : iterable
        Iterable of (Point, vector) or (ReferenceFrame, vector) tuples
        describing the forces on the system.
    auxiliary_eqs : Matrix
        If applicable, the set of auxiliary Kane's
        equations used to solve for non-contributing
        forces.
    mass_matrix : Matrix
        The system's dynamics mass matrix: [k_d; k_dnh]
    forcing : Matrix
        The system's dynamics forcing vector: -[f_d; f_dnh]
    mass_matrix_kin : Matrix
        The "mass matrix" for kinematic differential equations: k_kqdot
    forcing_kin : Matrix
        The forcing vector for kinematic differential equations: -(k_ku*u + f_k)
    mass_matrix_full : Matrix
        The "mass matrix" for the u's and q's with dynamics and kinematics
    forcing_full : Matrix
        The "forcing vector" for the u's and q's with dynamics and kinematics

    Parameters
    ==========

    frame : ReferenceFrame
        The inertial reference frame for the system.
    q_ind : iterable of dynamicsymbols
        Independent generalized coordinates.
    u_ind : iterable of dynamicsymbols
        Independent generalized speeds.
    kd_eqs : iterable of Expr, optional
        Kinematic differential equations, which linearly relate the generalized
        speeds to the time-derivatives of the generalized coordinates.
    q_dependent : iterable of dynamicsymbols, optional
        Dependent generalized coordinates.
    configuration_constraints : iterable of Expr, optional
        Constraints on the system's configuration, i.e. holonomic constraints.
    u_dependent : iterable of dynamicsymbols, optional
        Dependent generalized speeds.
    velocity_constraints : iterable of Expr, optional
        Constraints on the system's velocity, i.e. the combination of the
        nonholonomic constraints and the time-derivative of the holonomic
        constraints.
    acceleration_constraints : iterable of Expr, optional
        Constraints on the system's acceleration, by default these are the
        time-derivative of the velocity constraints.
    u_auxiliary : iterable of dynamicsymbols, optional
        Auxiliary generalized speeds.
    bodies : iterable of Particle and/or RigidBody, optional
        The particles and rigid bodies in the system.
    forcelist : iterable of tuple[Point | ReferenceFrame, Vector], optional
        Forces and torques applied on the system.
    explicit_kinematics : bool
        Boolean whether the mass matrices and forcing vectors should use the
        explicit form (default) or implicit form for kinematics.
        See the notes for more details.
    kd_eqs_solver : str, callable
        Method used to solve the kinematic differential equations. If a string
        is supplied, it should be a valid method that can be used with the
        :meth:`sympy.matrices.matrixbase.MatrixBase.solve`. If a callable is
        supplied, it should have the format ``f(A, rhs)``, where it solves the
        equations and returns the solution. The default utilizes LU solve. See
        the notes for more information.
    constraint_solver : str, callable
        Method used to solve the velocity constraints. If a string is
        supplied, it should be a valid method that can be used with the
        :meth:`sympy.matrices.matrixbase.MatrixBase.solve`. If a callable is
        supplied, it should have the format ``f(A, rhs)``, where it solves the
        equations and returns the solution. The default utilizes LU solve. See
        the notes for more information.

    Notes
    =====

    The mass matrices and forcing vectors related to kinematic equations
    are given in the explicit form by default. In other words, the kinematic
    mass matrix is $\mathbf{k_{k\dot{q}}} = \mathbf{I}$.
    In order to get the implicit form of those matrices/vectors, you can set the
    ``explicit_kinematics`` attribute to ``False``. So $\mathbf{k_{k\dot{q}}}$
    is not necessarily an identity matrix. This can provide more compact
    equations for non-simple kinematics.

    Two linear solvers can be supplied to ``KanesMethod``: one for solving the
    kinematic differential equations and one to solve the velocity constraints.
    Both of these sets of equations can be expressed as a linear system ``Ax = rhs``,
    which have to be solved in order to obtain the equations of motion.

    The default solver ``'LU'``, which stands for LU solve, results relatively low
    number of operations. The weakness of this method is that it can result in zero
    division errors.

    If zero divisions are encountered, a possible solver which may solve the problem
    is ``"CRAMER"``. This method uses Cramer's rule to solve the system. This method
    is slower and results in more operations than the default solver. However it only
    uses a single division by default per entry of the solution.

    While a valid list of solvers can be found at
    :meth:`sympy.matrices.matrixbase.MatrixBase.solve`, it is also possible to supply a
    `callable`. This way it is possible to use a different solver routine. If the
    kinematic differential equations are not too complex it can be worth it to simplify
    the solution by using ``lambda A, b: simplify(Matrix.LUsolve(A, b))``. Another
    option solver one may use is :func:`sympy.solvers.solveset.linsolve`. This can be
    done using `lambda A, b: tuple(linsolve((A, b)))[0]`, where we select the first
    solution as our system should have only one unique solution.

    Examples
    ========

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

    In this example, we first need to do the kinematics.
    This involves creating generalized speeds and coordinates and their
    derivatives.
    Then we create a point and set its velocity in a frame.

        >>> from sympy import symbols
        >>> from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame
        >>> from sympy.physics.mechanics import Point, Particle, KanesMethod
        >>> q, u = dynamicsymbols('q u')
        >>> qd, ud = dynamicsymbols('q u', 1)
        >>> m, c, k = symbols('m c k')
        >>> N = ReferenceFrame('N')
        >>> P = Point('P')
        >>> P.set_vel(N, u * N.x)

    Next we need to arrange/store information in the way that KanesMethod
    requires. The kinematic differential equations should be an iterable of
    expressions. A list of forces/torques must be constructed, where each entry
    in the list is a (Point, Vector) or (ReferenceFrame, Vector) tuple, where
    the Vectors represent the Force or Torque.
    Next a particle needs to be created, and it needs to have a point and mass
    assigned to it.
    Finally, a list of all bodies and particles needs to be created.

        >>> kd = [qd - u]
        >>> FL = [(P, (-k * q - c * u) * N.x)]
        >>> pa = Particle('pa', P, m)
        >>> BL = [pa]

    Finally we can generate the equations of motion.
    First we create the KanesMethod object and supply an inertial frame,
    coordinates, generalized speeds, and the kinematic differential equations.
    Additional quantities such as configuration and motion constraints,
    dependent coordinates and speeds, and auxiliary speeds are also supplied
    here (see the online documentation).
    Next we form FR* and FR to complete: Fr + Fr* = 0.
    We have the equations of motion at this point.
    It makes sense to rearrange them though, so we calculate the mass matrix and
    the forcing terms, for E.o.M. in the form: [MM] udot = forcing, where MM is
    the mass matrix, udot is a vector of the time derivatives of the
    generalized speeds, and forcing is a vector representing "forcing" terms.

        >>> KM = KanesMethod(N, q_ind=[q], u_ind=[u], kd_eqs=kd)
        >>> (fr, frstar) = KM.kanes_equations(BL, FL)
        >>> MM = KM.mass_matrix
        >>> forcing = KM.forcing
        >>> rhs = MM.inv() * forcing
        >>> rhs
        Matrix([[(-c*u(t) - k*q(t))/m]])
        >>> KM.linearize(A_and_B=True)[0]
        Matrix([
        [   0,    1],
        [-k/m, -c/m]])

    Please look at the documentation pages for more information on how to
    perform linearization and how to deal with dependent coordinates & speeds,
    and how do deal with bringing non-contributing forces into evidence.

    NTLUc                 C   s   |st dg}t dg}t|tstd|| _d| _d| _|| _|| _|| _	|| _
| |||||
 t| j| j | || | |||	| dS )z&Please read the online documentation. dummy_qdummy_kdz+An inertial ReferenceFrame must be suppliedN)r   
isinstancer   	TypeError	_inertial_fr_frstar
_forcelist	_bodylistexplicit_kinematics_constraint_solver_initialize_vectorsr   qu_initialize_kindiffeq_matrices_initialize_constraint_matrices)selfframeq_indu_indkd_eqsq_dependentconfiguration_constraintsu_dependentvelocity_constraintsacceleration_constraintsu_auxiliarybodies	forcelistr   kd_eqs_solverconstraint_solver r5   p/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/physics/mechanics/kane.py__init__   s*   


zKanesMethod.__init__c                 C   s   dd }||}t |stdt |stdt|}|| _t||g| _| jtj| _	||}t |s:tdt |sBtdt|}|| _
t||g| _| jtj| _||| _dS )z,Initialize the coordinate and speed vectors.c                 S      | rt | S t  S Nr   xr5   r5   r6   <lambda>       z1KanesMethod._initialize_vectors.<locals>.<lambda>z,Generalized coordinates must be an iterable.z*Dependent coordinates must be an iterable.z'Generalized speeds must be an iterable.z%Dependent speeds must be an iterable.N)r   r   r   _qdep_qr"   r   r   _t_qdot_udep_ur#   _udot_uaux)r&   r(   q_depr)   u_depu_auxnone_handlerr5   r5   r6   r!      s(   zKanesMethod._initialize_vectorsc                 C   s  t |}t| j}t| j}|| }dd }||}t| jt|kr'td||| _||}||}t||kr>td|rJt||krJtd|rt| jd}	t| j	d}
| j
duret|| j
}t||	| _|| j | j| _|s| jtj| j | jtj }| j
durt|| j
}|| _| j| _n| j
durt|| j
}t||
| _|| j | j	| _| jddd|f }| jdd||f }||| | _dS t | _t | _t | _t | _t | _dS )z Initializes constraint matrices.c                 S   r8   r9   r:   r;   r5   r5   r6   r=     r>   z=KanesMethod._initialize_constraint_matrices.<locals>.<lambda>zUThere must be an equal number of dependent coordinates and configuration constraints.zKThere must be an equal number of dependent speeds and velocity constraints.zOThere must be an equal number of dependent speeds and acceleration constraints.r   N)r   lenr#   rC   r?   
ValueError_f_hdictfromkeysrE   _qdot_u_mapr   _f_nhjacobian_k_nhr   r   rA   _f_dnh_k_dnh_Arsr   )r&   configvelacclinear_solveromprJ   u_zero	udot_zerorT   B_indB_depr5   r5   r6   r%     sT   






z+KanesMethod._initialize_constraint_matricesc                    s~  t |}|rt| jt|krtd| j}| j}t|}t|d}t| j	d}t|d}|
|}|
|}	|||}
t||	|
  fdd|dd |dd  D }|rjd}t|||
|| _||| _|	| _||	|
}||	|}tt||| |  | _||| _||| _tt|| _dS d| _t  | _| _t  | _| _t  | _| _dS )a]  Initialize the kinematic differential equation matrices.

        Parameters
        ==========
        kdeqs : sequence of sympy expressions
            Kinematic differential equations in the form of f(u,q',q,t) where
            f() = 0. The equations have to be linear in the generalized
            coordinates and generalized speeds.

        zRThere must be an equal number of kinematic differential equations and coordinates.r   c                    s   g | ]}| v r|qS r5   r5   ).0varidy_symsr5   r6   
<listcomp>t      z>KanesMethod._initialize_kindiffeq_matrices.<locals>.<listcomp>NzThe provided kinematic differential equations are nonlinear in {}. They must be linear in the generalized speeds and derivatives of the generalized coordinates.)r   rK   r"   rL   r#   rB   r   rN   rO   rF   rR   xreplacer   row_joinformat_f_k_implicit_k_ku_implicit_k_kqdot_implicitziprP   _f_k_k_kur   _k_kqdot)r&   kdeqsrZ   r#   qdotr^   	uaux_zero	qdot_zerok_kuk_kqdotf_knonlin_varsmsgf_k_explicitk_ku_explicitr5   rd   r6   r$   N  s>   

&


z*KanesMethod._initialize_kindiffeq_matricesc           
         s  |durt |dkst|stdj}t||\} fdd|D }fdd D  t j}t  }t|d}t|j|t|D ]t	 fdd	t|D |< qGj
r|t j
 }|d|df }|||df }	|jj|	 7 }|}|_|_|S )
z"Form the generalized active force.Nr   z>Force pairs must be supplied in an non-empty iterable or None.c                       g | ]}t | jqS r5   r   rP   rb   ir&   r5   r6   rf     rg   z(KanesMethod._form_fr.<locals>.<listcomp>c                    r}   r5   r~   r   r   r5   r6   rf     rg      c                 3   s&    | ]}|    | V  qd S r9   )dot)rb   j)f_listr   partialsr5   r6   	<genexpr>  s   $ z'KanesMethod._form_fr.<locals>.<genexpr>)rK   r   rL   r   r   r#   r   r	   rangesumrC   rV   Tr   r   )
r&   flNvel_listr[   bFRr]   FRtildeFRoldr5   )r   r   r   r&   r6   _form_fr  s*   

$zKanesMethod._form_frc                    s<  t |stdtjj tjdtjdfddjD }t|d}fddj	
 D }|j	  fddfd	d|D }tj}t||}t|d
}fdd}	fdd}
t|D ]&\}}t|tr6|	|j}|	|j}|	|j }|	|j }|
|j }|| ||  }|	||j|t||j  ||| }t|D ]j}|	|| d | }|	||| d
 | }t|D ]*}|||f  |||| d |  7  < |||f  ||| d
 | 7  < q||  ||| d | 7  < ||  ||| d
 | 7  < qqo|	|j}|	|j  }|
|j  }|| ||  }t|D ];}|	|| d | }t|D ]}|||f  |||| d |  7  < qj||  ||| d | 7  < qZqo|	t||}tt|||}|tt!j| |  }j"r|tj" }|d|df }|||df }|j#j$|  }|d|ddf }|||ddf }|j#j$|  }|d|ddf j#j$|||ddf   }|_%|_&|_'j(|  _)|S )z#Form the generalized inertia force.z'Bodies must be supplied in an iterable.r   c                    s   g | ]}t | qS r5   )r   r   )tr5   r6   rf     s    z,KanesMethod._form_frstar.<locals>.<listcomp>c                    s*   i | ]\}}| |  jqS r5   )r   rh   rP   )rb   kv)r&   r   r5   r6   
<dictcomp>  s
    z,KanesMethod._form_frstar.<locals>.<dictcomp>c                    sf   t | tr| j | j g}nt | tr| j g}ntdfdd|D }t	|j
 S )NzMThe body list may only contain either RigidBody or Particle as list elements.c                    r}   r5   r~   )rb   rX   r   r5   r6   rf     rg   zJKanesMethod._form_frstar.<locals>.get_partial_velocity.<locals>.<listcomp>)r   r   
masscenterrX   r'   
ang_vel_inr   pointr   r	   r#   )bodyvlistr   )r   r&   r5   r6   get_partial_velocity  s   

z6KanesMethod._form_frstar.<locals>.get_partial_velocityc                    s   g | ]} |qS r5   r5   )rb   r   )r   r5   r6   rf     s    r   c                    s
   t |  S r9   r   expr)rt   r5   r6   r=     s   
 z*KanesMethod._form_frstar.<locals>.<lambda>c                    s   t t |  S r9   r   r   )rt   r_   r5   r6   r=     s    N)*r   r   r   rA   r   rN   rO   rE   rF   rP   itemsupdaterK   r#   r   	enumerater   r   masscentral_inertiar   rX   r'   r   rY   r   dtr   r   
ang_acc_incrossr   r   r   rC   rV   r   r   r   _k_dr   _f_d)r&   bluauxdotuauxdot_zeroq_ddot_u_mapr   r[   MMnonMM	zero_uauxzero_udot_uauxr   r   MIrX   omegarY   inertial_forceinertial_torquer   tmp_veltmp_angr   tempfr_starr]   fr_star_indfr_star_depMMiMMdr5   )r   r   r&   r   rt   r_   r6   _form_frstar  s   





*("$
.&
0zKanesMethod._form_frstarc                    s\  | j du s
| jdu rtd| j}| jr#| jr#| j| jt| j  }nt }| jr8| j	r8| j| j	t| j
  }nt }t| jd}t| j
d}t| jd}tt| j| jgd}t| j|| jt| j  }	t| j|| jt| j  }
t| j|}t| j|| j  }tt|d}| j}| j}| jr|dt| j  }n|}| j}| jr|dt| j  }n|}| j}| j}|tj}tt||gd}tt|| j|| j
||g t fdd| j| j| j| j	| j| jfD rtdttt| j | }|j!t"d |D ]}t|tj|v rtd	q	t#|	|
||||||||||||||d
S )a  Returns an instance of the Linearizer class, initiated from the
        data in the KanesMethod class. This may be more desirable than using
        the linearize class method, as the Linearizer object will allow more
        efficient recalculation (i.e. about varying operating points).

        Parameters
        ==========
        linear_solver : str, callable
            Method used to solve the several symbolic linear systems of the
            form ``A*x=b`` in the linearization process. If a string is
            supplied, it should be a valid method that can be used with the
            :meth:`sympy.matrices.matrixbase.MatrixBase.solve`. If a callable is
            supplied, it should have the format ``x = f(A, b)``, where it
            solves the equations and returns the solution. The default is
            ``'LU'`` which corresponds to SymPy's ``A.LUsolve(b)``.
            ``LUsolve()`` is fast to compute but will often result in
            divide-by-zero and thus ``nan`` results.

        Returns
        =======
        Linearizer
            An instantiated
            :class:`sympy.physics.mechanics.linearize.Linearizer`.

        NNeed to compute Fr, Fr* first.r   r   c                 3   s    | ]}t | V  qd S r9   )r   r   sym_listr5   r6   r   e  s    z,KanesMethod.to_linearizer.<locals>.<genexpr>zWCannot have dynamicsymbols outside dynamic                              forcing vector.)keyzpCannot have derivatives of specified                                  quantities when linearizing forcing terms.rZ   )$r   r   rL   rM   rQ   rS   r   r#   rT   rU   rE   rN   rO   rB   r   ro   rq   rp   r   rK   r"   r?   rC   rF   r   r   rA   setanyr   listr   r   sortr   r   )r&   rZ   f_cf_vf_ar^   ud_zeroqd_zero	qd_u_zerof_0f_1f_2f_3f_4r"   r#   q_iq_du_iu_duauxr   rt   rr   r5   r   r6   to_linearizer  sZ   

zKanesMethod.to_linearizer)
new_methodrZ   c                K   s(   | j |d}|jdi |}||jf S )a   Linearize the equations of motion about a symbolic operating point.

        Parameters
        ==========
        new_method
            Deprecated, does nothing and will be removed.
        linear_solver : str, callable
            Method used to solve the several symbolic linear systems of the
            form ``A*x=b`` in the linearization process. If a string is
            supplied, it should be a valid method that can be used with the
            :meth:`sympy.matrices.matrixbase.MatrixBase.solve`. If a callable is
            supplied, it should have the format ``x = f(A, b)``, where it
            solves the equations and returns the solution. The default is
            ``'LU'`` which corresponds to SymPy's ``A.LUsolve(b)``.
            ``LUsolve()`` is fast to compute but will often result in
            divide-by-zero and thus ``nan`` results.
        **kwargs
            Extra keyword arguments are passed to
            :meth:`sympy.physics.mechanics.linearize.Linearizer.linearize`.

        Explanation
        ===========

        If kwarg A_and_B is False (default), returns M, A, B, r for the
        linearized form, M*[q', u']^T = A*[q_ind, u_ind]^T + B*r.

        If kwarg A_and_B is True, returns A, B, r for the linearized form
        dx = A*x + B*r, where x = [q_ind, u_ind]^T. Note that this is
        computationally intensive if there are many symbolic parameters. For
        this reason, it may be more desirable to use the default A_and_B=False,
        returning M, A, and B. Values may then be substituted in to these
        matrices, and the state space form found as
        A = P.T*M.inv()*A, B = P.T*M.inv()*B, where P = Linearizer.perm_mat.

        In both cases, r is found as all dynamicsymbols in the equations of
        motion that are not part of q, u, q', or u'. They are sorted in
        canonical form.

        The operating points may be also entered using the ``op_point`` kwarg.
        This takes a dictionary of {symbol: value}, or a an iterable of such
        dictionaries. The values may be numeric or symbolic. The more values
        you can specify beforehand, the faster this computation will run.

        For more documentation, please see the ``Linearizer`` class.

        r   Nr5   )r   	linearizer   )r&   r   rZ   kwargs
linearizerresultr5   r5   r6   r   x  s   0zKanesMethod.linearizec              
   C   s  |du r| j }|du r| jdur| j}|g krd}| js td| |}| |}| jr| js?t| j	| j
| j| j| jd}n t| j	| j
| j| j| j| j| j | j | j| j | j | jd}| j|_|| _||}||}|| | _||| _||| _| j| jfS )a   Method to form Kane's equations, Fr + Fr* = 0.

        Explanation
        ===========

        Returns (Fr, Fr*). In the case where auxiliary generalized speeds are
        present (say, s auxiliary speeds, o generalized speeds, and m motion
        constraints) the length of the returned vectors will be o - m + s in
        length. The first o - m equations will be the constrained Kane's
        equations, then the s auxiliary Kane's equations. These auxiliary
        equations can be accessed with the auxiliary_eqs property.

        Parameters
        ==========

        bodies : iterable
            An iterable of all RigidBody's and Particle's in the system.
            A system must have at least one body.
        loads : iterable
            Takes in an iterable of (Particle, Vector) or (ReferenceFrame, Vector)
            tuples which represent the force at a point or torque on a frame.
            Must be either a non-empty iterable of tuples or None which corresponds
            to a system with no constraints.
        N[Create an instance of KanesMethod with kinematic differential equations to use this method.)r0   r4   )r0   r-   r.   r/   r4   )r1   r   rq   AttributeErrorr   r   rF   rC   r   r   r"   r    rS   r#   rQ   rU   rE   rT   rP   _km_aux_eqcol_joinr   r   )r&   r1   loadsfrfrstarkmfraux	frstarauxr5   r5   r6   kanes_equations  sB   






zKanesMethod.kanes_equationsc                 C   s   |  | j| j\}}|| S r9   )r   bodylistr2   )r&   r   r   r5   r5   r6   
_form_eoms  s   zKanesMethod._form_eomsc                 C   s   t t| jt| j d}|  }t| jD ]\}}||  ||< q|du r9| j| j	|t| jddf< |S | jj
|dd| j	 |t| jddf< |S )a  Returns the system's equations of motion in first order form. The
        output is the right hand side of::

           x' = |q'| =: f(q, u, r, p, t)
                |u'|

        The right hand side is what is needed by most numerical ODE
        integrators.

        Parameters
        ==========

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

        r   Nr   T)try_block_diag)r   rK   r"   r#   kindiffdictr   r   mass_matrixLUsolveforcinginv)r&   
inv_methodrhskdesr   r   r5   r5   r6   r     s    zKanesMethod.rhsc                 C   s   | j std| j S )z%Returns a dictionary mapping q' to u.r   )rP   r   r   r5   r5   r6   r     s   zKanesMethod.kindiffdictc                 C   s(   | j r| js
td| jstd| jS )z,A matrix containing the auxiliary equations.r   z'No auxiliary speeds have been declared.)r   r   rL   rF   r   r   r5   r5   r6   auxiliary_eqs  s
   zKanesMethod.auxiliary_eqsc                 C   s   | j r| jS | jS )zBThe kinematic "mass matrix" $\mathbf{k_{k\dot{q}}}$ of the system.)r   rq   rm   r   r5   r5   r6   mass_matrix_kin  s   zKanesMethod.mass_matrix_kinc                 C   s6   | j r| jt| j | j  S | jt| j | j  S )z-The kinematic "forcing vector" of the system.)r   rp   r   r#   ro   rl   rk   r   r5   r5   r6   forcing_kin   s   zKanesMethod.forcing_kinc                 C   s$   | j r| js
tdt| j| jgS )zThe mass matrix of the system.r   )r   r   rL   r   r   rU   r   r5   r5   r6   r   (  s   zKanesMethod.mass_matrixc                 C   s&   | j r| js
tdt| j| jg S )z!The forcing vector of the system.r   )r   r   rL   r   r   rT   r   r5   r5   r6   r   /  s   zKanesMethod.forcingc                 C   sP   | j r| js
tdt| jt| j}}| jt||	t||| j
S )zvThe mass matrix of the system, augmented by the kinematic
        differential equations in explicit or implicit form.r   )r   r   rL   rK   r#   r"   r   ri   r   r   r   )r&   r[   nr5   r5   r6   mass_matrix_full6  s   zKanesMethod.mass_matrix_fullc                 C   s   t | j| jgS )zyThe forcing vector of the system, augmented by the kinematic
        differential equations in explicit or implicit form.)r   r   r   r   r5   r5   r6   forcing_full@  s   zKanesMethod.forcing_fullc                 C      | j S r9   )r@   r   r5   r5   r6   r"   F     zKanesMethod.qc                 C   r   r9   )rD   r   r5   r5   r6   r#   J  r   zKanesMethod.uc                 C   r   r9   r   r   r5   r5   r6   r   N  r   zKanesMethod.bodylistc                 C   r   r9   r   r   r5   r5   r6   r2   R  r   zKanesMethod.forcelistc                 C   r   r9   r   r   r5   r5   r6   r1   V  r   zKanesMethod.bodiesc                 C   r   r9   r   r   r5   r5   r6   r   Z  r   zKanesMethod.loads)NNNNNNNNNTr   r   )r   )NNr9   )__name__
__module____qualname____doc__r7   r!   r%   r$   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   r   r"   r#   r   r2   r1   r   r5   r5   r5   r6   r      s^     =
 

CH 
c_
4:
!





	





N)sympyr   r   r   r   sympy.core.sortingr   sympy.physics.vectorr   r   r	   sympy.physics.mechanics.methodr
    sympy.physics.mechanics.particler   !sympy.physics.mechanics.rigidbodyr   !sympy.physics.mechanics.functionsr   r   r   r   r   !sympy.physics.mechanics.linearizer   sympy.utilities.iterablesr   __all__r   r5   r5   r5   r6   <module>   s    