Control Libraries 6.3.4
Loading...
Searching...
No Matches
PointAttractor.cpp
1#include "dynamical_systems/PointAttractor.hpp"
2
3#include "dynamical_systems/exceptions/NotImplementedException.hpp"
4#include "dynamical_systems/exceptions/EmptyAttractorException.hpp"
5#include "state_representation/exceptions/InvalidParameterException.hpp"
6#include "dynamical_systems/exceptions/IncompatibleSizeException.hpp"
7#include "state_representation/exceptions/EmptyStateException.hpp"
8#include "state_representation/exceptions/IncompatibleReferenceFramesException.hpp"
9#include "state_representation/exceptions/IncompatibleStatesException.hpp"
10#include "state_representation/space/cartesian/CartesianPose.hpp"
11#include "state_representation/space/cartesian/CartesianState.hpp"
12#include "state_representation/space/joint/JointPositions.hpp"
13#include "state_representation/space/joint/JointState.hpp"
14
15using namespace state_representation;
16
17namespace dynamical_systems {
18
19template<>
21 attractor_(make_shared_parameter<CartesianState>("attractor", CartesianState())),
22 gain_(make_shared_parameter<Eigen::MatrixXd>("gain", Eigen::MatrixXd::Identity(6, 6))) {
23 this->parameters_.insert(std::make_pair("attractor", attractor_));
24 this->parameters_.insert(std::make_pair("gain", gain_));
25}
26
27template<>
28PointAttractor<JointState>::PointAttractor() :
29 attractor_(make_shared_parameter<JointState>("attractor", JointState())),
30 gain_(std::make_shared<Parameter<Eigen::MatrixXd>>("gain")) {
31 this->parameters_.insert(std::make_pair("attractor", attractor_));
32 this->parameters_.insert(std::make_pair("gain", gain_));
33}
34
35template<class S>
36bool PointAttractor<S>::is_compatible(const S& state) const {
38}
39
41
42template<>
44 auto attractor = this->get_parameter_value<JointState>("attractor");
45 if (attractor.is_empty()) {
46 throw exceptions::EmptyAttractorException("The attractor of the dynamical system is empty.");
47 }
48 bool compatible = (attractor.get_size() == state.get_size());
49 if (compatible) {
50 for (unsigned int i = 0; i < attractor.get_size(); ++i) {
51 compatible = (compatible && attractor.get_names()[i] == state.get_names()[i]);
52 }
53 }
54 return compatible;
55}
56
57template<class S>
58void PointAttractor<S>::set_gain(const std::shared_ptr<ParameterInterface>& parameter, unsigned int expected_size) {
59 if (parameter->get_parameter_type() == ParameterType::DOUBLE) {
60 auto gain = parameter->get_parameter_value<double>();
61 this->gain_->set_value(gain * Eigen::MatrixXd::Identity(expected_size, expected_size));
62 } else if (parameter->get_parameter_type() == ParameterType::DOUBLE_ARRAY) {
63 auto gain = parameter->get_parameter_value<std::vector<double>>();
64 if (gain.size() != expected_size) {
66 "The provided diagonal coefficients do not correspond to the expected size of the attractor");
67 }
68 Eigen::VectorXd diagonal = Eigen::VectorXd::Map(gain.data(), expected_size);
69 this->gain_->set_value(diagonal.asDiagonal());
70 } else if (parameter->get_parameter_type() == ParameterType::MATRIX) {
71 auto gain = parameter->get_parameter_value<Eigen::MatrixXd>();
72 if (gain.rows() != expected_size && gain.cols() != expected_size) {
74 "The provided gain matrix do not have the expected size (" + std::to_string(expected_size) + "x"
75 + std::to_string(expected_size) + ")");
76 }
77 this->gain_->set_value(gain);
78 } else {
79 throw state_representation::exceptions::InvalidParameterException("Parameter 'gain' has incorrect type");
80 }
81}
82
83template<class S>
84void PointAttractor<S>::set_attractor(const S&) {
85 throw exceptions::NotImplementedException("set_attractor is not implemented for this type of DS");
86}
87
88template<>
89void PointAttractor<CartesianState>::set_attractor(const CartesianState& attractor) {
90 if (attractor.is_empty()) {
91 throw state_representation::exceptions::EmptyStateException(attractor.get_name() + " state is empty");
92 }
93 if (this->get_base_frame().is_empty()) {
94 IDynamicalSystem<CartesianState>::set_base_frame(
96 }
97 // validate that the reference frame of the attractor is always compatible with the DS reference frame
98 if (attractor.get_reference_frame() != this->get_base_frame().get_name()) {
99 if (attractor.get_reference_frame() != this->get_base_frame().get_reference_frame()) {
101 "The reference frame of the attractor " + attractor.get_name() + " in frame "
102 + attractor.get_reference_frame() + " is incompatible with the base frame of the dynamical system "
103 + this->get_base_frame().get_name() + " in frame " + this->get_base_frame().get_reference_frame() + ".");
104 }
105 this->attractor_->set_value(this->get_base_frame().inverse() * attractor);
106 } else {
107 this->attractor_->set_value(attractor);
108 }
109}
110
111template<>
112void PointAttractor<JointState>::set_attractor(const JointState& attractor) {
113 if (attractor.is_empty()) {
114 throw state_representation::exceptions::EmptyStateException(attractor.get_name() + " state is empty");
115 }
116 this->attractor_->set_value(attractor);
117 if (this->gain_->get_value().size() == 0) {
118 this->gain_->set_value(Eigen::MatrixXd::Identity(attractor.get_size(), attractor.get_size()));
119 }
120}
121
122template<class S>
123void PointAttractor<S>::set_base_frame(const S& base_frame) {
124 this->IDynamicalSystem<S>::set_base_frame(base_frame);
125}
126
127template void PointAttractor<JointState>::set_base_frame(const JointState& base_frame);
128
129template<>
131 if (base_frame.is_empty()) {
132 throw state_representation::exceptions::EmptyStateException(base_frame.get_name() + " state is empty");
133 }
134 IDynamicalSystem<CartesianState>::set_base_frame(base_frame);
135 if (!this->attractor_->get_value().is_empty()) {
136 // update reference frame of attractor
137 auto attractor = this->attractor_->get_value();
138 attractor.set_reference_frame(base_frame.get_name());
139 this->set_attractor(attractor);
140 }
141}
142
143template<>
144void PointAttractor<CartesianState>::validate_and_set_parameter(const std::shared_ptr<ParameterInterface>& parameter) {
145 if (parameter->get_name() == "attractor") {
146 if (parameter->get_parameter_state_type() == StateType::CARTESIAN_STATE) {
147 this->set_attractor(parameter->get_parameter_value<CartesianState>());
148 } else if (parameter->get_parameter_state_type() == StateType::CARTESIAN_POSE) {
149 this->set_attractor(parameter->get_parameter_value<CartesianPose>());
150 }
151 } else if (parameter->get_name() == "gain") {
152 this->set_gain(parameter, 6);
153 } else {
155 "No parameter with name '" + parameter->get_name() + "' found");
156 }
157}
158
159template<>
160void PointAttractor<JointState>::validate_and_set_parameter(const std::shared_ptr<ParameterInterface>& parameter) {
161 if (parameter->get_name() == "attractor") {
162 if (parameter->get_parameter_state_type() == StateType::JOINT_STATE) {
163 this->set_attractor(parameter->get_parameter_value<JointState>());
164 } else if (parameter->get_parameter_state_type() == StateType::JOINT_POSITIONS) {
165 this->set_attractor(parameter->get_parameter_value<JointPositions>());
166 }
167 } else if (parameter->get_name() == "gain") {
168 this->set_gain(parameter, this->attractor_->get_value().get_size());
169 } else {
171 "No parameter with name '" + parameter->get_name() + "' found");
172 }
173}
174
175template<class S>
177 throw exceptions::NotImplementedException("compute_dynamics is not implemented for this type of DS");
178}
179
180template<>
182 if (this->attractor_->get_value().is_empty()) {
183 throw exceptions::EmptyAttractorException("The attractor of the dynamical system is empty.");
184 }
185 CartesianTwist twist = CartesianPose(this->attractor_->get_value()) - CartesianPose(state);
186 twist *= this->gain_->get_value();
187 return CartesianTwist(state.get_name(), twist.get_twist(), this->attractor_->get_value().get_reference_frame());
188}
189
190template<>
191JointState PointAttractor<JointState>::compute_dynamics(const JointState& state) const {
192 JointVelocities velocities = JointPositions(this->attractor_->get_value()) - JointPositions(state);
193 velocities *= this->gain_->get_value();
194 return JointVelocities(state.get_name(), this->attractor_->get_value().get_names(), velocities.get_velocities());
195}
196}// namespace dynamical_systems
Abstract class for a dynamical system.
Represents a dynamical system to move towards an attractor.
PointAttractor()
Empty constructor.
Class to define CartesianPose in cartesian space as 3D position and quaternion based orientation.
Class to represent a state in Cartesian space.
Eigen::Matrix< double, 6, 1 > get_twist() const
Getter of the 6d twist from linear and angular velocity attributes.
static CartesianState Identity(const std::string &name, const std::string &reference="world")
Constructor for the identity CartesianState (identity pose and 0 for the rest)
Class to define twist in cartesian space as 3D linear and angular velocity vectors.
Class to define a positions of the joints.
Class to define a state in joint space.
Definition: JointState.hpp:36
const Eigen::VectorXd & get_velocities() const
Getter of the velocities attribute.
Definition: JointState.cpp:118
unsigned int get_size() const
Getter of the size from the attributes.
Definition: JointState.hpp:656
Class to define velocities of the joints.
const std::string & get_reference_frame() const
Getter of the reference frame as const reference.
const std::string & get_name() const
Getter of the name as const reference.
Definition: State.cpp:48
bool is_empty() const
Getter of the empty attribute.
Definition: State.cpp:23
Systems of equations relating state variables to their derivatives.
Definition: Circular.hpp:7
Core state variables and objects.