16 #include <IpIpoptApplication.hpp>
20 #define CAST_IPOPTAPP(x) (static_cast<IpoptApplication*>(x))
21 #define IKINIPOPT_SHOULDER_MAXABDUCTION (100.0*CTRL_DEG2RAD)
24 using namespace yarp::sig;
25 using namespace yarp::math;
28 using namespace Ipopt;
32 iKinLinIneqConstr::iKinLinIneqConstr()
41 iKinLinIneqConstr::iKinLinIneqConstr(
const double _lowerBoundInf,
42 const double _upperBoundInf)
44 lowerBoundInf=_lowerBoundInf;
45 upperBoundInf=_upperBoundInf;
82 iKinLinIneqConstr::clone(obj);
97 iCubAdditionalArmConstraints::iCubAdditionalArmConstraints(
iCubArm &arm) :
102 size_t underscore=arm.
getType().find(
'_');
103 hw_version=(underscore!=string::npos)?strtod(arm.
getType().substr(underscore+2).c_str(),NULL):1.0;
105 double joint1_0, joint1_1;
106 double joint2_0, joint2_1;
111 shou_m=(joint1_1-joint1_0)/(joint2_1-joint2_0);
114 double joint3_0, joint3_1;
115 double joint4_0, joint4_1;
120 elb_m=(joint4_1-joint4_0)/(joint3_1-joint3_0);
137 yarp::sig::Matrix _C(0,row.length());
138 yarp::sig::Vector _lB;
139 yarp::sig::Vector _uB;
142 if (!(*
chain)[3+0].isBlocked() && !(*
chain)[3+1].isBlocked() &&
143 !(*
chain)[3+2].isBlocked())
149 for (
int i=0; i<3; i++)
150 if (!(*
chain)[i].isBlocked())
158 row[offs]=1.71; row[offs+1]=-1.71;
164 row[offs]=1.71; row[offs+1]=-1.71; row[offs+2]=-1.71;
170 row[offs+1]=1.0; row[offs+2]=1.0;
178 row[offs+1]=1.0; row[offs+2]=-
shou_m;
198 if (!(*
chain)[3+3].isBlocked() && !(*
chain)[3+3+1].isBlocked())
204 for (
int i=0; i<(3+3); i++)
205 if (!(*
chain)[i].isBlocked())
210 row[offs]=-
elb_m; row[offs+1]=1.0;
216 row[offs]=
elb_m; row[offs+1]=1.0;
249 yarp::sig::Vector &
xd;
254 yarp::sig::Vector
qd;
255 yarp::sig::Vector
q0;
292 yarp::sig::Vector new_q(dim);
293 for (Index i=0; i<(int)dim; i++)
296 if (!(q==new_q) || firstGo)
301 yarp::sig::Vector v(4,0.0);
311 yarp::sig::Matrix
H=chain.
getH();
312 yarp::sig::Matrix E=axis2dcm(v)*
H.transposed();
315 e_xyz[0]=xd[0]-
H(0,3);
316 e_xyz[1]=xd[1]-
H(1,3);
317 e_xyz[2]=xd[2]-
H(2,3);
323 submatrix(J1,J_xyz,0,2,0,dim-1);
324 submatrix(J1,J_ang,3,5,0,dim-1);
326 if (weight2ndTask!=0.0)
328 yarp::sig::Matrix H_2nd=chain2ndTask.
getH();
329 e_2nd[0]=w_2nd[0]*(xd_2nd[0]-H_2nd(0,3));
330 e_2nd[1]=w_2nd[1]*(xd_2nd[1]-H_2nd(1,3));
331 e_2nd[2]=w_2nd[2]*(xd_2nd[2]-H_2nd(2,3));
335 for (
unsigned int i=0; i<dim_2nd; i++)
337 J_2nd(0,i)=w_2nd[0]*J2(0,i);
338 J_2nd(1,i)=w_2nd[1]*J2(1,i);
339 J_2nd(2,i)=w_2nd[2]*J2(2,i);
343 if (weight3rdTask!=0.0)
344 for (
unsigned int i=0; i<dim; i++)
345 e_3rd[i]=w_3rd[i]*(qd_3rd[i]-q[i]);
356 yarp::sig::Vector &_xd,
double _weight2ndTask,
iKinChain &_chain2ndTask,
357 yarp::sig::Vector &_xd_2nd, yarp::sig::Vector &_w_2nd,
double _weight3rdTask,
359 bool *_exhalt=NULL) :
360 chain(c), q0(_q0), xd(_xd),
361 chain2ndTask(_chain2ndTask), xd_2nd(_xd_2nd), w_2nd(_w_2nd),
362 weight3rdTask(_weight3rdTask), qd_3rd(_qd_3rd), w_3rd(_w_3rd),
367 dim_2nd=chain2ndTask.
getDOF();
374 weight2ndTask=dim_2nd>0 ? _weight2ndTask : 0.0;
378 unsigned int n=(
unsigned int)q0.length();
390 e_zero.resize(3,0.0);
394 e_3rd.resize(dim,0.0);
396 J_zero.resize(3,dim); J_zero.zero();
397 J_xyz.resize(3,dim); J_xyz.zero();
398 J_ang.resize(3,dim); J_ang.zero();
399 J_2nd.resize(3,dim); J_2nd.zero();
428 yarp::sig::Vector
get_qd() {
return qd; }
434 void set_scaling(
double _obj_scaling,
double _x_scaling,
double _g_scaling)
436 __obj_scaling=_obj_scaling;
437 __x_scaling =_x_scaling;
438 __g_scaling =_g_scaling;
451 if (priority==
"position")
467 else if (priority==
"orientation")
491 IndexStyleEnum& index_style)
499 int lenLower=(int)LIC.
getlB().length();
500 int lenUpper=(int)LIC.
getuB().length();
502 if (lenLower && (lenLower==lenUpper) && (LIC.
getC().cols()==dim))
505 nnz_jac_g+=lenLower*dim;
511 nnz_h_lag=(dim*(dim+1))>>1;
512 index_style=TNLP::C_STYLE;
521 for (Index i=0; i<
n; i++)
523 x_l[i]=chain(i).getMin();
524 x_u[i]=chain(i).getMax();
529 for (Index i=0; i<m; i++)
538 g_l[i]=LIC.
getlB()[i-offs];
539 g_u[i]=LIC.
getuB()[i-offs];
548 Number* z_L, Number* z_U, Index m,
bool init_lambda,
551 for (Index i=0; i<
n; i++)
558 bool eval_f(Index
n,
const Number*
x,
bool new_x, Number& obj_value)
560 computeQuantities(
x);
562 obj_value=
norm2(*e_1st);
564 if (weight2ndTask!=0.0)
565 obj_value+=weight2ndTask*
norm2(e_2nd);
567 if (weight3rdTask!=0.0)
568 obj_value+=weight3rdTask*
norm2(e_3rd);
576 computeQuantities(
x);
578 yarp::sig::Vector grad=-2.0*(J_1st->transposed() * *e_1st);
580 if (weight2ndTask!=0.0)
581 grad=grad-2.0*weight2ndTask*(J_2nd.transposed()*e_2nd);
583 if (weight3rdTask!=0.0)
584 grad=grad-2.0*weight3rdTask*(w_3rd*e_3rd);
586 for (Index i=0; i<
n; i++)
593 bool eval_g(Index
n,
const Number*
x,
bool new_x, Index m, Number* g)
595 computeQuantities(
x);
599 for (Index i=0; i<m; i++)
614 bool eval_jac_g(Index
n,
const Number*
x,
bool new_x, Index m, Index nele_jac,
615 Index* iRow, Index *jCol, Number* values)
623 for (Index row=0; row<m; row++)
625 for (Index col=0; col<
n; col++)
635 computeQuantities(
x);
637 yarp::sig::Vector grad=-2.0*(J_cst->transposed() * *e_cst);
642 for (Index row=0; row<m; row++)
644 for (Index col=0; col<
n; col++)
652 values[
idx]=LIC.
getC()(row-offs,col);
664 bool eval_h(Index
n,
const Number*
x,
bool new_x, Number obj_factor,
665 Index m,
const Number* lambda,
bool new_lambda,
666 Index nele_hess, Index* iRow, Index* jCol, Number* values)
672 for (Index row=0; row<
n; row++)
674 for (Index col=0; col<=row; col++)
686 computeQuantities(
x);
689 if (weight2ndTask!=0.0)
693 for (Index row=0; row<
n; row++)
695 for (Index col=0; col<=row; col++)
700 yarp::sig::Vector h_xyz(3), h_ang(3), h_zero(3,0.0);
708 yarp::sig::Vector *h_1st,*h_cst;
720 values[
idx]=2.0*(obj_factor*(
dot(*J_1st,row,*J_1st,col)-
dot(*h_1st,*e_1st))+
721 lambda[0]*(
dot(*J_cst,row,*J_cst,col)-
dot(*h_cst,*e_cst)));
723 if ((weight2ndTask!=0.0) && (row<(int)dim_2nd) && (col<(int)dim_2nd))
728 yarp::sig::Vector h_2nd(3);
729 h_2nd[0]=(w_2nd[0]*w_2nd[0])*h2[0];
730 h_2nd[1]=(w_2nd[1]*w_2nd[1])*h2[1];
731 h_2nd[2]=(w_2nd[2]*w_2nd[2])*h2[2];
733 values[
idx]+=2.0*obj_factor*weight2ndTask*(
dot(J_2nd,row,J_2nd,col)-
dot(h_2nd,e_2nd));
746 Number inf_pr, Number inf_du, Number mu, Number d_norm,
747 Number regularization_size, Number alpha_du, Number alpha_pr,
748 Index ls_trials,
const IpoptData* ip_data,
749 IpoptCalculatedQuantities* ip_cq)
752 callback->
exec(xd,q);
762 Number* x_scaling,
bool& use_g_scaling, Index m,
765 obj_scaling=__obj_scaling;
767 for (Index i=0; i<
n; i++)
768 x_scaling[i]=__x_scaling;
770 for (Index j=0; j<m; j++)
771 g_scaling[j]=__g_scaling;
773 use_x_scaling=use_g_scaling=
true;
780 const Number* z_L,
const Number* z_U, Index m,
781 const Number* g,
const Number* lambda, Number obj_value,
782 const IpoptData* ip_data, IpoptCalculatedQuantities* ip_cq)
784 for (Index i=0; i<
n; i++)
796 iKinIpOptMin::iKinIpOptMin(
iKinChain &c,
const unsigned int _ctrlPose,
const double tol,
797 const double constr_tol,
const int max_iter,
798 const unsigned int verbose,
bool useHessian) :
810 App=
new IpoptApplication();
813 CAST_IPOPTAPP(
App)->Options()->SetNumericValue(
"constr_viol_tol",constr_tol);
826 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"hessian_approximation",
"limited-memory");
845 if ((priority==
"position") || (priority==
"orientation"))
863 for (
unsigned int i=0; i<_n; i++)
903 CAST_IPOPTAPP(
App)->Options()->SetNumericValue(
"max_cpu_time",max_cpu_time);
912 CAST_IPOPTAPP(
App)->Options()->GetNumericValue(
"max_cpu_time",max_cpu_time,
"");
937 CAST_IPOPTAPP(
App)->Options()->SetNumericValue(
"constr_viol_tol",constr_tol);
946 CAST_IPOPTAPP(
App)->Options()->GetNumericValue(
"constr_viol_tol",constr_tol,
"");
964 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"hessian_approximation",
"exact");
966 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"hessian_approximation",
"limited-memory");
974 const double _x_scaling,
const double _g_scaling)
982 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"nlp_scaling_method",
"user-scaling");
985 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"nlp_scaling_method",
"gradient-based");
997 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"derivative_test",
"second-order");
999 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"derivative_test",
"first-order");
1001 CAST_IPOPTAPP(
App)->Options()->SetStringValue(
"derivative_test_print_all",
"yes");
1014 CAST_IPOPTAPP(
App)->Options()->GetNumericValue(
"nlp_upper_bound_inf",upper,
"");
1022 CAST_IPOPTAPP(
App)->Options()->SetNumericValue(
"nlp_upper_bound_inf",upper);
1031 double weight2ndTask, yarp::sig::Vector &xd_2nd,
1032 yarp::sig::Vector &w_2nd,
double weight3rdTask,
1033 yarp::sig::Vector &qd_3rd, yarp::sig::Vector &w_3rd,
1038 weight3rdTask,qd_3rd,w_3rd,
1044 nlp->set_callback(iterate);
1046 ApplicationReturnStatus status=
CAST_IPOPTAPP(
App)->OptimizeTNLP(GetRawPtr(nlp));
1048 if (exit_code!=NULL)
1051 return nlp->get_qd();
1057 double weight2ndTask, yarp::sig::Vector &xd_2nd,
1058 yarp::sig::Vector &w_2nd)
1060 yarp::sig::Vector dummy(1);
1061 return solve(q0,xd,weight2ndTask,xd_2nd,w_2nd,0.0,dummy,dummy);
1068 yarp::sig::Vector dummy(1);
1069 return solve(q0,xd,0.0,dummy,dummy,0.0,dummy,dummy);
Class for dealing with additional iCub arm's constraints.
void update(void *)
Updates internal state.
A class for defining the iCub Arm.
A Base class for defining a Serial Link Chain.
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...
yarp::sig::Matrix getHN() const
Returns HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
bool setHN(const yarp::sig::Matrix &_HN)
Sets HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
void prepareForHessian()
Prepares computation for a successive call to fastHessian_ij().
yarp::sig::Matrix GeoJacobian(const unsigned int i)
Returns the geometric Jacobian of the ith link.
void clear()
Removes all Links.
yarp::sig::Vector fastHessian_ij(const unsigned int i, const unsigned int j)
Returns the 6x1 vector where is the forward kinematic function and is the DOF couple.
yarp::sig::Vector setAng(const yarp::sig::Vector &q)
Sets the free joint angles to values of q[i].
yarp::sig::Matrix getH0() const
Returns H0, the rigid roto-translation matrix from the root reference frame to the 0th frame.
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 setH0(const yarp::sig::Matrix &_H0)
Sets H0, the rigid roto-translation matrix from the root reference frame to the 0th frame.
void setAllConstraints(bool _constrained)
Sets the constraint status of all chain links.
void setTol(const double tol)
Sets cost function tolerance.
double getConstrTol() const
Retrieves constraints tolerance.
double getMaxCpuTime() const
Retrieves the current value of Maximum CPU seconds.
void setConstrTol(const double constr_tol)
Sets constraints tolerance.
void setHessianOpt(const bool useHessian)
Selects whether to rely on exact Hessian computation or enable Quasi-Newton approximation (Hessian is...
void setUserScaling(const bool useUserScaling, const double _obj_scaling, const double _x_scaling, const double _g_scaling)
Enables/disables user scaling factors.
bool set_posePriority(const std::string &priority)
Sets the Pose priority for weighting more either position or orientation while reaching in full pose.
virtual ~iKinIpOptMin()
Default destructor.
int getMaxIter() const
Retrieves the current value of Maximum Iteration.
double getTol() const
Retrieves cost function tolerance.
void setMaxIter(const int max_iter)
Sets Maximum Iteration.
void getBoundsInf(double &lower, double &upper)
Returns the lower and upper bounds to represent -inf and +inf.
void setDerivativeTest(const bool enableTest, const bool enable2ndDer=false)
Enable\disable derivative test at each call to solve method (disabled at start-up by default).
iKinChain & get2ndTaskChain()
Retrieves the 2nd task's chain.
void setBoundsInf(const double lower, const double upper)
Sets the lower and upper bounds to represent -inf and +inf.
void set_ctrlPose(const unsigned int _ctrlPose)
Sets the state of Pose control settings.
void specify2ndTaskEndEff(const unsigned int n)
Selects the End-Effector of the 2nd task by giving the ordinal number n of last joint pointing at it.
virtual yarp::sig::Vector solve(const yarp::sig::Vector &q0, yarp::sig::Vector &xd, double weight2ndTask, yarp::sig::Vector &xd_2nd, yarp::sig::Vector &w_2nd, double weight3rdTask, yarp::sig::Vector &qd_3rd, yarp::sig::Vector &w_3rd, int *exit_code=NULL, bool *exhalt=NULL, iKinIterateCallback *iterate=NULL)
Executes the IpOpt algorithm trying to converge on target.
void setVerbosity(const unsigned int verbose)
Sets Verbosity.
void setMaxCpuTime(const double max_cpu_time)
Sets Maximum CPU seconds.
Class for defining iteration callback.
virtual void exec(const yarp::sig::Vector &xd, const yarp::sig::Vector &q)=0
Defines the callback body to be called at each iteration.
iKinChain * asChain()
Returns a pointer to the Limb seen as Chain object.
std::string getType() const
Returns the Limb type as a string.
Class for defining Linear Inequality Constraints of the form lB <= C*q <= uB for the nonlinear proble...
yarp::sig::Vector & getlB()
Returns a reference to the lower bounds vector lB.
bool isActive()
Returns the state of inequality constraints evaluation.
void setActive(bool _active)
Sets the state of inequality constraints evaluation.
yarp::sig::Vector & getuB()
Returns a reference to the upper bounds vector uB.
yarp::sig::Matrix & getC()
Returns a reference to the constraints matrix C.
yarp::sig::Vector * e_cst
yarp::sig::Vector & w_2nd
iKinIterateCallback * callback
void set_scaling(double _obj_scaling, double _x_scaling, double _g_scaling)
bool get_nlp_info(Index &n, Index &m, Index &nnz_jac_g, Index &nnz_h_lag, IndexStyleEnum &index_style)
bool get_starting_point(Index n, bool init_x, Number *x, bool init_z, Number *z_L, Number *z_U, Index m, bool init_lambda, Number *lambda)
virtual void computeQuantities(const Number *x)
void set_bound_inf(double lower, double upper)
bool get_bounds_info(Index n, Number *x_l, Number *x_u, Index m, Number *g_l, Number *g_u)
bool eval_g(Index n, const Number *x, bool new_x, Index m, Number *g)
yarp::sig::Vector get_qd()
bool eval_h(Index n, const Number *x, bool new_x, Number obj_factor, Index m, const Number *lambda, bool new_lambda, Index nele_hess, Index *iRow, Index *jCol, Number *values)
yarp::sig::Vector & qd_3rd
bool eval_f(Index n, const Number *x, bool new_x, Number &obj_value)
bool intermediate_callback(AlgorithmMode mode, Index iter, Number obj_value, Number inf_pr, Number inf_du, Number mu, Number d_norm, Number regularization_size, Number alpha_du, Number alpha_pr, Index ls_trials, const IpoptData *ip_data, IpoptCalculatedQuantities *ip_cq)
yarp::sig::Vector & w_3rd
yarp::sig::Vector & xd_2nd
yarp::sig::Matrix * J_1st
void finalize_solution(SolverReturn status, Index n, const Number *x, const Number *z_L, const Number *z_U, Index m, const Number *g, const Number *lambda, Number obj_value, const IpoptData *ip_data, IpoptCalculatedQuantities *ip_cq)
bool set_posePriority(const string &priority)
yarp::sig::Matrix * J_cst
iKin_NLP(iKinChain &c, unsigned int _ctrlPose, const yarp::sig::Vector &_q0, yarp::sig::Vector &_xd, double _weight2ndTask, iKinChain &_chain2ndTask, yarp::sig::Vector &_xd_2nd, yarp::sig::Vector &_w_2nd, double _weight3rdTask, yarp::sig::Vector &_qd_3rd, yarp::sig::Vector &_w_3rd, iKinLinIneqConstr &_LIC, bool *_exhalt=NULL)
void set_callback(iKinIterateCallback *_callback)
bool get_scaling_parameters(Number &obj_scaling, bool &use_x_scaling, Index n, Number *x_scaling, bool &use_g_scaling, Index m, Number *g_scaling)
bool eval_grad_f(Index n, const Number *x, bool new_x, Number *grad_f)
bool eval_jac_g(Index n, const Number *x, bool new_x, Index m, Index nele_jac, Index *iRow, Index *jCol, Number *values)
yarp::sig::Vector * e_1st
static uint32_t idx[BOARD_NUM]
double dot(const yarp::sig::Matrix &A, int colA, const yarp::sig::Matrix &B, int colB)
Returns the dot product between two vectors given in the form: matrix(:,col).
double norm2(const yarp::sig::Matrix &M, int col)
Returns the squared norm of the vector given in the form: matrix(:,col).
#define IKINCTRL_POSE_FULL
#define IKINCTRL_POSE_ANG
#define IKINIPOPT_SHOULDER_MAXABDUCTION
bool lower(Value &a, Value &b)