Add the BalloonSim and MagicCarpet fdm's back in (i seriously thought this had been done, oops)
This commit is contained in:
parent
f6301ea1d7
commit
a40e040e24
6 changed files with 919 additions and 0 deletions
205
src/FDM/SP/Balloon.cxx
Normal file
205
src/FDM/SP/Balloon.cxx
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
|
||||||
|
Module: BalloonSimInterface.cxx
|
||||||
|
Author: Christian Mayer
|
||||||
|
Date started: 07.10.99
|
||||||
|
Called by:
|
||||||
|
|
||||||
|
-------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Interface to the hot air balloon simulator
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
01.09.1999 Christian Mayer Created
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* INCLUDES */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <simgear/constants.h>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
|
#include <Aircraft/aircraft.hxx>
|
||||||
|
#include <Main/globals.hxx>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
#include "Balloon.h"
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/********************************** CODE ************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
FGBalloonSim::FGBalloonSim( double dt ) {
|
||||||
|
//set the dt of the model
|
||||||
|
current_balloon.set_dt(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FGBalloonSim::~FGBalloonSim() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the BalloonSim flight model, dt is the time increment for
|
||||||
|
// each subsequent iteration through the EOM
|
||||||
|
void FGBalloonSim::init() {
|
||||||
|
|
||||||
|
//do init common to all the FDM's
|
||||||
|
common_init();
|
||||||
|
|
||||||
|
//now do init specific to the Balloon
|
||||||
|
|
||||||
|
sgVec3 temp;
|
||||||
|
|
||||||
|
SG_LOG( SG_FLIGHT, SG_INFO, "Starting initializing BalloonSim" );
|
||||||
|
|
||||||
|
SG_LOG( SG_FLIGHT, SG_INFO, " created a balloon" );
|
||||||
|
|
||||||
|
//set position
|
||||||
|
sgSetVec3( temp,
|
||||||
|
get_Latitude(),
|
||||||
|
get_Longitude(),
|
||||||
|
get_Altitude() * SG_FEET_TO_METER);
|
||||||
|
current_balloon.setPosition( temp );
|
||||||
|
|
||||||
|
//set Euler angles (?)
|
||||||
|
sgSetVec3( temp,
|
||||||
|
get_Phi(),
|
||||||
|
get_Theta(),
|
||||||
|
get_Psi() );
|
||||||
|
current_balloon.setHPR( temp );
|
||||||
|
|
||||||
|
//set velocities
|
||||||
|
sgSetVec3( temp,
|
||||||
|
fgGetDouble("/sim/presets/uBody-fps"),
|
||||||
|
fgGetDouble("/sim/presets/vBody-fps"),
|
||||||
|
fgGetDouble("/sim/presets/wBody-fps") );
|
||||||
|
current_balloon.setVelocity( temp );
|
||||||
|
|
||||||
|
SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing BalloonSim" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Run an iteration of the EOM (equations of motion)
|
||||||
|
void FGBalloonSim::update( double dt ) {
|
||||||
|
double save_alt = 0.0;
|
||||||
|
|
||||||
|
if (is_suspended())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int multiloop = _calc_multiloop(dt);
|
||||||
|
|
||||||
|
// lets try to avoid really screwing up the BalloonSim model
|
||||||
|
if ( get_Altitude() < -9000 ) {
|
||||||
|
save_alt = get_Altitude();
|
||||||
|
set_Altitude( 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set control positions
|
||||||
|
current_balloon.set_burner_strength ( globals->get_controls()->get_throttle(0) );
|
||||||
|
//not more implemented yet
|
||||||
|
|
||||||
|
// Inform BalloonSim of the local terrain altitude
|
||||||
|
current_balloon.setGroundLevel ( get_Runway_altitude() * SG_FEET_TO_METER);
|
||||||
|
|
||||||
|
// old -- FGInterface_2_JSBsim() not needed except for Init()
|
||||||
|
// translate FG to JSBsim structure
|
||||||
|
// FGInterface_2_JSBsim(f);
|
||||||
|
// printf("FG_Altitude = %.2f\n", FG_Altitude * 0.3048);
|
||||||
|
// printf("Altitude = %.2f\n", Altitude * 0.3048);
|
||||||
|
// printf("Radius to Vehicle = %.2f\n", Radius_to_vehicle * 0.3048);
|
||||||
|
|
||||||
|
/* FDMExec.GetState()->Setsim_time(State->Getsim_time()
|
||||||
|
+ State->Getdt() * multiloop); */
|
||||||
|
|
||||||
|
for ( int i = 0; i < multiloop; i++ ) {
|
||||||
|
current_balloon.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate BalloonSim back to FG structure so that the
|
||||||
|
// autopilot (and the rest of the sim can use the updated
|
||||||
|
// values
|
||||||
|
|
||||||
|
copy_from_BalloonSim();
|
||||||
|
|
||||||
|
/*sgVec3 temp, temp2;
|
||||||
|
current_balloon.getPosition( temp );
|
||||||
|
current_balloon.getVelocity( temp2 );
|
||||||
|
SG_LOG( SG_FLIGHT, SG_INFO, "T: " << current_balloon.getTemperature() <<
|
||||||
|
" alt: " << temp[2] <<
|
||||||
|
" gr_alt: " << get_Runway_altitude() <<
|
||||||
|
" burner: " << controls.get_elevator() <<
|
||||||
|
" v[2]: " << temp2[2]); */
|
||||||
|
|
||||||
|
// but lets restore our original bogus altitude when we are done
|
||||||
|
if ( save_alt < -9000.0 ) {
|
||||||
|
set_Altitude( save_alt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Convert from the FGInterface struct to the BalloonSim
|
||||||
|
bool FGBalloonSim::copy_to_BalloonSim() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Convert from the BalloonSim to the FGInterface struct
|
||||||
|
bool FGBalloonSim::copy_from_BalloonSim() {
|
||||||
|
|
||||||
|
sgVec3 temp;
|
||||||
|
|
||||||
|
// Velocities
|
||||||
|
current_balloon.getVelocity( temp );
|
||||||
|
_set_Velocities_Local( temp[0], temp[1], temp[2] );
|
||||||
|
|
||||||
|
/* ***FIXME*** */ _set_V_equiv_kts( sgLengthVec3 ( temp ) );
|
||||||
|
|
||||||
|
_set_Omega_Body( 0.0, 0.0, 0.0 );
|
||||||
|
|
||||||
|
// Positions
|
||||||
|
current_balloon.getPosition( temp );
|
||||||
|
//temp[0]: geocentric latitude
|
||||||
|
//temp[1]: longitude
|
||||||
|
//temp[2]: altitude (meters)
|
||||||
|
|
||||||
|
_updateGeocentricPosition( temp[0], temp[1], temp[2] * SG_METER_TO_FEET );
|
||||||
|
|
||||||
|
current_balloon.getHPR( temp );
|
||||||
|
set_Euler_Angles( temp[0], temp[1], temp[2] );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
87
src/FDM/SP/Balloon.h
Normal file
87
src/FDM/SP/Balloon.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
|
||||||
|
Header: BalloonSimInterface.h
|
||||||
|
Author: Christian Mayer
|
||||||
|
Date started: 07.10.99
|
||||||
|
|
||||||
|
-------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
interface to the the hot air balloon simulator
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
07.10.1999 Christian Mayer Created
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* SENTRY */
|
||||||
|
/****************************************************************************/
|
||||||
|
#ifndef BalloonSimInterface_H
|
||||||
|
#define BalloonSimInterface_H
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* INCLUDES */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#include <Aircraft/aircraft.hxx>
|
||||||
|
#include <FDM/flight.hxx>
|
||||||
|
|
||||||
|
#include "BalloonSim.h"
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* DEFINES */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* DECLARATIONS */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
class FGBalloonSim: public FGInterface {
|
||||||
|
|
||||||
|
balloon current_balloon;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGBalloonSim( double dt );
|
||||||
|
~FGBalloonSim();
|
||||||
|
|
||||||
|
// copy FDM state to BalloonSim structures
|
||||||
|
bool copy_to_BalloonSim();
|
||||||
|
|
||||||
|
// copy FDM state from BalloonSim structures
|
||||||
|
bool copy_from_BalloonSim();
|
||||||
|
|
||||||
|
// reset flight params to a specific position
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// update position based on inputs, positions, velocities, etc.
|
||||||
|
void update( double dt );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
#endif /*BalloonSimInterface_H*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
345
src/FDM/SP/BalloonSim.cpp
Normal file
345
src/FDM/SP/BalloonSim.cpp
Normal file
|
@ -0,0 +1,345 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
|
||||||
|
Module: BalloonSim.cpp
|
||||||
|
Author: Christian Mayer
|
||||||
|
Date started: 01.09.99
|
||||||
|
Called by:
|
||||||
|
|
||||||
|
-------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
A hot air balloon simulator
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
01.09.1999 Christian Mayer Created
|
||||||
|
03.10.1999 Christian Mayer cleaned the code by moveing WeatherDatabase
|
||||||
|
calls inside the update()
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* INCLUDES */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
// #include <conio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <simgear/constants.h>
|
||||||
|
|
||||||
|
#include <Aircraft/aircraft.hxx>
|
||||||
|
|
||||||
|
#include "BalloonSim.h"
|
||||||
|
|
||||||
|
#include <plib/sg.h>
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/********************************** CODE ************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Constructor: */
|
||||||
|
/* Set the balloon model to some values that seem reasonable as I haven't */
|
||||||
|
/* got much original values */
|
||||||
|
/* */
|
||||||
|
/****************************************************************************/
|
||||||
|
balloon::balloon()
|
||||||
|
{
|
||||||
|
dt = 0.1;
|
||||||
|
ground_level = 3400.0;
|
||||||
|
|
||||||
|
sgSetVec3(gravity_vector, 0.0, 0.0, -9.81);
|
||||||
|
sgSetVec3(velocity, 0.0, 0.0, 0.0);
|
||||||
|
sgSetVec3(position, 0.0, 0.0, 0.0);
|
||||||
|
sgSetVec3(hpr, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* My balloon has a radius of 8.8 metres as that gives a envelope */
|
||||||
|
/* volume of about 2854 m^3 which is about 77000 ft^3, a very common */
|
||||||
|
/* size for hot air balloons */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
balloon_envelope_area = 4.0 * (8.8 * 8.8) * SGD_PI;
|
||||||
|
balloon_envelope_volume = (4.0/3.0) * (8.8 * 8.8 * 8.8) * SGD_PI;
|
||||||
|
|
||||||
|
wind_facing_area_of_balloon = SGD_PI * (8.8 * 8.8);
|
||||||
|
wind_facing_area_of_basket = 2.0; //guessed: 2 m^2
|
||||||
|
|
||||||
|
cw_envelope=0.45; //a sphere in this case
|
||||||
|
cw_basket=0.8;
|
||||||
|
|
||||||
|
weight_of_total_fuel = 40.0; //big guess
|
||||||
|
weight_of_envelope = 200.0; //big guess
|
||||||
|
weight_of_basket = 40.0; //big guess
|
||||||
|
weight_of_cargo = 750.0; //big guess
|
||||||
|
|
||||||
|
fuel_left=1.0;
|
||||||
|
max_flow_of_fuel_per_second=10.0*1.0/3600.0; //assuming 10% of one hour of total burn time
|
||||||
|
current_burner_strength = 0.0; //the throttle
|
||||||
|
|
||||||
|
lambda = 0.15; //for plasic
|
||||||
|
l_of_the_envelope = 1.0/1000.0; //the thickness of the envelope (in m): 1mm
|
||||||
|
|
||||||
|
T = 273.16 + 130.6; //Temperature in the envelope => still at ground level
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::update()
|
||||||
|
{
|
||||||
|
/************************************************************************/
|
||||||
|
/* I'm simplifying the balloon by reducing the simulation to two */
|
||||||
|
/* points: */
|
||||||
|
/* the center of the basket (CB) and the center of the envelope (CE) */
|
||||||
|
/* */
|
||||||
|
/* ce */
|
||||||
|
/* I */
|
||||||
|
/* I */
|
||||||
|
/* cg (=center of gravity) */
|
||||||
|
/* I */
|
||||||
|
/* cb */
|
||||||
|
/* */
|
||||||
|
/* On each center are forces acting: gravity and wind resitance. CE */
|
||||||
|
/* additionally got the lift (=> I need to calculate the weight of the */
|
||||||
|
/* air inside, too) */
|
||||||
|
/* */
|
||||||
|
/* The weight of the air in the envelope is dependant of the tempera- */
|
||||||
|
/* ture. This temperature is decreasing over the time that is dependant */
|
||||||
|
/* of the insulation of the envelope material (lambda), the gas used */
|
||||||
|
/* (air) and the wind speed. For a plane surface it's for air: */
|
||||||
|
/* */
|
||||||
|
/* alpha = 4.8 + 3.4*v with v < 5.0 m/s */
|
||||||
|
/* */
|
||||||
|
/* The value k that takes all of that into account is defined as: */
|
||||||
|
/* */
|
||||||
|
/* 1 / k = 1 / alpha1 + 1 / alpha2 + l / lambda */
|
||||||
|
/* */
|
||||||
|
/* with 'l' beeing the 'length' i.e. thickness of the insulator, alpha1 */
|
||||||
|
/* the air inside and alpha2 the air outside of the envelope. So our k */
|
||||||
|
/* is: */
|
||||||
|
/* */
|
||||||
|
/* k = 1 / [1/4.8 + 1/(4.8+3.4v) + l/lambda] */
|
||||||
|
/* */
|
||||||
|
/* The energy lost by this process is defined as: */
|
||||||
|
/* */
|
||||||
|
/* dQ = k * A * t * dT */
|
||||||
|
/* */
|
||||||
|
/* with Q being the energy, k that value defined above, A the total */
|
||||||
|
/* area of the envelope, t the time (in hours) and dT the temperature */
|
||||||
|
/* difference between the inside and the outside. */
|
||||||
|
/* To get the temperature of the air in the inside I need the formula: */
|
||||||
|
/* */
|
||||||
|
/* dQ = cAir * m * dT */
|
||||||
|
/* */
|
||||||
|
/* with cAir being the specific heat capacity(?) of air (= 1.00 kcal / */
|
||||||
|
/* kg * degree), m the mass of the air and dT the temperature change. */
|
||||||
|
/* As the envelope is open I'm assuming that the same air pressure is */
|
||||||
|
/* inside and outside of it (practical there should be a slightly */
|
||||||
|
/* higher air pressure in the inside or the envelope would collapse). */
|
||||||
|
/* So it's easy to calculate the density of the air inside: */
|
||||||
|
/* */
|
||||||
|
/* rho = p / R * T */
|
||||||
|
/* */
|
||||||
|
/* with p being the pressure, R the gas constant(?) which is for air */
|
||||||
|
/* 287.14 N * m / kg * K and T the absolute temperature. */
|
||||||
|
/* */
|
||||||
|
/* The value returned by this function is the displacement of the CB */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* NOTE: This is the simplified version: I'm assuming that the whole */
|
||||||
|
/* balloon consists only of the envelope.I will improove the simulation */
|
||||||
|
/* later, but currently was my main concern to get it going... */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
// I realy don't think there is a solution for this without WeatherCM
|
||||||
|
// but this is a hack, and it's working -- EMH
|
||||||
|
double mAir = 1;
|
||||||
|
float Q = 0;
|
||||||
|
|
||||||
|
// gain of energy by heating:
|
||||||
|
if (fuel_left > 0.0) //but only with some fuel left ;-)
|
||||||
|
{
|
||||||
|
float fuel_burning = current_burner_strength * max_flow_of_fuel_per_second * dt * weight_of_total_fuel; //in kg
|
||||||
|
|
||||||
|
//convert to cubemetres (I'm wrongly assuming 'normal' conditions; but that's correct for my special case)
|
||||||
|
float cube_metres_burned = fuel_burning / 2.2; //2.2 is the density for propane
|
||||||
|
|
||||||
|
fuel_left -= fuel_burning / weight_of_total_fuel;
|
||||||
|
|
||||||
|
// get energy through burning.
|
||||||
|
Q += 22250.0 * cube_metres_burned; //22250 for propan, 29500 would be butane and if you dare: 2580 would be hydrogen...
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the new temperature in the inside:
|
||||||
|
T += Q / (1.00 * mAir);
|
||||||
|
|
||||||
|
//calculate the masses of the envelope and the basket
|
||||||
|
float mEnvelope = mAir + weight_of_envelope;
|
||||||
|
float mBasket = weight_of_total_fuel*fuel_left + weight_of_basket + weight_of_cargo;
|
||||||
|
|
||||||
|
float mTotal = mEnvelope + mBasket;
|
||||||
|
|
||||||
|
//calulate the forces
|
||||||
|
sgVec3 fTotal, fFriction, fLift;
|
||||||
|
|
||||||
|
sgScaleVec3(fTotal, gravity_vector, mTotal);
|
||||||
|
|
||||||
|
//sgAddVec3(fTotal, fLift); //FIXME: uninitialized fLift
|
||||||
|
//sgAddVec3(fTotal, fFriction); //FIXME: uninitialized fFriction
|
||||||
|
|
||||||
|
//claculate acceleration: a = F / m
|
||||||
|
sgVec3 aTotal, vTotal, dTotal;
|
||||||
|
|
||||||
|
sgScaleVec3(aTotal, fTotal, 1.0 / mTotal);
|
||||||
|
|
||||||
|
//integrate the displacement: d = 0.5 * a * dt**2 + v * dt + d
|
||||||
|
sgScaleVec3(vTotal, velocity, dt);
|
||||||
|
sgScaleVec3(dTotal, aTotal, 0.5*dt*dt); sgAddVec3(dTotal, vTotal);
|
||||||
|
|
||||||
|
//integrate the velocity to 'velocity': v = a * dt + v
|
||||||
|
sgScaleVec3(vTotal, aTotal, dt); sgAddVec3(velocity, vTotal);
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* VERY WRONG STUFF: it's just here to get some results to start with */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
// care for the ground
|
||||||
|
if (position[2] < (ground_level+0.001) )
|
||||||
|
position[2] = ground_level;
|
||||||
|
|
||||||
|
//return results
|
||||||
|
sgAddVec3(position, dTotal);
|
||||||
|
|
||||||
|
//cout << "BallonSim: T: " << (T-273.16) << " alt: " << position[2] << " ground: " << ground_level << " throttle: " << current_burner_strength << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::set_burner_strength(const float bs)
|
||||||
|
{
|
||||||
|
if ((bs>=0.0) && (bs<=1.0))
|
||||||
|
current_burner_strength = bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::getVelocity(sgVec3 v) const
|
||||||
|
{
|
||||||
|
sgCopyVec3(v, velocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::setVelocity(const sgVec3 v)
|
||||||
|
{
|
||||||
|
sgCopyVec3(velocity, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::getPosition(sgVec3 v) const
|
||||||
|
{
|
||||||
|
sgCopyVec3(v, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::setPosition(const sgVec3 v)
|
||||||
|
{
|
||||||
|
sgCopyVec3(position, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::getHPR(sgVec3 angles) const //the balloon isn't allways exactly vertical
|
||||||
|
{
|
||||||
|
sgCopyVec3(angles, hpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::setHPR(const sgVec3 angles) //the balloon isn't allways exactly vertical
|
||||||
|
{
|
||||||
|
sgCopyVec3(hpr, angles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void balloon::setGroundLevel(const float altitude)
|
||||||
|
{
|
||||||
|
ground_level = altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
float balloon::getTemperature(void) const
|
||||||
|
{
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
float balloon::getFuelLeft(void) const
|
||||||
|
{
|
||||||
|
return fuel_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
bool burner = true;
|
||||||
|
balloon bal;
|
||||||
|
bool exit = false;
|
||||||
|
sgVec3 pos={0.0, 0.0, 0.0};
|
||||||
|
char c;
|
||||||
|
float acc_dt = 0.0;
|
||||||
|
float alt;
|
||||||
|
|
||||||
|
bool hysteresis = false; // moving up
|
||||||
|
for (;!exit;)
|
||||||
|
{
|
||||||
|
for (int i=0; i<100; i++)
|
||||||
|
{
|
||||||
|
bal.update(0.1); acc_dt += 0.1;
|
||||||
|
bal.getPosition(pos);
|
||||||
|
alt = pos[2];
|
||||||
|
|
||||||
|
if (alt > 3010)
|
||||||
|
{
|
||||||
|
hysteresis = true;
|
||||||
|
burner = false;
|
||||||
|
}
|
||||||
|
if ((alt < 2990) && (hysteresis == true))
|
||||||
|
{
|
||||||
|
hysteresis = false;
|
||||||
|
burner = true;
|
||||||
|
}
|
||||||
|
if ((bal.getTemperature()-273.16)>250.0)
|
||||||
|
burner = false; //emergency
|
||||||
|
}
|
||||||
|
|
||||||
|
// toogle burner
|
||||||
|
c = getch();
|
||||||
|
if (c==' ')
|
||||||
|
burner=!burner;
|
||||||
|
//if (c=='s')
|
||||||
|
// show=!show;
|
||||||
|
|
||||||
|
//printf("Position: (%f/%f/%f), dP: (%f/%f/%f), burner: ", pos[0], pos[1], pos[2], dp[0], dp[1], dp[2]);
|
||||||
|
printf("%f \t%f \t%f \t%f\n", acc_dt/60.0, bal.getTemperature()-273.16, pos[2], bal.getFuelLeft());
|
||||||
|
if (burner==true)
|
||||||
|
{
|
||||||
|
//printf("on\n");
|
||||||
|
bal.set_burner_strength(1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//printf("off\n");
|
||||||
|
bal.set_burner_strength(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
115
src/FDM/SP/BalloonSim.h
Normal file
115
src/FDM/SP/BalloonSim.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
|
||||||
|
Header: BalloonSim.h
|
||||||
|
Author: Christian Mayer
|
||||||
|
Date started: 01.09.99
|
||||||
|
|
||||||
|
-------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Further information about the GNU General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
FUNCTIONAL DESCRIPTION
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Header for the hot air balloon simulator
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
01.09.1999 Christian Mayer Created
|
||||||
|
03.10.1999 Christian Mayer cleaned the code by moveing WeatherDatabase
|
||||||
|
calls inside the update()
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* SENTRY */
|
||||||
|
/****************************************************************************/
|
||||||
|
#ifndef BalloonSim_H
|
||||||
|
#define BalloonSim_H
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* INCLUDES */
|
||||||
|
/****************************************************************************/
|
||||||
|
#include <plib/sg.h>
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* DEFINES */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* CLASS DECLARATION */
|
||||||
|
/****************************************************************************/
|
||||||
|
class balloon
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float dt; //in s
|
||||||
|
|
||||||
|
sgVec3 gravity_vector; //in m/s*s
|
||||||
|
sgVec3 hpr; //the balloon isn't allways exactly vertical (e.g. during gusts); normalized
|
||||||
|
sgVec3 velocity; //current velocity; it gets iterated at each 'update'
|
||||||
|
sgVec3 position; //current position in lat/lon/alt
|
||||||
|
|
||||||
|
float balloon_envelope_area; //area of the envelope
|
||||||
|
float balloon_envelope_volume; //volume of the envelope
|
||||||
|
|
||||||
|
float wind_facing_area_of_balloon;
|
||||||
|
float wind_facing_area_of_basket;
|
||||||
|
|
||||||
|
float cw_envelope; //wind resistance of the envelope
|
||||||
|
float cw_basket; //wind resistance of the bakset
|
||||||
|
|
||||||
|
//all weights in kg
|
||||||
|
float weight_of_total_fuel;
|
||||||
|
float weight_of_envelope;
|
||||||
|
float weight_of_basket; //weight of all the unmovable stuff such as the basket, the burner and the empty tanks
|
||||||
|
float weight_of_cargo; //passengers and anything left (e.g. sand bags that are thrown away to give additional lift)
|
||||||
|
|
||||||
|
float fuel_left; //as a percentage
|
||||||
|
float max_flow_of_fuel_per_second; //in percent per second
|
||||||
|
float current_burner_strength;
|
||||||
|
|
||||||
|
float lambda; //waermeuebergangskoeffizient (heat transmission coefficent?!?) for the envelope
|
||||||
|
float l_of_the_envelope; //the thickness of the envelope (in m)
|
||||||
|
|
||||||
|
float T; //tempereature inside the balloon
|
||||||
|
|
||||||
|
float ground_level;
|
||||||
|
|
||||||
|
public:
|
||||||
|
balloon(); //constructor for initializing the balloon
|
||||||
|
|
||||||
|
void update(); //dt = time in seconds since last call
|
||||||
|
void set_burner_strength(const float bs);
|
||||||
|
|
||||||
|
void getVelocity(sgVec3 v) const;
|
||||||
|
void setVelocity(const sgVec3 v);
|
||||||
|
|
||||||
|
void getPosition(sgVec3 v) const;
|
||||||
|
void setPosition(const sgVec3 v);
|
||||||
|
|
||||||
|
void getHPR(sgVec3 angles) const; //the balloon isn't allways exactly vertical
|
||||||
|
void setHPR(const sgVec3 angles); //the balloon isn't allways exactly vertical
|
||||||
|
|
||||||
|
void setGroundLevel(const float altitude);
|
||||||
|
|
||||||
|
float getTemperature(void) const;
|
||||||
|
float getFuelLeft(void) const;
|
||||||
|
|
||||||
|
void set_dt(const float new_dt) { dt = new_dt; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
#endif /*BalloonSim_H*/
|
121
src/FDM/SP/MagicCarpet.cxx
Normal file
121
src/FDM/SP/MagicCarpet.cxx
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
// MagicCarpet.cxx -- interface to the "Magic Carpet" flight model
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started October 1999.
|
||||||
|
//
|
||||||
|
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
#include <simgear/math/point3d.hxx>
|
||||||
|
#include <simgear/math/polar3d.hxx>
|
||||||
|
|
||||||
|
#include <Aircraft/controls.hxx>
|
||||||
|
#include <Main/globals.hxx>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
#include "MagicCarpet.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
FGMagicCarpet::FGMagicCarpet( double dt ) {
|
||||||
|
// set_delta_t( dt );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FGMagicCarpet::~FGMagicCarpet() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the Magic Carpet flight model, dt is the time increment
|
||||||
|
// for each subsequent iteration through the EOM
|
||||||
|
void FGMagicCarpet::init() {
|
||||||
|
common_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Run an iteration of the EOM (equations of motion)
|
||||||
|
void FGMagicCarpet::update( double dt ) {
|
||||||
|
// cout << "FGLaRCsim::update()" << endl;
|
||||||
|
|
||||||
|
if (is_suspended())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// int multiloop = _calc_multiloop(dt);
|
||||||
|
|
||||||
|
double time_step = dt;
|
||||||
|
|
||||||
|
// speed and distance traveled
|
||||||
|
double speed = globals->get_controls()->get_throttle( 0 ) * 2000; // meters/sec
|
||||||
|
if ( globals->get_controls()->get_brake_left() > 0.0
|
||||||
|
|| globals->get_controls()->get_brake_right() > 0.0 )
|
||||||
|
{
|
||||||
|
speed = -speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dist = speed * time_step;
|
||||||
|
double kts = speed * SG_METER_TO_NM * 3600.0;
|
||||||
|
_set_V_equiv_kts( kts );
|
||||||
|
_set_V_calibrated_kts( kts );
|
||||||
|
_set_V_ground_speed( kts );
|
||||||
|
|
||||||
|
// angle of turn
|
||||||
|
double turn_rate = globals->get_controls()->get_aileron() * SGD_PI_4; // radians/sec
|
||||||
|
double turn = turn_rate * time_step;
|
||||||
|
|
||||||
|
// update euler angles
|
||||||
|
_set_Euler_Angles( get_Phi(), get_Theta(),
|
||||||
|
fmod(get_Psi() + turn, SGD_2PI) );
|
||||||
|
_set_Euler_Rates(0,0,0);
|
||||||
|
|
||||||
|
// update (lon/lat) position
|
||||||
|
double lat2, lon2, az2;
|
||||||
|
if ( fabs( speed ) > SG_EPSILON ) {
|
||||||
|
geo_direct_wgs_84 ( get_Altitude(),
|
||||||
|
get_Latitude() * SGD_RADIANS_TO_DEGREES,
|
||||||
|
get_Longitude() * SGD_RADIANS_TO_DEGREES,
|
||||||
|
get_Psi() * SGD_RADIANS_TO_DEGREES,
|
||||||
|
dist, &lat2, &lon2, &az2 );
|
||||||
|
|
||||||
|
_set_Longitude( lon2 * SGD_DEGREES_TO_RADIANS );
|
||||||
|
_set_Latitude( lat2 * SGD_DEGREES_TO_RADIANS );
|
||||||
|
}
|
||||||
|
|
||||||
|
// cout << "lon error = " << fabs(end.x()*SGD_RADIANS_TO_DEGREES - lon2)
|
||||||
|
// << " lat error = " << fabs(end.y()*SGD_RADIANS_TO_DEGREES - lat2)
|
||||||
|
// << endl;
|
||||||
|
|
||||||
|
double sl_radius, lat_geoc;
|
||||||
|
sgGeodToGeoc( get_Latitude(), get_Altitude(), &sl_radius, &lat_geoc );
|
||||||
|
|
||||||
|
// update altitude
|
||||||
|
double real_climb_rate = -globals->get_controls()->get_elevator() * 5000; // feet/sec
|
||||||
|
_set_Climb_Rate( real_climb_rate / 500.0 );
|
||||||
|
double climb = real_climb_rate * time_step;
|
||||||
|
|
||||||
|
_set_Geocentric_Position( lat_geoc, get_Longitude(),
|
||||||
|
sl_radius + get_Altitude() + climb );
|
||||||
|
// cout << "sea level radius (ft) = " << sl_radius << endl;
|
||||||
|
// cout << "(setto) sea level radius (ft) = " << get_Sea_level_radius() << endl;
|
||||||
|
_update_ground_elev_at_pos();
|
||||||
|
_set_Sea_level_radius( sl_radius * SG_METER_TO_FEET);
|
||||||
|
_set_Altitude( get_Altitude() + climb );
|
||||||
|
}
|
46
src/FDM/SP/MagicCarpet.hxx
Normal file
46
src/FDM/SP/MagicCarpet.hxx
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// MagicCarpet.hxx -- interface to the "Magic Carpet" flight model
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started October 1999.
|
||||||
|
//
|
||||||
|
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _MAGICCARPET_HXX
|
||||||
|
#define _MAGICCARPET_HXX
|
||||||
|
|
||||||
|
|
||||||
|
#include <FDM/flight.hxx>
|
||||||
|
|
||||||
|
|
||||||
|
class FGMagicCarpet: public FGInterface {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGMagicCarpet( double dt );
|
||||||
|
~FGMagicCarpet();
|
||||||
|
|
||||||
|
// reset flight params to a specific position
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// update position based on inputs, positions, velocities, etc.
|
||||||
|
void update( double dt );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _MAGICCARPET_HXX
|
Loading…
Add table
Reference in a new issue