1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3 Module: FGSurface.cpp
4 Author: Erik Hofman
5 Date started: 01/15/14
6 Purpose: Base class for all surface properties
7 Called by: GroundReactions
8
9 ------------- Copyright (C) 2014 Jon S. Berndt (jon@jsbsim.org) -------------
10
11 This program is free software; you can redistribute it and/or modify it under
12 the terms of the GNU Lesser General Public License as published by the Free Software
13 Foundation; either version 2 of the License, or (at your option) any later
14 version.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19 details.
20
21 You should have received a copy of the GNU Lesser General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place - Suite 330, Boston, MA 02111-1307, USA.
24
25 Further information about the GNU Lesser General Public License can also be found on
26 the world wide web at http://www.gnu.org.
27
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This base class for the GroundReactions class defines methoed and holds data
31 for all surface types.
32
33 HISTORY
34 --------------------------------------------------------------------------------
35 01/15/14 EMH Created
36
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 #include "input_output/FGPropertyManager.h"
42 #include "models/FGSurface.h"
43
44 using namespace std;
45
46 namespace JSBSim {
47
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 CLASS IMPLEMENTATION
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
51
FGSurface(FGFDMExec * fdmex,int number)52 FGSurface::FGSurface(FGFDMExec* fdmex, int number) :
53 contactNumber(number)
54 {
55 eSurfaceType = ctBOGEY;
56 _PropertyManager = fdmex->GetPropertyManager();
57 resetValues();
58 }
59
60 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61
~FGSurface()62 FGSurface::~FGSurface()
63 {
64 }
65
66 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67
resetValues(void)68 void FGSurface::resetValues(void)
69 {
70 staticFFactor = 1.0;
71 rollingFFactor = 1.0;
72 maximumForce = DBL_MAX;
73 bumpiness = 0.0;
74 isSolid = true;
75 pos[0] = 0.0;
76 pos[1] = 0.0;
77 pos[2] = 0.0;
78 }
79
80 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81
bind(void)82 void FGSurface::bind(void)
83 {
84 if (!_PropertyManager) return;
85
86 string base_property_name;
87 string property_name;
88
89 switch(eSurfaceType) {
90 case ctBOGEY:
91 base_property_name = _CreateIndexedPropertyName("gear/unit", contactNumber);
92 break;
93 case ctSTRUCTURE:
94 base_property_name = _CreateIndexedPropertyName("contact/unit", contactNumber);
95 break;
96 case ctGROUND:
97 base_property_name = "ground";
98 break;
99 default:
100 return;
101 }
102
103 property_name = base_property_name + "/solid";
104 _PropertyManager->Tie( property_name.c_str(), &isSolid);
105 property_name = base_property_name + "/bumpiness";
106 _PropertyManager->Tie( property_name.c_str(), &bumpiness);
107 property_name = base_property_name + "/maximum-force-lbs";
108 _PropertyManager->Tie( property_name.c_str(), &maximumForce);
109 property_name = base_property_name + "/rolling_friction-factor";
110 _PropertyManager->Tie( property_name.c_str(), &rollingFFactor);
111 property_name = base_property_name + "/static-friction-factor";
112 _PropertyManager->Tie( property_name.c_str(), &staticFFactor);
113 }
114
115 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116
GetBumpHeight()117 float FGSurface::GetBumpHeight()
118 {
119 if (bumpiness < 0.001) return 0.0f;
120
121 double x = pos[0]*0.1;
122 double y = pos[1]*0.1;
123 x -= floor(x);
124 y -= floor(y);
125 x *= 2*M_PI;
126 y *= 2*M_PI;
127 //now x and y are in the range of 0..2pi
128 //we need a function, that is periodically on 2pi and gives some
129 //height. This is not very fast, but for a beginning.
130 //maybe this should be done by interpolating between some precalculated
131 //values
132 static const float maxGroundBumpAmplitude=0.4;
133 float h = sin(x)+sin(7*x)+sin(8*x)+sin(13*x);
134 h += sin(2*y)+sin(5*y)+sin(9*y*x)+sin(17*y);
135
136 return h*(1/8.)*bumpiness*maxGroundBumpAmplitude;
137 }
138
139 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140
_CreateIndexedPropertyName(const string & Property,int index)141 string FGSurface::_CreateIndexedPropertyName(const string& Property, int index)
142 {
143 std::ostringstream buf;
144 buf << Property << '[' << index << ']';
145 return buf.str();
146 }
147
148 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149
GetSurfaceStrings(string delimeter) const150 string FGSurface::GetSurfaceStrings(string delimeter) const
151 {
152 std::ostringstream buf;
153
154 buf << "staticFFactor" << delimeter
155 << "rollingFFactor" << delimeter
156 << "maximumForce" << delimeter
157 << "bumpiness" << delimeter
158 << "isSolid";
159
160 return buf.str();
161 }
162
163 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164
GetSurfaceValues(string delimeter) const165 string FGSurface::GetSurfaceValues(string delimeter) const
166 {
167 std::ostringstream buf;
168
169 buf << staticFFactor << delimeter
170 << rollingFFactor << delimeter
171 << maximumForce << delimeter
172 << bumpiness << delimeter
173 << (isSolid ? "1" : "0");
174
175 return buf.str();
176 }
177
178 } // namespace JSBSim
179