Probabilistic Movement Primitives Part 1: Introduction
In the previous post, we talked about Dynamic Movement Primitive (DMP) framework. While DMP is an attractive MP architecture for generating stroke-based and rhythmic movements, it is a deterministic approach that can only represent the mean solution, which is known to be suboptimal. This creates a need for a more sophisticated MP architecture that not can not only overcome these problems but can also exhibit various useful properties like conditioning of trajectories and adaptation to new situations. Probabilistic Movement Primitives (ProMPs) is the only existing approach that exhibits many such properties in one unified framework. In this ProMP series, we will be talking about the theory behind this framework and simultaneously code each part of this framework in Python.
Probabilistic Movement Primitives is a probabilistic formulation of MPs that maintains a distribution over trajectories. Such a distribution over trajectories automatically encodes the variance of the movements, hence modeling the stochastic behavior (ensuring optimality). This probabilistic approach facilitates the generation of many properties by manipulating probabilistic distributions of the trajectories.
Probabilistic Trajectory Representation
For simplicity we start with a case of single degree of freedom. Consider a scalar joint angle
where
A distribution
Let's Code
In this series of posts, we will write a code to learn a stroke-based ProMP over a custom one-dimensional dynamical system. Consider a system having the following dynamics
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
num_trajs = 100 # number of demo trajectories to be generated
num_points = 200 # number of points in each trajectory.
A = np.array([ [0.,1.], [0., 0.] ])
B = np.array([ [0.], [1.] ])
start_x = np.array([[0],[0]]) #initial state (pos, vel)
def next_x(prev_x, cmd):
dt = 0.005
return np.dot(np.eye(2) + A*dt, prev_x) + np.dot(B*dt, cmd)
We generate a set of 100 demonstration trajectories using these dynamics with some noise for variations. Each trajectory is set such that it starts at 0 positions and has 200 points. The change in time variable
for _ in range(num_trajs):
prev_x = start_x
# arrays to hold the position and velocity points in each trajectory
pos_arr = np.zeros(num_points)
vel_arr = np.zeros(num_points)
pos_arr[0] = start_x[0]
vel_arr[0] = start_x[1]
# control commands in the form of sine wave
x = (np.linspace(0,4*np.pi,num_points))
cmd = np.sin(x) + np.random.randn(num_points)*0.1 #noise added for variations
for i in range(1,num_points):
x = next_x(prev_x, cmd[i-1])
pos_arr[i] = x[0]
vel_arr[i] = x[1]
prev_x = x
The control commands are computed using the sine wave from
P.S.: The code is explained and written in fragments in this series. You will have to combine everything in one script one-after-another to have the ProMP running.
References:
Comments
Post a Comment