Control Libraries 6.3.4
Loading...
Searching...
No Matches
Circular.cpp
1#include "dynamical_systems/Circular.hpp"
2
3#include "dynamical_systems/exceptions/EmptyAttractorException.hpp"
4#include "state_representation/exceptions/InvalidParameterException.hpp"
5
6#include "state_representation/exceptions/EmptyStateException.hpp"
7
8using namespace state_representation;
9
10namespace dynamical_systems {
11
13 limit_cycle_(std::make_shared<Parameter<Ellipsoid>>("limit_cycle", Ellipsoid("limit_cycle", "limit_cycle"))),
14 planar_gain_(std::make_shared<Parameter<double>>("planar_gain", 1.0)),
15 normal_gain_(std::make_shared<Parameter<double>>("normal_gain", 1.0)),
16 circular_velocity_(std::make_shared<Parameter<double>>("circular_velocity", M_PI / 2)) {
17 this->limit_cycle_->get_value().set_center_state(CartesianState("limit_cycle", "limit_cycle"));
18 this->parameters_.insert(std::make_pair("limit_cycle", this->limit_cycle_));
19 this->parameters_.insert(std::make_pair("planar_gain", this->planar_gain_));
20 this->parameters_.insert(std::make_pair("normal_gain", this->normal_gain_));
21 this->parameters_.insert(std::make_pair("circular_velocity", this->circular_velocity_));
22}
23
24Circular::Circular(const std::list<std::shared_ptr<state_representation::ParameterInterface>>& parameters) :
25 Circular() {
26 this->set_parameters(parameters);
27}
28
29void Circular::set_limit_cycle(Ellipsoid& limit_cycle) {
30 const auto& center = limit_cycle.get_center_state();
31 if (center.is_empty()) {
32 throw state_representation::exceptions::EmptyStateException(center.get_name() + " state is empty");
33 }
34 if (this->get_base_frame().is_empty()) {
37 center.get_reference_frame(), center.get_reference_frame()));
38 }
39 if (center.get_reference_frame() != this->get_base_frame().get_name()) {
40 if (center.get_reference_frame() != this->get_base_frame().get_reference_frame()) {
42 "The reference frame of the center " + center.get_name() + " in frame " + center.get_reference_frame()
43 + " is incompatible with the base frame of the dynamical system " + this->get_base_frame().get_name()
44 + " in frame " + this->get_base_frame().get_reference_frame() + "."
45 );
46 }
47 limit_cycle.set_center_state(this->get_base_frame().inverse() * center);
48 }
49 this->limit_cycle_->set_value(limit_cycle);
50}
51
53 if (base_frame.is_empty()) {
54 throw state_representation::exceptions::EmptyStateException(base_frame.get_name() + " state is empty");
55 }
57 // update reference frame of center
58 if (!this->limit_cycle_->get_value().get_center_state().is_empty()) {
59 auto center_state = this->limit_cycle_->get_value().get_center_state();
60 center_state.set_reference_frame(base_frame.get_name());
61 this->limit_cycle_->get_value().set_center_state(center_state);
62 }
63}
64
65void Circular::validate_and_set_parameter(const std::shared_ptr<ParameterInterface>& parameter) {
66 if (parameter->get_name() == "limit_cycle") {
67 this->assert_parameter_valid(parameter);
68 this->set_limit_cycle(std::static_pointer_cast<Parameter<Ellipsoid>>(parameter)->get_value());
69 } else if (parameter->get_name() == "planar_gain") {
70 this->assert_parameter_valid(parameter);
71 this->planar_gain_->set_value(std::static_pointer_cast<Parameter<double>>(parameter)->get_value());
72 } else if (parameter->get_name() == "normal_gain") {
73 this->assert_parameter_valid(parameter);
74 this->normal_gain_->set_value(std::static_pointer_cast<Parameter<double>>(parameter)->get_value());
75 } else if (parameter->get_name() == "circular_velocity") {
76 this->assert_parameter_valid(parameter);
77 this->circular_velocity_->set_value(std::static_pointer_cast<Parameter<double>>(parameter)->get_value());
78 } else {
80 "No parameter with name '" + parameter->get_name() + "' found"
81 );
82 }
83}
84
86 if (this->limit_cycle_->get_value().get_center_state().is_empty()) {
87 throw exceptions::EmptyAttractorException("The limit cycle of the dynamical system is empty.");
88 }
89 // put the point in the reference of the center
90 auto pose = CartesianPose(state);
91 pose = this->limit_cycle_->get_value().get_rotation().inverse()
92 * this->limit_cycle_->get_value().get_center_pose().inverse() * pose;
93
94 CartesianTwist velocity(pose.get_name(), pose.get_reference_frame());
95 Eigen::Vector3d linear_velocity;
96 linear_velocity(2) = -this->normal_gain_->get_value() * pose.get_position()(2);
97
98 std::vector<double> radiuses = this->limit_cycle_->get_value().get_axis_lengths();
99
100 double a2ratio = (pose.get_position()[0] * pose.get_position()[0]) / (radiuses[0] * radiuses[0]);
101 double b2ratio = (pose.get_position()[1] * pose.get_position()[1]) / (radiuses[1] * radiuses[1]);
102 double dradius = -this->planar_gain_->get_value() * radiuses[0] * radiuses[1] * (a2ratio + b2ratio - 1);
103 double tangent_velocity_x = -radiuses[0] / radiuses[1] * pose.get_position()[1];
104 double tangent_velocity_y = radiuses[1] / radiuses[0] * pose.get_position()[0];
105
106 linear_velocity(0) = this->circular_velocity_->get_value() * tangent_velocity_x + dradius * tangent_velocity_y;
107 linear_velocity(1) = this->circular_velocity_->get_value() * tangent_velocity_y - dradius * tangent_velocity_x;
108
109 velocity.set_linear_velocity(linear_velocity);
110 velocity.set_angular_velocity(Eigen::Vector3d::Zero());
111
112 //compute back the linear velocity in the desired frame
113 auto frame = this->limit_cycle_->get_value().get_center_pose() * this->limit_cycle_->get_value().get_rotation();
114 return CartesianState(frame) * velocity;
115}
116}// namespace dynamical_systems
Represent a Circular dynamical system to move around an center.
Definition: Circular.hpp:13
void set_base_frame(const state_representation::CartesianState &base_frame) override
Set a parameter.
Definition: Circular.cpp:52
state_representation::CartesianState compute_dynamics(const state_representation::CartesianState &state) const override
Compute the dynamics of the input state. Internal function, to be redefined based on the type of dyna...
Definition: Circular.cpp:85
Circular()
Empty constructor.
Definition: Circular.cpp:12
state_representation::CartesianState get_base_frame() const
Return the base frame of the dynamical system.
virtual void set_base_frame(const S &base_frame)
Set the base frame of the dynamical system.
Class to define CartesianPose in cartesian space as 3D position and quaternion based orientation.
Class to represent a state in Cartesian space.
static CartesianState Identity(const std::string &name, const std::string &reference="world")
Constructor for the identity CartesianState (identity pose and 0 for the rest)
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.
Class to define twist in cartesian space as 3D linear and angular velocity vectors.
void assert_parameter_valid(const std::shared_ptr< ParameterInterface > &parameter)
Check if a parameter has the expected type, throw an exception otherwise.
void set_parameters(const ParameterInterfaceList &parameters)
Set parameters from a list of parameters.
ParameterInterfaceMap parameters_
map of parameters by name
void set_center_state(const CartesianState &state)
Setter of the state.
Definition: Shape.hpp:137
const CartesianState & get_center_state() const
Getter of the state.
Definition: Shape.hpp:117
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.