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);
74 (*finger_tip->asChain())[i].setMin(
DEG2RAD*min);
75 (*finger_tip->asChain())[i].setMax(
DEG2RAD*max);
76 (*elbow->asChain())[i].setMin(
DEG2RAD*min);
77 (*elbow->asChain())[i].setMax(
DEG2RAD*max);
81 finger_tip->blockLink(0,0.0);
82 finger_tip->blockLink(1,0.0);
83 finger_tip->blockLink(2,0.0);
86 finger_tip->blockLink(8,0.0);
87 finger_tip->blockLink(9,0.0);
90 elbow->blockLink(0,0.0);
91 elbow->blockLink(1,0.0);
92 elbow->blockLink(2,0.0);
95 for (
auto i=0; i<4; i++)
96 elbow->asChain()->rmLink(7);
99 finger_tip->asChain()->setAllConstraints(
false);
100 elbow->asChain()->setAllConstraints(
false);
103 finger->asChain()->setAllConstraints(
false);
125 finger->getChainJoints(finger_joints,chain_joints);
126 finger->setAng(
DEG2RAD*chain_joints);
129 finger_tip->asChain()->setHN(finger->getH());
135 q.resize(finger_tip->getN());
136 for (
unsigned int i=0; i<q.length(); i++)
137 q[i]=
RAD2DEG*finger_tip->getAng(i);
138 x=finger_tip->EndEffPose();
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)
145 n=finger_tip->getDOF();
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++)
188 finger_tip->setAng(q);
189 elbow->asChain()->setAng(q);
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);
210 Matrix dtipZ=finger_tip->AnaJacobian(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)
221 Vector elbowPos=elbow->asChain()->EndEffPosition();
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++)
255 Vector elbowPos=elbow->asChain()->EndEffPosition();
256 Vector pe_dir=point-elbowPos;
258 Matrix tip=finger_tip->getH();
259 Vector te_dir=tip.getCol(3).subVector(0,2)-elbowPos;
261 Matrix dpe_dir=-1.0*elbow->asChain()->AnaJacobian().removeRows(3,3);
262 dpe_dir=cat(dpe_dir,
zeros(3,finger_tip->getDOF()-elbow->asChain()->getDOF()));
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);
273 Matrix dtip=-1.0*finger_tip->AnaJacobian();
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.
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)