26 #include <yarp/math/Math.h> 27 #include <yarp/math/SVD.h> 34 #include "superquadric.h" 39 points_downsampled.clear();
46 if (point_cloud.size()<optimizer_points)
48 for (
size_t i=0;i<point_cloud.size();i++)
50 points_downsampled.push_back(point_cloud[i].subVector(0,2));
55 int count=point_cloud.size()/optimizer_points;
57 for (
size_t i=0; i<point_cloud.size(); i+=count)
59 points_downsampled.push_back(point_cloud[i].subVector(0,2));
63 yInfo(
"[Superquadric]: points actually used for modeling: %lu ",points_downsampled.size());
66 computeX0(x0, points_downsampled);
71 Ipopt::Index &nnz_h_lag, Ipopt::TNLP::IndexStyleEnum &index_style)
74 m=nnz_jac_g=nnz_h_lag=0;
75 index_style=TNLP::C_STYLE;
84 if (bounds_automatic==
true)
86 bounds(0,1)=x0[0]*2.0;
87 bounds(1,1)=x0[1]*2.0;
88 bounds(2,1)=x0[2]*2.0;
94 bounds(5,0)=x0[5]-bounds(0,1);
95 bounds(6,0)=x0[6]-bounds(1,1);
96 bounds(7,0)=x0[7]-bounds(2,1);
97 bounds(5,1)=x0[5]+bounds(0,1);
98 bounds(6,1)=x0[6]+bounds(1,1);
99 bounds(7,1)=x0[7]+bounds(2,1);
112 Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
116 for (Ipopt::Index i=0; i<n; i++)
127 bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U,
128 Ipopt::Index m,
bool init_lambda, Ipopt::Number *lambda)
130 for (Ipopt::Index i=0;i<n;i++)
139 Ipopt::Number &obj_value)
141 F(x,points_downsampled, new_x);
142 obj_value=aux_objvalue;
157 Matrix R=euler2dcm(euler);
159 for(
size_t i=0;i<points.size();i++)
161 double tmp=pow(f(x,R,points[i]),x[3])-1;
164 value*=x[0]*x[1]*x[2]/points.size();
171 const Vector &point_cloud)
173 double num1 = R(0, 0)*point_cloud[0] + R(0, 1)*point_cloud[1] + R(0, 2)*point_cloud[2] - x[5] * R(0, 0) - x[6] * R(0, 1) - x[7] * R(0, 2);
174 double num2 = R(1, 0)*point_cloud[0] + R(1, 1)*point_cloud[1] + R(1, 2)*point_cloud[2] - x[5] * R(1, 0) - x[6] * R(1, 1) - x[7] * R(1, 2);
175 double num3 = R(2, 0)*point_cloud[0] + R(2, 1)*point_cloud[1] + R(2, 2)*point_cloud[2] - x[5] * R(2, 0) - x[6] * R(2, 1) - x[7] * R(2, 2);
176 double tmp = pow(abs(num1 / x[0]), 2.0 / x[4]) + pow(abs(num2 / x[1]), 2.0 / x[4]);
177 return pow(abs(tmp), x[4] / x[3]) + pow(abs(num3 / x[2]), (2.0 / x[3]));
189 Matrix R=euler2dcm(euler);
191 for (
size_t i=0;i<points.size();i++)
193 double tmp=pow(f_v(x,R,points[i]),x[3])-1;
197 value*=x[0]*x[1]*x[2]/points.size();
203 const Vector &point_cloud)
205 double num1 = R(0, 0)*point_cloud[0] + R(0, 1)*point_cloud[1] + R(0, 2)*point_cloud[2] - x[5] * R(0, 0) - x[6] * R(0, 1) - x[7] * R(0, 2);
206 double num2 = R(1, 0)*point_cloud[0] + R(1, 1)*point_cloud[1] + R(1, 2)*point_cloud[2] - x[5] * R(1, 0) - x[6] * R(1, 1) - x[7] * R(1, 2);
207 double num3 = R(2, 0)*point_cloud[0] + R(2, 1)*point_cloud[1] + R(2, 2)*point_cloud[2] - x[5] * R(2, 0) - x[6] * R(2, 1) - x[7] * R(2, 2);
208 double tmp = pow(abs(num1 / x[0]), 2.0 / x[4]) + pow(abs(num2 / x[1]), 2.0 / x[4]);
209 return pow(abs(tmp), x[4] / x[3]) + pow(abs(num3 / x[2]), (2.0 / x[3]));
214 Ipopt::Number *grad_f)
217 double grad_p, grad_n;
220 for (Ipopt::Index j=0;j<n;j++)
223 for (Ipopt::Index j=0;j<n;j++)
227 grad_p=F_v(x_tmp,points_downsampled);
231 grad_n=F_v(x_tmp,points_downsampled);
233 grad_f[j]=(grad_p-grad_n)/(2.0*eps);
241 Ipopt::Index m, Ipopt::Number *g)
248 Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow,
249 Ipopt::Index *jCol, Ipopt::Number *values)
259 bounds_automatic=b_automatic;
260 obj_class=object_class;
262 readMatrix(
"bounds_"+object_class,bounds, 11, rf);
274 for (
size_t i=0; i<point_cloud.size();i++)
276 Vector &point=point_cloud[i];
282 x0[5]/=point_cloud.size();
283 x0[6]/=point_cloud.size();
284 x0[7]/=point_cloud.size();
286 computeInitialOrientation(x0,point_cloud);
288 Matrix bounding_box(3,2);
289 bounding_box=computeBoundingBox(point_cloud,x0);
291 x0[0]=(-bounding_box(0,0)+bounding_box(0,1))/2;
292 x0[1]=(-bounding_box(1,0)+bounding_box(1,1))/2;
293 x0[2]=(-bounding_box(2,0)+bounding_box(2,1))/2;
309 for (
size_t i=0;i<point_cloud.size(); i++)
311 Vector &point=point_cloud[i];
312 M(0,0)= M(0,0) + (point[1]-x0[6])*(point[1]-x0[6]) + (point[2]-x0[7])*(point[2]-x0[7]);
313 M(0,1)= M(0,1) - (point[1]-x0[6])*(point[0]-x0[5]);
314 M(0,2)= M(0,2) - (point[2]-x0[7])*(point[0]-x0[5]);
315 M(1,1)= M(1,1) + (point[0]-x0[5])*(point[0]-x0[5]) + (point[2]-x0[7])*(point[2]-x0[7]);
316 M(2,2)= M(2,2) + (point[1]-x0[6])*(point[1]-x0[6]) + (point[0]-x0[5])*(point[0]-x0[5]);
317 M(1,2)= M(1,2) - (point[2]-x0[7])*(point[1]-x0[6]);
320 M(0,0)= M(0,0)/point_cloud.size();
321 M(0,1)= M(0,1)/point_cloud.size();
322 M(0,2)= M(0,2)/point_cloud.size();
323 M(1,1)= M(1,1)/point_cloud.size();
324 M(2,2)= M(2,2)/point_cloud.size();
325 M(1,2)= M(1,2)/point_cloud.size();
340 x0.setSubvector(8,dcm2euler(R));
349 R3=euler2dcm(x0.subVector(8,10)).submatrix(0,2,0,2);
352 point=R3.transposed()*points[0];
361 for (
size_t i=0; i<points.size();i++)
363 Vector &pnt=points[i];
364 point=R3.transposed()*pnt;
390 string tag_x=tag+
"_x";
391 string tag_y=tag+
"_y";
396 if (Bottle *b=rf->find(tag.c_str()).asList())
399 if (b->size()>=dimension)
401 for(
int i=0; i<b->size();i++)
402 col.push_back(b->get(i).asDouble());
404 matrix.setCol(0, col);
411 if (tag==
"bounds_"+obj_class)
417 if (Bottle *b=rf->find(tag_x.c_str()).asList())
420 if (b->size()>=dimension)
422 for(
int i=0; i<b->size();i++)
423 col.push_back(b->get(i).asDouble());
425 matrix.setCol(0, col);
431 if (Bottle *b=rf->find(tag_y.c_str()).asList())
434 if (b->size()>=dimension)
436 for (
int i=0; i<b->size();i++)
437 col.push_back(b->get(i).asDouble());
438 matrix.setCol(1, col);
451 const Ipopt::Number *x,
const Ipopt::Number *z_L,
452 const Ipopt::Number *z_U, Ipopt::Index m,
453 const Ipopt::Number *g,
const Ipopt::Number *lambda,
454 Ipopt::Number obj_value,
const Ipopt::IpoptData *ip_data,
455 Ipopt::IpoptCalculatedQuantities *ip_cq)
458 for (Ipopt::Index i=0; i<n; i++)
double f_v(const yarp::sig::Vector &x, const yarp::sig::Matrix &R, const yarp::sig::Vector &point_cloud)
Auxiliary function for computing cost function of the nonlinear problem to be solved with ipopt...
void computeBounds()
Compute bounds variable from the point cloud for speeding up optimization.
void F(const Ipopt::Number *x, std::deque< yarp::sig::Vector > &points, bool &new_x)
Auxiliary function for computing cost function of the nonlinear problem to be solved with ipopt...
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)
Get the starting point for the nonlinear problem to be solved with ipopt.
bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
Cost function of the nonlinear problem to be solved with ipopt.
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)
Get variable bounds for the nonlinear problem to be solved with ipopt.
void setPoints(const std::deque< yarp::sig::Vector > &point_cloud, const int &optimizer_points)
Set point to be used for superquadric estimation.
void computeInitialOrientation(yarp::sig::Vector &x0, std::deque< yarp::sig::Vector > &point_cloud)
Compute initial superquadric orientation from the point cloud.
bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
Gradient of the cost function of the nonlinear problem.
yarp::sig::Vector get_result() const
Extract the solution.
bool readMatrix(const std::string &tag, yarp::sig::Matrix &matrix, const int &dimension, yarp::os::ResourceFinder *rf)
Function for reading matrices from config files.
double f(const Ipopt::Number *x, const yarp::sig::Matrix &R, const yarp::sig::Vector &point_cloud)
Auxiliary function for computing cost function of the nonlinear problem to be solved with ipopt...
yarp::sig::Matrix computeBoundingBox(std::deque< yarp::sig::Vector > &points, const yarp::sig::Vector &x0)
Compute bounding box from the point cloud.
void configure(yarp::os::ResourceFinder *rf, bool bounds_aut, const std::string &object_class)
Configure function.
void computeX0(yarp::sig::Vector &x0, std::deque< yarp::sig::Vector > &point_cloud)
Compute a good starting point for the nonlinear problem.
bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, Ipopt::TNLP::IndexStyleEnum &index_style)
Get info for the nonlinear problem to be solved with ipopt.
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)
Finalize the solution.
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)
Jacobian of the constraints of the nonlinear problem.
bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
Constraints of the nonlinear problem.
void init()
Init function.
double F_v(const yarp::sig::Vector &x, const std::deque< yarp::sig::Vector > &points)
Auxiliary function for computing the gradient of cost function of the nonlinear problem.