FlightGear next
FGExternalForce.cpp
Go to the documentation of this file.
1/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3 Source: FGExternalForce.cpp
4 Author: Jon Berndt, Dave Culp
5 Date started: 9/21/07
6
7 ------------- Copyright (C) 2007 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
11 Software Foundation; either version 2 of the License, or (at your option) any
12 later 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
20 with this program; if not, write to the Free Software Foundation, Inc., 59
21 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 Further information about the GNU Lesser General Public License can also be
24 found on the world wide web at http://www.gnu.org.
25
26 HISTORY
27--------------------------------------------------------------------------------
289/21/07 JB Created
29
30<external_reactions>
31
32 <!-- Interface properties, a.k.a. property declarations -->
33 <property> ... </property>
34
35 <force name="name" frame="BODY|LOCAL|WIND">
36
37 <function> ... </function>
38
39 <location unit="units"> <!-- location -->
40 <x> value </x>
41 <y> value </y>
42 <z> value </z>
43 </location>
44 <direction> <!-- optional for initial direction vector -->
45 <x> value </x>
46 <y> value </y>
47 <z> value </z>
48 </direction>
49 </force>
50
51 <moment name="name" frame="BODY|LOCAL|WIND">
52
53 <function> ... </function>
54
55 <direction> <!-- optional for initial direction vector -->
56 <x> value </x>
57 <y> value </y>
58 <z> value </z>
59 </direction>
60 </force>
61
62</external_reactions>
63
64*/
65
66#include "FGFDMExec.h"
67#include "FGExternalForce.h"
69
70using namespace std;
71
72namespace JSBSim {
73
74//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75
77 const std::string& baseName,
78 const std::string& xcmp,
79 const std::string& ycmp,
80 const std::string& zcmp)
81{
82 data[0] = pm->CreatePropertyObject<double>(baseName + "/" + xcmp);
83 data[1] = pm->CreatePropertyObject<double>(baseName + "/" + ycmp);
84 data[2] = pm->CreatePropertyObject<double>(baseName + "/" + zcmp);
85}
86
87//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88
89FGParameter* FGExternalForce::bind(Element *el, const string& magName,
91{
92 // Set frame (from FGForce).
93 string sFrame = el->GetAttributeValue("frame");
94 if (sFrame.empty()) {
95 cerr << el->ReadFrom()
96 << "No frame specified for external " << el->GetName() << ", \""
97 << Name << "\"." << endl
98 << "Frame set to Body" << endl;
99 ttype = tNone;
100 } else if (sFrame == "BODY") {
101 ttype = tNone;
102 } else if (sFrame == "LOCAL") {
104 } else if (sFrame == "WIND") {
106 } else {
107 cerr << el->ReadFrom()
108 << "Invalid frame specified for external " << el->GetName() << ", \""
109 << Name << "\"." << endl
110 << "Frame set to Body" << endl;
111 ttype = tNone;
112 }
113
114 Element* direction_element = el->FindElement("direction");
115 if (!direction_element) {
116 cerr << el->ReadFrom()
117 << "No direction element specified in " << el->GetName()
118 << " object. Default is (0,0,0)." << endl;
119 } else {
120 FGColumnVector3 direction = direction_element->FindElementTripletConvertTo("IN");
121 direction.Normalize();
122 v = direction;
123 }
124
125 // The value sent to the sim through the external_reactions/{force
126 // name}/magnitude property will be multiplied against the unit vector, which
127 // can come in initially in the direction vector. The frame in which the
128 // vector is defined is specified with the frame attribute. The vector is
129 // normalized to magnitude 1.
130
131 Element* function_element = el->FindElement("function");
132 if (function_element) {
133 return new FGFunction(fdmex, function_element);
134 } else {
135 FGPropertyManager* pm = fdmex->GetPropertyManager();
136 FGPropertyNode* node = pm->GetNode(magName, true);
137 return new FGPropertyValue(node);
138 }
139}
140
141//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142
144{
145 FGPropertyManager* PropertyManager = fdmex->GetPropertyManager();
146 Name = el->GetAttributeValue("name");
147 string BasePropertyName = "external_reactions/" + Name;
148
149 forceDirection = FGPropertyVector3(PropertyManager, BasePropertyName,
150 "x", "y", "z");
151 forceMagnitude = bind(el, BasePropertyName + "/magnitude", forceDirection);
152
153 Element* location_element = el->FindElement("location");
154 if (!location_element) {
155 cerr << el->ReadFrom()
156 << "No location element specified in force object." << endl;
157 } else {
158 FGColumnVector3 location = location_element->FindElementTripletConvertTo("IN");
159 SetLocation(location);
160 }
161 PropertyManager->Tie( BasePropertyName + "/location-x-in", (FGForce*)this,
163 PropertyManager->Tie( BasePropertyName + "/location-y-in", (FGForce*)this,
165 PropertyManager->Tie( BasePropertyName + "/location-z-in", (FGForce*)this,
167}
168
169//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170
172{
173 FGPropertyManager* PropertyManager = fdmex->GetPropertyManager();
174 Name = el->GetAttributeValue("name");
175 string BasePropertyName = "external_reactions/" + Name;
176
177 momentDirection = FGPropertyVector3(PropertyManager, BasePropertyName,
178 "l", "m", "n");
179 momentMagnitude = bind(el, BasePropertyName + "/magnitude-lbsft",
180 momentDirection);
181}
182
183//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184
186{
187 delete forceMagnitude;
188 delete momentMagnitude;
189 Debug(1);
190}
191
192//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193
195{
196 if (forceMagnitude)
197 vFn = forceMagnitude->GetValue() * forceDirection;
198
199 if (momentMagnitude)
200 vMn = Transform() * (momentMagnitude->GetValue() * momentDirection);
201
202 return FGForce::GetBodyForces();
203}
204
205//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206// The bitmasked value choices are as follows:
207// unset: In this case (the default) JSBSim would only print
208// out the normally expected messages, essentially echoing
209// the config files as they are read. If the environment
210// variable is not set, debug_lvl is set to 1 internally
211// 0: This requests JSBSim not to output any messages
212// whatsoever.
213// 1: This value explicity requests the normal JSBSim
214// startup messages
215// 2: This value asks for a message to be printed out when
216// a class is instantiated
217// 4: When this value is set, a message is displayed when a
218// FGModel object executes its Run() method
219// 8: When this value is set, various runtime state variables
220// are printed out periodically
221// 16: When set various parameters are sanity checked and
222// a message is printed out when they go out of bounds
223
224void FGExternalForce::Debug(int from)
225{
226 if (debug_lvl <= 0) return;
227
228 if (debug_lvl & 1) { // Standard console startup message output
229 if (from == 0) { // Constructor
230 cout << " " << Name << endl;
231 cout << " Frame: ";
232 switch(ttype) {
233 case tNone:
234 cout << "BODY";
235 break;
236 case tLocalBody:
237 cout << "LOCAL";
238 break;
239 case tWindBody:
240 cout << "WIND";
241 break;
242 default:
243 cout << "ERROR/UNKNOWN";
244 }
245 cout << endl << " Location: (" << vXYZn(eX) << ", " << vXYZn(eY) << ", " << vXYZn(eZ) << ")" << endl;
246 }
247 }
248 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
249 if (from == 0) cout << "Instantiated: FGExternalForce" << endl;
250 if (from == 1) cout << "Destroyed: FGExternalForce" << endl;
251 }
252 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
253 }
254 if (debug_lvl & 8 ) { // Runtime state variables
255 }
256 if (debug_lvl & 16) { // Sanity checking
257 }
258 if (debug_lvl & 64) {
259 if (from == 0) { // Constructor
260 }
261 }
262}
263}
FGColumnVector3 FindElementTripletConvertTo(const std::string &target_units)
Composes a 3-element column vector for the supplied location or orientation.
const std::string & GetName(void) const
Retrieves the element name.
FGColumnVector3 FindElementTripletConvertTo(const std::string &target_units)
Composes a 3-element column vector for the supplied location or orientation.
std::string ReadFrom(void) const
Return a string that contains a description of the location where the current XML element was read fr...
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
Element * FindElement(const std::string &el="")
Searches for a specified element.
This class implements a 3 element column vector.
const FGColumnVector3 & GetBodyForces(void) override
void setMoment(Element *el)
~FGExternalForce() override
Destructor.
virtual const FGColumnVector3 & GetBodyForces(void)
Definition FGForce.cpp:81
const FGMatrix33 & Transform(void) const
Definition FGForce.cpp:98
double GetLocationZ(void) const
Definition FGForce.h:273
void SetLocationY(double y)
Definition FGForce.h:263
double GetLocationY(void) const
Definition FGForce.h:272
void SetLocationX(double x)
Definition FGForce.h:262
void SetLocationZ(double z)
Definition FGForce.h:264
FGFDMExec * fdmex
Definition FGForce.h:308
FGColumnVector3 vMn
Definition FGForce.h:311
FGColumnVector3 vXYZn
Definition FGForce.h:314
FGForce(FGFDMExec *FDMExec)
Constructor.
Definition FGForce.cpp:53
double GetLocationX(void) const
Definition FGForce.h:271
void SetLocation(double x, double y, double z)
Definition FGForce.h:242
FGColumnVector3 vFn
Definition FGForce.h:310
TransformType ttype
Definition FGForce.h:313
static short debug_lvl
Definition FGJSBBase.h:190
Represents various types of parameters.
Definition FGParameter.h:59
void Tie(const std::string &name, T *pointer)
Tie a property to an external variable.
simgear::PropertyObject< T > CreatePropertyObject(const std::string &path)
short debug_lvl
@ tNone
Definition FGTrim.h:66