Control Libraries 7.4.0
Loading...
Searching...
No Matches
CartesianState.cpp
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"
5
6namespace state_representation {
7
8using namespace exceptions;
9
10static Eigen::Vector4d quat2vec(const Eigen::Quaterniond quat) {
11 return {quat.w(), quat.x(), quat.y(), quat.z()};
12}
13
14static Eigen::Quaterniond vec2quat(const Eigen::Vector4d vec) {
15 return Eigen::Quaterniond(vec(0), vec(1), vec(2), vec(3)).normalized();
16}
17
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:
27 return 3;
28 case CartesianStateVariable::ORIENTATION:
29 return 4;
30 case CartesianStateVariable::TWIST:
31 case CartesianStateVariable::ACCELERATION:
32 case CartesianStateVariable::WRENCH:
33 return 6;
34 case CartesianStateVariable::POSE:
35 return 7;
36 case CartesianStateVariable::ALL:
37 return 25;
38 default:
39 return 0;
40 }
41}
42
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);
54}
55
56CartesianState::CartesianState(const std::string& name, const std::string& reference) : CartesianState() {
57 this->set_name(name);
58 this->set_reference_frame(reference);
59}
60
62 CartesianState(state.get_name(), state.get_reference_frame()) {
63 if (state) {
64 this->set_state_variable(state.get_state_variable(CartesianStateVariable::ALL), CartesianStateVariable::ALL);
65 }
66}
67
68CartesianState CartesianState::Identity(const std::string& name, const std::string& reference) {
69 CartesianState identity = CartesianState(name, reference);
70 // as opposed to the constructor specify this state to be filled
71 identity.set_empty(false);
72 return identity;
73}
74
75CartesianState CartesianState::Random(const std::string& name, const std::string& reference) {
76 CartesianState random = CartesianState(name, reference);
77 // set all the state variables to random
78 random.set_state_variable(Eigen::VectorXd::Random(25), CartesianStateVariable::ALL);
79 random.set_orientation(Eigen::Quaterniond::UnitRandom());
80 return random;
81}
82
84 CartesianState tmp(state);
85 swap(*this, tmp);
86 return *this;
87}
88
89Eigen::VectorXd CartesianState::get_state_variable(const CartesianStateVariable& state_variable_type) const {
90 this->assert_not_empty();
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_);
99 return pose;
100 }
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_;
108 return twist;
109 }
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_;
117 return acceleration;
118 }
119 case CartesianStateVariable::FORCE:
120 return this->force_;
121 case CartesianStateVariable::TORQUE:
122 return this->torque_;
123 case CartesianStateVariable::WRENCH: {
124 Eigen::VectorXd wrench(6);
125 wrench << this->force_, this->torque_;
126 return wrench;
127 }
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_;
132 return all_fields;
133 }
134 default:
135 return {};
136 }
137}
138
139const Eigen::Vector3d& CartesianState::get_position() const {
140 this->assert_not_empty();
141 return this->position_;
142}
143
144const Eigen::Quaterniond& CartesianState::get_orientation() const {
145 this->assert_not_empty();
146 return this->orientation_;
147}
148
150 return this->get_state_variable(CartesianStateVariable::ORIENTATION);
151}
152
153Eigen::Matrix<double, 7, 1> CartesianState::get_pose() const {
154 return this->get_state_variable(CartesianStateVariable::POSE);
155}
156
158 this->assert_not_empty();
159 Eigen::Matrix4d pose;
160 pose << this->orientation_.toRotationMatrix(), this->position_, 0., 0., 0., 1;
161 return pose;
162}
163
164const Eigen::Vector3d& CartesianState::get_linear_velocity() const {
165 this->assert_not_empty();
166 return this->linear_velocity_;
167}
168
169const Eigen::Vector3d& CartesianState::get_angular_velocity() const {
170 this->assert_not_empty();
171 return this->angular_velocity_;
172}
173
174Eigen::Matrix<double, 6, 1> CartesianState::get_twist() const {
175 return this->get_state_variable(CartesianStateVariable::TWIST);
176}
177
178const Eigen::Vector3d& CartesianState::get_linear_acceleration() const {
179 this->assert_not_empty();
180 return this->linear_acceleration_;
181}
182
183const Eigen::Vector3d& CartesianState::get_angular_acceleration() const {
184 this->assert_not_empty();
185 return this->angular_acceleration_;
186}
187
188Eigen::Matrix<double, 6, 1> CartesianState::get_acceleration() const {
189 return this->get_state_variable(CartesianStateVariable::ACCELERATION);
190}
191
192const Eigen::Vector3d& CartesianState::get_force() const {
193 this->assert_not_empty();
194 return this->force_;
195}
196
197const Eigen::Vector3d& CartesianState::get_torque() const {
198 this->assert_not_empty();
199 return this->torque_;
200}
201
202Eigen::Matrix<double, 6, 1> CartesianState::get_wrench() const {
203 return this->get_state_variable(CartesianStateVariable::WRENCH);
204}
205
206Eigen::VectorXd CartesianState::data() const {
207 return this->get_state_variable(CartesianStateVariable::ALL);
208}
209
210Eigen::ArrayXd CartesianState::array() const {
211 return this->data().array();
212}
213
214std::vector<double> CartesianState::to_std_vector() const {
215 Eigen::VectorXd data = this->data();
216 return {data.data(), data.data() + data.size()};
217}
218
220 const std::vector<double>& new_value, const CartesianStateVariable& state_variable_type
221) {
222 this->set_state_variable(Eigen::VectorXd::Map(new_value.data(), new_value.size()), state_variable_type);
223}
224
226 const Eigen::VectorXd& new_value, const CartesianStateVariable& state_variable_type
227) {
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()));
233 }
234 switch (state_variable_type) {
235 case CartesianStateVariable::POSITION:
236 this->position_ = new_value;
237 break;
238 case CartesianStateVariable::ORIENTATION:
239 this->orientation_ = vec2quat(new_value);
240 break;
241 case CartesianStateVariable::POSE:
242 this->position_ = new_value.head(3);
243 this->orientation_ = vec2quat(new_value.tail(4));
244 break;
245 case CartesianStateVariable::LINEAR_VELOCITY:
246 this->linear_velocity_ = new_value;
247 break;
248 case CartesianStateVariable::ANGULAR_VELOCITY:
249 this->angular_velocity_ = new_value;
250 break;
251 case CartesianStateVariable::TWIST:
252 this->linear_velocity_ = new_value.head(3);
253 this->angular_velocity_ = new_value.tail(3);
254 break;
255 case CartesianStateVariable::LINEAR_ACCELERATION:
256 this->linear_acceleration_ = new_value;
257 break;
258 case CartesianStateVariable::ANGULAR_ACCELERATION:
259 this->angular_acceleration_ = new_value;
260 break;
261 case CartesianStateVariable::ACCELERATION:
262 this->linear_acceleration_ = new_value.head(3);
263 this->angular_acceleration_ = new_value.tail(3);
264 break;
265 case CartesianStateVariable::FORCE:
266 this->force_ = new_value;
267 break;
268 case CartesianStateVariable::TORQUE:
269 this->torque_ = new_value;
270 break;
271 case CartesianStateVariable::WRENCH:
272 this->force_ = new_value.head(3);
273 this->torque_ = new_value.tail(3);
274 break;
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);
284 break;
285 }
286 this->set_empty(false);
287}
288
289void CartesianState::set_position(const Eigen::Vector3d& position) {
290 this->set_state_variable(position, CartesianStateVariable::POSITION);
291}
292
293void CartesianState::set_position(const std::vector<double>& position) {
294 this->set_state_variable(position, CartesianStateVariable::POSITION);
295}
296
297void CartesianState::set_position(const double& x, const double& y, const double& z) {
298 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::POSITION);
299}
300
301void CartesianState::set_orientation(const Eigen::Quaterniond& orientation) {
302 // orientation is a special case, to avoid transforming between vector and quaternion, set it here directly
303 // but also set filled as in set_state_variable
304 this->orientation_ = orientation.normalized();
305 this->set_empty(false);
306}
307
308void CartesianState::set_orientation(const Eigen::Vector4d& orientation) {
309 this->set_state_variable(orientation, CartesianStateVariable::ORIENTATION);
310}
311
312void CartesianState::set_orientation(const std::vector<double>& orientation) {
313 this->set_state_variable(orientation, CartesianStateVariable::ORIENTATION);
314}
315
316void CartesianState::set_orientation(const double& w, const double& x, const double& y, const double& z) {
317 this->set_state_variable(Eigen::Vector4d(w, x, y, z), CartesianStateVariable::ORIENTATION);
318}
319
320void CartesianState::set_pose(const Eigen::Vector3d& position, const Eigen::Quaterniond& orientation) {
321 this->orientation_ = orientation.normalized();
322 this->set_state_variable(position, CartesianStateVariable::POSITION);
323}
324
325void CartesianState::set_pose(const Eigen::Matrix<double, 7, 1>& pose) {
326 this->set_state_variable(pose, CartesianStateVariable::POSE);
327}
328
329void CartesianState::set_pose(const std::vector<double>& pose) {
330 this->set_state_variable(pose, CartesianStateVariable::POSE);
331}
332
333void CartesianState::set_linear_velocity(const Eigen::Vector3d& linear_velocity) {
334 this->set_state_variable(linear_velocity, CartesianStateVariable::LINEAR_VELOCITY);
335}
336
337void CartesianState::set_linear_velocity(const std::vector<double>& linear_velocity) {
338 this->set_state_variable(linear_velocity, CartesianStateVariable::LINEAR_VELOCITY);
339}
340
341void CartesianState::set_linear_velocity(const double& x, const double& y, const double& z) {
342 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::LINEAR_VELOCITY);
343}
344
345void CartesianState::set_angular_velocity(const Eigen::Vector3d& angular_velocity) {
346 this->set_state_variable(angular_velocity, CartesianStateVariable::ANGULAR_VELOCITY);
347}
348
349void CartesianState::set_angular_velocity(const std::vector<double>& angular_velocity) {
350 this->set_state_variable(angular_velocity, CartesianStateVariable::ANGULAR_VELOCITY);
351}
352
353void CartesianState::set_angular_velocity(const double& x, const double& y, const double& z) {
354 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::ANGULAR_VELOCITY);
355}
356
357void CartesianState::set_twist(const Eigen::Matrix<double, 6, 1>& twist) {
358 this->set_state_variable(twist, CartesianStateVariable::TWIST);
359}
360
361void CartesianState::set_twist(const std::vector<double>& twist) {
362 this->set_state_variable(twist, CartesianStateVariable::TWIST);
363}
364
365void CartesianState::set_linear_acceleration(const Eigen::Vector3d& linear_acceleration) {
366 this->set_state_variable(linear_acceleration, CartesianStateVariable::LINEAR_ACCELERATION);
367}
368
369void CartesianState::set_linear_acceleration(const std::vector<double>& linear_acceleration) {
370 this->set_state_variable(linear_acceleration, CartesianStateVariable::LINEAR_ACCELERATION);
371}
372
373void CartesianState::set_linear_acceleration(const double& x, const double& y, const double& z) {
374 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::LINEAR_ACCELERATION);
375}
376
377void CartesianState::set_angular_acceleration(const Eigen::Vector3d& angular_acceleration) {
378 this->set_state_variable(angular_acceleration, CartesianStateVariable::ANGULAR_ACCELERATION);
379}
380
381void CartesianState::set_angular_acceleration(const std::vector<double>& angular_acceleration) {
382 this->set_state_variable(angular_acceleration, CartesianStateVariable::ANGULAR_ACCELERATION);
383}
384
385void CartesianState::set_angular_acceleration(const double& x, const double& y, const double& z) {
386 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::ANGULAR_ACCELERATION);
387}
388
389void CartesianState::set_acceleration(const Eigen::Matrix<double, 6, 1>& acceleration) {
390 this->set_state_variable(acceleration, CartesianStateVariable::ACCELERATION);
391}
392
393void CartesianState::set_acceleration(const std::vector<double>& acceleration) {
394 this->set_state_variable(acceleration, CartesianStateVariable::ACCELERATION);
395}
396
397void CartesianState::set_force(const Eigen::Vector3d& force) {
398 this->set_state_variable(force, CartesianStateVariable::FORCE);
399}
400
401void CartesianState::set_force(const std::vector<double>& force) {
402 this->set_state_variable(force, CartesianStateVariable::FORCE);
403}
404
405void CartesianState::set_force(const double& x, const double& y, const double& z) {
406 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::FORCE);
407}
408
409void CartesianState::set_torque(const Eigen::Vector3d& torque) {
410 this->set_state_variable(torque, CartesianStateVariable::TORQUE);
411}
412
413void CartesianState::set_torque(const std::vector<double>& torque) {
414 this->set_state_variable(torque, CartesianStateVariable::TORQUE);
415}
416
417void CartesianState::set_torque(const double& x, const double& y, const double& z) {
418 this->set_state_variable(Eigen::Vector3d(x, y, z), CartesianStateVariable::TORQUE);
419}
420
421void CartesianState::set_wrench(const Eigen::Matrix<double, 6, 1>& wrench) {
422 this->set_state_variable(wrench, CartesianStateVariable::WRENCH);
423}
424
425void CartesianState::set_wrench(const std::vector<double>& wrench) {
426 this->set_state_variable(wrench, CartesianStateVariable::WRENCH);
427}
428
429void CartesianState::set_data(const Eigen::VectorXd& data) {
430 this->set_state_variable(data, CartesianStateVariable::ALL);
431}
432
433void CartesianState::set_data(const std::vector<double>& data) {
434 this->set_state_variable(data, CartesianStateVariable::ALL);
435}
436
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();
446 this->set_empty(false);
447}
448
450 double max_norm, const CartesianStateVariable& state_variable_type, double noise_ratio
451) {
452 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
453 || state_variable_type == CartesianStateVariable::ALL) {
454 throw NotImplementedException("clamp_state_variable is not implemented for this CartesianStateVariable");
455 }
456 Eigen::VectorXd state_variable_value = this->get_state_variable(state_variable_type);
457 if (noise_ratio != 0 && state_variable_value.norm() < noise_ratio * max_norm) {
458 // apply a dead zone
459 state_variable_value.setZero();
460 } else if (state_variable_value.norm() > max_norm) {
461 // clamp the values to their maximum amplitude provided
462 state_variable_value = max_norm * state_variable_value.normalized();
463 }
464 this->set_state_variable(state_variable_value, state_variable_type);
465}
466
468 CartesianState result(*this);
469 return result;
470}
471
472double CartesianState::dist(const CartesianState& state, const CartesianStateVariable& state_variable_type) const {
473 if (!(this->get_reference_frame() == state.get_reference_frame())) {
474 throw IncompatibleReferenceFramesException("The two states do not have the same reference frame");
475 }
476 // calculation
477 double result = 0;
478 if (state_variable_type == CartesianStateVariable::POSITION || state_variable_type == CartesianStateVariable::POSE
479 || state_variable_type == CartesianStateVariable::ALL) {
480 result += (this->get_position() - state.get_position()).norm();
481 }
482 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
483 || state_variable_type == CartesianStateVariable::ALL) {
484 result += this->get_orientation().angularDistance(state.get_orientation());
485 }
486 if (state_variable_type == CartesianStateVariable::LINEAR_VELOCITY
487 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
488 result += (this->get_linear_velocity() - state.get_linear_velocity()).norm();
489 }
490 if (state_variable_type == CartesianStateVariable::ANGULAR_VELOCITY
491 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
492 result += (this->get_angular_velocity() - state.get_angular_velocity()).norm();
493 }
494 if (state_variable_type == CartesianStateVariable::LINEAR_ACCELERATION
495 || state_variable_type == CartesianStateVariable::ACCELERATION
496 || state_variable_type == CartesianStateVariable::ALL) {
497 result += (this->get_linear_acceleration() - state.get_linear_acceleration()).norm();
498 }
499 if (state_variable_type == CartesianStateVariable::ANGULAR_ACCELERATION
500 || state_variable_type == CartesianStateVariable::ACCELERATION
501 || state_variable_type == CartesianStateVariable::ALL) {
502 result += (this->get_angular_acceleration() - state.get_angular_acceleration()).norm();
503 }
504 if (state_variable_type == CartesianStateVariable::FORCE || state_variable_type == CartesianStateVariable::WRENCH
505 || state_variable_type == CartesianStateVariable::ALL) {
506 result += (this->get_force() - state.get_force()).norm();
507 }
508 if (state_variable_type == CartesianStateVariable::TORQUE || state_variable_type == CartesianStateVariable::WRENCH
509 || state_variable_type == CartesianStateVariable::ALL) {
510 result += (this->get_torque() - state.get_torque()).norm();
511 }
512 return result;
513}
514
515double dist(const CartesianState& s1, const CartesianState& s2, const CartesianStateVariable& state_variable_type) {
516 return s1.dist(s2, state_variable_type);
517}
518
520 this->set_zero();
521 this->State::reset();
522}
523
525 CartesianState inverse(*this);
526 // invert name and reference frame
527 std::string ref = inverse.get_reference_frame();
529 inverse.set_name(ref);
530
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); // radially induced velocity
536
537 Eigen::Vector3d inverse_angular_acceleration = inverse_orientation * (-this->get_angular_acceleration());
538 Eigen::Vector3d inverse_linear_acceleration = inverse_orientation * (-this->get_linear_acceleration());
539 inverse_linear_acceleration += inverse_angular_acceleration.cross(inverse_position); // Euler acceleration
540 inverse_linear_acceleration += 2 * inverse_angular_velocity.cross(inverse_linear_velocity); // Coriolis acceleration
541 inverse_linear_acceleration -=
542 inverse_angular_velocity.cross(inverse_angular_velocity.cross(inverse_position)); // centrifugal acceleration
543
544 // collect the results
545 inverse.set_position(inverse_position);
546 inverse.set_orientation(inverse_orientation);
547 inverse.set_linear_velocity(inverse_linear_velocity);
548 inverse.set_angular_velocity(inverse_angular_velocity);
549 inverse.set_linear_acceleration(inverse_linear_acceleration);
550 inverse.set_angular_acceleration(inverse_angular_acceleration);
551
552 // the inverse wrench is not supported by this operation
553 inverse.set_wrench(Eigen::Vector<double, 6>::Zero());
554
555 return inverse;
556}
557
558void CartesianState::normalize(const CartesianStateVariable& state_variable_type) {
559 this->assert_not_empty();
560 if (state_variable_type == CartesianStateVariable::POSITION || state_variable_type == CartesianStateVariable::POSE
561 || state_variable_type == CartesianStateVariable::ALL) {
562 this->position_.normalize();
563 }
564 // there shouldn't be a need to renormalize orientation as it is already normalized
565 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
566 || state_variable_type == CartesianStateVariable::ALL) {
567 this->orientation_.normalize();
568 }
569 if (state_variable_type == CartesianStateVariable::LINEAR_VELOCITY
570 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
571 this->linear_velocity_.normalize();
572 }
573 if (state_variable_type == CartesianStateVariable::ANGULAR_VELOCITY
574 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
575 this->angular_velocity_.normalize();
576 }
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();
581 }
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();
586 }
587 if (state_variable_type == CartesianStateVariable::FORCE || state_variable_type == CartesianStateVariable::WRENCH
588 || state_variable_type == CartesianStateVariable::ALL) {
589 this->force_.normalize();
590 }
591 if (state_variable_type == CartesianStateVariable::TORQUE || state_variable_type == CartesianStateVariable::WRENCH
592 || state_variable_type == CartesianStateVariable::ALL) {
593 this->torque_.normalize();
594 }
595 this->reset_timestamp();
596}
597
598CartesianState CartesianState::normalized(const CartesianStateVariable& state_variable_type) const {
599 CartesianState result(*this);
600 result.normalize(state_variable_type);
601 return result;
602}
603
604std::vector<double> CartesianState::norms(const CartesianStateVariable& state_variable_type) const {
605 // compute the norms for each independent state variable
606 std::vector<double> norms;
607 if (state_variable_type == CartesianStateVariable::POSITION || state_variable_type == CartesianStateVariable::POSE
608 || state_variable_type == CartesianStateVariable::ALL) {
609 norms.push_back(this->get_position().norm());
610 }
611 if (state_variable_type == CartesianStateVariable::ORIENTATION || state_variable_type == CartesianStateVariable::POSE
612 || state_variable_type == CartesianStateVariable::ALL) {
613 norms.push_back(this->get_orientation().norm());
614 }
615 if (state_variable_type == CartesianStateVariable::LINEAR_VELOCITY
616 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
617 norms.push_back(this->get_linear_velocity().norm());
618 }
619 if (state_variable_type == CartesianStateVariable::ANGULAR_VELOCITY
620 || state_variable_type == CartesianStateVariable::TWIST || state_variable_type == CartesianStateVariable::ALL) {
621 norms.push_back(this->get_angular_velocity().norm());
622 }
623 if (state_variable_type == CartesianStateVariable::LINEAR_ACCELERATION
624 || state_variable_type == CartesianStateVariable::ACCELERATION
625 || state_variable_type == CartesianStateVariable::ALL) {
626 norms.push_back(this->get_linear_acceleration().norm());
627 }
628 if (state_variable_type == CartesianStateVariable::ANGULAR_ACCELERATION
629 || state_variable_type == CartesianStateVariable::ACCELERATION
630 || state_variable_type == CartesianStateVariable::ALL) {
631 norms.push_back(this->get_angular_acceleration().norm());
632 }
633 if (state_variable_type == CartesianStateVariable::FORCE || state_variable_type == CartesianStateVariable::WRENCH
634 || state_variable_type == CartesianStateVariable::ALL) {
635 norms.push_back(this->get_force().norm());
636 }
637 if (state_variable_type == CartesianStateVariable::TORQUE || state_variable_type == CartesianStateVariable::WRENCH
638 || state_variable_type == CartesianStateVariable::ALL) {
639 norms.push_back(this->get_torque().norm());
640 }
641 return norms;
642}
643
645 if (this->get_name() != state.get_reference_frame()) {
646 throw IncompatibleReferenceFramesException("Expected " + this->get_name() + ", got " + state.get_reference_frame());
647 }
648 this->set_name(state.get_name());
649
650 // intermediate variables for f_S_b
651 Eigen::Vector3d f_P_b = this->get_position();
652 Eigen::Quaterniond f_R_b = this->get_orientation();
653 Eigen::Vector3d f_v_b = this->get_linear_velocity();
654 Eigen::Vector3d f_omega_b = this->get_angular_velocity();
655 Eigen::Vector3d f_a_b = this->get_linear_acceleration();
656 Eigen::Vector3d f_alpha_b = this->get_angular_acceleration();
657
658 // intermediate variables for b_S_c
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();
667 // pose
668 this->set_position(f_P_b + f_R_b * b_P_c);
669 auto orientation = f_R_b * b_R_c;
670
671 // specific operation on quaternion using Hamilton product, keeping the resulting quaternion on the same hemisphere
672 if (orientation.dot(this->get_orientation()) < 0) {
673 orientation = Eigen::Quaterniond(-orientation.coeffs());
674 }
675 this->set_orientation(orientation);
676
677 // twist
678 this->set_linear_velocity(f_v_b + f_R_b * b_v_c + f_omega_b.cross(f_R_b * b_P_c));
679 this->set_angular_velocity(f_omega_b + f_R_b * b_omega_c);
680
681 // acceleration
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)));
685 this->set_angular_acceleration(f_alpha_b + f_R_b * b_alpha_c + f_omega_b.cross(f_R_b * b_omega_c));
686
687 // keep only the wrench measured at the distal frame, aligned with the new reference frame
688 this->set_force(f_R_b * b_F_c);
689 this->set_torque(f_R_b * b_tau_c);
690
691 return (*this);
692}
693
695 CartesianState result(*this);
696 result *= state;
697 return result;
698}
699
701 // operation
702 this->set_position(lambda * this->get_position());
703 // calculate the scaled rotation as a displacement from identity
704 auto q = math_tools::exp(math_tools::log(this->get_orientation()), lambda);
705 if (this->get_orientation().w() * q.w() < 0) {
706 q = Eigen::Quaterniond(-q.coeffs());
707 }
708 this->set_orientation(q);
709 // calculate the other vectors normally
710 this->set_twist(lambda * this->get_twist());
711 this->set_acceleration(lambda * this->get_acceleration());
712 this->set_wrench(lambda * this->get_wrench());
713 return (*this);
714}
715
717 CartesianState result(*this);
718 result *= lambda;
719 return result;
720}
721
722CartesianState operator*(double lambda, const CartesianState& state) {
723 return state * lambda;
724}
725
726Eigen::Vector3d CartesianState::operator*(const Eigen::Vector3d& vector) const {
727 return this->get_orientation() * vector + this->get_position();
728}
729
731 if (std::abs(lambda) < std::numeric_limits<double>::min()) {
732 throw std::runtime_error("Division by zero is not allowed");
733 }
734 lambda = 1.0 / lambda;
735 return this->operator*=(lambda);
736}
737
739 CartesianState result(*this);
740 result /= lambda;
741 return result;
742}
743
745 if (!(this->get_reference_frame() == state.get_reference_frame())) {
746 throw IncompatibleReferenceFramesException("The two states do not have the same reference frame");
747 }
748 // operation on pose
749 this->set_position(this->get_position() + state.get_position());
750 // specific operation on quaternion using Hamilton product, keeping the resulting quaternion on the same hemisphere
751 auto orientation = this->get_orientation() * state.get_orientation();
752 if (orientation.dot(this->get_orientation()) < 0) {
753 orientation = Eigen::Quaterniond(-orientation.coeffs());
754 }
755 this->set_orientation(orientation);
756 // operation on twist
757 this->set_twist(this->get_twist() + state.get_twist());
758 // operation on acceleration
759 this->set_acceleration(this->get_acceleration() + state.get_acceleration());
760 // operation on wrench
761 this->set_wrench(this->get_wrench() + state.get_wrench());
762 return (*this);
763}
764
766 CartesianState result(*this);
767 result += state;
768 return result;
769}
770
772 // create a copy of the state
773 CartesianState result(*this);
774 // operation on pose
775 result.set_position(-result.get_position());
776 result.set_orientation(result.get_orientation().conjugate());
777 // operation on twist
778 result.set_twist(-result.get_twist());
779 // operation on acceleration
780 result.set_acceleration(-result.get_acceleration());
781 // operation on wrench
782 result.set_wrench(-result.get_wrench());
783 return result;
784}
785
787 (*this) += -state;
788 return (*this);
789}
790
792 CartesianState result(*this);
793 result -= state;
794 return result;
795}
796
797std::ostream& operator<<(std::ostream& os, const Eigen::Vector3d& field) {
798 os << "(" << field(0) << ", " << field(1) << ", " << field(2) << ")";
799 return os;
800}
801
802std::string CartesianState::to_string() const {
803 std::stringstream s;
804 s << this->SpatialState::to_string();
805 if (this->is_empty()) {
806 return s.str();
807 }
808 if (this->get_type() == StateType::CARTESIAN_POSE || this->get_type() == StateType::CARTESIAN_STATE) {
809 s << std::endl << "position: " << this->get_position() << std::endl;
810 s << "orientation: (" << this->get_orientation().w() << ", ";
811 s << this->get_orientation().x() << ", ";
812 s << this->get_orientation().y() << ", ";
813 s << this->get_orientation().z() << ")";
814 Eigen::AngleAxisd axis_angle(this->get_orientation());
815 s << " <=> theta: " << axis_angle.angle() << ", ";
816 s << "axis: " << axis_angle.axis();
817 }
818 if (this->get_type() == StateType::CARTESIAN_TWIST || this->get_type() == StateType::CARTESIAN_STATE) {
819 s << std::endl << "linear velocity: " << this->get_linear_velocity() << std::endl;
820 s << "angular velocity: " << this->get_angular_velocity();
821 }
822 if (this->get_type() == StateType::CARTESIAN_ACCELERATION || this->get_type() == StateType::CARTESIAN_STATE) {
823 s << std::endl << "linear acceleration: " << this->get_linear_acceleration() << std::endl;
824 s << "angular acceleration: " << this->get_angular_acceleration();
825 }
826 if (this->get_type() == StateType::CARTESIAN_WRENCH || this->get_type() == StateType::CARTESIAN_STATE) {
827 s << std::endl << "force: " << this->get_force() << std::endl;
828 s << "torque: " << this->get_torque();
829 }
830 return s.str();
831}
832
833std::ostream& operator<<(std::ostream& os, const CartesianState& state) {
834 os << state.to_string();
835 return os;
836}
837}// namespace state_representation
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.
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.
Definition State.cpp:61
const std::string & get_name() const
Getter of the name attribute.
Definition State.cpp:29
virtual void set_name(const std::string &name)
Setter of the name attribute.
Definition State.cpp:45
const StateType & get_type() const
Getter of the type attribute.
Definition State.cpp:25
void set_type(const StateType &type)
Setter of the state type attribute.
Definition State.cpp:41
virtual void reset()
Reset the object to a post-construction state.
Definition State.cpp:77
void assert_not_empty() const
Throw an exception if the state is empty.
Definition State.cpp:55
bool is_empty() const
Getter of the empty attribute.
Definition State.cpp:33
void set_empty(bool empty=true)
Setter of the empty attribute.
Definition State.cpp:50
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)