Control Libraries 7.4.0
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/EmptyStateException.hpp"
5#include "state_representation/exceptions/IncompatibleReferenceFramesException.hpp"
6#include "state_representation/exceptions/InvalidParameterException.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->parameters_.insert(std::make_pair("limit_cycle", this->limit_cycle_));
18 this->parameters_.insert(std::make_pair("planar_gain", this->planar_gain_));
19 this->parameters_.insert(std::make_pair("normal_gain", this->normal_gain_));
20 this->parameters_.insert(std::make_pair("circular_velocity", this->circular_velocity_));
21}
22
23Circular::Circular(const std::list<std::shared_ptr<state_representation::ParameterInterface>>& parameters) :
24 Circular() {
25 this->set_parameters(parameters);
26}
27
28void Circular::set_limit_cycle(Ellipsoid& limit_cycle) {
29 if (limit_cycle.is_empty()) {
30 throw state_representation::exceptions::EmptyStateException(limit_cycle.get_name() + " limit cycle is empty");
31 }
32 const auto& center = limit_cycle.get_center_state();
33 if (this->get_base_frame().is_empty()) {
36 center.get_reference_frame(), center.get_reference_frame()));
37 }
38 if (center.get_reference_frame() != this->get_base_frame().get_name()) {
39 if (center.get_reference_frame() != this->get_base_frame().get_reference_frame()) {
41 "The reference frame of the center " + center.get_name() + " in frame " + center.get_reference_frame()
42 + " is incompatible with the base frame of the dynamical system " + this->get_base_frame().get_name()
43 + " in frame " + this->get_base_frame().get_reference_frame() + "."
44 );
45 }
46 limit_cycle.set_center_state(this->get_base_frame().inverse() * center);
47 }
48 this->limit_cycle_->set_value(limit_cycle);
49}
50
52 if (base_frame.is_empty()) {
53 throw state_representation::exceptions::EmptyStateException(base_frame.get_name() + " state is empty");
54 }
56 // update reference frame of center
57 if (this->limit_cycle_->get_value()) {
58 auto center_state = this->limit_cycle_->get_value().get_center_state();
59 center_state.set_reference_frame(base_frame.get_name());
60 this->limit_cycle_->get_value().set_center_state(center_state);
61 }
62}
63
64void Circular::validate_and_set_parameter(const std::shared_ptr<ParameterInterface>& parameter) {
65 if (parameter->get_name() == "limit_cycle") {
66 this->assert_parameter_valid(parameter);
67 this->set_limit_cycle(std::static_pointer_cast<Parameter<Ellipsoid>>(parameter)->get_value());
68 } else if (parameter->get_name() == "planar_gain") {
69 this->assert_parameter_valid(parameter);
70 this->planar_gain_->set_value(std::static_pointer_cast<Parameter<double>>(parameter)->get_value());
71 } else if (parameter->get_name() == "normal_gain") {
72 this->assert_parameter_valid(parameter);
73 this->normal_gain_->set_value(std::static_pointer_cast<Parameter<double>>(parameter)->get_value());
74 } else if (parameter->get_name() == "circular_velocity") {
75 this->assert_parameter_valid(parameter);
76 this->circular_velocity_->set_value(std::static_pointer_cast<Parameter<double>>(parameter)->get_value());
77 } else {
79 "No parameter with name '" + parameter->get_name() + "' found"
80 );
81 }
82}
83
85 if (this->limit_cycle_->get_value().is_empty()) {
86 throw exceptions::EmptyAttractorException("The limit cycle of the dynamical system is empty.");
87 }
88 // put the point in the reference of the center
89 auto pose = CartesianPose(state);
90 pose = this->limit_cycle_->get_value().get_rotation().inverse()
91 * this->limit_cycle_->get_value().get_center_pose().inverse() * pose;
92
93 CartesianTwist velocity(pose.get_name(), pose.get_reference_frame());
94 Eigen::Vector3d linear_velocity;
95 linear_velocity(2) = -this->normal_gain_->get_value() * pose.get_position()(2);
96
97 std::vector<double> radiuses = this->limit_cycle_->get_value().get_axis_lengths();
98
99 double a2ratio = (pose.get_position()[0] * pose.get_position()[0]) / (radiuses[0] * radiuses[0]);
100 double b2ratio = (pose.get_position()[1] * pose.get_position()[1]) / (radiuses[1] * radiuses[1]);
101 double dradius = -this->planar_gain_->get_value() * radiuses[0] * radiuses[1] * (a2ratio + b2ratio - 1);
102 double tangent_velocity_x = -radiuses[0] / radiuses[1] * pose.get_position()[1];
103 double tangent_velocity_y = radiuses[1] / radiuses[0] * pose.get_position()[0];
104
105 linear_velocity(0) = this->circular_velocity_->get_value() * tangent_velocity_x + dradius * tangent_velocity_y;
106 linear_velocity(1) = this->circular_velocity_->get_value() * tangent_velocity_y - dradius * tangent_velocity_x;
107
108 velocity.set_linear_velocity(linear_velocity);
109 velocity.set_angular_velocity(Eigen::Vector3d::Zero());
110
111 //compute back the linear velocity in the desired frame
112 auto frame = this->limit_cycle_->get_value().get_center_pose() * this->limit_cycle_->get_value().get_rotation();
113 return CartesianState(frame) * velocity;
114}
115}// 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:51
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:84
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 Cartesian pose 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 Cartesian state (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.
Class to represent name-value pairs of different types.
Definition Parameter.hpp:18
void assert_parameter_valid(const std::shared_ptr< ParameterInterface > &parameter)
Check if a parameter exists and 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.cpp:60
const CartesianState & get_center_state() const
Getter of the state.
Definition Shape.cpp:35
const std::string & get_name() const
Getter of the name attribute.
Definition State.cpp:29
bool is_empty() const
Getter of the empty attribute.
Definition State.cpp:33
Systems of equations relating state variables to their derivatives.
Definition Circular.hpp:7
Core state variables and objects.