1#include "state_representation/space/Jacobian.hpp"
3#include "state_representation/exceptions/EmptyStateException.hpp"
4#include "state_representation/exceptions/IncompatibleStatesException.hpp"
5#include "state_representation/exceptions/InvalidCastException.hpp"
9using namespace exceptions;
11static void assert_matrix_size(
const Eigen::MatrixXd& matrix,
unsigned int expected_rows,
unsigned int expected_cols) {
12 if (expected_rows != matrix.rows() || expected_cols != matrix.cols()) {
13 throw exceptions::IncompatibleSizeException(
14 "Matrix is of incorrect size, expected " + std::to_string(expected_rows) +
"x" + std::to_string(expected_cols)
15 +
" got " + std::to_string(matrix.rows()) +
"x" + std::to_string(matrix.cols()));
24 const std::string& robot_name,
unsigned int nb_joints,
const std::string& frame,
const std::string& reference_frame
27 joint_names_(nb_joints),
29 reference_frame_(reference_frame),
30 data_(Eigen::MatrixXd::Zero(6, nb_joints)) {
36 const std::string& robot_name,
const std::vector<std::string>& joint_names,
const std::string& frame,
37 const std::string& reference_frame
38) :
Jacobian(robot_name, joint_names.size(), frame, reference_frame) {
43 const std::string& robot_name,
const std::string& frame,
const Eigen::MatrixXd& data,
44 const std::string& reference_frame
45) :
Jacobian(robot_name, data.cols(), frame, reference_frame) {
46 assert_matrix_size(
data, 6,
data.cols());
52 const std::string& robot_name,
const std::vector<std::string>& joint_names,
const std::string& frame,
53 const Eigen::MatrixXd& data,
const std::string& reference_frame
54) :
Jacobian(robot_name, frame, data, reference_frame) {
59 Jacobian(jacobian.get_name(), jacobian.joint_names_, jacobian.frame_, jacobian.reference_frame_) {
61 this->data_ = jacobian.data_;
67 const std::string& robot_name,
unsigned int nb_joints,
const std::string& frame,
const std::string& reference_frame
69 return {robot_name, frame, Eigen::MatrixXd::Random(6, nb_joints), reference_frame};
73 const std::string& robot_name,
const std::vector<std::string>& joint_names,
const std::string& frame,
74 const std::string& reference_frame
76 return {robot_name, joint_names, frame, Eigen::MatrixXd::Random(6, joint_names.size()), reference_frame};
90 return this->
data().row(index);
94 return this->joint_names_.size();
98 return this->
data().col(index);
102 return this->joint_names_;
110 return this->reference_frame_;
119 if (this->joint_names_.size() != nb_joints) {
121 "Input number of joints is of incorrect size, expected " + std::to_string(this->joint_names_.size()) +
" got "
122 + std::to_string(nb_joints));
124 for (
unsigned int i = 0; i < nb_joints; ++i) {
125 this->joint_names_[i] =
"joint" + std::to_string(i);
131 if (this->joint_names_.size() != joint_names.size()) {
133 "Input vector of joint names is of incorrect size, expected " + std::to_string(this->joint_names_.size())
134 +
" got " + std::to_string(joint_names.size()));
136 this->joint_names_ = joint_names;
141 this->frame_ = frame;
146 this->reference_frame_ = reference_frame;
157 this->data_.resize(this->
rows(), this->
cols());
158 this->data_.setZero();
175 "The Jacobian matrix is not invertible, use the pseudoinverse function instead");
177 return this->
data().inverse();
181 assert_matrix_size(matrix, this->
rows(), matrix.cols());
182 return this->
data().colPivHouseholderQr().solve(matrix);
194 switch (state.get_type()) {
195 case StateType::JACOBIAN: {
196 auto other =
dynamic_cast<const Jacobian&
>(state);
197 if (this->
cols() != other.joint_names_.size()) {
200 if (this->reference_frame_ != other.reference_frame_) {
203 for (
unsigned int i = 0; i < this->
cols(); ++i) {
204 if (this->joint_names_[i] != other.joint_names_[i]) {
210 case StateType::JOINT_STATE:
211 case StateType::JOINT_POSITIONS:
212 case StateType::JOINT_VELOCITIES:
213 case StateType::JOINT_ACCELERATIONS:
214 case StateType::JOINT_TORQUES: {
215 auto other =
dynamic_cast<const JointState&
>(state);
216 if (this->
cols() != other.get_names().size()) {
219 for (
unsigned int i = 0; i < this->
cols(); ++i) {
220 if (this->joint_names_[i] != other.get_names()[i]) {
226 case StateType::CARTESIAN_STATE:
227 case StateType::CARTESIAN_POSE:
228 case StateType::CARTESIAN_TWIST:
229 case StateType::CARTESIAN_ACCELERATION:
230 case StateType::CARTESIAN_WRENCH: {
232 if (this->reference_frame_ != other.get_reference_frame()) {
240 }
catch (
const std::bad_cast& ex) {
246 return this->
data().completeOrthogonalDecomposition().pseudoInverse();
250 assert_matrix_size(matrix, this->
rows(), matrix.cols());
262 return this->
data().transpose();
273 assert_matrix_size(matrix, this->
cols(), matrix.cols());
274 return this->
data() * matrix;
287 Eigen::Vector<double, 6> twist = (*this) * dq.
data();
294 "The CartesianPose and the Jacobian are incompatible, expected pose of '" + jacobian.
get_reference_frame()
295 +
"', got '" + pose.
get_name() +
"'.");
299 for (
unsigned int i = 0; i < jacobian.
cols(); ++i) {
312 if (row > this->
rows()) {
313 throw std::out_of_range(
"Given row is out of range: number of rows is " + std::to_string(this->
rows()));
315 if (col > this->
cols()) {
316 throw std::out_of_range(
"Given column is out of range: number of columns is " + std::to_string(this->
cols()));
319 return this->data_(
row,
col);
324 if (row > this->
rows()) {
325 throw std::out_of_range(
"Given row is out of range: number of rows is " + std::to_string(this->
rows()));
327 if (col > this->
cols()) {
328 throw std::out_of_range(
"Given column is out of range: number of columns is " + std::to_string(this->
cols()));
330 return this->data_(
row,
col);
335 os <<
" associated to '" << jacobian.
get_frame();
337 os <<
"joint names: [";
344 os <<
"number of rows: " << jacobian.
rows() << std::endl;
345 os <<
"number of columns: " << jacobian.
cols() << std::endl;
346 for (
unsigned int i = 0; i < jacobian.
rows(); ++i) {
347 os <<
"| " << jacobian(i, 0);
348 for (
unsigned int j = 1; j < jacobian.cols(); ++j) {
349 os <<
", " << jacobian(i, j);
352 if (i != jacobian.rows() - 1) {
Class to define Cartesian pose in Cartesian space as 3D position and quaternion based orientation.
Class to represent a state in Cartesian space.
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.
Eigen::VectorXd data() const override
Returns the twist data as an Eigen vector.
Class to define wrench in Cartesian space as 3D force and torque vectors.
Eigen::VectorXd data() const override
Returns the wrench data as an Eigen vector.
Class to define a robot Jacobian matrix.
friend void swap(Jacobian &jacobian1, Jacobian &jacobian2)
Swap the values of the two Jacobians.
Jacobian copy() const
Return a copy of the Jacobian.
const std::vector< std::string > & get_joint_names() const
Getter of the joint names attribute.
void reset() override
Reset the object to a post-construction state.
Eigen::VectorXd row(unsigned int index) const
Accessor of the row data at given index.
const Eigen::MatrixXd & data() const
Getter of the data attribute.
void set_frame(const std::string &frame)
Setter of the frame.
void set_zero()
Set the Jacobian matrix to a zero value.
Eigen::MatrixXd pseudoinverse() const
Return the pseudoinverse of the Jacobian matrix.
unsigned int cols() const
Getter of the number of columns attribute.
Eigen::MatrixXd transpose() const
Return the transpose of the Jacobian matrix.
const std::string & get_reference_frame() const
Getter of the reference frame attribute.
unsigned int rows() const
Getter of the number of rows attribute.
Eigen::MatrixXd inverse() const
Return the inverse of the Jacobian matrix.
const std::string & get_frame() const
Getter of the frame attribute.
friend Jacobian operator*(const Eigen::Matrix< double, 6, 6 > &matrix, const Jacobian &jacobian)
Overload the * operator with a 6x6 matrix on the left side.
void set_joint_names(unsigned int nb_joints)
Setter of the joint names attribute from the number of joints.
Jacobian & operator=(const Jacobian &jacobian)
Copy assignment operator that has to be defined to the custom assignment operator.
bool is_incompatible(const State &state) const override
Check if the Jacobian is incompatible for operations with the state given as argument.
void set_data(const Eigen::MatrixXd &data) override
Setter of the data attribute.
Jacobian()
Empty constructor for a Jacobian.
void set_reference_frame(const std::string &reference_frame)
Setter of the reference frame.
double & operator()(unsigned int row, unsigned int col)
Overload the () operator in a non const fashion to modify the value at given (row,...
Eigen::VectorXd col(unsigned int index) const
Accessor of the column data at given index.
JointTorques transpose(const CartesianWrench &wrench) const
Transform a Cartesian wrench to joint space by pre-multiplying the Jacobian transpose.
static Jacobian Random(const std::string &robot_name, unsigned int nb_joints, const std::string &frame, const std::string &reference_frame="world")
Constructor for a random Jacobian.
Class to define a state in joint space.
Class to define torques of the joints.
Class to define velocities of the joints.
Eigen::VectorXd data() const override
Returns the velocities data as an Eigen vector.
const std::string & get_reference_frame() const
Getter of the reference frame as const reference.
Abstract class to represent a state.
void reset_timestamp()
Reset the timestamp attribute to now.
const std::string & get_name() const
Getter of the name attribute.
void set_type(const StateType &type)
Setter of the state type attribute.
virtual std::string to_string() const
Convert the state to its string representation.
virtual void reset()
Reset the object to a post-construction state.
void assert_not_empty() const
Throw an exception if the state is empty.
bool is_empty() const
Getter of the empty attribute.
void set_empty(bool empty=true)
Setter of the empty attribute.
Core state variables and objects.
std::ostream & operator<<(std::ostream &os, const AnalogIOState &state)
CartesianAcceleration operator*(double lambda, const CartesianAcceleration &acceleration)