Probabilistic Movement Primitives Part 2: Phase variable and Basis functions
As a continuation of our series on ProMPs, we will introduce the concepts of phase variable and basis functions in this post.
Temporal Modulation
The execution speed of the movement can be adjusted with temporal modulation. A phase variable
Let's code
We choose a monotonically increasing function with time that starts at 0 and ends at 1. By default, the phase speed is taken as 1.
def get_phase_variables(phase_speed):
phase_start = 0
time_steps = int(num_points/phase_speed)
phase_end = 1
Dz = np.ones(time_steps)*phase_speed # derivative of phase variable z dot
phase_z = np.cumsum(Dz)*dt # phase variable z
return phase_z, Dz
def get_phase_from_time(time_step):
phase_end = 1
return time_step/phase_end
Rhythmic and Stroke-Based Movements
Similar to DMPs, we choose the basis functions depending upon the type of movement. Gaussian basis functions
Let's code
For our case of learning a stroke-based ProMP, 35 radial basis function are defined with variance of
n_bfs = 35 # number of basis function
bfs_sigma = 0.0286 # variance of the basis function
bfs_centres = np.linspace(0, 1, n_bfs) # centers of the basis function
def generate_basis_function(phase_z, phase_zd):
phase_minus_centre = np.array(map(lambda x: x - bfs_centres,
np.tile(phase_z, (n_bfs, 1)).T)).T
Phi = np.exp(-0.5 *np.power(phase_minus_centre/bfs_sigma, 2))
PhiD = np.multiply(Phi, -phase_minus_centre/(bfs_sigma)) * phase_zd
# normalization
sum_bfs = np.sum(Phi, axis=0)
sum_bfsD = np.sum(PhiD, axis=0)
PhiD_normalized = ( (PhiD * sum_bfs - Phi * sum_bfsD) * 1./np.power(sum_bfs, 2) )
Phi_normalized = Phi/sum_bfs[None, :]
return Phi_normalized, PhiD_normalized
# Generate the Basis Function for the default phase speed = 1
z, z_dot = get_phase_variables(1)
Phi, Phi_dot = generate_basis_function(z, z_dot)
The radial basis functions generated from the above code are shown in the Figure below.
References:
Comments
Post a Comment