quadrotor_dynamics_solver.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2019, Wolfgang Merkt
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without specific
15 // prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 
31 
33 
34 namespace exotica
35 {
36 QuadrotorDynamicsSolver::QuadrotorDynamicsSolver()
37 {
38  num_positions_ = 6;
39  num_velocities_ = 6;
40  num_controls_ = 4;
41 
42  J_.setZero();
43  J_.diagonal() = Eigen::Vector3d(0.0023, 0.0023, 0.004);
44 
45  J_inv_.setZero();
46  J_inv_.diagonal() = Eigen::Vector3d(1. / 0.0023, 1. / 0.0023, 1. / 0.0040);
47 }
48 
49 void QuadrotorDynamicsSolver::AssignScene(ScenePtr scene_in)
50 {
51  const int num_positions_in = scene_in->GetKinematicTree().GetNumControlledJoints();
52  // TODO: This is a terrible check (not against name etc.), but can stop _some_ mismatches between URDF/model and dynamics
53  if ((num_positions_in) != 6 || scene_in->GetKinematicTree().GetControlledBaseType() != BaseType::FLOATING)
54  ThrowPretty("Robot model may not be a quadrotor.");
55 }
56 
57 Eigen::VectorXd QuadrotorDynamicsSolver::f(const StateVector& x, const ControlVector& u)
58 {
59  double phi = x(3),
60  theta = x(4),
61  psi = x(5),
62  x_dot = x(6),
63  y_dot = x(7),
64  z_dot = x(8),
65  phi_dot = x(9),
66  theta_dot = x(10),
67  psi_dot = x(11);
68 
69  const double F_1 = k_f_ * u(0);
70  const double F_2 = k_f_ * u(1);
71  const double F_3 = k_f_ * u(2);
72  const double F_4 = k_f_ * u(3);
73 
74  const double M_1 = k_m_ * u(0);
75  const double M_2 = k_m_ * u(1);
76  const double M_3 = k_m_ * u(2);
77  const double M_4 = k_m_ * u(3);
78 
79  // clang-format off
80  double sin_phi = std::sin(phi), cos_phi = std::cos(phi),
81  sin_theta = std::sin(theta), cos_theta = std::cos(theta),
82  sin_psi = std::sin(psi), cos_psi = std::cos(psi);
83  // clang-format on
84 
85  Eigen::MatrixXd Rx(3, 3), Ry(3, 3), Rz(3, 3), R;
86  Rx << 1, 0, 0, 0, cos_phi, -sin_phi, 0, sin_phi, cos_phi;
87  Ry << cos_theta, 0, sin_theta, 0, 1, 0, -sin_theta, 0, cos_theta;
88  Rz << cos_psi, -sin_psi, 0, sin_psi, cos_psi, 0, 0, 0, 1;
89  R = Rz * Rx * Ry;
90 
91  // x,y,z dynamics
92  Eigen::Vector3d Gtot, Ftot;
93  Gtot << 0, 0, -g_;
94  Ftot << 0, 0, F_1 + F_2 + F_3 + F_4;
95 
96  Eigen::Vector3d pos_ddot = Gtot + R * Ftot / mass_;
97 
98  // phi, theta, psi dynamics
99  Eigen::Vector3d tau, omega, omega_dot;
100  tau << L_ * (F_1 - F_2),
101  L_ * (F_1 - F_3),
102  (M_1 - M_2 + M_3 - M_4);
103  omega << phi_dot, theta_dot, psi_dot;
104 
105  double radius = L_ / 2.0;
106  double Ix = 2 * mass_ * (radius * radius) / 5.0 + 2 * radius * radius * mass_,
107  Iy = 2 * mass_ * (radius * radius) / 5.0 + 2 * radius * radius * mass_,
108  Iz = 2 * mass_ * (radius * radius) / 5.0 + 4 * radius * radius * mass_;
109 
110  Eigen::Matrix3d I, Iinv;
111  I << Ix, 0, 0, 0, Iy, 0, 0, 0, Iz;
112  Iinv << 1 / Ix, 0, 0, 0, 1 / Iy, 0, 0, 0, 1 / Iz;
113 
114  omega_dot = Iinv * (tau - omega.cross(I * omega));
115 
116  Eigen::VectorXd state_dot(12);
117  state_dot << x_dot, y_dot, z_dot,
119  pos_ddot(0), pos_ddot(1), pos_ddot(2),
120  omega_dot(0), omega_dot(1), omega_dot(2);
121 
122  return state_dot;
123 }
124 
125 Eigen::MatrixXd QuadrotorDynamicsSolver::fx(const StateVector& x, const ControlVector& u)
126 {
127  double phi = x(3),
128  theta = x(4),
129  psi = x(5),
130  phi_dot = x(9),
131  theta_dot = x(10),
132  psi_dot = x(11);
133 
134  // clang-format off
135  double sin_phi = std::sin(phi), cos_phi = std::cos(phi),
136  sin_theta = std::sin(theta), cos_theta = std::cos(theta),
137  sin_psi = std::sin(psi), cos_psi = std::cos(psi);
138 
139  Eigen::MatrixXd fx(num_positions_ + num_velocities_, num_positions_ + num_velocities_);
140  fx <<
141  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
142  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
143  0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
144  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
145  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
146  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
147  0, 0, 0, (k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))*sin_psi*cos_phi*cos_theta/mass_, (-sin_phi*sin_psi*sin_theta + cos_psi*cos_theta)*(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))/mass_, (sin_phi*cos_psi*cos_theta - sin_psi*sin_theta)*(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))/mass_, 0, 0, 0, 0, 0, 0,
148  0, 0, 0, -(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))*cos_phi*cos_psi*cos_theta/mass_, (sin_phi*sin_theta*cos_psi + sin_psi*cos_theta)*(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))/mass_, (sin_phi*sin_psi*cos_theta + sin_theta*cos_psi)*(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))/mass_, 0, 0, 0, 0, 0, 0,
149  0, 0, 0, -(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))*sin_phi*cos_theta/mass_, -(k_f_*u(0) + k_f_*u(1) + k_f_*u(2) + k_f_*u(3))*sin_theta*cos_phi/mass_, 0, 0, 0, 0, 0, 0, 0,
150  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.833333333333334*psi_dot, -0.833333333333334*theta_dot,
151  0, 0, 0, 0, 0, 0, 0, 0, 0, 0.833333333333334*psi_dot, 0, 0.833333333333334*phi_dot,
152  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
153 
154  // clang-format on
155  return fx;
156 }
157 
158 Eigen::MatrixXd QuadrotorDynamicsSolver::fu(const StateVector& x, const ControlVector& u)
159 {
160  double phi = x(3),
161  theta = x(4),
162  psi = x(5);
163 
164  // clang-format off
165  double sin_phi = std::sin(phi), cos_phi = std::cos(phi),
166  sin_theta = std::sin(theta), cos_theta = std::cos(theta),
167  sin_psi = std::sin(psi), cos_psi = std::cos(psi);
168 
169  Eigen::MatrixXd fu(num_positions_ + num_velocities_, num_controls_);
170  fu <<
171  0, 0, 0, 0,
172  0, 0, 0, 0,
173  0, 0, 0, 0,
174  0, 0, 0, 0,
175  0, 0, 0, 0,
176  0, 0, 0, 0,
178  k_f_*(-sin_phi*cos_psi*cos_theta + sin_psi*sin_theta)/mass_, k_f_*(-sin_phi*cos_psi*cos_theta + sin_psi*sin_theta)/mass_, k_f_*(-sin_phi*cos_psi*cos_theta + sin_psi*sin_theta)/mass_, k_f_*(-sin_phi*cos_psi*cos_theta + sin_psi*sin_theta)/mass_,
180  1.66666666666667*k_f_/(L_*mass_), -1.66666666666667*k_f_/(L_*mass_), 0, 0,
181  1.66666666666667*k_f_/(L_*mass_), 0, -1.66666666666667*k_f_/(L_*mass_), 0,
182  0.909090909090909*k_m_/(L_*L_*2*mass_), -0.909090909090909*k_m_/(L_*L_*2*mass_), 0.909090909090909*k_m_/(L_*L_*mass_), -0.909090909090909*k_m_/(L_*L_*mass_);
183 
184  // clang-format on
185  return fu;
186 }
187 
188 } // namespace exotica
#define REGISTER_DYNAMICS_SOLVER_TYPE(TYPE, DERIV)
#define ThrowPretty(m)
std::shared_ptr< Scene > ScenePtr
Quadrotor dynamics with quaternion representation Based on D. Mellinger, N. Michael, and V. Kumar, "Trajectory generation and control for precise aggressive maneuvers with quadrotors", Proceedings of the 12th International Symposium on Experimental Robotics (ISER 2010), 2010. Cf. https://journals.sagepub.com/doi/abs/10.1177/0278364911434236.
Eigen::Matrix< T, NU, 1 > ControlVector
Eigen::Matrix< T, NX, 1 > StateVector


exotica_quadrotor_dynamics_solver
Author(s):
autogenerated on Sat Apr 10 2021 02:36:44