Extension - NLP interface: Low-level NLP formulation and solving
This is completely independent from all robotics code. Provides a generic interface to NLP formulation and calling various solvers.
[ ]:
import robotic as ry
import numpy as np
import matplotlib.pylab as plt
Define a function to compute differentiable features
[ ]:
#the function needs to have the signature (array) -> (array, array) with dimensionalities (n) -> (d, d-times-n)
def sqrPot(x):
y = np.array(x)
y[0] = y[0] - 1.
J = np.eye(y.size)
return y,J
Define a NLP (non-linear mathematical program)
[ ]:
nlp = ry.NLP_Factory()
nlp.setDimension(3)
nlp.setBounds([-2,-2,-2],[2,2,2])
nlp.setFeatureTypes([ry.OT.sos, ry.OT.sos, ry.OT.sos])
nlp.setEvalCallback(sqrPot)
Define a solver
[ ]:
solver = ry.NLP_Solver()
solver.setProblem(nlp)
solver.setSolver(ry.NLP_SolverID.newton)
[ ]:
solver.solve(True)
[ ]:
solver.getTrace_costs()
[ ]:
import robotic as ry
from robotic import nlp
import numpy as np
import matplotlib.pylab as plt
[ ]:
class MyNLP(nlp.NLP):
b = 3
def evaluate(self, x):
phi = np.array([ x[0]-1,
self.b*(x[1]-x[0]**2) ])
J = np.array([[ 1, 0 ],
[ -2*self.b*x[0], self.b ]])
return phi, J
def f(self, x):
phi, _ = self.evaluate(x)
return np.sum(phi**2)
def getDimension(self):
return 2
def getFeatureTypes(self):
return [ry.nlp.OT.sos] * 2
def getBounds(self):
return np.array([[-2,-1], [2,3]])
[ ]:
p = MyNLP()
[ ]:
solver = ry.NLP_Solver()
solver.setPyProblem(p)
solver.setOptions(maxStep=.5, damping=1e-4)
[ ]:
for i in range(20):
ret = solver.solve(1)
print(ret)
x = solver.getTrace_x()
z = solver.getTrace_costs()
plt.plot(x[:,0], x[:,1], 'o-')
[ ]:
X = np.arange(-2, 2, 0.15)
Y = np.arange(-1, 3, 0.15)
X, Y = np.meshgrid(X, Y)
xy = np.hstack((X.reshape(-1,1),Y.reshape(-1,1)))
Z = np.apply_along_axis(p.f, 1, xy).reshape(X.shape)
[ ]:
fig, ax = plt.subplots()
ax.contour(X,Y,Z, 200)
ax.plot(x[:,0], x[:,1], 'o-r', ms=3)
[ ]:
for i in range(20):
x = solver.getProblem().getInitializationSample()
r = solver.getProblem().checkJacobian(x, 1e-6)
print(r, x)
[ ]: