attitude_controller.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Fadri Furrer, ASL, ETH Zurich, Switzerland
3  * Copyright 2015 Michael Burri, ASL, ETH Zurich, Switzerland
4  * Copyright 2015 Mina Kamel, ASL, ETH Zurich, Switzerland
5  * Copyright 2015 Janosch Nikolic, ASL, ETH Zurich, Switzerland
6  * Copyright 2015 Markus Achtelik, ASL, ETH Zurich, Switzerland
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
22 
24  : gravity_(9.81),
25  mass_(1.56779) {
26 }
27 
29 }
30 
31 std::shared_ptr<ControllerBase> AttitudeController::Clone() {
32  std::shared_ptr<ControllerBase> controller(new AttitudeController);
33 
34  return controller;
35 }
36 
38  gain_attitude_(0) = 3; //4
39  gain_attitude_(1) = 3; //4
40  gain_attitude_(2) = 0.035;
41 
42  gain_angular_rate_(0) = 0.52;//0.6;
43  gain_angular_rate_(1) = 0.52;//0.6;
44  gain_angular_rate_(2) = 0.025;
45 
46  amount_rotors_ = 6;
47  allocation_matrix_.resize(4,amount_rotors_);
48  allocation_matrix_ << sin(M_PI/6), 1, sin(M_PI/6), -sin(M_PI/6), -1, -sin(M_PI/6),
49  -cos(M_PI/6), 0, cos(M_PI/6), cos(M_PI/6), 0, -cos(M_PI/6),
50  -1, 1, -1, 1, -1, 1,
51  1, 1, 1, 1, 1, 1;
52 
53  inertia_matrix_<< 0.0347563, 0, 0,
54  0, 0.0458929, 0,
55  0, 0, 0.0977;
56 
57  // to make the tuning independent of the inertia matrix we divide here
58  gain_attitude_ = gain_attitude_.transpose() * inertia_matrix_.inverse();
59 
60  // to make the tuning independent of the inertia matrix we divide here
61  gain_angular_rate_ = gain_angular_rate_.transpose() * inertia_matrix_.inverse();
62 
63  const double rotor_force_constant = 0.00000854858; //F_i = k_n * rotor_velocity_i^2
64  const double rotor_moment_constant = 0.016; // M_i = k_m * F_i
65 
66  angular_acc_to_rotor_velocities_.resize(amount_rotors_, 4);
67  const double arm_length = 0.215;
68 
69  Eigen::Matrix4d K;
70  K.setZero();
71  K(0, 0) = arm_length * rotor_force_constant;
72  K(1, 1) = arm_length * rotor_force_constant;
73  K(2, 2) = rotor_force_constant * rotor_moment_constant;
74  K(3, 3) = rotor_force_constant;
75 
76  Eigen::Matrix4d I;
77  I.setZero();
78  I.block<3, 3>(0, 0) = inertia_matrix_;
79  I(3, 3) = 1;
81  * (allocation_matrix_ * allocation_matrix_.transpose()).inverse() * K.inverse() * I;
82  initialized_params_ = true;
83 }
84 
85 void AttitudeController::CalculateRotorVelocities(Eigen::VectorXd* rotor_velocities) const {
86  assert(rotor_velocities);
87  assert(initialized_params_);
88 
89  rotor_velocities->resize(amount_rotors_);
90 
91  Eigen::Vector3d angular_acceleration;
92  ComputeDesiredAngularAcc(&angular_acceleration);
93 
94  Eigen::Vector4d angular_acceleration_thrust;
95  angular_acceleration_thrust.block<3, 1>(0, 0) = angular_acceleration;
96  angular_acceleration_thrust(3) = control_attitude_thrust_reference_(3);
97 
98  *rotor_velocities = angular_acc_to_rotor_velocities_ * angular_acceleration_thrust;
99  *rotor_velocities = rotor_velocities->cwiseMax(Eigen::VectorXd::Zero(rotor_velocities->rows()));
100  *rotor_velocities = rotor_velocities->cwiseSqrt();
101 }
102 
103 // Implementation from the T. Lee et al. paper
104 // Control of complex maneuvers for a quadrotor UAV using geometric methods on SE(3)
105 void AttitudeController::ComputeDesiredAngularAcc(Eigen::Vector3d* angular_acceleration) const {
106  assert(angular_acceleration);
107 
108  Eigen::Matrix3d R = attitude_.toRotationMatrix();
109 
110  // get desired rotation matrix
111  Eigen::Matrix3d R_des;
112  double yaw = atan2(R(1, 0), R(0, 0));
113  R_des = Eigen::AngleAxisd(yaw, Eigen::Vector3d::UnitZ()) // yaw
114  * Eigen::AngleAxisd(control_attitude_thrust_reference_(0), Eigen::Vector3d::UnitX()) // roll
115  * Eigen::AngleAxisd(control_attitude_thrust_reference_(1), Eigen::Vector3d::UnitY()); // pitch
116 
117  // angle error according to lee et al.
118  Eigen::Matrix3d angle_error_matrix = 0.5 * (R_des.transpose() * R - R.transpose() * R_des);
119  Eigen::Vector3d angle_error;
120  angle_error << angle_error_matrix(2, 1), // inverse skew operator
121  angle_error_matrix(0, 2), 0; // angle_error_matrix(1,0);
122 
123  Eigen::Vector3d angular_rate_des(Eigen::Vector3d::Zero());
124  angular_rate_des[2] = control_attitude_thrust_reference_(2);
125 
126  Eigen::Vector3d angular_rate_error = angular_rate_ - R_des.transpose() * R * angular_rate_des;
127 
128  *angular_acceleration = -1 * angle_error.cwiseProduct(gain_attitude_)
129  - angular_rate_error.cwiseProduct(gain_angular_rate_)
130  + angular_rate_.cross(angular_rate_); // we don't need the inertia matrix here
131 }
132 
virtual std::shared_ptr< ControllerBase > Clone()
ROTORS_CONTROL_REGISTER_CONTROLLER(AttitudeController)
Eigen::Matrix3d inertia_matrix_
Eigen::Matrix4Xd allocation_matrix_
Eigen::Vector3d gain_attitude_
Eigen::Vector3d gain_angular_rate_
Eigen::MatrixX4d angular_acc_to_rotor_velocities_
void ComputeDesiredAngularAcc(Eigen::Vector3d *angular_acceleration) const
virtual void InitializeParams()
virtual void CalculateRotorVelocities(Eigen::VectorXd *rotor_velocities) const


rotors_control
Author(s): Fadri Furrer, Michael Burri, Mina Kamel, Janosch Nikolic, Markus Achtelik
autogenerated on Mon Feb 28 2022 23:38:55