23#include <IpIpoptApplication.hpp>
25#include <yarp/os/Property.h>
26#include <yarp/os/LogStream.h>
27#include <yarp/dev/CartesianControl.h>
28#include <yarp/sig/Vector.h>
29#include <yarp/sig/Matrix.h>
30#include <yarp/math/Math.h>
35#define RAD2DEG (180.0/M_PI)
36#define DEG2RAD (M_PI/180.0)
39using namespace yarp::os;
41using namespace yarp::sig;
42using namespace yarp::math;
61 string hand=info.find(
"arm_type").asString();
65 size_t underscore=hand.find(
'_');
66 if (underscore!=string::npos)
67 hand=hand.substr(0,underscore);
70 for (
unsigned int i=0; i<finger_tip->
getN(); i++)
73 iarm->getLimits(i,&min,&max);
95 for (
auto i=0; i<4; i++)
135 q.resize(finger_tip->
getN());
136 for (
unsigned int i=0; i<q.length(); i++)
142 bool get_nlp_info(Ipopt::Index&
n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
143 Ipopt::Index& nnz_h_lag, IndexStyleEnum& index_style)
149 index_style=TNLP::C_STYLE;
155 Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u)
157 for (Ipopt::Index i=0; i<
n; i++)
159 x_l[i]=(*finger_tip->
asChain())(i).getMin();
160 x_u[i]=(*finger_tip->
asChain())(i).getMax();
164 g_u[0]=std::numeric_limits<double>::max();
166 g_l[1]=-std::numeric_limits<double>::max();
173 bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U,
174 Ipopt::Index m,
bool init_lambda, Ipopt::Number* lambda)
176 for (Ipopt::Index i=0; i<
n; i++)
177 x[i]=0.5*((*finger_tip->
asChain())(i).getMin()+
178 (*finger_tip->
asChain())(i).getMax());
185 Vector q(finger_tip->
getDOF());
186 for (
size_t i=0; i<q.length(); i++)
193 bool eval_f(Ipopt::Index
n,
const Ipopt::Number*
x,
bool new_x,
194 Ipopt::Number& obj_value)
197 Matrix tip=finger_tip->
getH();
198 double e=-1.0-tip(2,2);
205 Ipopt::Number* grad_f)
208 Matrix tip=finger_tip->
getH();
209 double e=-1.0-tip(2,2);
211 for (Ipopt::Index i=0; i<
n; i++)
212 grad_f[i]=-2.0*
e*dtipZ(2,i);
217 bool eval_g(Ipopt::Index
n,
const Ipopt::Number*
x,
bool new_x,
218 Ipopt::Index m, Ipopt::Number* g)
222 Vector pe_dir=point-elbowPos;
224 Matrix tip=finger_tip->
getH();
225 Vector te_dir=tip.getCol(3).subVector(0,2)-elbowPos;
226 g[0]=dot(pe_dir,te_dir)/(norm(pe_dir)*norm(te_dir));
228 Vector pt_dir=point-tip.getCol(3).subVector(0,2);
235 Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow,
236 Ipopt::Index *jCol, Ipopt::Number* values)
241 for (Ipopt::Index i=0; i<
n; i++,
idx++)
246 for (Ipopt::Index i=0; i<
n; i++,
idx++)
256 Vector pe_dir=point-elbowPos;
258 Matrix tip=finger_tip->
getH();
259 Vector te_dir=tip.getCol(3).subVector(0,2)-elbowPos;
263 Matrix dte_dir=finger_tip->
AnaJacobian().removeRows(3,3)+dpe_dir;
265 double npe=norm(pe_dir);
266 double nte=norm(te_dir);
269 for (Ipopt::Index i=0; i<
n; i++)
270 values[i]=(dot(dpe_dir.getCol(i),te_dir)+dot(pe_dir,dte_dir.getCol(i)))/nn-
271 dot(pe_dir,te_dir)*(dot(pe_dir,dpe_dir.getCol(i))*nte/npe)/(nn*nn);
274 for (Ipopt::Index i=0; i<
n; i++)
275 values[
n+i]=dtip(0,i);
281 bool eval_h(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
282 Ipopt::Number obj_factor, Ipopt::Index m,
283 const Ipopt::Number *lambda,
bool new_lambda,
284 Ipopt::Index nele_hess, Ipopt::Index *iRow,
285 Ipopt::Index *jCol, Ipopt::Number *values)
292 const Ipopt::Number*
x,
const Ipopt::Number* z_L,
293 const Ipopt::Number* z_U, Ipopt::Index m,
294 const Ipopt::Number* g,
const Ipopt::Number* lambda,
295 Ipopt::Number obj_value,
const Ipopt::IpoptData* ip_data,
296 Ipopt::IpoptCalculatedQuantities* ip_cq)
304 Vector& q, Vector&
x)
308 yError()<<
"Cartesian controller not configured";
312 Bottle *bPoint=requirements.find(
"point").asList();
315 yError()<<
"Target point not provided";
320 for (
int i=0; i<bPoint->size(); i++)
321 point[i]=bPoint->get(i).asFloat64();
323 Ipopt::SmartPtr<Ipopt::IpoptApplication> app=
new Ipopt::IpoptApplication;
324 app->Options()->SetNumericValue(
"tol",0.01);
325 app->Options()->SetNumericValue(
"constr_viol_tol",0.01);
326 app->Options()->SetIntegerValue(
"acceptable_iter",0);
327 app->Options()->SetStringValue(
"mu_strategy",
"adaptive");
328 app->Options()->SetIntegerValue(
"max_iter",200);
329 app->Options()->SetStringValue(
"nlp_scaling_method",
"gradient-based");
330 app->Options()->SetStringValue(
"hessian_approximation",
"limited-memory");
331 app->Options()->SetStringValue(
"derivative_test",
"none");
332 app->Options()->SetIntegerValue(
"print_level",0);
338 nlp->setPoint(
point);
339 if (Bottle *bFingerJoints=requirements.find(
"finger-joints").asList())
341 Vector finger_joints(bFingerJoints->size());
342 for (
size_t i=0; i<finger_joints.length(); i++)
343 finger_joints[i]=bFingerJoints->get(i).asFloat64();
344 nlp->setFingerJoints(finger_joints);
347 Ipopt::ApplicationReturnStatus status=app->OptimizeTNLP(GetRawPtr(nlp));
356 if ((q.length()>=10) && (
x.length()>=7))
359 iarm->storeContext(&context);
363 iarm->setDOF(dof,dof);
364 for (
unsigned int i=0; i<q.length(); i++)
365 iarm->setLimits(i,q[i],q[i]);
368 iarm->getTrajTime(&traj);
369 iarm->setInTargetTol(0.02);
370 iarm->goToPoseSync(
x.subVector(0,2),
x.subVector(3,6));
371 iarm->waitMotionDone(0.2,5.0*traj);
374 iarm->restoreContext(context);
375 iarm->deleteContext(context);
bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x, bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U, Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
PointingFarNLP(ICartesianControl *iarm)
bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
virtual ~PointingFarNLP()
bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda, bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
void setFingerJoints(const Vector &finger_joints)
void setAng(const Ipopt::Number *x)
void finalize_solution(Ipopt::SolverReturn status, Ipopt::Index n, const Ipopt::Number *x, const Ipopt::Number *z_L, const Ipopt::Number *z_U, Ipopt::Index m, const Ipopt::Number *g, const Ipopt::Number *lambda, Ipopt::Number obj_value, const Ipopt::IpoptData *ip_data, Ipopt::IpoptCalculatedQuantities *ip_cq)
void setPoint(const Vector &point)
bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u, Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, IndexStyleEnum &index_style)
void getResult(Vector &q, Vector &x) const
bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
A class for defining the iCub Arm.
A class for defining the iCub Finger.
virtual bool getChainJoints(const yarp::sig::Vector &motorEncoders, yarp::sig::Vector &chainJoints)
Retrieves the vector of actual finger's joint values (to be used in conjuction with the iKinLimb meth...
yarp::sig::Matrix getH(const unsigned int i, const bool allLink=false)
Returns the rigid roto-translation matrix from the root reference frame to the ith frame in Denavit-H...
bool setHN(const yarp::sig::Matrix &_HN)
Sets HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
yarp::sig::Vector EndEffPosition()
Returns the 3D coordinates of end-effector position.
yarp::sig::Matrix AnaJacobian(const unsigned int i, unsigned int col)
Returns the analitical Jacobian of the ith link.
bool rmLink(const unsigned int i)
Removes the ith Link from the Chain.
yarp::sig::Vector EndEffPose(const bool axisRep=true)
Returns the coordinates of end-effector.
yarp::sig::Vector getAng()
Returns the current free joint angles values.
yarp::sig::Vector setAng(const yarp::sig::Vector &q)
Sets the free joint angles to values of q[i].
unsigned int getN() const
Returns the number of Links belonging to the Chain.
unsigned int getDOF() const
Returns the current number of Chain's DOF.
bool blockLink(const unsigned int i, double Ang)
Blocks the ith Link at the a certain value of its joint angle.
void setAllConstraints(bool _constrained)
Sets the constraint status of all chain links.
iKinChain * asChain()
Returns a pointer to the Limb seen as Chain object.
static uint32_t idx[BOARD_NUM]
static bool compute(yarp::dev::ICartesianControl *iarm, const yarp::os::Property &requirements, yarp::sig::Vector &q, yarp::sig::Vector &x)
static bool point(yarp::dev::ICartesianControl *iarm, const yarp::sig::Vector &q, const yarp::sig::Vector &x)