1#include "state_representation/space/cartesian/CartesianState.hpp"
2#include "state_representation/exceptions/EmptyStateException.hpp"
3#include "state_representation/exceptions/IncompatibleReferenceFramesException.hpp"
4#include "state_representation/exceptions/NotImplementedException.hpp"
8using namespace exceptions;
10static Eigen::Vector4d quat2vec(
const Eigen::Quaterniond quat) {
11 return {quat.w(), quat.x(), quat.y(), quat.z()};
14static Eigen::Quaterniond vec2quat(
const Eigen::Vector4d vec) {
15 return Eigen::Quaterniond(vec(0), vec(1), vec(2), vec(3)).normalized();
18static unsigned long get_state_variable_size(
const CartesianStateVariable& state_variable_type) {
19 switch (state_variable_type) {
20 case CartesianStateVariable::POSITION:
21 case CartesianStateVariable::LINEAR_VELOCITY:
22 case CartesianStateVariable::ANGULAR_VELOCITY:
23 case CartesianStateVariable::LINEAR_ACCELERATION:
24 case CartesianStateVariable::ANGULAR_ACCELERATION:
25 case CartesianStateVariable::FORCE:
26 case CartesianStateVariable::TORQUE:
28 case CartesianStateVariable::ORIENTATION:
30 case CartesianStateVariable::TWIST:
31 case CartesianStateVariable::ACCELERATION:
32 case CartesianStateVariable::WRENCH:
34 case CartesianStateVariable::POSE:
36 case CartesianStateVariable::ALL:
45 position_(Eigen::Vector3d::Zero()),
46 orientation_(Eigen::Quaterniond::Identity()),
47 linear_velocity_(Eigen::Vector3d::Zero()),
48 angular_velocity_(Eigen::Vector3d::Zero()),
49 linear_acceleration_(Eigen::Vector3d::Zero()),
50 angular_acceleration_(Eigen::Vector3d::Zero()),
51 force_(Eigen::Vector3d::Zero()),
52 torque_(Eigen::Vector3d::Zero()) {
53 this->
set_type(StateType::CARTESIAN_STATE);
91 switch (state_variable_type) {
92 case CartesianStateVariable::POSITION:
93 return this->position_;
94 case CartesianStateVariable::ORIENTATION:
95 return quat2vec(this->orientation_);
96 case CartesianStateVariable::POSE: {
97 Eigen::VectorXd pose(7);
98 pose << this->position_, quat2vec(this->orientation_);
101 case CartesianStateVariable::LINEAR_VELOCITY:
102 return this->linear_velocity_;
103 case CartesianStateVariable::ANGULAR_VELOCITY:
104 return this->angular_velocity_;
105 case CartesianStateVariable::TWIST: {
106 Eigen::VectorXd twist(6);
107 twist << this->linear_velocity_, this->angular_velocity_;
110 case CartesianStateVariable::LINEAR_ACCELERATION:
111 return this->linear_acceleration_;
112 case CartesianStateVariable::ANGULAR_ACCELERATION:
113 return this->angular_acceleration_;
114 case CartesianStateVariable::ACCELERATION: {
115 Eigen::VectorXd acceleration(6);
116 acceleration << this->linear_acceleration_, this->angular_acceleration_;
119 case CartesianStateVariable::FORCE:
121 case CartesianStateVariable::TORQUE:
122 return this->torque_;
123 case CartesianStateVariable::WRENCH: {
124 Eigen::VectorXd wrench(6);
125 wrench << this->force_, this->torque_;
128 case CartesianStateVariable::ALL: {
129 Eigen::VectorXd all_fields(25);
130 all_fields << this->position_, quat2vec(this->orientation_), this->linear_velocity_, this->angular_velocity_,
131 this->linear_acceleration_, this->angular_acceleration_, this->force_, this->torque_;
141 return this->position_;
146 return this->orientation_;
159 Eigen::Matrix4d pose;
160 pose << this->orientation_.toRotationMatrix(), this->position_, 0., 0., 0., 1;
166 return this->linear_velocity_;
171 return this->angular_velocity_;
180 return this->linear_acceleration_;
185 return this->angular_acceleration_;
199 return this->torque_;
211 return this->
data().array();
215 Eigen::VectorXd
data = this->
data();
216 return {data.data(),
data.data() +
data.size()};
220 const std::vector<double>& new_value,
const CartesianStateVariable& state_variable_type
222 this->
set_state_variable(Eigen::VectorXd::Map(new_value.data(), new_value.size()), state_variable_type);
226 const Eigen::VectorXd& new_value,
const CartesianStateVariable& state_variable_type
228 auto expected_size = long(get_state_variable_size(state_variable_type));
229 if (new_value.size() != expected_size) {
231 "Input is of incorrect size, expected " + std::to_string(expected_size) +
", got "
232 + std::to_string(new_value.size()));
234 switch (state_variable_type) {
235 case CartesianStateVariable::POSITION:
236 this->position_ = new_value;
238 case CartesianStateVariable::ORIENTATION:
239 this->orientation_ = vec2quat(new_value);
241 case CartesianStateVariable::POSE:
242 this->position_ = new_value.head(3);
243 this->orientation_ = vec2quat(new_value.tail(4));
245 case CartesianStateVariable::LINEAR_VELOCITY:
246 this->linear_velocity_ = new_value;
248 case CartesianStateVariable::ANGULAR_VELOCITY:
249 this->angular_velocity_ = new_value;
251 case CartesianStateVariable::TWIST:
252 this->linear_velocity_ = new_value.head(3);
253 this->angular_velocity_ = new_value.tail(3);
255 case CartesianStateVariable::LINEAR_ACCELERATION:
256 this->linear_acceleration_ = new_value;
258 case CartesianStateVariable::ANGULAR_ACCELERATION:
259 this->angular_acceleration_ = new_value;
261 case CartesianStateVariable::ACCELERATION:
262 this->linear_acceleration_ = new_value.head(3);
263 this->angular_acceleration_ = new_value.tail(3);
265 case CartesianStateVariable::FORCE:
266 this->force_ = new_value;
268 case CartesianStateVariable::TORQUE:
269 this->torque_ = new_value;
271 case CartesianStateVariable::WRENCH:
272 this->force_ = new_value.head(3);
273 this->torque_ = new_value.tail(3);
275 case CartesianStateVariable::ALL:
276 this->position_ = new_value.segment(0, 3);
277 this->orientation_ = vec2quat(new_value.segment(3, 4));
278 this->linear_velocity_ = new_value.segment(7, 3);
279 this->angular_velocity_ = new_value.segment(10, 3);
280 this->linear_acceleration_ = new_value.segment(13, 3);
281 this->angular_acceleration_ = new_value.segment(16, 3);
282 this->force_ = new_value.segment(19, 3);
283 this->torque_ = new_value.segment(22, 3);
304 this->orientation_ = orientation.normalized();
317 this->
set_state_variable(Eigen::Vector4d(w, x, y, z), CartesianStateVariable::ORIENTATION);
321 this->orientation_ = orientation.normalized();
342 this->
set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::LINEAR_VELOCITY);
354 this->
set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::ANGULAR_VELOCITY);
366 this->
set_state_variable(linear_acceleration, CartesianStateVariable::LINEAR_ACCELERATION);
370 this->
set_state_variable(linear_acceleration, CartesianStateVariable::LINEAR_ACCELERATION);
374 this->
set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::LINEAR_ACCELERATION);
378 this->
set_state_variable(angular_acceleration, CartesianStateVariable::ANGULAR_ACCELERATION);
382 this->
set_state_variable(angular_acceleration, CartesianStateVariable::ANGULAR_ACCELERATION);
386 this->
set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::ANGULAR_ACCELERATION);
438 this->position_.setZero();
439 this->orientation_.setIdentity();
440 this->linear_velocity_.setZero();
441 this->angular_velocity_.setZero();
442 this->linear_acceleration_.setZero();
443 this->angular_acceleration_.setZero();
444 this->force_.setZero();
445 this->torque_.setZero();
450 double max_norm,
const CartesianStateVariable& state_variable_type,
double noise_ratio
452 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
453 || state_variable_type == CartesianStateVariable::ALL) {
457 if (noise_ratio != 0 && state_variable_value.norm() < noise_ratio * max_norm) {
459 state_variable_value.setZero();
460 }
else if (state_variable_value.norm() > max_norm) {
462 state_variable_value = max_norm * state_variable_value.normalized();
478 if (state_variable_type == CartesianStateVariable::POSITION || state_variable_type == CartesianStateVariable::POSE
479 || state_variable_type == CartesianStateVariable::ALL) {
482 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
483 || state_variable_type == CartesianStateVariable::ALL) {
486 if (state_variable_type == CartesianStateVariable::LINEAR_VELOCITY
487 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
490 if (state_variable_type == CartesianStateVariable::ANGULAR_VELOCITY
491 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
494 if (state_variable_type == CartesianStateVariable::LINEAR_ACCELERATION
495 || state_variable_type == CartesianStateVariable::ACCELERATION
496 || state_variable_type == CartesianStateVariable::ALL) {
499 if (state_variable_type == CartesianStateVariable::ANGULAR_ACCELERATION
500 || state_variable_type == CartesianStateVariable::ACCELERATION
501 || state_variable_type == CartesianStateVariable::ALL) {
504 if (state_variable_type == CartesianStateVariable::FORCE || state_variable_type == CartesianStateVariable::WRENCH
505 || state_variable_type == CartesianStateVariable::ALL) {
508 if (state_variable_type == CartesianStateVariable::TORQUE || state_variable_type == CartesianStateVariable::WRENCH
509 || state_variable_type == CartesianStateVariable::ALL) {
516 return s1.
dist(s2, state_variable_type);
531 Eigen::Quaterniond inverse_orientation = this->
get_orientation().conjugate();
532 Eigen::Vector3d inverse_position = inverse_orientation * (-this->
get_position());
533 Eigen::Vector3d inverse_angular_velocity = inverse_orientation * (-this->
get_angular_velocity());
534 Eigen::Vector3d inverse_linear_velocity = inverse_orientation * (-this->
get_linear_velocity());
535 inverse_linear_velocity += inverse_angular_velocity.cross(inverse_position);
539 inverse_linear_acceleration += inverse_angular_acceleration.cross(inverse_position);
540 inverse_linear_acceleration += 2 * inverse_angular_velocity.cross(inverse_linear_velocity);
541 inverse_linear_acceleration -=
542 inverse_angular_velocity.cross(inverse_angular_velocity.cross(inverse_position));
560 if (state_variable_type == CartesianStateVariable::POSITION || state_variable_type == CartesianStateVariable::POSE
561 || state_variable_type == CartesianStateVariable::ALL) {
562 this->position_.normalize();
565 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
566 || state_variable_type == CartesianStateVariable::ALL) {
567 this->orientation_.normalize();
569 if (state_variable_type == CartesianStateVariable::LINEAR_VELOCITY
570 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
571 this->linear_velocity_.normalize();
573 if (state_variable_type == CartesianStateVariable::ANGULAR_VELOCITY
574 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
575 this->angular_velocity_.normalize();
577 if (state_variable_type == CartesianStateVariable::LINEAR_ACCELERATION
578 || state_variable_type == CartesianStateVariable::ACCELERATION
579 || state_variable_type == CartesianStateVariable::ALL) {
580 this->linear_acceleration_.normalize();
582 if (state_variable_type == CartesianStateVariable::ANGULAR_ACCELERATION
583 || state_variable_type == CartesianStateVariable::ACCELERATION
584 || state_variable_type == CartesianStateVariable::ALL) {
585 this->angular_acceleration_.normalize();
587 if (state_variable_type == CartesianStateVariable::FORCE || state_variable_type == CartesianStateVariable::WRENCH
588 || state_variable_type == CartesianStateVariable::ALL) {
589 this->force_.normalize();
591 if (state_variable_type == CartesianStateVariable::TORQUE || state_variable_type == CartesianStateVariable::WRENCH
592 || state_variable_type == CartesianStateVariable::ALL) {
593 this->torque_.normalize();
606 std::vector<double>
norms;
607 if (state_variable_type == CartesianStateVariable::POSITION || state_variable_type == CartesianStateVariable::POSE
608 || state_variable_type == CartesianStateVariable::ALL) {
611 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
612 || state_variable_type == CartesianStateVariable::ALL) {
615 if (state_variable_type == CartesianStateVariable::LINEAR_VELOCITY
616 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
619 if (state_variable_type == CartesianStateVariable::ANGULAR_VELOCITY
620 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
623 if (state_variable_type == CartesianStateVariable::LINEAR_ACCELERATION
624 || state_variable_type == CartesianStateVariable::ACCELERATION
625 || state_variable_type == CartesianStateVariable::ALL) {
628 if (state_variable_type == CartesianStateVariable::ANGULAR_ACCELERATION
629 || state_variable_type == CartesianStateVariable::ACCELERATION
630 || state_variable_type == CartesianStateVariable::ALL) {
633 if (state_variable_type == CartesianStateVariable::FORCE || state_variable_type == CartesianStateVariable::WRENCH
634 || state_variable_type == CartesianStateVariable::ALL) {
637 if (state_variable_type == CartesianStateVariable::TORQUE || state_variable_type == CartesianStateVariable::WRENCH
638 || state_variable_type == CartesianStateVariable::ALL) {
659 Eigen::Vector3d b_P_c = state.get_position();
660 Eigen::Quaterniond b_R_c = state.get_orientation();
661 Eigen::Vector3d b_v_c = state.get_linear_velocity();
662 Eigen::Vector3d b_omega_c = state.get_angular_velocity();
663 Eigen::Vector3d b_a_c = state.get_linear_acceleration();
664 Eigen::Vector3d b_alpha_c = state.get_angular_acceleration();
665 Eigen::Vector3d b_F_c = state.get_force();
666 Eigen::Vector3d b_tau_c = state.get_torque();
669 auto orientation = f_R_b * b_R_c;
672 if (orientation.dot(this->get_orientation()) < 0) {
673 orientation = Eigen::Quaterniond(-orientation.coeffs());
683 f_a_b + f_R_b * b_a_c + f_alpha_b.cross(f_R_b * b_P_c) + 2 * f_omega_b.cross(f_R_b * b_v_c)
684 + f_omega_b.cross(f_omega_b.cross(f_R_b * b_P_c)));
704 auto q = math_tools::exp(math_tools::log(this->
get_orientation()), lambda);
706 q = Eigen::Quaterniond(-q.coeffs());
723 return state * lambda;
731 if (std::abs(lambda) < std::numeric_limits<double>::min()) {
732 throw std::runtime_error(
"Division by zero is not allowed");
734 lambda = 1.0 / lambda;
752 if (orientation.dot(this->get_orientation()) < 0) {
753 orientation = Eigen::Quaterniond(-orientation.coeffs());
797std::ostream&
operator<<(std::ostream& os,
const Eigen::Vector3d& field) {
798 os <<
"(" << field(0) <<
", " << field(1) <<
", " << field(2) <<
")";
808 if (this->
get_type() == StateType::CARTESIAN_POSE || this->
get_type() == StateType::CARTESIAN_STATE) {
809 s << std::endl <<
"position: " << this->
get_position() << std::endl;
815 s <<
" <=> theta: " << axis_angle.angle() <<
", ";
816 s <<
"axis: " << axis_angle.axis();
818 if (this->
get_type() == StateType::CARTESIAN_TWIST || this->
get_type() == StateType::CARTESIAN_STATE) {
822 if (this->
get_type() == StateType::CARTESIAN_ACCELERATION || this->
get_type() == StateType::CARTESIAN_STATE) {
826 if (this->
get_type() == StateType::CARTESIAN_WRENCH || this->
get_type() == StateType::CARTESIAN_STATE) {
827 s << std::endl <<
"force: " << this->
get_force() << std::endl;
834 os << state.to_string();
Class to represent a state in Cartesian space.
void set_zero()
Set the State to a zero value.
const Eigen::Vector3d & get_force() const
Getter of the force attribute.
void set_acceleration(const Eigen::Matrix< double, 6, 1 > &acceleration)
Setter of the linear and angular acceleration from a 6d acceleration vector.
CartesianState inverse() const
Compute the inverse of the current Cartesian state.
Eigen::ArrayXd array() const
Return the data vector as an Eigen Array.
const Eigen::Vector3d & get_torque() const
Getter of the torque attribute.
static CartesianState Random(const std::string &name, const std::string &reference="world")
Constructor for a random Cartesian state.
void set_state_variable(const Eigen::VectorXd &new_value, const CartesianStateVariable &state_variable_type)
Setter of the variable value corresponding to the input.
void set_orientation(const Eigen::Quaterniond &orientation)
Setter of the orientation.
const Eigen::Vector3d & get_linear_velocity() const
Getter of the linear velocity attribute.
void set_angular_acceleration(const Eigen::Vector3d &angular_acceleration)
Setter of the angular velocity attribute.
const Eigen::Vector3d & get_position() const
Getter of the position attribute.
void normalize(const CartesianStateVariable &state_variable_type=CartesianStateVariable::ALL)
Normalize inplace the state at the state variable given in argument. Default is full state.
virtual std::vector< double > norms(const CartesianStateVariable &state_variable_type=CartesianStateVariable::ALL) const
Compute the norms of the state variable specified by the input type. Default is full state.
void set_force(const Eigen::Vector3d &force)
Setter of the force attribute.
Eigen::Matrix< double, 6, 1 > get_twist() const
Getter of the 6d twist from linear and angular velocity attributes.
CartesianState normalized(const CartesianStateVariable &state_variable_type=CartesianStateVariable::ALL) const
Compute the normalized state at the state variable given in argument. Default is full state.
friend double dist(const CartesianState &s1, const CartesianState &s2, const CartesianStateVariable &state_variable_type)
Compute the distance between two Cartesian states.
CartesianState()
Empty constructor.
static CartesianState Identity(const std::string &name, const std::string &reference="world")
Constructor for the identity Cartesian state (identity pose and 0 for the rest)
CartesianState & operator/=(double lambda)
Scale inplace by a scalar.
const Eigen::Vector3d & get_linear_acceleration() const
Getter of the linear acceleration attribute.
Eigen::Matrix4d get_transformation_matrix() const
Getter of a pose from position and orientation attributes.
void set_linear_acceleration(const Eigen::Vector3d &linear_acceleration)
Setter of the linear acceleration attribute.
void clamp_state_variable(double max_norm, const CartesianStateVariable &state_variable_type, double noise_ratio=0)
Clamp inplace the norm of the a specific state variable.
Eigen::Matrix< double, 7, 1 > get_pose() const
Getter of the pose from position and orientation attributes.
void set_position(const Eigen::Vector3d &position)
Setter of the position.
std::string to_string() const override
Convert the state to its string representation.
void set_wrench(const Eigen::Matrix< double, 6, 1 > &wrench)
Setter of the force and torque from a 6d wrench vector.
const Eigen::Quaterniond & get_orientation() const
Getter of the orientation attribute.
Eigen::Matrix< double, 6, 1 > get_wrench() const
Getter of the 6d wrench from force and torque attributes.
Eigen::VectorXd get_state_variable(const CartesianStateVariable &state_variable_type) const
Getter of the variable value corresponding to the input.
void set_twist(const Eigen::Matrix< double, 6, 1 > &twist)
Setter of the linear and angular velocities from a 6d twist vector.
CartesianState & operator+=(const CartesianState &state)
Add inplace another Cartesian state.
CartesianState operator-() const
Negate a Cartesian state.
CartesianState & operator=(const CartesianState &state)
Copy assignment operator that has to be defined to the custom assignment operator.
virtual Eigen::VectorXd data() const
Return the data as the concatenation of all the state variables in a single vector.
const Eigen::Vector3d & get_angular_velocity() const
Getter of the angular velocity attribute.
void set_pose(const Eigen::Vector3d &position, const Eigen::Quaterniond &orientation)
Setter of the pose from both position and orientation.
CartesianState copy() const
Return a copy of the Cartesian state.
CartesianState & operator-=(const CartesianState &state)
Compute inplace the difference with another Cartesian state.
void set_torque(const Eigen::Vector3d &torque)
Setter of the torque attribute.
virtual void set_data(const Eigen::VectorXd &data) override
Set the data of the state from all the state variables in a single Eigen vector.
Eigen::Vector4d get_orientation_coefficients() const
Getter of the orientation attribute as Vector4d of coefficients.
CartesianState & operator*=(const CartesianState &state)
Transform inplace a Cartesian state into the current reference frame.
const Eigen::Vector3d & get_angular_acceleration() const
Getter of the angular acceleration attribute.
CartesianState operator/(double lambda) const
Scale a Cartesian state by a scalar.
double dist(const CartesianState &state, const CartesianStateVariable &state_variable_type=CartesianStateVariable::ALL) const
Compute the distance to another state as the sum of distances between each features.
std::vector< double > to_std_vector() const
Return the state as a std vector.
void set_linear_velocity(const Eigen::Vector3d &linear_velocity)
Setter of the linear velocity attribute.
void set_angular_velocity(const Eigen::Vector3d &angular_velocity)
Setter of the angular velocity attribute.
friend CartesianState operator*(double lambda, const CartesianState &state)
Scale a Cartesian state by a scalar.
Eigen::Matrix< double, 6, 1 > get_acceleration() const
Getter of the 6d acceleration from linear and angular acceleration attributes.
friend void swap(CartesianState &state1, CartesianState &state2)
Swap the values of two Cartesian states.
void reset() override
Reset the object to a post-construction state.
CartesianState operator+(const CartesianState &state) const
Add another Cartesian state.
virtual void set_reference_frame(const std::string &reference_frame)
Setter of the reference frame.
std::string to_string() const override
Convert the state to its string representation.
const std::string & get_reference_frame() const
Getter of the reference frame as const reference.
void reset_timestamp()
Reset the timestamp attribute to now.
const std::string & get_name() const
Getter of the name attribute.
virtual void set_name(const std::string &name)
Setter of the name attribute.
const StateType & get_type() const
Getter of the type attribute.
void set_type(const StateType &type)
Setter of the state type attribute.
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.
double dist(const CartesianState &s1, const CartesianState &s2, const CartesianStateVariable &state_variable_type=CartesianStateVariable::ALL)
Compute the distance between two Cartesian states.
std::ostream & operator<<(std::ostream &os, const AnalogIOState &state)
CartesianAcceleration operator*(double lambda, const CartesianAcceleration &acceleration)