68 int num_r = request.
d + 1;
69 Eigen::MatrixXd x_t(num_r, request.
xy.cols());
72 for (
auto r = 0;
r < num_r;
r++)
73 x_t.row(
r) = request.
xy.row(0).array().pow(
r);
75 Eigen::MatrixXd mat = x_t * x_t.transpose();
76 Eigen::VectorXd vec = x_t * request.
xy.row(1);
78 result.
p = mat.lu().solve(vec).head(num_r);
82 int num_constraints = request.
xyfp.cols() + request.
xyfs.cols();
84 Eigen::MatrixXd a_t(num_r, num_constraints);
85 Eigen::MatrixXd a_tp(num_r, request.
xyfp.cols());
86 Eigen::MatrixXd a_ts(num_r, request.
xyfs.cols());
88 for (
auto r = 0;
r < num_r;
r++)
90 x_t.row(
r) = request.
xy.row(0).array().pow(
r);
93 a_tp.row(
r) = request.
xyfp.row(0).array().pow(
r);
97 a_ts.row(
r) = request.
xyfs.row(0).array() * 0.0;
99 a_ts.row(
r) = request.
xyfs.row(0).array().pow(
r - 1) /
r;
103 Eigen::MatrixXd top(num_r, num_r + num_constraints);
104 Eigen::MatrixXd bot(num_constraints, num_r + num_constraints);
105 Eigen::MatrixXd mat(num_r + num_constraints, num_r + num_constraints);
106 Eigen::VectorXd vec(num_r + num_constraints);
111 vec << 2*x_t*request.
xy.row(1).transpose(), request.
xyfp.row(1).transpose(), request.
xyfs.row(1).transpose();
116 vec << 2*x_t*request.
xy.row(1).transpose(), request.
xyfp.row(1).transpose();
121 vec << 2*x_t*request.
xy.row(1).transpose(), request.
xyfs.row(1).transpose();
124 top << 2*x_t*x_t.transpose(), a_t;
125 bot << a_t.transpose(), Eigen::MatrixXd::Zero(num_constraints, num_constraints);
129 result.
p = mat.lu().solve(vec).head(num_r);
134 result.
x = request.
xy.row(0);
135 result.
y = x_t.transpose() * result.
p;
143 result.
y = x_t.transpose() * result.
p;
151 v = Eigen::MatrixXd::Ones(order+1, domain_vals.size());
152 for(
auto p = 1u; p <= order; p++)
153 v.row(p) = domain_vals.pow(p);
157 const Eigen::MatrixXd ¶meters,Eigen::VectorXd &domain_values)
159 Eigen::VectorXd
distance(parameters.rows());
160 Eigen::VectorXd velocity(parameters.rows());
161 Eigen::VectorXd t(parameters.rows());
162 Eigen::VectorXd domain_dist(parameters.cols());
165 domain_values.resize(parameters.cols());
166 for(
auto r = 0;
r < parameters.rows();
r++)
171 domain_dist(0) = 0.0;
172 for(
auto c = 1; c < parameters.cols(); c++)
174 distance(
r) += std::abs((parameters(
r, c)) - (parameters(
r, c - 1)));
182 domain_values = domain_dist/velocity(
r);
187 bool applyPolynomialSmoothing(moveit::core::RobotModelConstPtr robot_model,
const std::string& group_name, Eigen::MatrixXd& parameters,
188 int poly_order,
double joint_limit_margin)
190 using namespace Eigen;
193 const std::vector<const JointModel*> &joint_models = robot_model->getJointModelGroup(group_name)->getActiveJointModels();
195 int num_timesteps = parameters.cols();
197 VectorXd domain_vals;
198 domain_vals.setLinSpaced(num_timesteps,0,1);
200 request.
d = poly_order;
201 request.
xy.resize(2, num_timesteps);
202 request.
xy.row(0) = domain_vals;
203 for(
auto r = 0;
r < parameters.rows();
r++)
205 request.
xy.row(1) = parameters.row(
r);
206 request.
xyfp.resize(2, 2);
207 request.
xyfp(0, 0) = request.
xy(0, 0);
208 request.
xyfp(1, 0) = request.
xy(1, 0);
209 request.
xyfp(0, 1) = request.
xy(0, num_timesteps - 1);
210 request.
xyfp(1, 1) = request.
xy(1, num_timesteps - 1);
214 for(
auto i = 0; i < results.
y.size(); ++i)
215 joint_models[
r]->enforcePositionBounds(&results.
y[i]);
219 double min = results.
y.minCoeff();
220 double max = results.
y.maxCoeff();
221 finished = joint_models[
r]->satisfiesPositionBounds(&min, joint_limit_margin) &&
222 joint_models[
r]->satisfiesPositionBounds(&max, joint_limit_margin);
224 if ((results.
p.array() != results.
p.array()).any())
226 ROS_ERROR(
"Smoother, joint %s polynomial fit failed!", joint_models[
r]->
getName().c_str());
232 ROS_ERROR(
"Smoother, joint %s not within limits, Min: %f, Max: %f", joint_models[
r]->
getName().c_str(), min, max);
236 parameters.row(
r) = results.
y;
Eigen::VectorXd y
The fit values.
bool hasSlopeConstraints() const
Check if request has slope constraints.
The Polynomial Fit request data.
Eigen::VectorXd p
The polynomial parameter found during fit.
bool hasConstraints() const
Check if request has constraints.
Eigen::Matrix< double, 2, Eigen::Dynamic > xyfp
The position constraint data.
std::string getName(void *handle)
Eigen::VectorXd x
The fit domain values.
The Polynomial Fit results data.
double min(double a, double b)
Eigen::Matrix< double, 2, Eigen::Dynamic > xy
The fit data.
bool successful
True if polynomial fit was found, otherwise false.
void fillVandermondeMatrix(const Eigen::ArrayXd &domain_vals, const int &order, Eigen::MatrixXd &v)
Generates a Vandermonde matrix from the domain values as described here https://en.wikipedia.org/wiki/Vandermonde_matrix. It uses the poly_order parameter in order to set the size of the matrix.
int d
Degree of the polynomial.
Eigen::VectorXd output_domain
The fit output domain. If not provided it will use the input domain.
void generateMinimumDomainValues(const std::vector< const moveit::core::JointModel * > joint_models, const Eigen::MatrixXd ¶meters, Eigen::VectorXd &domain_values)
Get the polynomial smoother domain values.
bool hasPositionConstraints() const
Check if request has position constraints.
Eigen::Matrix< double, 2, Eigen::Dynamic > xyfs
The slope constraint data.
bool applyPolynomialSmoothing(moveit::core::RobotModelConstPtr robot_model, const std::string &group_name, Eigen::MatrixXd ¶meters, int poly_order=5, double joint_limit_margin=1e-5)
Applies a polynomial smoothing method to a trajectory. It checks for joint limits and makes correctio...
double max(double a, double b)
double distance(const urdf::Pose &transform)
PolyFitResults polyFit(const PolyFitRequest &request)
Fit a polynomial with fixed indices.