コード例 #1
0
    def Jdiff(self, x1, x2, firstsecond='both'):
        """ Compute the partial derivatives for diff operator using Pinocchio.

        :param x1: current state
        :param x2: next state
        :param firstsecond: desired partial derivative
        :return the partial derivative(s) of the diff(x1,x2) function
        """
        assert (firstsecond in ['first', 'second', 'both'])
        if firstsecond == 'both':
            return [self.Jdiff(x1, x2, 'first'), self.Jdiff(x1, x2, 'second')]
        if firstsecond == 'second':
            dx = self.diff(x1, x2)
            q = a2m(x1[:self.model.nq])
            dq = a2m(dx[:self.model.nv])
            Jdq = pinocchio.dIntegrate(self.model, q, dq)[1]
            return block_diag(np.asarray(np.linalg.inv(Jdq)),
                              np.eye(self.model.nv))
        else:
            dx = self.diff(x2, x1)
            q = a2m(x2[:self.model.nq])
            dq = a2m(dx[:self.model.nv])
            Jdq = pinocchio.dIntegrate(self.model, q, dq)[1]
            return -block_diag(np.asarray(np.linalg.inv(Jdq)),
                               np.eye(self.model.nv))
コード例 #2
0
    def calc(self, data, x, u=None):
        if u is None:
            u = self.unone
        nq, nv = self.nq, self.nv
        q = a2m(x[:nq])
        v = a2m(x[-nv:])

        pinocchio.computeAllTerms(self.pinocchio, data.pinocchio, q, v)
        pinocchio.updateFramePlacements(self.pinocchio, data.pinocchio)

        data.tauq[:] = self.actuation.calc(data.actuation, x, u)
        self.contact.calc(data.contact, x)

        data.K[:nv, :nv] = data.pinocchio.M
        if hasattr(self.pinocchio, 'armature'):
            data.K[range(nv), range(nv)] += self.pinocchio.armature.flat
        data.K[nv:, :nv] = data.contact.J
        data.K.T[nv:, :nv] = data.contact.J
        data.Kinv = np.linalg.inv(data.K)

        data.r[:nv] = data.tauq - m2a(data.pinocchio.nle)
        data.r[nv:] = -data.contact.a0
        data.af[:] = np.dot(data.Kinv, data.r)
        data.f[:] *= -1.

        # Convert force array to vector of spatial forces.
        self.contact.setForces(data.contact, data.f)

        data.cost = self.costs.calc(data.costs, x, u)
        return data.xout, data.cost
コード例 #3
0
 def calcDiff(self, data, x, u=None, recalc=True):
     if u is None:
         u = self.unone
     if recalc:
         xout, cost = self.calc(data, x, u)
     nq, nv = self.nq, self.nv
     q = a2m(x[:nq])
     v = a2m(x[-nv:])
     tauq = a2m(u)
     a = a2m(data.xout)
     # --- Dynamics
     if self.forceAba:
         pinocchio.computeABADerivatives(self.pinocchio, data.pinocchio, q,
                                         v, tauq)
         data.Fx[:, :nv] = data.pinocchio.ddq_dq
         data.Fx[:, nv:] = data.pinocchio.ddq_dv
         data.Fu[:, :] = data.pinocchio.Minv
     else:
         pinocchio.computeRNEADerivatives(self.pinocchio, data.pinocchio, q,
                                          v, a)
         data.Fx[:, :nv] = -np.dot(data.Minv, data.pinocchio.dtau_dq)
         data.Fx[:, nv:] = -np.dot(data.Minv, data.pinocchio.dtau_dv)
         data.Fu[:, :] = data.Minv
     # --- Cost
     pinocchio.computeJointJacobians(self.pinocchio, data.pinocchio, q)
     pinocchio.updateFramePlacements(self.pinocchio, data.pinocchio)
     self.costs.calcDiff(data.costs, x, u, recalc=False)
     return data.xout, data.cost
コード例 #4
0
    def calcDiff(self, data, x, u=None, recalc=True):
        if u is None:
            u = self.unone
        if recalc:
            xout, cost = self.calc(data, x, u)
        nq, nv = self.nq, self.nv
        q = a2m(x[:nq])
        v = a2m(x[-nv:])
        a = a2m(data.a)
        fs = data.contact.forces

        pinocchio.computeRNEADerivatives(self.pinocchio, data.pinocchio, q, v, a, fs)
        pinocchio.updateFramePlacements(self.pinocchio, data.pinocchio)

        # [a;-f] = K^-1 [ tau - b, -gamma ]
        # [a';-f'] = -K^-1 [ K'a + b' ; J'a + gamma' ]  = -K^-1 [ rnea'(q,v,a,fs) ; acc'(q,v,a) ]

        # Derivative of the actuation model tau = tau(q,u)
        # dtau_dq and dtau_dv are the rnea derivatives rnea'
        did_dq = data.pinocchio.dtau_dq
        did_dv = data.pinocchio.dtau_dv

        # Derivative of the contact constraint
        # da0_dq and da0_dv are the acceleration derivatives acc'
        self.contact.calcDiff(data.contact, x, recalc=False)
        dacc_dq = data.contact.Aq
        dacc_dv = data.contact.Av

        data.Kinv = np.linalg.inv(data.K)

        # We separate the Kinv into the a and f rows, and the actuation and acceleration columns
        da_did = -data.Kinv[:nv, :nv]
        df_did = data.Kinv[nv:, :nv]
        da_dacc = -data.Kinv[:nv, nv:]
        df_dacc = data.Kinv[nv:, nv:]

        da_dq = np.dot(da_did, did_dq) + np.dot(da_dacc, dacc_dq)
        da_dv = np.dot(da_did, did_dv) + np.dot(da_dacc, dacc_dv)
        da_dtau = data.Kinv[:nv, :nv]  # Add this alias just to make the code clearer
        df_dtau = -data.Kinv[nv:, :nv]  # Add this alias just to make the code clearer

        # tau is a function of x and u (typically trivial in x), whose derivatives are Ax and Au
        dtau_dx = data.actuation.Ax
        dtau_du = data.actuation.Au

        data.Fx[:, :nv] = da_dq
        data.Fx[:, nv:] = da_dv
        data.Fx += np.dot(da_dtau, dtau_dx)
        data.Fu[:, :] = np.dot(da_dtau, dtau_du)

        data.df_dq[:, :] = np.dot(df_did, did_dq) + np.dot(df_dacc, dacc_dq)
        data.df_dv[:, :] = np.dot(df_did, did_dv) + np.dot(df_dacc, dacc_dv)
        data.df_dx += np.dot(df_dtau, dtau_dx)
        data.df_du[:, :] = np.dot(df_dtau, dtau_du)

        self.contact.setForcesDiff(data.contact, data.df_dx, data.df_du)
        self.costs.calcDiff(data.costs, x, u, recalc=False)
        return data.xout, data.cost
コード例 #5
0
    def integrate(self, x, dx):
        """ Integrate the current robot's state.

        :param x: current state
        :param dx: displacement of the state
        :return x [+] dx value
        """
        nq, nv, nx, ndx = self.model.nq, self.model.nv, self.nx, self.ndx
        assert (x.shape == (nx, ) and dx.shape == (ndx, ))
        q = x[:nq]
        v = x[-nv:]
        dq = dx[:nv]
        dv = dx[-nv:]
        qn = pinocchio.integrate(self.model, a2m(q), a2m(dq))
        return np.concatenate([qn.flat, v + dv])
コード例 #6
0
    def diff(self, x0, x1):
        """ Difference between the robot's states x2 and x1.

        :param x1: current state
        :param x2: next state
        :return x2 [-] x1 value
        """
        nq, nv, nx = self.model.nq, self.model.nv, self.nx
        assert (x0.shape == (nx, ) and x1.shape == (nx, ))
        q0 = x0[:nq]
        q1 = x1[:nq]
        v0 = x0[-nv:]
        v1 = x1[-nv:]
        dq = pinocchio.difference(self.model, a2m(q0), a2m(q1))
        return np.concatenate([dq.flat, v1 - v0])
コード例 #7
0
 def setForces(self, data, forcesArr, forcesVec=None):
     '''
     Convert a numpy array of forces into a stdVector of spatial forces.
     '''
     # In the dynamic equation, we wrote M*a + J.T*fdyn, while in the ABA it would be
     # M*a + b = tau + J.T faba, so faba = -fdyn (note the minus operator before a2m).
     data.f = forcesArr
     if forcesVec is None:
         forcesVec = data.forces
         data.forces[data.joint] *= 0
     forcesVec[data.joint] += data.jMf * pinocchio.Force(
         a2m(forcesArr), np.zeros((3, 1)))
     return forcesVec
コード例 #8
0
 def calc(self, data, x, u=None):
     if u is None:
         u = self.unone
     nq, nv = self.nq, self.nv
     q = a2m(x[:nq])
     v = a2m(x[-nv:])
     tauq = a2m(u)
     # --- Dynamics
     if self.forceAba:
         data.xout[:] = pinocchio.aba(self.pinocchio, data.pinocchio, q, v,
                                      tauq).flat
     else:
         pinocchio.computeAllTerms(self.pinocchio, data.pinocchio, q, v)
         data.M = data.pinocchio.M
         if hasattr(self.pinocchio, 'armature'):
             data.M[range(nv), range(nv)] += self.pinocchio.armature.flat
         data.Minv = np.linalg.inv(data.M)
         data.xout[:] = data.Minv * (tauq - data.pinocchio.nle).flat
     # --- Cost
     pinocchio.forwardKinematics(self.pinocchio, data.pinocchio, q, v)
     pinocchio.updateFramePlacements(self.pinocchio, data.pinocchio)
     data.cost = self.costs.calc(data.costs, x, u)
     return data.xout, data.cost
コード例 #9
0
    def Jintegrate(self, x, dx, firstsecond='both'):
        """ Compute the partial derivatives for integrate operator using Pinocchio.

        :param x: current state
        :param dx: displacement of the state
        :param firstsecond: desired partial derivative
        :return the partial derivative(s) of the integrate(x,dx) function
        """
        assert (firstsecond in ['first', 'second', 'both'])
        assert (x.shape == (self.nx, ) and dx.shape == (self.ndx, ))
        if firstsecond == 'both':
            return [
                self.Jintegrate(x, dx, 'first'),
                self.Jintegrate(x, dx, 'second')
            ]
        q = a2m(x[:self.model.nq])
        dq = a2m(dx[:self.model.nv])
        Jq, Jdq = pinocchio.dIntegrate(self.model, q, dq)
        if firstsecond == 'first':
            # Derivative wrt x
            return block_diag(np.asarray(Jq), np.eye(self.model.nv))
        else:
            # Derivative wrt v
            return block_diag(np.asarray(Jdq), np.eye(self.model.nv))