20#include <yarp/math/Math.h>
25#include <IpIpoptApplication.hpp>
28using namespace yarp::os;
29using namespace yarp::sig;
30using namespace yarp::math;
45 A(0,0)=
x[0];
A(0,1)=
x[3];
A(0,2)=
x[6];
A(0,3)=
x[9];
46 A(1,0)=
x[1];
A(1,1)=
x[4];
A(1,2)=
x[7];
A(1,3)=
x[10];
47 A(2,0)=
x[2];
A(2,1)=
x[5];
A(2,2)=
x[8];
A(2,3)=
x[11];
57 const deque<Vector> &
p0;
58 const deque<Vector> &
p1;
69 const deque<Vector> &_p1,
70 const Matrix &_min,
const Matrix &_max) :
77 for (
int c=0; c<
A0.cols(); c++)
79 for (
int r=0; r<
A0.rows()-1; r++)
82 this->dA.push_back(
dA);
90 int row_max=(int)std::min(this->A0.rows()-1,
A0.rows()-1);
91 int col_max=(int)std::min(this->A0.cols(),
A0.cols());
92 this->A0.setSubmatrix(
A0.submatrix(0,row_max,0,col_max),0,0);
102 bool get_nlp_info(Ipopt::Index &
n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g,
103 Ipopt::Index &nnz_h_lag, IndexStyleEnum &index_style)
106 m=nnz_jac_g=nnz_h_lag=0;
107 index_style=TNLP::C_STYLE;
114 Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
117 for (
int c=0; c<
A0.cols(); c++)
119 for (
int r=0; r<
A0.rows()-1; r++)
132 bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U,
133 Ipopt::Index m,
bool init_lambda, Ipopt::Number *lambda)
136 for (
int c=0; c<
A0.cols(); c++)
138 for (
int r=0; r<
A0.rows()-1; r++)
146 bool eval_f(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
147 Ipopt::Number &obj_value)
154 for (
size_t i=0; i<
p0.size(); i++)
157 obj_value/=
p0.size();
165 Ipopt::Number *grad_f)
168 for (Ipopt::Index i=0; i<
n; i++)
173 for (
size_t i=0; i<
p0.size(); i++)
175 Vector d=
p1[i]-
A*
p0[i];
176 for (Ipopt::Index j=0; j<
n; j++)
177 grad_f[j]-=2.0*
dot(d,(
dA[j]*
p0[i]));
180 for (Ipopt::Index i=0; i<
n; i++)
181 grad_f[i]/=
p0.size();
188 bool eval_g(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
189 Ipopt::Index m, Ipopt::Number *g)
196 Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow,
197 Ipopt::Index *jCol, Ipopt::Number *values)
203 bool eval_h(Ipopt::Index
n,
const Ipopt::Number *
x,
bool new_x,
204 Ipopt::Number obj_factor, Ipopt::Index m,
const Ipopt::Number *lambda,
205 bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow,
206 Ipopt::Index *jCol, Ipopt::Number *values)
213 const Ipopt::Number *
x,
const Ipopt::Number *z_L,
214 const Ipopt::Number *z_U, Ipopt::Index m,
215 const Ipopt::Number *g,
const Ipopt::Number *lambda,
216 Ipopt::Number obj_value,
const Ipopt::IpoptData *ip_data,
217 Ipopt::IpoptCalculatedQuantities *ip_cq)
235 for (
int c=0; c<
min.cols(); c++)
237 for (
int r=0; r<
min.rows()-1; r++)
254 row_max=(int)std::min(this->min.rows()-1,
min.rows()-1);
255 col_max=(int)std::min(this->min.cols(),
min.cols());
256 this->min.setSubmatrix(
min.submatrix(0,row_max,0,col_max),0,0);
258 row_max=(int)std::min(this->max.rows()-1,
max.rows()-1);
259 col_max=(int)std::min(this->max.cols(),
max.cols());
260 this->max.setSubmatrix(
max.submatrix(0,row_max,0,col_max),0,0);
270 for (
size_t i=0; i<
p0.size(); i++)
284 if ((
p0.length()>=3) && (
p1.length()>=3))
286 Vector _p0=
p0.subVector(0,2); _p0.push_back(1.0);
287 Vector _p1=
p1.subVector(0,2); _p1.push_back(1.0);
289 this->p0.push_back(_p0);
290 this->p1.push_back(_p1);
301 deque<Vector> &p1)
const
319 int row_max=(int)std::min(
A0.rows()-1,
A.rows()-1);
320 int col_max=(int)std::min(
A0.cols(),
A.cols());
321 A0.setSubmatrix(
A.submatrix(0,row_max,0,col_max),0,0);
330 if (options.check(
"max_iter"))
331 max_iter=options.find(
"max_iter").asInt32();
333 if (options.check(
"tol"))
334 tol=options.find(
"tol").asFloat64();
345 Ipopt::SmartPtr<Ipopt::IpoptApplication> app=
new Ipopt::IpoptApplication;
346 app->Options()->SetNumericValue(
"tol",
tol);
347 app->Options()->SetIntegerValue(
"acceptable_iter",0);
348 app->Options()->SetStringValue(
"mu_strategy",
"adaptive");
349 app->Options()->SetIntegerValue(
"max_iter",
max_iter);
350 app->Options()->SetStringValue(
"nlp_scaling_method",
"gradient-based");
351 app->Options()->SetStringValue(
"jac_c_constant",
"yes");
352 app->Options()->SetStringValue(
"jac_d_constant",
"yes");
353 app->Options()->SetStringValue(
"hessian_constant",
"yes");
354 app->Options()->SetStringValue(
"hessian_approximation",
"limited-memory");
355 app->Options()->SetIntegerValue(
"print_level",0);
356 app->Options()->SetStringValue(
"derivative_test",
"none");
362 Ipopt::ApplicationReturnStatus status=app->OptimizeTNLP(GetRawPtr(nlp));
367 return (status==Ipopt::Solve_Succeeded);
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)
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)
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)
bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, IndexStyleEnum &index_style)
const deque< Vector > & p0
AffinityWithMatchedPointsNLP(const deque< Vector > &_p0, const deque< Vector > &_p1, const Matrix &_min, const Matrix &_max)
bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
const deque< Vector > & p1
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)
virtual Matrix get_result() const
bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
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)
virtual void set_A0(const Matrix &A0)
std::deque< yarp::sig::Vector > p1
virtual bool setInitialGuess(const yarp::sig::Matrix &A)
Allow specifiying the initial guess for the affine transformation matrix we seek for.
virtual void setBounds(const yarp::sig::Matrix &min, const yarp::sig::Matrix &max)
Allow specifying the minimum and maximum bounds of the elements belonging to the affine transformatio...
virtual bool calibrate(yarp::sig::Matrix &A, double &error)
Perform optimization to determine the affine matrix A.
std::deque< yarp::sig::Vector > p0
double evalError(const yarp::sig::Matrix &A)
virtual bool addPoints(const yarp::sig::Vector &p0, const yarp::sig::Vector &p1)
Add to the internal database the 3D-point p0 and the 3D-point p1 which is supposed to correspond to A...
virtual bool setCalibrationOptions(const yarp::os::Property &options)
Allow setting further options used during calibration.
virtual void clearPoints()
Clear the internal database of 3D points.
virtual void getPoints(std::deque< yarp::sig::Vector > &p0, std::deque< yarp::sig::Vector > &p1) const
Retrieve copies of the database of 3D-points pairs.
AffinityWithMatchedPoints()
Default Constructor.
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).
double norm(const yarp::sig::Matrix &M, int col)
Returns the norm of the vector given in the form: matrix(:,col).
Matrix computeA(const Ipopt::Number *x)
This file contains the definition of unique IDs for the body parts and the skin parts of the robot.