コード例 #1
0
ファイル: dmp_cartesian.py プロジェクト: mginesi/dmp_pp
    def rollout(self, tau = 1.0, v0 = None, **kwargs):
        '''
        Generate a system trial, no feedback is incorporated.
          tau scalar, time rescaling constant
          v0 scalar, initial velocity of the system
        '''

        # Reset the state of the DMP
        if v0 is None:
            v0 = 0.0 * self.x_0
        self.reset_state(v0 = v0)
        x_track = np.array([self.x_0])
        dx_track = np.array([v0])
        t_track = np.array([0])
        state = np.zeros(2 * self.n_dmps)
        state[range(0, 2*self.n_dmps, 2)] = copy.deepcopy(v0)
        state[range(1, 2*self.n_dmps + 1, 2)] = copy.deepcopy(self.x_0)
        if self.rescale == 'rotodilatation':
            M = roto_dilatation(self.learned_position, self.x_goal - self.x_0)
        elif self.rescale == 'diagonal':
            M = np.diag((self.x_goal - self.x_0) / self.learned_position)
        else:
            M = np.eye(self.n_dmps)
        psi = self.gen_psi(self.cs.s)
        f0 = (np.dot(self.w, psi[:, 0])) / (np.sum(psi[:, 0])) * self.cs.s
        f0 = np.nan_to_num(np.dot(M, f0))
        ddx_track = np.array([-self.D * v0 + self.K*f0])
        err = np.linalg.norm(state[range(1, 2*self.n_dmps + 1, 2)] - self.x_goal)
        P = phi1(self.cs.dt * self.linear_part / tau)
        while err > self.tol:
            psi = self.gen_psi(self.cs.s)
            f = (np.dot(self.w, psi[:, 0])) / (np.sum(psi[:, 0])) * self.cs.s
            f = np.nan_to_num(np.dot(M, f))
            beta = np.zeros(2 * self.n_dmps)
            beta[range(0, 2*self.n_dmps, 2)] = \
                self.K * (self.x_goal * (1.0 - self.cs.s) + 
                self.x_0 * self.cs.s + f) / tau
            vect_field = np.dot(self.linear_part / tau, state) + beta
            state += self.cs.dt * np.dot(P, vect_field)
            x_track = np.append(x_track,
                np.array([state[range(1, 2*self.n_dmps + 1, 2)]]), axis=0)
            dx_track = np.append(dx_track,
                np.array([state[range(0, 2*self.n_dmps, 2)]]), axis=0)
            t_track = np.append(t_track, t_track[-1] + self.cs.dt)
            err = np.linalg.norm(state[range(1, 2*self.n_dmps + 1, 2)] - self.x_goal)
            self.cs.step(tau=tau)
            ddx_track = np.append(ddx_track,
                np.array([self.K * (self.x_goal - x_track[-1]) -
                    self.D * dx_track[-1] -
                    self.K * (self.x_goal - self.x_0) * self.cs.s +
                    self.K * f]), axis=0)
        return x_track, dx_track, ddx_track, t_track
コード例 #2
0
ファイル: dmp_cartesian.py プロジェクト: xyyeh/dmp_pp
    def step(self,
             tau=1.0,
             error=0.0,
             external_force=None,
             adapt=False,
             tols=None,
             **kwargs):
        '''
        Run the DMP system for a single timestep.
          tau float: time rescaling constant
          error float: optional system feedback
          external_force 1D array: external force to add to the system
          adapt bool: says if using adaptive step
          tols float list: [rel_tol, abs_tol]
        '''

        ## Initialize
        if tols is None:
            tols = [1e-03, 1e-06]
        ## Setup
        # Scaling matrix
        if self.rescale == 'rotodilatation':
            M = roto_dilatation(self.learned_position, self.x_goal - self.x_0)
        elif self.rescale == 'diagonal':
            M = np.diag((self.x_goal - self.x_0) / self.learned_position)
        else:
            M = np.eye(self.n_dmps)
        # Coupling term in canonical system
        error_coupling = 1.0 / (1.0 + error)
        alpha_tilde = -self.cs.alpha_s / tau / error_coupling
        # State definition
        state = np.zeros(2 * self.n_dmps)
        state[0::2] = self.dx
        state[1::2] = self.x
        # Linear part of the dynamical system
        A_m = self.linear_part / tau

        # s-dep part of the dynamical system
        def beta_s(s, x, v):
            psi = self.gen_psi(s)
            f = (np.dot(self.w, psi[:, 0])) / (np.sum(psi[:, 0])) * self.cs.s
            f = np.nan_to_num(np.dot(M, f))
            out = np.zeros(2 * self.n_dmps)
            out[0::2] = self.K * (self.x_goal * (1.0 - s) + self.x_0 * s + f)
            if external_force is not None:
                out[0::2] += external_force(x, v)
            return out / tau

        ## Initialization of the adaptive step
        flag_tol = False
        while not flag_tol:
            # Bogacki–Shampine method
            # Defining the canonical system in the time of the scheme
            s1 = copy.deepcopy(self.cs.s)
            s2 = s1 * np.exp(-alpha_tilde * self.cs.dt * 1.0 / 2.0)
            s3 = s1 * np.exp(-alpha_tilde * self.cs.dt * 3.0 / 4.0)
            s4 = s1 * np.exp(-alpha_tilde * self.cs.dt)
            xi1 = np.dot(A_m, state) + beta_s(s1, state[1::2], state[0::2])
            xi2 = np.dot(A_m, state + self.cs.dt * xi1 * 1.0/2.0) + \
                beta_s(s2, state[1::2] + self.cs.dt * xi1[1::2] * 1.0/2.0,
                    state[0::2] + self.cs.dt * xi1[0::2] * 1.0/2.0)
            xi3 = np.dot(A_m, state + self.cs.dt * xi2 * 3.0/4.0) + \
                beta_s(s3, state[1::2] + self.cs.dt * xi2[1::2] * 3.0/4.0,
                state[0::2] + self.cs.dt * xi2[0::2] * 3.0/4.0)
            xi4 = np.dot(A_m, state + self.cs.dt * (2.0 * xi1 + 3.0 * xi2 + 4.0 * xi3) / 9.0) + \
                beta_s(s4, state[1::2] + self.cs.dt * (2.0 * xi1[1::2] + 3.0 * xi2[1::2] + 4.0 * xi3[1::2]) / 9.0,
                state[0::2] + self.cs.dt * (2.0 * xi1[0::2] + 3.0 * xi2[0::2] + 4.0 * xi3[0::2]) / 9.0)
            y_ord2 = state + self.cs.dt * (2.0 * xi1 + 3.0 * xi2 +
                                           4.0 * xi3) / 9.0
            y_ord3 = state + self.cs.dt * (7.0 * xi1 + 6.0 * xi2 + 8.0 * xi3 +
                                           3.0 * xi4) / 24.0
            if (np.linalg.norm(y_ord2 - y_ord3) <
                    tols[0] * np.linalg.norm(state) + tols[1]) or (not adapt):
                flag_tol = True
                state = copy.deepcopy(y_ord3)
            else:
                self.cs.dt /= 1.1
        self.cs.step()
        self.x = copy.deepcopy(state[1::2])
        self.dx = copy.deepcopy(state[0::2])
        psi = self.gen_psi(self.cs.s)
        f = (np.dot(self.w, psi[:, 0])) / (np.sum(psi[:, 0])) * self.cs.s
        f = np.nan_to_num(np.dot(M, f))
        self.ddx = (self.K * (self.x_goal - self.x) - self.D * self.dx \
            - self.K * (self.x_goal - self.x_0) * self.cs.s + self.K * f) / tau
        if external_force is not None:
            self.ddx += external_force(self.x, self.dx) / tau
        return self.x, self.dx, self.ddx
コード例 #3
0
ファイル: dmp_cartesian.py プロジェクト: xyyeh/dmp_pp
    def paths_regression(self, traj_set, t_set=None):
        '''
        Takes in a set (list) of desired trajectories (with possibly the
        execution times) and generate the weight which realize the best
        approximation.
          each element of traj_set should be shaped num_timesteps x n_dim
          trajectories
        '''

        ## Step 1: Generate the set of the forcing terms
        f_set = np.zeros([len(traj_set), self.n_dmps, self.cs.timesteps])
        g_new = np.ones(self.n_dmps)
        for it in range(len(traj_set)):
            if t_set is None:
                t_des_tmp = None
            else:
                t_des_tmp = t_set[it]
                t_des_tmp -= t_des_tmp[0]
                t_des_tmp /= t_des_tmp[-1]
                t_des_tmp *= self.cs.run_time

            # Alignment of the trajectory so that
            # x_0 = [0; 0; ...; 0] and g = [1; 1; ...; 1].
            x_des_tmp = copy.deepcopy(traj_set[it])
            x_des_tmp -= x_des_tmp[0]  # translation to x_0 = 0
            g_old = x_des_tmp[-1]  # original x_goal position
            R = roto_dilatation(g_old, g_new)  # rotodilatation

            # Rescaled and rotated trajectory
            x_des_tmp = np.dot(x_des_tmp, np.transpose(R))

            # Learning of the forcing term for the particular trajectory
            f_tmp = self.imitate_path(x_des=x_des_tmp,
                                      t_des=t_des_tmp,
                                      g_w=False,
                                      add_force=None)
            f_set[
                it, :, :] = f_tmp.copy()  # add the new forcing term to the set

        ## Step 2: Learning of the weights using linear regression
        self.w = np.zeros([self.n_dmps, self.n_bfs + 1])
        s_track = self.cs.rollout()
        psi_set = self.gen_psi(s_track)
        psi_sum = np.sum(psi_set, 0)
        psi_sum_2 = psi_sum * psi_sum
        s_track_2 = s_track * s_track
        A = np.zeros([self.n_bfs + 1, self.n_bfs + 1])
        for k in range(self.n_bfs + 1):
            A[k, k] = scipy.integrate.simps(
                psi_set[k, :] * psi_set[k, :] * s_track_2 / psi_sum_2, s_track)
            for h in range(k + 1, self.n_bfs + 1):
                A[h, k] = scipy.integrate.simps(
                    psi_set[k, :] * psi_set[h, :] * s_track_2 / psi_sum_2,
                    s_track)
                A[k, h] = A[h, k].copy()
        A *= len(traj_set)
        LU = scipy.linalg.lu_factor(A)

        # The weights are learned dimension by dimension
        for d in range(self.n_dmps):
            f_d_set = f_set[:, d, :].copy()
            # Set up the minimization problem
            b = np.zeros([self.n_bfs + 1])
            for k in range(self.n_bfs + 1):
                b[k] = scipy.integrate.simps(
                    np.sum(f_d_set * psi_set[k, :] * s_track / psi_sum, 0),
                    s_track)

            # Solve the minimization problem
            self.w[d, :] = scipy.linalg.lu_solve(LU, b)
        self.learned_position = np.ones(self.n_dmps)
コード例 #4
0
ファイル: demo_regression.py プロジェクト: xyyeh/dmp_pp
    rho = 1. - np.random.rand() / 5.
    x0 = rho * np.array([np.cos(theta), np.sin(theta)])
    tf = 6. + 2. * (np.random.rand() - 0.5)
    m = int (500 + np.floor(500 * np.random.rand()))
    t_set.append(np.linspace(0, tf, m))
    # Execute the trajectory
    X = RK4(x0, m, tf)
    traj_set.append(X.copy())
    # Plot
    plt.figure(1)
    plt.plot(X[:, 0], X[:, 1], '-b', lw = 0.5)
    plt.axis('equal')
    # Plot after translation and roto dilatation
    Z = X - X[0]
    old_pos = Z[-1]
    R = roto_dilatation(old_pos, np.array([1,1]))
    Z = np.dot(Z, R.transpose())
    plt.figure(2)
    plt.plot(Z[:, 0], Z[:, 1], '-b', lw = 0.5)
    plt.axis('equal')

MP = dmp(n_dmps = 2, n_bfs = 50, K = 1000, alpha_s = 4.,rescale = 'rotodilatation', T = 2.)
MP.paths_regression(traj_set, t_set)
x_track, _, _, _ = MP.rollout()
plt.figure(2)
plt.plot(x_track[:, 0], x_track[:, 1], '-r', lw = 2)
plt.xlabel(r'$x_1$')
plt.ylabel(r'$x_2$')
plt.plot(0, 0, '.k', markersize = 10)
plt.plot(1, 1, '*k', markersize = 10)
plt.title('Scaled reference frame')