fixedwing_forces_and_moments.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Daniel Koch, James Jackson and Gary Ellingson, BYU MAGICC Lab.
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, this
9  * list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * * Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
33 
34 namespace rosflight_sim
35 {
37 {
38  nh_ = nh;
39 
40  // physical parameters
41  mass_ = nh_->param<double>("mass", 13.5);
42  Jx_ = nh_->param<double>("Jx", 0.8244);
43  Jy_ = nh_->param<double>("Jy", 1.135);
44  Jz_ = nh_->param<double>("Jz", 1.759);
45  Jxz_ = nh_->param<double>("Jxz", .1204);
46  rho_ = nh_->param<double>("rho", 1.2682);
47 
48  // Wing Geometry
49  wing_.S = nh_->param<double>("wing_s", 0.55);
50  wing_.b = nh_->param<double>("wing_b", 2.8956);
51  wing_.c = nh_->param<double>("wing_c", 0.18994);
52  wing_.M = nh_->param<double>("wing_M", 0.55);
53  wing_.epsilon = nh_->param<double>("wing_epsilon", 2.8956);
54  wing_.alpha0 = nh_->param<double>("wing_alpha0", 0.18994);
55 
56  // Propeller Coefficients
57  prop_.k_motor = nh_->param<double>("k_motor", 80.0);
58  prop_.k_T_P = nh_->param<double>("k_T_P", 0.0);
59  prop_.k_Omega = nh_->param<double>("k_Omega", 0.0);
60  prop_.e = nh_->param<double>("prop_e", 0.9);
61  prop_.S = nh_->param<double>("prop_S", 0.202);
62  prop_.C = nh_->param<double>("prop_C", 1.0);
63 
64  // Lift Params
65  CL_.O = nh_->param<double>("C_L_O", 0.28);
66  CL_.alpha = nh_->param<double>("C_L_alpha", 3.45);
67  CL_.beta = nh_->param<double>("C_L_beta", 0.0);
68  CL_.p = nh_->param<double>("C_L_p", 0.0);
69  CL_.q = nh_->param<double>("C_L_q", 0.0);
70  CL_.r = nh_->param<double>("C_L_r", 0.0);
71  CL_.delta_a = nh_->param<double>("C_L_delta_a", 0.0);
72  CL_.delta_e = nh_->param<double>("C_L_delta_e", -0.36);
73  CL_.delta_r = nh_->param<double>("C_L_delta_r", 0.0);
74 
75  // Drag Params
76  CD_.O = nh_->param<double>("C_D_O", 0.03);
77  CD_.alpha = nh_->param<double>("C_D_alpha", 0.30);
78  CD_.beta = nh_->param<double>("C_D_beta", 0.0);
79  CD_.p = nh_->param<double>("C_D_p", 0.0437);
80  CD_.q = nh_->param<double>("C_D_q", 0.0);
81  CD_.r = nh_->param<double>("C_D_r", 0.0);
82  CD_.delta_a = nh_->param<double>("C_D_delta_a", 0.0);
83  CD_.delta_e = nh_->param<double>("C_D_delta_e", 0.0);
84  CD_.delta_r = nh_->param<double>("C_D_delta_r", 0.0);
85 
86  // ell Params (x axis moment)
87  Cell_.O = nh_->param<double>("C_ell_O", 0.0);
88  Cell_.alpha = nh_->param<double>("C_ell_alpha", 0.00);
89  Cell_.beta = nh_->param<double>("C_ell_beta", -0.12);
90  Cell_.p = nh_->param<double>("C_ell_p", -0.26);
91  Cell_.q = nh_->param<double>("C_ell_q", 0.0);
92  Cell_.r = nh_->param<double>("C_ell_r", 0.14);
93  Cell_.delta_a = nh_->param<double>("C_ell_delta_a", 0.08);
94  Cell_.delta_e = nh_->param<double>("C_ell_delta_e", 0.0);
95  Cell_.delta_r = nh_->param<double>("C_ell_delta_r", 0.105);
96 
97  // m Params (y axis moment)
98  Cm_.O = nh_->param<double>("C_m_O", -0.02338);
99  Cm_.alpha = nh_->param<double>("C_m_alpha", -0.38);
100  Cm_.beta = nh_->param<double>("C_m_beta", 0.0);
101  Cm_.p = nh_->param<double>("C_m_p", 0.0);
102  Cm_.q = nh_->param<double>("C_m_q", -3.6);
103  Cm_.r = nh_->param<double>("C_m_r", 0.0);
104  Cm_.delta_a = nh_->param<double>("C_m_delta_a", 0.0);
105  Cm_.delta_e = nh_->param<double>("C_m_delta_e", -0.5);
106  Cm_.delta_r = nh_->param<double>("C_m_delta_r", 0.0);
107 
108  // n Params (z axis moment)
109  Cn_.O = nh_->param<double>("C_n_O", 0.0);
110  Cn_.alpha = nh_->param<double>("C_n_alpha", 0.0);
111  Cn_.beta = nh_->param<double>("C_n_beta", 0.25);
112  Cn_.p = nh_->param<double>("C_n_p", 0.022);
113  Cn_.q = nh_->param<double>("C_n_q", 0.0);
114  Cn_.r = nh_->param<double>("C_n_r", -0.35);
115  Cn_.delta_a = nh_->param<double>("C_n_delta_a", 0.06);
116  Cn_.delta_e = nh_->param<double>("C_n_delta_e", 0.0);
117  Cn_.delta_r = nh_->param<double>("C_n_delta_r", -0.032);
118 
119  // Y Params (Sideslip Forces)
120  CY_.O = nh_->param<double>("C_Y_O", 0.0);
121  CY_.alpha = nh_->param<double>("C_Y_alpha", 0.00);
122  CY_.beta = nh_->param<double>("C_Y_beta", -0.98);
123  CY_.p = nh_->param<double>("C_Y_p", 0.0);
124  CY_.q = nh_->param<double>("C_Y_q", 0.0);
125  CY_.r = nh_->param<double>("C_Y_r", 0.0);
126  CY_.delta_a = nh_->param<double>("C_Y_delta_a", 0.0);
127  CY_.delta_e = nh_->param<double>("C_Y_delta_e", 0.0);
128  CY_.delta_r = nh_->param<double>("C_Y_delta_r", -0.017);
129 
130  wind_ = Eigen::Vector3d::Zero();
131 }
132 
133 Eigen::Matrix<double, 6, 1> Fixedwing::updateForcesAndTorques(Current_State x, const int act_cmds[])
134 {
135  delta_.a = (act_cmds[0] - 1500.0) / 500.0;
136  delta_.e = -(act_cmds[1] - 1500.0) / 500.0;
137  delta_.t = (act_cmds[2] - 1000.0) / 1000.0;
138  delta_.r = -(act_cmds[3] - 1500.0) / 500.0;
139 
140  double p = x.omega(0);
141  double q = x.omega(1);
142  double r = x.omega(2);
143 
144  // Calculate airspeed
145  Eigen::Vector3d V_airspeed = x.vel + x.rot.inverse() * wind_;
146  double ur = V_airspeed(0);
147  double vr = V_airspeed(1);
148  double wr = V_airspeed(2);
149 
150  double Va = V_airspeed.norm();
151 
152  Eigen::Matrix<double, 6, 1> forces;
153 
154  // Be sure that we have some significant airspeed before we run aerodynamics, and don't let NaNs get through
155  if (Va > 1.0 && std::isfinite(Va))
156  {
157  /*
158  * The following math follows the method described in chapter 4 of
159  * Small Unmanned Aircraft: Theory and Practice
160  * By Randy Beard and Tim McLain.
161  * Look there for a detailed explanation of each line in the rest of this function
162  */
163  double alpha = atan2(wr, ur);
164  double beta = asin(vr / Va);
165 
166  double ca = cos(alpha);
167  double sa = sin(alpha);
168 
169  double sign = (alpha >= 0 ? 1 : -1); // Sigmoid function
170  double sigma_a = (1 + exp(-(wing_.M * (alpha - wing_.alpha0))) + exp((wing_.M * (alpha + wing_.alpha0))))
171  / ((1 + exp(-(wing_.M * (alpha - wing_.alpha0)))) * (1 + exp((wing_.M * (alpha + wing_.alpha0)))));
172  double CL_a = (1 - sigma_a) * (CL_.O + CL_.alpha * alpha) + sigma_a * (2 * sign * sa * sa * ca);
173  double AR = (pow(wing_.b, 2.0)) / wing_.S;
174  double CD_a =
175  CD_.p
176  + ((pow((CL_.O + CL_.alpha * (alpha)), 2.0))
177  / (3.14159 * 0.9
178  * AR)); // the const 0.9 in this equation replaces the e (Oswald Factor) variable and may be inaccurate
179 
180  double CX_a = -CD_a * ca + CL_a * sa;
181  double CX_q_a = -CD_.q * ca + CL_.q * sa;
182  double CX_deltaE_a = -CD_.delta_e * ca + CL_.delta_e * sa;
183 
184  double CZ_a = -CD_a * sa - CL_a * ca;
185  double CZ_q_a = -CD_.q * sa - CL_.q * ca;
186  double CZ_deltaE_a = -CD_.delta_e * sa - CL_.delta_e * ca;
187 
188  forces(0) = 0.5 * (rho_)*Va * Va * wing_.S * (CX_a + (CX_q_a * wing_.c * q) / (2.0 * Va) + CX_deltaE_a * delta_.e)
189  + 0.5 * rho_ * prop_.S * prop_.C * (pow((prop_.k_motor * delta_.t), 2.0) - Va * Va);
190  forces(1) = 0.5 * (rho_)*Va * Va * wing_.S
191  * (CY_.O + CY_.beta * beta + ((CY_.p * wing_.b * p) / (2.0 * Va)) + ((CY_.r * wing_.b * r) / (2.0 * Va))
192  + CY_.delta_a * delta_.a + CY_.delta_r * delta_.r);
193  forces(2) = 0.5 * (rho_)*Va * Va * wing_.S * (CZ_a + (CZ_q_a * wing_.c * q) / (2.0 * Va) + CZ_deltaE_a * delta_.e);
194 
195  forces(3) = 0.5 * (rho_)*Va * Va * wing_.S * wing_.b
196  * (Cell_.O + Cell_.beta * beta + (Cell_.p * wing_.b * p) / (2.0 * Va)
197  + (Cell_.r * wing_.b * r) / (2.0 * Va) + Cell_.delta_a * delta_.a + Cell_.delta_r * delta_.r)
198  - prop_.k_T_P * pow((prop_.k_Omega * delta_.t), 2.0);
199  forces(4) = 0.5 * (rho_)*Va * Va * wing_.S * wing_.c
200  * (Cm_.O + Cm_.alpha * alpha + (Cm_.q * wing_.c * q) / (2.0 * Va) + Cm_.delta_e * delta_.e);
201  forces(5) = 0.5 * (rho_)*Va * Va * wing_.S * wing_.b
202  * (Cn_.O + Cn_.beta * beta + (Cn_.p * wing_.b * p) / (2.0 * Va) + (Cn_.r * wing_.b * r) / (2.0 * Va)
203  + Cn_.delta_a * delta_.a + Cn_.delta_r * delta_.r);
204  }
205  else
206  {
207  forces(0) = 0.5 * rho_ * prop_.S * prop_.C * ((prop_.k_motor * delta_.t * prop_.k_motor * delta_.t));
208  forces(1) = 0.0;
209  forces(2) = 0.0;
210  forces(3) = 0.0;
211  forces(4) = 0.0;
212  forces(5) = 0.0;
213  }
214 
215  return forces;
216 }
217 
218 void Fixedwing::set_wind(Eigen::Vector3d wind)
219 {
220  wind_ = wind;
221 }
222 
223 } // namespace rosflight_sim
float cos(float x)
float sin(float x)
float atan2(float y, float x)
Eigen::Matrix< double, 6, 1 > updateForcesAndTorques(Current_State x, const int act_cmds[])
void set_wind(Eigen::Vector3d wind)
float asin(float x)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
struct rosflight_sim::Fixedwing::PropCoeff prop_
struct rosflight_sim::Fixedwing::Actuators delta_
struct rosflight_sim::Fixedwing::WingCoeff wing_


rosflight_sim
Author(s): James Jackson, Gary Ellingson, Daniel Koch
autogenerated on Thu Apr 15 2021 05:09:57