FlightGear next
AircraftMesh.cxx
Go to the documentation of this file.
1// AircraftMesh.cxx -- Mesh for the computation of the wake induced force and
2// moment on an aircraft.
3
4// Written by Bertrand Coconnier, started March 2017.
5//
6// Copyright (C) 2017 Bertrand Coconnier - bcoconni@users.sf.net
7//
8// This program is free software; you can redistribute it and/or modify it under
9// the terms of the GNU General Public License as published by the Free Software
10// Foundation; either version 2 of the License, or (at your option) any later
11// version.
12//
13// This program is distributed in the hope that it will be useful, but WITHOUT
14// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16// details.
17//
18// You should have received a copy of the GNU General Public License along with
19// this program; if not, write to the Free Software Foundation, Inc., 51
20// Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21//
22// $Id$
23
24#include <vector>
25#include <cmath>
26
27#include <simgear/structure/SGSharedPtr.hxx>
28#include <simgear/math/SGVec3.hxx>
29#include <simgear/math/SGGeoc.hxx>
30#include <simgear/math/SGGeod.hxx>
31#include <simgear/math/SGQuat.hxx>
32#include "AircraftMesh.hxx"
33#include <FDM/flight.hxx>
34#include "AIWakeGroup.hxx"
36
37AircraftMesh::AircraftMesh(double _span, double _chord, const std::string& name)
38 : WakeMesh(_span, _chord, name)
39{
40 collPt.resize(nelm, SGVec3d::zeros());
41 midPt.resize(nelm, SGVec3d::zeros());
42}
43
44void AircraftMesh::setPosition(const SGVec3d& _pos, const SGQuatd& orient)
45{
46 SGVec3d pos = _pos * SG_METER_TO_FEET;
47 SGGeoc geoc = SGGeoc::fromCart(pos);
48 SGQuatd Te2l = SGQuatd::fromLonLatRad(geoc.getLongitudeRad(),
49 geoc.getLatitudeRad());
50 Te2b = Te2l * orient;
51
52 for (int i=0; i<nelm; ++i) {
53 SGVec3d pt = elements[i]->getCollocationPoint();
54 collPt[i] = pos + Te2b.backTransform(pt);
55 pt = elements[i]->getBoundVortexMidPoint();
56 midPt[i] = pos + Te2b.backTransform(pt);
57 }
58}
59
60SGVec3d AircraftMesh::GetForce(const AIWakeGroup& wg, const SGVec3d& vel,
61 double rho)
62{
63 std::vector<double> rhs;
64 rhs.resize(nelm, 0.0);
65
66 for (int i=0; i<nelm; ++i)
67 rhs[i] = dot(elements[i]->getNormal(),
68 Te2b.transform(wg.getInducedVelocityAt(collPt[i])));
69
70 for (int i=1; i<=nelm; ++i) {
71 Gamma[i][1] = 0.0;
72 for (int k=1; k<=nelm; ++k)
73 Gamma[i][1] += influenceMtx[i][k]*rhs[k-1];
74 }
75
76 SGVec3d f(0.,0.,0.);
77 moment = SGVec3d::zeros();
78
79 for (int i=0; i<nelm; ++i) {
80 SGVec3d mp = elements[i]->getBoundVortexMidPoint();
81 SGVec3d v = Te2b.transform(wg.getInducedVelocityAt(midPt[i]));
82 v += getInducedVelocityAt(mp);
83
84 // The minus sign before vel to transform the aircraft velocity from the
85 // body frame to wind frame.
86 SGVec3d Fi = rho*Gamma[i+1][1]*cross(v-vel,
87 elements[i]->getBoundVortex());
88 f += Fi;
89 moment += cross(mp, Fi);
90 }
91
92 return f;
93}
#define i(x)
SGVec3d getInducedVelocityAt(const SGVec3d &pt) const
SGVec3d GetForce(const AIWakeGroup &wg, const SGVec3d &vel, double rho)
void setPosition(const SGVec3d &pos, const SGQuatd &orient)
AircraftMesh(double _span, double _chord, const std::string &name)
std::vector< AeroElement_ptr > elements
Definition WakeMesh.hxx:45
double ** influenceMtx
Definition WakeMesh.hxx:46
double ** Gamma
Definition WakeMesh.hxx:46
SGVec3d getInducedVelocityAt(const SGVec3d &at) const
Definition WakeMesh.cxx:113
WakeMesh(double _span, double _chord, const std::string &aircraft_name)
Definition WakeMesh.cxx:36
const char * name