Esempio n. 1
0
    def to_linearizer(self, q_ind=None, qd_ind=None, q_dep=None, qd_dep=None):
        """Returns an instance of the Linearizer class, initiated from the
        data in the LagrangesMethod 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
        ----------
        q_ind, qd_ind : array_like, optional
            The independent generalized coordinates and speeds.
        q_dep, qd_dep : array_like, optional
            The dependent generalized coordinates and speeds.
        """

        # Compose vectors
        t = dynamicsymbols._t
        q = Matrix(self._q)
        u = Matrix(self._qdots)
        ud = u.diff(t)
        # Get vector of lagrange multipliers
        lams = self.lam_vec

        mat_build = lambda x: Matrix(x) if x else Matrix()
        q_i = mat_build(q_ind)
        q_d = mat_build(q_dep)
        u_i = mat_build(qd_ind)
        u_d = mat_build(qd_dep)

        # Compose general form equations
        f_c = self._hol_coneqs
        f_v = self.coneqs
        f_a = f_v.diff(t)
        f_0 = u
        f_1 = -u
        f_2 = self._term1
        f_3 = -(self._term2 + self._term4)
        f_4 = -self._term3

        # Check that there are an appropriate number of independent and
        # dependent coordinates
        if len(q_d) != len(f_c) or len(u_d) != len(f_v):
            raise ValueError(("Must supply {:} dependent coordinates, and " +
                    "{:} dependent speeds").format(len(f_c), len(f_v)))
        if set(Matrix([q_i, q_d])) != set(q):
            raise ValueError("Must partition q into q_ind and q_dep, with " +
                    "no extra or missing symbols.")
        if set(Matrix([u_i, u_d])) != set(u):
            raise ValueError("Must partition qd into qd_ind and qd_dep, " +
                    "with no extra or missing symbols.")

        # Find all other dynamic symbols, forming the forcing vector r.
        # Sort r to make it canonical.
        insyms = set(Matrix([q, u, ud, lams]))
        r = list(_find_dynamicsymbols(f_3, insyms))
        r.sort(key=default_sort_key)
        # Check for any derivatives of variables in r that are also found in r.
        for i in r:
            if diff(i, dynamicsymbols._t) in r:
                raise ValueError('Cannot have derivatives of specified \
                                 quantities when linearizing forcing terms.')

        return Linearizer(f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a, q, u, q_i,
                q_d, u_i, u_d, r, lams)
Esempio n. 2
0
    def to_linearizer(self):
        """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)."""

        if (self._fr is None) or (self._frstar is None):
            raise ValueError('Need to compute Fr, Fr* first.')

        # Get required equation components. The Kane's method class breaks
        # these into pieces. Need to reassemble
        f_c = self._f_h
        if self._f_nh and self._k_nh:
            f_v = self._f_nh + self._k_nh * Matrix(self._u)
        else:
            f_v = Matrix([])
        if self._f_dnh and self._k_dnh:
            f_a = self._f_dnh + self._k_dnh * Matrix(self._udot)
        else:
            f_a = Matrix([])
        # Dicts to sub to zero, for splitting up expressions
        u_zero = dict((i, 0) for i in self._u)
        ud_zero = dict((i, 0) for i in self._udot)
        qd_zero = dict((i, 0) for i in self._qdot)
        qd_u_zero = dict((i, 0) for i in self._qdot + self._u)
        # Break the kinematic differential eqs apart into f_0 and f_1
        f_0 = self._f_k.subs(u_zero) + self._k_kqdot * Matrix(self._qdot)
        f_1 = self._f_k.subs(qd_zero) + self._k_ku * Matrix(self._u)
        # Break the dynamic differential eqs into f_2 and f_3
        f_2 = _subs_keep_derivs(self._frstar, qd_u_zero)
        f_3 = self._frstar.subs(ud_zero) + self._fr
        f_4 = zeros(len(f_2), 1)

        # Get the required vector components
        q = self._q
        u = self._u
        if self._qdep:
            q_i = q[:-len(self._qdep)]
        else:
            q_i = q
        q_d = self._qdep
        if self._udep:
            u_i = u[:-len(self._udep)]
        else:
            u_i = u
        u_d = self._udep

        # Form dictionary of auxiliary speeds & and their derivatives,
        # setting each to 0.
        uaux = self._uaux
        uauxdot = [diff(i, dynamicsymbols._t) for i in uaux]
        uaux_zero = dict((i, 0) for i in uaux + uauxdot)

        # Checking for dynamic symbols outside the dynamic differential
        # equations; throws error if there is.
        insyms = set(q + self._qdot + u + self._udot + uaux + uauxdot)
        if any(
                _find_dynamicsymbols(i, insyms) for i in [
                    self._k_kqdot, self._k_ku, self._f_k, self._k_dnh,
                    self._f_dnh, self._k_d
                ]):
            raise ValueError('Cannot have dynamicsymbols outside dynamic \
                             forcing vector.')

        # Find all other dynamic symbols, forming the forcing vector r.
        # Sort r to make it canonical.
        r = list(_find_dynamicsymbols(self._f_d.subs(uaux_zero), insyms))
        r.sort(key=default_sort_key)

        # Check for any derivatives of variables in r that are also found in r.
        for i in r:
            if diff(i, dynamicsymbols._t) in r:
                raise ValueError('Cannot have derivatives of specified \
                                 quantities when linearizing forcing terms.')
        return Linearizer(f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a, q, u, q_i,
                          q_d, u_i, u_d, r)
Esempio n. 3
0
    def to_linearizer(self):
        """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)."""

        if (self._fr is None) or (self._frstar is None):
            raise ValueError('Need to compute Fr, Fr* first.')

        # Get required equation components. The Kane's method class breaks
        # these into pieces. Need to reassemble
        f_c = self._f_h
        if self._f_nh and self._k_nh:
            f_v = self._f_nh + self._k_nh*Matrix(self._u)
        else:
            f_v = Matrix([])
        if self._f_dnh and self._k_dnh:
            f_a = self._f_dnh + self._k_dnh*Matrix(self._udot)
        else:
            f_a = Matrix([])
        # Dicts to sub to zero, for splitting up expressions
        u_zero = dict((i, 0) for i in self._u)
        ud_zero = dict((i, 0) for i in self._udot)
        qd_zero = dict((i, 0) for i in self._qdot)
        qd_u_zero = dict((i, 0) for i in self._qdot + self._u)
        # Break the kinematic differential eqs apart into f_0 and f_1
        f_0 = self._f_k.subs(u_zero) + self._k_kqdot*Matrix(self._qdot)
        f_1 = self._f_k.subs(qd_zero) + self._k_ku*Matrix(self._u)
        # Break the dynamic differential eqs into f_2 and f_3
        f_2 = _subs_keep_derivs(self._frstar, qd_u_zero)
        f_3 = self._frstar.subs(ud_zero) + self._fr
        f_4 = zeros(len(f_2), 1)

        # Get the required vector components
        q = self._q
        u = self._u
        if self._qdep:
            q_i = q[:-len(self._qdep)]
        else:
            q_i = q
        q_d = self._qdep
        if self._udep:
            u_i = u[:-len(self._udep)]
        else:
            u_i = u
        u_d = self._udep

        # Form dictionary of auxiliary speeds & and their derivatives,
        # setting each to 0.
        uaux = self._uaux
        uauxdot = [diff(i, dynamicsymbols._t) for i in uaux]
        uaux_zero = dict((i, 0) for i in uaux + uauxdot)

        # Checking for dynamic symbols outside the dynamic differential
        # equations; throws error if there is.
        insyms = set(q + self._qdot + u + self._udot + uaux + uauxdot)
        if any(_find_dynamicsymbols(i, insyms) for i in [self._k_kqdot,
                self._k_ku, self._f_k, self._k_dnh, self._f_dnh, self._k_d]):
            raise ValueError('Cannot have dynamicsymbols outside dynamic \
                             forcing vector.')

        # Find all other dynamic symbols, forming the forcing vector r.
        # Sort r to make it canonical.
        r = list(_find_dynamicsymbols(self._f_d.subs(uaux_zero), insyms))
        r.sort(key=default_sort_key)

        # Check for any derivatives of variables in r that are also found in r.
        for i in r:
            if diff(i, dynamicsymbols._t) in r:
                raise ValueError('Cannot have derivatives of specified \
                                 quantities when linearizing forcing terms.')
        return Linearizer(f_0, f_1, f_2, f_3, f_4, f_c, f_v, f_a, q, u, q_i, q_d,
                u_i, u_d, r)