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 {
36 
38 {
39  nh_ = nh;
40 
41  // physical parameters
42  mass_ = nh_->param<double>("mass", 13.5);
43  Jx_ = nh_->param<double>("Jx", 0.8244);
44  Jy_ = nh_->param<double>("Jy", 1.135);
45  Jz_ = nh_->param<double>("Jz", 1.759);
46  Jxz_ = nh_->param<double>("Jxz", .1204);
47  rho_ = nh_->param<double>("rho", 1.2682);
48 
49  // Wing Geometry
50  wing_.S = nh_->param<double>("wing_s", 0.55);
51  wing_.b = nh_->param<double>("wing_b", 2.8956);
52  wing_.c = nh_->param<double>("wing_c", 0.18994);
53  wing_.M = nh_->param<double>("wing_M", 0.55);
54  wing_.epsilon = nh_->param<double>("wing_epsilon", 2.8956);
55  wing_.alpha0 = nh_->param<double>("wing_alpha0", 0.18994);
56 
57  // Propeller Coefficients
58  prop_.k_motor = nh_->param<double>("k_motor", 80.0);
59  prop_.k_T_P = nh_->param<double>("k_T_P", 0.0);
60  prop_.k_Omega = nh_->param<double>("k_Omega", 0.0);
61  prop_.e = nh_->param<double>("prop_e", 0.9);
62  prop_.S = nh_->param<double>("prop_S", 0.202);
63  prop_.C = nh_->param<double>("prop_C", 1.0);
64 
65  // Lift Params
66  CL_.O = nh_->param<double>("C_L_O", 0.28);
67  CL_.alpha = nh_->param<double>("C_L_alpha", 3.45);
68  CL_.beta = nh_->param<double>("C_L_beta", 0.0);
69  CL_.p = nh_->param<double>("C_L_p", 0.0);
70  CL_.q = nh_->param<double>("C_L_q", 0.0);
71  CL_.r = nh_->param<double>("C_L_r", 0.0);
72  CL_.delta_a = nh_->param<double>("C_L_delta_a", 0.0);
73  CL_.delta_e = nh_->param<double>("C_L_delta_e", -0.36);
74  CL_.delta_r = nh_->param<double>("C_L_delta_r", 0.0);
75 
76  // Drag Params
77  CD_.O = nh_->param<double>("C_D_O", 0.03);
78  CD_.alpha = nh_->param<double>("C_D_alpha", 0.30);
79  CD_.beta = nh_->param<double>("C_D_beta", 0.0);
80  CD_.p = nh_->param<double>("C_D_p", 0.0437);
81  CD_.q = nh_->param<double>("C_D_q", 0.0);
82  CD_.r = nh_->param<double>("C_D_r", 0.0);
83  CD_.delta_a = nh_->param<double>("C_D_delta_a", 0.0);
84  CD_.delta_e = nh_->param<double>("C_D_delta_e", 0.0);
85  CD_.delta_r = nh_->param<double>("C_D_delta_r", 0.0);
86 
87  // ell Params (x axis moment)
88  Cell_.O = nh_->param<double>("C_ell_O", 0.0);
89  Cell_.alpha = nh_->param<double>("C_ell_alpha", 0.00);
90  Cell_.beta = nh_->param<double>("C_ell_beta", -0.12);
91  Cell_.p = nh_->param<double>("C_ell_p", -0.26);
92  Cell_.q = nh_->param<double>("C_ell_q", 0.0);
93  Cell_.r = nh_->param<double>("C_ell_r", 0.14);
94  Cell_.delta_a = nh_->param<double>("C_ell_delta_a", 0.08);
95  Cell_.delta_e = nh_->param<double>("C_ell_delta_e", 0.0);
96  Cell_.delta_r = nh_->param<double>("C_ell_delta_r", 0.105);
97 
98  // m Params (y axis moment)
99  Cm_.O = nh_->param<double>("C_m_O", -0.02338);
100  Cm_.alpha = nh_->param<double>("C_m_alpha", -0.38);
101  Cm_.beta = nh_->param<double>("C_m_beta", 0.0);
102  Cm_.p = nh_->param<double>("C_m_p", 0.0);
103  Cm_.q = nh_->param<double>("C_m_q", -3.6);
104  Cm_.r = nh_->param<double>("C_m_r", 0.0);
105  Cm_.delta_a = nh_->param<double>("C_m_delta_a", 0.0);
106  Cm_.delta_e = nh_->param<double>("C_m_delta_e", -0.5);
107  Cm_.delta_r = nh_->param<double>("C_m_delta_r", 0.0);
108 
109  // n Params (z axis moment)
110  Cn_.O = nh_->param<double>("C_n_O", 0.0);
111  Cn_.alpha = nh_->param<double>("C_n_alpha", 0.0);
112  Cn_.beta = nh_->param<double>("C_n_beta", 0.25);
113  Cn_.p = nh_->param<double>("C_n_p", 0.022);
114  Cn_.q = nh_->param<double>("C_n_q", 0.0);
115  Cn_.r = nh_->param<double>("C_n_r", -0.35);
116  Cn_.delta_a = nh_->param<double>("C_n_delta_a", 0.06);
117  Cn_.delta_e = nh_->param<double>("C_n_delta_e", 0.0);
118  Cn_.delta_r = nh_->param<double>("C_n_delta_r", -0.032);
119 
120  // Y Params (Sideslip Forces)
121  CY_.O = nh_->param<double>("C_Y_O", 0.0);
122  CY_.alpha = nh_->param<double>("C_Y_alpha", 0.00);
123  CY_.beta = nh_->param<double>("C_Y_beta", -0.98);
124  CY_.p = nh_->param<double>("C_Y_p", 0.0);
125  CY_.q = nh_->param<double>("C_Y_q", 0.0);
126  CY_.r = nh_->param<double>("C_Y_r", 0.0);
127  CY_.delta_a = nh_->param<double>("C_Y_delta_a", 0.0);
128  CY_.delta_e = nh_->param<double>("C_Y_delta_e", 0.0);
129  CY_.delta_r = nh_->param<double>("C_Y_delta_r", -0.017);
130 
131  wind_ = Eigen::Vector3d::Zero();
132 }
133 
134 Eigen::Matrix<double, 6, 1> Fixedwing::updateForcesAndTorques(Current_State x, const int act_cmds[])
135 {
136  delta_.a = (act_cmds[0] - 1500.0)/500.0;
137  delta_.e = -(act_cmds[1] - 1500.0)/500.0;
138  delta_.t = (act_cmds[2] - 1000.0)/1000.0;
139  delta_.r = -(act_cmds[3] - 1500.0)/500.0;
140 
141  double p = x.omega(0);
142  double q = x.omega(1);
143  double r = x.omega(2);
144 
145  // Calculate airspeed
146  Eigen::Vector3d V_airspeed = x.vel + x.rot.inverse()*wind_;
147  double ur = V_airspeed(0);
148  double vr = V_airspeed(1);
149  double wr = V_airspeed(2);
150 
151  double Va = V_airspeed.norm();
152 
153  Eigen::Matrix<double, 6, 1> forces;
154 
155  // Be sure that we have some significant airspeed before we run aerodynamics, and don't let NaNs get through
156  if(Va > 1.0 && std::isfinite(Va))
157  {
158  /*
159  * The following math follows the method described in chapter 4 of
160  * Small Unmanned Aircraft: Theory and Practice
161  * By Randy Beard and Tim McLain.
162  * Look there for a detailed explanation of each line in the rest of this function
163  */
164  double alpha = atan2(wr , ur);
165  double beta = asin(vr/Va);
166 
167  double ca = cos(alpha);
168  double sa = sin(alpha);
169 
170  double sign = (alpha >= 0? 1: -1);//Sigmoid function
171  double sigma_a = (1 + exp(-(wing_.M*(alpha - wing_.alpha0))) + exp((wing_.M*(alpha + wing_.alpha0))))/((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 = CD_.p + ((pow((CL_.O + CL_.alpha*(alpha)),2.0))/(3.14159*0.9*AR));//the const 0.9 in this equation replaces the e (Oswald Factor) variable and may be inaccurate
175 
176  double CX_a = -CD_a*ca + CL_a*sa;
177  double CX_q_a = -CD_.q*ca + CL_.q*sa;
178  double CX_deltaE_a = -CD_.delta_e*ca + CL_.delta_e*sa;
179 
180  double CZ_a = -CD_a*sa - CL_a*ca;
181  double CZ_q_a = -CD_.q*sa - CL_.q*ca;
182  double CZ_deltaE_a = -CD_.delta_e*sa - CL_.delta_e*ca;
183 
184  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) + 0.5*rho_*prop_.S*prop_.C*(pow((prop_.k_motor*delta_.t),2.0) - Va*Va);
185  forces(1) = 0.5*(rho_)*Va*Va*wing_.S*(CY_.O + CY_.beta*beta + ((CY_.p*wing_.b*p)/(2.0*Va)) + ((CY_.r*wing_.b*r)/(2.0*Va)) + CY_.delta_a*delta_.a + CY_.delta_r*delta_.r);
186  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);
187 
188  forces(3) = 0.5*(rho_)*Va*Va*wing_.S*wing_.b*(Cell_.O + Cell_.beta*beta + (Cell_.p*wing_.b*p)/(2.0*Va) + (Cell_.r*wing_.b*r)/(2.0*Va) + Cell_.delta_a*delta_.a + Cell_.delta_r*delta_.r) - prop_.k_T_P*pow((prop_.k_Omega*delta_.t),2.0);
189  forces(4) = 0.5*(rho_)*Va*Va*wing_.S*wing_.c*(Cm_.O + Cm_.alpha*alpha + (Cm_.q*wing_.c*q)/(2.0*Va) + Cm_.delta_e*delta_.e);
190  forces(5) = 0.5*(rho_)*Va*Va*wing_.S*wing_.b*(Cn_.O + Cn_.beta*beta + (Cn_.p*wing_.b*p)/(2.0*Va) + (Cn_.r*wing_.b*r)/(2.0*Va) + Cn_.delta_a*delta_.a + Cn_.delta_r*delta_.r);
191  }
192  else
193  {
194  forces(0) = 0.5*rho_*prop_.S*prop_.C*((prop_.k_motor*delta_.t*prop_.k_motor*delta_.t));
195  forces(1) = 0.0;
196  forces(2) = 0.0;
197  forces(3) = 0.0;
198  forces(4) = 0.0;
199  forces(5) = 0.0;
200  }
201 
202  return forces;
203 }
204 
205 void Fixedwing::set_wind(Eigen::Vector3d wind)
206 {
207  wind_ = wind;
208 }
209 
210 }
float cos(float x)
double sign(double y)
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 Wed Jul 3 2019 20:00:29