Control Libraries 6.3.4
Loading...
Searching...
No Matches
Model.cpp
1#include <iostream>
2#include <pinocchio/algorithm/frames.hpp>
3#include <pinocchio/algorithm/joint-configuration.hpp>
4#include "robot_model/Model.hpp"
5#include "robot_model/exceptions/FrameNotFoundException.hpp"
6#include "robot_model/exceptions/InverseKinematicsNotConvergingException.hpp"
7#include "robot_model/exceptions/InvalidJointStateSizeException.hpp"
8
9namespace robot_model {
10Model::Model(const std::string& robot_name, const std::string& urdf_path) :
11 robot_name_(std::make_shared<state_representation::Parameter<std::string>>("robot_name", robot_name)),
12 urdf_path_(std::make_shared<state_representation::Parameter<std::string>>("urdf_path", urdf_path)) {
13 this->init_model();
14}
15
16Model::Model(const Model& model) :
17 robot_name_(model.robot_name_),
18 urdf_path_(model.urdf_path_) {
19 this->init_model();
20}
21
22bool Model::create_urdf_from_string(const std::string& urdf_string, const std::string& desired_path) {
23 std::ofstream file(desired_path);
24 if (file.good() && file.is_open()) {
25 file << urdf_string;
26 file.close();
27 return true;
28 }
29 return false;
30}
31
32void Model::init_model() {
33 pinocchio::urdf::buildModel(this->get_urdf_path(), this->robot_model_);
34 this->robot_data_ = pinocchio::Data(this->robot_model_);
35 // get the frames
36 std::vector<std::string> frames;
37 for (auto& f : this->robot_model_.frames) {
38 frames.push_back(f.name);
39 }
40 // remove universe and root_joint frame added by Pinocchio
41 this->frames_ = std::vector<std::string>(frames.begin() + 2, frames.end());
42 this->init_qp_solver();
43}
44
45bool Model::init_qp_solver() {
46 // clear the solver
47 this->solver_.data()->clearHessianMatrix();
48 this->solver_.data()->clearLinearConstraintsMatrix();
49 this->solver_.clearSolver();
50
51 unsigned int nb_joints = this->get_number_of_joints();
52 // initialize the matrices
53 this->hessian_ = Eigen::SparseMatrix<double>(nb_joints + 1, nb_joints + 1);
54 this->gradient_ = Eigen::VectorXd::Zero(nb_joints + 1);
55 this->constraint_matrix_ = Eigen::SparseMatrix<double>(3 * nb_joints + 1 + 2, nb_joints + 1);
56 this->lower_bound_constraints_ = Eigen::VectorXd::Zero(3 * nb_joints + 1 + 2);
57 this->upper_bound_constraints_ = Eigen::VectorXd::Zero(3 * nb_joints + 1 + 2);
58
59 // reserve the size of the matrices
60 this->hessian_.reserve(nb_joints * nb_joints + 1);
61 this->constraint_matrix_.reserve(5 * nb_joints + 2 * (nb_joints * nb_joints + nb_joints) + 4 * nb_joints + 3);
62
63 Eigen::VectorXd lower_position_limit = this->robot_model_.lowerPositionLimit;
64 Eigen::VectorXd upper_position_limit = this->robot_model_.upperPositionLimit;
65 Eigen::VectorXd velocity_limit = this->robot_model_.velocityLimit;
66
67 // configure the QP problem
68 this->solver_.settings()->setVerbosity(false);
69 this->solver_.settings()->setWarmStart(true);
70
71 // joint dependent constraints
72 for (unsigned int n = 0; n < nb_joints; ++n) {
73 // joint limits
74 this->constraint_matrix_.coeffRef(n, n) = 1.0;
75 // joint velocity limits
76 this->constraint_matrix_.coeffRef(n + nb_joints, n) = 1.0;
77 this->constraint_matrix_.coeffRef(n + nb_joints, nb_joints) = velocity_limit(n);
78 this->upper_bound_constraints_(n + nb_joints) = std::numeric_limits<double>::infinity();
79 this->constraint_matrix_.coeffRef(n + 2 * nb_joints, n) = 1.0;
80 this->constraint_matrix_.coeffRef(n + 2 * nb_joints, nb_joints) = -velocity_limit(n);
81 this->lower_bound_constraints_(n + 2 * nb_joints) = -std::numeric_limits<double>::infinity();
82 }
83
84 // time constraint
85 this->constraint_matrix_.coeffRef(3 * nb_joints, nb_joints) = 1.0;
86 this->upper_bound_constraints_(3 * nb_joints) = std::numeric_limits<double>::infinity();
87 // cartesian velocity constraints
88 this->upper_bound_constraints_(3 * nb_joints + 1) = std::numeric_limits<double>::infinity();
89 this->upper_bound_constraints_(3 * nb_joints + 2) = std::numeric_limits<double>::infinity();
90
91 // set the initial data of the QP solver_
92 this->solver_.data()->setNumberOfVariables(static_cast<int>(nb_joints) + 1);
93 this->solver_.data()->setNumberOfConstraints(this->lower_bound_constraints_.size());
94 if (!this->solver_.data()->setHessianMatrix(this->hessian_)) { return false; }
95 if (!this->solver_.data()->setGradient(this->gradient_)) { return false; }
96 if (!this->solver_.data()->setLinearConstraintsMatrix(this->constraint_matrix_)) { return false; }
97 if (!this->solver_.data()->setLowerBound(this->lower_bound_constraints_)) { return false; }
98 if (!this->solver_.data()->setUpperBound(this->upper_bound_constraints_)) { return false; }
99 // instantiate the solver_
100 return this->solver_.initSolver();
101}
102
103std::vector<unsigned int> Model::get_frame_ids(const std::vector<std::string>& frames) {
104 std::vector<unsigned int> frame_ids;
105 frame_ids.reserve(frames.size());
106
107 for (auto& frame : frames) {
108 if (frame.empty()) {
109 // get last frame if none specified
110 frame_ids.push_back(this->robot_model_.frames.size() - 1);
111 } else {
112 // throw error if specified frame does not exist
113 if (!this->robot_model_.existFrame(frame)) {
114 throw (exceptions::FrameNotFoundException(frame));
115 }
116 frame_ids.push_back(this->robot_model_.getFrameId(frame));
117 }
118 }
119 return frame_ids;
120}
121
122unsigned int Model::get_frame_id(const std::string& frame) {
123 return get_frame_ids(std::vector<std::string>{frame}).back();
124}
125
126state_representation::Jacobian Model::compute_jacobian(const state_representation::JointPositions& joint_positions,
127 unsigned int frame_id) {
128 if (joint_positions.get_size() != this->get_number_of_joints()) {
129 throw (exceptions::InvalidJointStateSizeException(joint_positions.get_size(), this->get_number_of_joints()));
130 }
131 // compute the Jacobian from the joint state
132 pinocchio::Data::Matrix6x J(6, this->get_number_of_joints());
133 J.setZero();
134 pinocchio::computeFrameJacobian(this->robot_model_,
135 this->robot_data_,
136 joint_positions.data(),
137 frame_id,
138 pinocchio::LOCAL_WORLD_ALIGNED,
139 J);
140 // the model does not have any reference frame
142 this->get_joint_frames(),
143 this->robot_model_.frames[frame_id].name,
144 J,
145 this->get_base_frame());
146}
147
148state_representation::Jacobian Model::compute_jacobian(const state_representation::JointPositions& joint_positions,
149 const std::string& frame) {
150 auto frame_id = get_frame_id(frame);
151 return this->compute_jacobian(joint_positions, frame_id);
152}
153
154Eigen::MatrixXd Model::compute_jacobian_time_derivative(const state_representation::JointPositions& joint_positions,
155 const state_representation::JointVelocities& joint_velocities,
156 unsigned int frame_id) {
157 if (joint_positions.get_size() != this->get_number_of_joints()) {
158 throw (exceptions::InvalidJointStateSizeException(joint_positions.get_size(), this->get_number_of_joints()));
159 }
160 if (joint_velocities.get_size() != this->get_number_of_joints()) {
161 throw (exceptions::InvalidJointStateSizeException(joint_velocities.get_size(), this->get_number_of_joints()));
162 }
163 // compute the Jacobian from the joint state
164 pinocchio::Data::Matrix6x dJ = Eigen::MatrixXd::Zero(6, this->get_number_of_joints());
165 pinocchio::computeJointJacobiansTimeVariation(this->robot_model_,
166 this->robot_data_,
167 joint_positions.data(),
168 joint_velocities.data());
169 pinocchio::getFrameJacobianTimeVariation(this->robot_model_,
170 this->robot_data_,
171 frame_id,
172 pinocchio::LOCAL_WORLD_ALIGNED,
173 dJ);
174 // the model does not have any reference frame
175 return dJ;
176}
177
178Eigen::MatrixXd Model::compute_jacobian_time_derivative(const state_representation::JointPositions& joint_positions,
179 const state_representation::JointVelocities& joint_velocities,
180 const std::string& frame) {
181 auto frame_id = get_frame_id(frame);
182 return this->compute_jacobian_time_derivative(joint_positions, joint_velocities, frame_id);
183}
184
186 // compute only the upper part of the triangular inertia matrix stored in robot_data_.M
187 pinocchio::crba(this->robot_model_, this->robot_data_, joint_positions.data());
188 // copy the symmetric lower part
189 this->robot_data_.M.triangularView<Eigen::StrictlyLower>() =
190 this->robot_data_.M.transpose().triangularView<Eigen::StrictlyLower>();
191 return this->robot_data_.M;
192}
193
195 Eigen::MatrixXd inertia = this->compute_inertia_matrix(joint_state);
196 return state_representation::JointTorques(joint_state.get_name(),
197 joint_state.get_names(),
198 inertia * joint_state.get_accelerations());
199}
200
202 return pinocchio::computeCoriolisMatrix(this->robot_model_,
203 this->robot_data_,
204 joint_state.get_positions(),
205 joint_state.get_velocities());
206}
207
210 Eigen::MatrixXd coriolis_matrix = this->compute_coriolis_matrix(joint_state);
211 return state_representation::JointTorques(joint_state.get_name(),
212 joint_state.get_names(),
213 coriolis_matrix * joint_state.get_velocities());
214}
215
218 Eigen::VectorXd gravity_torque =
219 pinocchio::computeGeneralizedGravity(this->robot_model_, this->robot_data_, joint_positions.data());
220 return state_representation::JointTorques(joint_positions.get_name(), joint_positions.get_names(), gravity_torque);
221}
222
223state_representation::CartesianPose Model::forward_kinematics(const state_representation::JointPositions& joint_positions,
224 unsigned int frame_id) {
225 return this->forward_kinematics(joint_positions, std::vector<unsigned int>{frame_id}).front();
226}
227
228std::vector<state_representation::CartesianPose> Model::forward_kinematics(const state_representation::JointPositions& joint_positions,
229 const std::vector<unsigned int>& frame_ids) {
230 if (joint_positions.get_size() != this->get_number_of_joints()) {
231 throw (exceptions::InvalidJointStateSizeException(joint_positions.get_size(), this->get_number_of_joints()));
232 }
233 std::vector<state_representation::CartesianPose> pose_vector;
234 pinocchio::forwardKinematics(this->robot_model_, this->robot_data_, joint_positions.data());
235 for (unsigned int id : frame_ids) {
236 if (id >= static_cast<unsigned int>(this->robot_model_.nframes)) {
237 throw (exceptions::FrameNotFoundException(std::to_string(id)));
238 }
239 pinocchio::updateFramePlacement(this->robot_model_, this->robot_data_, id);
240 pinocchio::SE3 pose = this->robot_data_.oMf[id];
241 Eigen::Vector3d translation = pose.translation();
242 Eigen::Quaterniond quaternion;
243 pinocchio::quaternion::assignQuaternion(quaternion, pose.rotation());
244 state_representation::CartesianPose frame_pose(this->robot_model_.frames[id].name,
245 translation,
246 quaternion,
247 this->get_base_frame());
248 pose_vector.push_back(frame_pose);
249 }
250 return pose_vector;
251}
252
253state_representation::CartesianPose Model::forward_kinematics(const state_representation::JointPositions& joint_positions,
254 const std::string& frame) {
255 std::string actual_frame = frame.empty() ? this->robot_model_.frames.back().name : frame;
256 return this->forward_kinematics(joint_positions, std::vector<std::string>{actual_frame}).front();
257}
258
259std::vector<state_representation::CartesianPose> Model::forward_kinematics(const state_representation::JointPositions& joint_positions,
260 const std::vector<std::string>& frames) {
261 auto frame_ids = get_frame_ids(frames);
262 return this->forward_kinematics(joint_positions, frame_ids);
263}
264
265Eigen::MatrixXd Model::cwln_weighted_matrix(const state_representation::JointPositions& joint_positions,
266 const double margin) {
267 Eigen::MatrixXd W_b = Eigen::MatrixXd::Identity(this->robot_model_.nq, this->robot_model_.nq);
268 for (int n = 0; n < this->robot_model_.nq; ++n) {
269 double d = 1;
270 W_b(n, n) = 1;
271 if (joint_positions.data()[n] < this->robot_model_.lowerPositionLimit[n] + margin) {
272 if (joint_positions.data()[n] < this->robot_model_.lowerPositionLimit[n]) {
273 W_b(n, n) = 0;
274 } else {
275 d = (this->robot_model_.lowerPositionLimit[n] + margin - joint_positions.data()[n]) / margin;
276 W_b(n, n) = -2 * d * d * d + 3 * d * d;
277 }
278 } else if (this->robot_model_.upperPositionLimit[n] - margin < joint_positions.data()[n]) {
279 if (this->robot_model_.upperPositionLimit[n] < joint_positions.data()[n]) {
280 W_b(n, n) = 0;
281 } else {
282 d = (joint_positions.data()[n] - (this->robot_model_.upperPositionLimit[n] - margin)) / margin;
283 W_b(n, n) = -2 * d * d * d + 3 * d * d;
284 }
285 }
286 }
287 return W_b;
288}
289
290Eigen::VectorXd Model::cwln_repulsive_potential_field(const state_representation::JointPositions& joint_positions,
291 double margin) {
292 Eigen::VectorXd Psi(this->robot_model_.nq);
293 Eigen::VectorXd q = joint_positions.data();
294 for (int i = 0; i < this->robot_model_.nq; ++i) {
295 Psi[i] = 0;
296 if (q[i] < this->robot_model_.lowerPositionLimit[i] + margin) {
297 Psi[i] = this->robot_model_.upperPositionLimit[i] - margin
298 - std::max(q[i], this->robot_model_.lowerPositionLimit[i]);
299 } else if (this->robot_model_.upperPositionLimit[i] - margin < q[i]) {
300 Psi[i] = this->robot_model_.lowerPositionLimit[i] + margin
301 - std::min(q[i], this->robot_model_.upperPositionLimit[i]);
302 }
303 }
304 return Psi;
305}
306
309 const state_representation::JointPositions& joint_positions,
310 const InverseKinematicsParameters& parameters,
311 const std::string& frame) {
312 std::string actual_frame = frame.empty() ? this->robot_model_.frames.back().name : frame;
313 if (!this->robot_model_.existFrame(actual_frame)) {
314 throw (exceptions::FrameNotFoundException(actual_frame));
315 }
316 // 1 second for the Newton-Raphson method
317 const std::chrono::nanoseconds dt(static_cast<int>(1e9));
318 // initialization of the loop variables
319 state_representation::JointPositions q(joint_positions);
322 this->get_joint_frames(),
323 actual_frame,
324 this->get_base_frame());
325 Eigen::MatrixXd J_b = Eigen::MatrixXd::Zero(6, this->get_number_of_joints());
326 Eigen::MatrixXd JJt(6, 6);
327 Eigen::MatrixXd W_b = Eigen::MatrixXd::Identity(this->get_number_of_joints(), this->get_number_of_joints());
328 Eigen::MatrixXd W_c = Eigen::MatrixXd::Identity(this->get_number_of_joints(), this->get_number_of_joints());
329 Eigen::VectorXd psi(this->get_number_of_joints());
330 Eigen::VectorXd err(6);
331 for (unsigned int i = 0; i < parameters.max_number_of_iterations; ++i) {
332 err = ((cartesian_pose - this->forward_kinematics(q, actual_frame)) / dt).data();
333 // break in case of convergence
334 if (err.cwiseAbs().maxCoeff() < parameters.tolerance) {
335 return q;
336 }
337 J = this->compute_jacobian(q, actual_frame);
338 W_b = this->cwln_weighted_matrix(q, parameters.margin);
339 W_c = Eigen::MatrixXd::Identity(this->get_number_of_joints(), this->get_number_of_joints()) - W_b;
340 psi = parameters.gamma * this->cwln_repulsive_potential_field(q, parameters.margin);
341 J_b = J * W_b;
342 JJt.noalias() = J_b * J_b.transpose();
343 JJt.diagonal().array() += parameters.damp;
344 dq.set_velocities(W_c * psi + parameters.alpha * W_b * (J_b.transpose() * JJt.ldlt().solve(err - J * W_c * psi)));
345 q += dq * dt;
346 q = this->clamp_in_range(q);
347 }
348 throw (exceptions::InverseKinematicsNotConvergingException(parameters.max_number_of_iterations,
349 err.array().abs().maxCoeff()));
350}
351
354 const InverseKinematicsParameters& parameters,
355 const std::string& frame) {
356 Eigen::VectorXd q(pinocchio::neutral(this->robot_model_));
358 return this->inverse_kinematics(cartesian_pose, positions, parameters, frame);
359}
360
361std::vector<state_representation::CartesianTwist>
363 const std::vector<std::string>& frames) {
364 std::vector<state_representation::CartesianTwist> cartesian_twists(frames.size());
365 for (std::size_t i = 0; i < frames.size(); ++i) {
366 cartesian_twists.at(i) = this->compute_jacobian(joint_state, frames.at(i))
367 * static_cast<state_representation::JointVelocities>(joint_state);
368 }
369 return cartesian_twists;
370}
371
373 const std::string& frame) {
374 return this->forward_velocity(joint_state, std::vector<std::string>{frame}).front();
375}
376
377void Model::check_inverse_velocity_arguments(const std::vector<state_representation::CartesianTwist>& cartesian_twists,
378 const state_representation::JointPositions& joint_positions,
379 const std::vector<std::string>& frames) {
380 if (cartesian_twists.size() != frames.size()) {
381 throw (std::invalid_argument("The number of provided twists and frames does not match"));
382 }
383 if (joint_positions.get_size() != this->get_number_of_joints()) {
384 throw (exceptions::InvalidJointStateSizeException(joint_positions.get_size(), this->get_number_of_joints()));
385 }
386 for (auto& frame : frames) {
387 if (!this->robot_model_.existFrame(frame)) {
388 throw (exceptions::FrameNotFoundException(frame));
389 }
390 }
391}
392
394Model::inverse_velocity(const std::vector<state_representation::CartesianTwist>& cartesian_twists,
395 const state_representation::JointPositions& joint_positions,
396 const std::vector<std::string>& frames) {
397 // sanity check
398 this->check_inverse_velocity_arguments(cartesian_twists, joint_positions, frames);
399
400 const unsigned int nb_joints = this->get_number_of_joints();
401 // the velocity vector contains position of the intermediate frame and full pose of the end-effector
402 Eigen::VectorXd dX(3 * cartesian_twists.size() + 3);
403 Eigen::MatrixXd jacobian(3 * cartesian_twists.size() + 3, nb_joints);
404 for (unsigned int i = 0; i < cartesian_twists.size() - 1; ++i) {
405 // extract only the linear velocity for intermediate points
406 dX.segment<3>(3 * i) = cartesian_twists[i].get_linear_velocity();
407 jacobian.block(3 * i, 0, 3 * i + 3, nb_joints) =
408 this->compute_jacobian(joint_positions, frames.at(i)).data().block(0, 0, 3, nb_joints);
409 }
410 // full twist for the last provided frame
411 dX.tail(6) = cartesian_twists.back().data();
412 jacobian.bottomRows(6) = this->compute_jacobian(joint_positions, frames.back()).data();
413
414 // solve a linear system
415 return state_representation::JointVelocities(joint_positions.get_name(),
416 joint_positions.get_names(),
417 jacobian.colPivHouseholderQr().solve(dX));
418}
419
421 const state_representation::JointPositions& joint_positions,
422 const std::string& frame) {
423 std::string actual_frame = frame.empty() ? this->robot_model_.frames.back().name : frame;
424 return this->inverse_velocity(std::vector<state_representation::CartesianTwist>({cartesian_twist}),
425 joint_positions,
426 std::vector<std::string>({actual_frame}));
427}
428
430Model::inverse_velocity(const std::vector<state_representation::CartesianTwist>& cartesian_twists,
431 const state_representation::JointPositions& joint_positions,
432 const QPInverseVelocityParameters& parameters,
433 const std::vector<std::string>& frames) {
434 using namespace state_representation;
435 using namespace std::chrono;
436 // sanity check
437 this->check_inverse_velocity_arguments(cartesian_twists, joint_positions, frames);
438
439 const unsigned int nb_joints = this->get_number_of_joints();
440 // the velocity vector contains position of the intermediate frame and full pose of the end-effector
441 Eigen::VectorXd delta_r(3 * cartesian_twists.size() + 3);
442 Eigen::MatrixXd jacobian(3 * cartesian_twists.size() + 3, nb_joints);
443 for (unsigned int i = 0; i < cartesian_twists.size() - 1; ++i) {
444 // first convert the twist to a displacement
445 CartesianPose displacement = cartesian_twists[i];
446 // extract only the position for intermediate points
447 delta_r.segment<3>(3 * i) = displacement.get_position();
448 jacobian.block(3 * i, 0, 3 * i + 3, nb_joints) =
449 this->compute_jacobian(joint_positions, frames.at(i)).data().block(0, 0, 3, nb_joints);
450 }
451 // extract pose for the last provided frame
452 CartesianPose full_displacement = cartesian_twists.back();
453 delta_r.segment<3>(3 * (cartesian_twists.size() - 1)) = full_displacement.get_position();
454 delta_r.tail(3) = full_displacement.get_orientation().vec();
455 jacobian.bottomRows(6) = this->compute_jacobian(joint_positions, frames.back()).data();
456 // compute the Jacobian
457 Eigen::MatrixXd hessian_matrix = jacobian.transpose() * jacobian;
458 // set the hessian sparse matrix
459 std::vector<Eigen::Triplet<double>> coefficients;
460 for (unsigned int i = 0; i < nb_joints; ++i) {
461 for (unsigned int j = 0; j < nb_joints; ++j) {
462 coefficients.emplace_back(Eigen::Triplet<double>(i, j, hessian_matrix(i, j)));
463 }
464 }
465 coefficients.emplace_back(Eigen::Triplet<double>(nb_joints, nb_joints, parameters.alpha));
466 this->hessian_.setFromTriplets(coefficients.begin(), coefficients.end());
467 //set the gradient
468 this->gradient_.head(nb_joints) = -parameters.proportional_gain * delta_r.transpose() * jacobian;
469 // update minimal time as dt expressed in seconds
470 this->lower_bound_constraints_(3 * nb_joints) = duration_cast<duration<float>>(parameters.dt).count();
471 // update joint position constraints
472 Eigen::VectorXd lower_position_limit = this->robot_model_.lowerPositionLimit;
473 Eigen::VectorXd upper_position_limit = this->robot_model_.upperPositionLimit;
474 for (unsigned int n = 0; n < nb_joints; ++n) {
475 this->lower_bound_constraints_(n) = lower_position_limit(n) - joint_positions.data()(n);
476 this->upper_bound_constraints_(n) = upper_position_limit(n) - joint_positions.data()(n);
477 }
478 // update Cartesian velocity
479 this->constraint_matrix_.coeffRef(3 * nb_joints + 1, nb_joints) = parameters.linear_velocity_limit;
480 this->constraint_matrix_.coeffRef(3 * nb_joints + 2, nb_joints) = parameters.angular_velocity_limit;
481 this->lower_bound_constraints_(3 * nb_joints + 1) = full_displacement.get_position().norm();
482 this->lower_bound_constraints_(3 * nb_joints + 2) = full_displacement.get_orientation().vec().norm();
483
484 // update the constraints
485 this->solver_.updateHessianMatrix(this->hessian_);
486 this->solver_.updateGradient(this->gradient_);
487 this->solver_.updateBounds(this->lower_bound_constraints_, this->upper_bound_constraints_);
488 this->solver_.updateLinearConstraintsMatrix(this->constraint_matrix_);
489 // solve the QP problem
490 this->solver_.solve();
491 // extract the solution
492 JointPositions joint_displacement(joint_positions.get_name(),
493 joint_positions.get_names(),
494 this->solver_.getSolution().head(nb_joints));
495 double dt = this->solver_.getSolution().tail(1)(0);
496 return JointPositions(joint_displacement) / dt;
497}
498
500 const state_representation::JointPositions& joint_positions,
501 const QPInverseVelocityParameters& parameters,
502 const std::string& frame) {
503 std::string actual_frame = frame.empty() ? this->robot_model_.frames.back().name : frame;
504 return this->inverse_velocity(std::vector<state_representation::CartesianTwist>({cartesian_twist}),
505 joint_positions,
506 parameters,
507 std::vector<std::string>({actual_frame}));
508}
509
511 std::cout << "hessian:" << std::endl;
512 std::cout << this->hessian_ << std::endl;
513
514 std::cout << "gradient:" << std::endl;
515 std::cout << this->gradient_ << std::endl;
516
517 for (unsigned int i = 0; i < this->constraint_matrix_.rows(); ++i) {
518 std::cout << this->lower_bound_constraints_(i);
519 std::cout << " < | ";
520 for (unsigned int j = 0; j < this->constraint_matrix_.cols(); ++j) {
521 std::cout << this->constraint_matrix_.coeffRef(i, j) << " | ";
522 }
523 std::cout << " < ";
524 std::cout << this->upper_bound_constraints_(i) << std::endl;
525 }
526}
527
528bool Model::in_range(const Eigen::VectorXd& vector,
529 const Eigen::VectorXd& lower_limits,
530 const Eigen::VectorXd& upper_limits) {
531 return ((vector.array() >= lower_limits.array()).all() && (vector.array() <= upper_limits.array()).all());
532}
533
534bool Model::in_range(const state_representation::JointPositions& joint_positions) const {
535 return this->in_range(joint_positions.get_positions(),
536 this->robot_model_.lowerPositionLimit,
537 this->robot_model_.upperPositionLimit);
538}
539
540bool Model::in_range(const state_representation::JointVelocities& joint_velocities) const {
541 return this->in_range(joint_velocities.get_velocities(),
542 -this->robot_model_.velocityLimit,
543 this->robot_model_.velocityLimit);
544}
545
546bool Model::in_range(const state_representation::JointTorques& joint_torques) const {
547 return this->in_range(joint_torques.get_torques(), -this->robot_model_.effortLimit, this->robot_model_.effortLimit);
548}
549
550bool Model::in_range(const state_representation::JointState& joint_state) const {
551 return (this->in_range(static_cast<state_representation::JointPositions>(joint_state))
552 && this->in_range(static_cast<state_representation::JointVelocities>(joint_state))
553 && this->in_range(static_cast<state_representation::JointTorques>(joint_state)));
554}
555
556Eigen::VectorXd Model::clamp_in_range(const Eigen::VectorXd& vector,
557 const Eigen::VectorXd& lower_limits,
558 const Eigen::VectorXd& upper_limits) {
559 return lower_limits.cwiseMax(upper_limits.cwiseMin(vector));
560}
561
562state_representation::JointState Model::clamp_in_range(const state_representation::JointState& joint_state) const {
563 state_representation::JointState joint_state_clamped(joint_state);
564 joint_state_clamped.set_positions(this->clamp_in_range(joint_state.get_positions(),
565 this->robot_model_.lowerPositionLimit,
566 this->robot_model_.upperPositionLimit));
567 joint_state_clamped.set_velocities(this->clamp_in_range(joint_state.get_velocities(),
568 -this->robot_model_.velocityLimit,
569 this->robot_model_.velocityLimit));
570 joint_state_clamped.set_torques(this->clamp_in_range(joint_state.get_torques(),
571 -this->robot_model_.effortLimit,
572 this->robot_model_.effortLimit));
573 return joint_state_clamped;
574}
575}// namespace robot_model
The Model class is a wrapper around pinocchio dynamic computation library with state_representation e...
Definition: Model.hpp:62
unsigned int get_number_of_joints() const
Getter of the number of joints.
Definition: Model.hpp:529
std::vector< state_representation::CartesianTwist > forward_velocity(const state_representation::JointState &joint_state, const std::vector< std::string > &frames)
Compute the forward velocity kinematics, i.e. the twist of certain frames from the joint states.
Definition: Model.cpp:362
Eigen::MatrixXd compute_coriolis_matrix(const state_representation::JointState &joint_state)
Compute the Coriolis matrix from a given joint state.
Definition: Model.cpp:201
state_representation::JointTorques compute_inertia_torques(const state_representation::JointState &joint_state)
Compute the Inertia torques, i.e the inertia matrix multiplied by the joint accelerations....
Definition: Model.cpp:194
state_representation::JointVelocities inverse_velocity(const std::vector< state_representation::CartesianTwist > &cartesian_twists, const state_representation::JointPositions &joint_positions, const std::vector< std::string > &frames)
Compute the inverse velocity kinematics, i.e. joint velocities from the velocities of the frames in p...
Definition: Model.cpp:394
const std::string & get_base_frame() const
Getter of the base frame of the robot.
Definition: Model.hpp:539
state_representation::JointTorques compute_gravity_torques(const state_representation::JointPositions &joint_positions)
Compute the gravity torques.
Definition: Model.cpp:217
Eigen::MatrixXd compute_inertia_matrix(const state_representation::JointPositions &joint_positions)
Compute the Inertia matrix from a given joint positions.
Definition: Model.cpp:185
state_representation::JointVelocities inverse_velocity(const state_representation::CartesianTwist &cartesian_twist, const state_representation::JointPositions &joint_positions, const std::string &frame="")
Compute the inverse velocity kinematics, i.e. joint velocities from the twist of the end-effector usi...
Definition: Model.cpp:420
Model(const std::string &robot_name, const std::string &urdf_path)
Constructor with robot name and path to URDF file.
Definition: Model.cpp:10
const std::string & get_urdf_path() const
Getter of the URDF path.
Definition: Model.hpp:525
state_representation::JointPositions inverse_kinematics(const state_representation::CartesianPose &cartesian_pose, const InverseKinematicsParameters &parameters=InverseKinematicsParameters(), const std::string &frame="")
Compute the inverse kinematics, i.e. joint positions from the pose of the end-effector in an iterativ...
Definition: Model.cpp:353
state_representation::JointTorques compute_coriolis_torques(const state_representation::JointState &joint_state)
Compute the Coriolis torques, i.e. the Coriolis matrix multiplied by the joint velocities and express...
Definition: Model.cpp:209
void print_qp_problem()
Helper function to print the qp_problem (for debugging)
Definition: Model.cpp:510
const std::string & get_robot_name() const
Getter of the robot name.
Definition: Model.hpp:517
std::vector< std::string > get_joint_frames() const
Getter of the joint frames from the model.
Definition: Model.hpp:533
static bool create_urdf_from_string(const std::string &urdf_string, const std::string &desired_path)
Creates a URDF file with desired path and name from a string (possibly the robot description string f...
Definition: Model.cpp:22
Class to define CartesianPose in cartesian space as 3D position and quaternion based orientation.
const Eigen::Vector3d & get_position() const
Getter of the position attribute.
const Eigen::Quaterniond & get_orientation() const
Getter of the orientation attribute.
Class to define twist in cartesian space as 3D linear and angular velocity vectors.
Class to define a robot Jacobian matrix.
Definition: Jacobian.hpp:20
const Eigen::MatrixXd & data() const
Getter of the data attribute.
Definition: Jacobian.hpp:392
Jacobian transpose() const
Return the transpose of the Jacobian matrix.
Definition: Jacobian.cpp:137
Class to define a positions of the joints.
Class to define a state in joint space.
Definition: JointState.hpp:36
void set_positions(const Eigen::VectorXd &positions)
Setter of the positions attribute.
Definition: JointState.cpp:99
void set_torques(const Eigen::VectorXd &torques)
Setter of the torques attribute.
Definition: JointState.cpp:195
const std::vector< std::string > & get_names() const
Getter of the names attribute.
Definition: JointState.hpp:660
void set_velocities(const Eigen::VectorXd &velocities)
Setter of the velocities attribute.
Definition: JointState.cpp:131
Class to define torques of the joints.
Class to define velocities of the joints.
Robot kinematics and dynamics.
Core state variables and objects.
parameters for the inverse kinematics function
Definition: Model.hpp:32
parameters for the inverse velocity kinematics function
Definition: Model.hpp:49