JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
FGWaypoint.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGWaypoint.cpp
4  Author: Jon S. Berndt
5  Date started: 6/2013
6 
7  ------------- Copyright (C) 2013 Jon S. Berndt (jon@jsbsim.org) -------------
8 
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17  details.
18 
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25 
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28 
29 HISTORY
30 --------------------------------------------------------------------------------
31 
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 COMMENTS, REFERENCES, and NOTES
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 INCLUDES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39 
40 #include "FGWaypoint.h"
41 #include "input_output/FGXMLElement.h"
42 #include "input_output/FGPropertyManager.h"
43 #include "math/FGLocation.h"
44 
45 using namespace std;
46 
47 namespace JSBSim {
48 
49 IDENT(IdSrc,"$Id: FGWaypoint.cpp,v 1.8 2016/05/05 15:32:42 bcoconni Exp $");
50 IDENT(IdHdr,ID_WAYPOINT);
51 
52 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 CLASS IMPLEMENTATION
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
55 
56 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 
58 FGWaypoint::FGWaypoint(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
59 {
60  if (Type == "WAYPOINT_HEADING") WaypointType = eHeading;
61  else if (Type == "WAYPOINT_DISTANCE") WaypointType = eDistance;
62 
63  target_latitude_unit = 1.0;
64  target_longitude_unit = 1.0;
65  source_latitude_unit = 1.0;
66  source_longitude_unit = 1.0;
67 
68  if (element->FindElement("target_latitude") ) {
69  target_latitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("target_latitude"));
70  if (element->FindElement("target_latitude")->HasAttribute("unit")) {
71  if (element->FindElement("target_latitude")->GetAttributeValue("unit") == "DEG") {
72  target_latitude_unit = 0.017453293;
73  }
74  }
75  } else {
76  cerr << element->ReadFrom() << endl
77  << "Target latitude is required for waypoint component: " << Name
78  << endl;
79  throw("Malformed waypoint definition");
80  }
81 
82  if (element->FindElement("target_longitude") ) {
83  target_longitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("target_longitude"));
84  if (element->FindElement("target_longitude")->HasAttribute("unit")) {
85  if (element->FindElement("target_longitude")->GetAttributeValue("unit") == "DEG") {
86  target_longitude_unit = 0.017453293;
87  }
88  }
89  } else {
90  cerr << element->ReadFrom() << endl
91  << "Target longitude is required for waypoint component: " << Name
92  << endl;
93  throw("Malformed waypoint definition");
94  }
95 
96  if (element->FindElement("source_latitude") ) {
97  source_latitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("source_latitude"));
98  if (element->FindElement("source_latitude")->HasAttribute("unit")) {
99  if (element->FindElement("source_latitude")->GetAttributeValue("unit") == "DEG") {
100  source_latitude_unit = 0.017453293;
101  }
102  }
103  } else {
104  cerr << element->ReadFrom() << endl
105  << "Source latitude is required for waypoint component: " << Name
106  << endl;
107  throw("Malformed waypoint definition");
108  }
109 
110  if (element->FindElement("source_longitude") ) {
111  source_longitude = PropertyManager->CreatePropertyObject<double>(element->FindElementValue("source_longitude"));
112  if (element->FindElement("source_longitude")->HasAttribute("unit")) {
113  if (element->FindElement("source_longitude")->GetAttributeValue("unit") == "DEG") {
114  source_longitude_unit = 0.017453293;
115  }
116  }
117  } else {
118  cerr << element->ReadFrom() << endl
119  << "Source longitude is required for waypoint component: " << Name
120  << endl;
121  throw("Malformed waypoint definition");
122  }
123 
124  if (element->FindElement("radius"))
125  radius = element->FindElementValueAsNumberConvertTo("radius", "FT");
126  else {
127  FGLocation source(source_longitude * source_latitude_unit,
128  source_latitude * source_longitude_unit, 1.0);
129  radius = source.GetSeaLevelRadius(); // Radius of Earth in feet.
130  }
131 
132  unit = element->GetAttributeValue("unit");
133  if (WaypointType == eHeading) {
134  if (!unit.empty()) {
135  if (unit == "DEG") eUnit = eDeg;
136  else if (unit == "RAD") eUnit = eRad;
137  else {
138  cerr << element->ReadFrom() << endl
139  << "Unknown unit " << unit << " in HEADING waypoint component, "
140  << Name << endl;
141  throw("Malformed waypoint definition");
142  }
143  } else {
144  eUnit = eRad; // Default is radians if unspecified
145  }
146  } else {
147  if (!unit.empty()) {
148  if (unit == "FT") eUnit = eFeet;
149  else if (unit == "M") eUnit = eMeters;
150  else {
151  cerr << element->ReadFrom() << endl
152  << "Unknown unit " << unit << " in DISTANCE waypoint component, "
153  << Name << endl;
154  throw("Malformed waypoint definition");
155  }
156  } else {
157  eUnit = eFeet; // Default is feet if unspecified
158  }
159  }
160 
161  FGFCSComponent::bind();
162  Debug(0);
163 }
164 
165 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166 
167 FGWaypoint::~FGWaypoint()
168 {
169  Debug(1);
170 }
171 
172 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 
174 bool FGWaypoint::Run(void )
175 {
176  double target_latitude_rad = target_latitude * target_latitude_unit;
177  double target_longitude_rad = target_longitude * target_longitude_unit;
178  FGLocation source(source_longitude * source_latitude_unit,
179  source_latitude * source_longitude_unit, radius);
180 
181  if (WaypointType == eHeading) { // Calculate Heading
182  double heading_to_waypoint_rad = source.GetHeadingTo(target_longitude_rad,
183  target_latitude_rad);
184 
185  if (eUnit == eDeg) Output = heading_to_waypoint_rad * radtodeg;
186  else Output = heading_to_waypoint_rad;
187 
188  } else { // Calculate Distance
189  double wp_distance = source.GetDistanceTo(target_longitude_rad,
190  target_latitude_rad);
191 
192  if (eUnit == eMeters) Output = FeetToMeters(wp_distance);
193  else Output = wp_distance;
194  }
195 
196  Clip();
197  if (IsOutput) SetOutput();
198 
199  return true;
200 }
201 
202 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 // The bitmasked value choices are as follows:
204 // unset: In this case (the default) JSBSim would only print
205 // out the normally expected messages, essentially echoing
206 // the config files as they are read. If the environment
207 // variable is not set, debug_lvl is set to 1 internally
208 // 0: This requests JSBSim not to output any messages
209 // whatsoever.
210 // 1: This value explicity requests the normal JSBSim
211 // startup messages
212 // 2: This value asks for a message to be printed out when
213 // a class is instantiated
214 // 4: When this value is set, a message is displayed when a
215 // FGModel object executes its Run() method
216 // 8: When this value is set, various runtime state variables
217 // are printed out periodically
218 // 16: When set various parameters are sanity checked and
219 // a message is printed out when they go out of bounds
220 
221 void FGWaypoint::Debug(int from)
222 {
223  if (debug_lvl <= 0) return;
224 
225  if (debug_lvl & 1) { // Standard console startup message output
226  if (from == 0) { // Constructor
227  }
228  }
229  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
230  if (from == 0) cout << "Instantiated: FGWaypoint" << endl;
231  if (from == 1) cout << "Destroyed: FGWaypoint" << endl;
232  }
233  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
234  }
235  if (debug_lvl & 8 ) { // Runtime state variables
236  }
237  if (debug_lvl & 16) { // Sanity checking
238  }
239  if (debug_lvl & 64) {
240  if (from == 0) { // Constructor
241  cout << IdSrc << endl;
242  cout << IdHdr << endl;
243  }
244  }
245 }
246 }
STL namespace.
static double FeetToMeters(double measure)
Converts from feet to meters.
Definition: FGJSBBase.h:260