From c682dec8983613ae26aa320740cf9ab0869af818 Mon Sep 17 00:00:00 2001 From: curt Date: Tue, 12 Oct 1999 03:27:06 +0000 Subject: [PATCH] Initial revision of balloon simulator code. --- src/FDM/Balloon.cxx | 218 ++++++++++++++++++++ src/FDM/Balloon.h | 95 +++++++++ src/FDM/Balloon/BalloonSim.cpp | 357 +++++++++++++++++++++++++++++++++ src/FDM/Balloon/BalloonSim.h | 115 +++++++++++ src/FDM/Balloon/Makefile.am | 5 + src/FDM/Makefile.am | 6 +- src/FDM/flight.cxx | 1 + src/FDM/flight.hxx | 12 +- 8 files changed, 802 insertions(+), 7 deletions(-) create mode 100644 src/FDM/Balloon.cxx create mode 100644 src/FDM/Balloon.h create mode 100644 src/FDM/Balloon/BalloonSim.cpp create mode 100644 src/FDM/Balloon/BalloonSim.h create mode 100644 src/FDM/Balloon/Makefile.am diff --git a/src/FDM/Balloon.cxx b/src/FDM/Balloon.cxx new file mode 100644 index 000000000..ec77205b0 --- /dev/null +++ b/src/FDM/Balloon.cxx @@ -0,0 +1,218 @@ +/***************************************************************************** + + 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., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, 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 */ +/****************************************************************************/ + +#include + +#ifdef FG_MATH_EXCEPTION_CLASH +# include +#endif + +#include STL_STRING + +#include +#include +#include +#include +#include
+#include +#include + +#include "Balloon.h" + +/****************************************************************************/ +/********************************** CODE ************************************/ +/****************************************************************************/ + + +// Initialize the BalloonSim flight model, dt is the time increment for +// each subsequent iteration through the EOM +int FGBalloonSim::init( double dt ) { + sgVec3 temp; + + FG_LOG( FG_FLIGHT, FG_INFO, "Starting initializing BalloonSim" ); + + FG_LOG( FG_FLIGHT, FG_INFO, " created a balloon" ); + + //set the dt of the model + current_balloon.set_dt(dt); + + //set position + sgSetVec3( temp, + get_Latitude(), + get_Longitude(), + get_Altitude() * 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, + current_options.get_uBody(), + current_options.get_vBody(), + current_options.get_wBody() ); + current_balloon.setVelocity( temp ); + + FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing BalloonSim" ); + + return 1; +} + + +// Run an iteration of the EOM (equations of motion) +int FGBalloonSim::update( int multiloop ) { + double save_alt = 0.0; + + // 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 ( controls.get_elevator() ); /*controls.get_throttle( 0 )*/ + //not more implemented yet + + // Inform BalloonSim of the local terrain altitude + current_balloon.setGroundLevel ( get_Runway_altitude() * 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 ); + FG_LOG( FG_FLIGHT, FG_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 ); + } + + return 1; +} + + +// Convert from the FGInterface struct to the BalloonSim +int FGBalloonSim::copy_to_BalloonSim() { + return 1; +} + + +// Convert from the BalloonSim to the FGInterface struct +int 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 ); + double lat_geoc = temp[0]; + double lon = temp[1]; + double alt = temp[2] * METER_TO_FEET; + + double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc; + fgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER, + &lat_geod, &tmp_alt, &sl_radius1 ); + fgGeodToGeoc( lat_geod, alt * FEET_TO_METER, &sl_radius2, &tmp_lat_geoc ); + + FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << lon << " lat_geod = " << lat_geod + << " lat_geoc = " << lat_geoc + << " alt = " << alt << " tmp_alt = " << tmp_alt * METER_TO_FEET + << " sl_radius1 = " << sl_radius1 * METER_TO_FEET + << " sl_radius2 = " << sl_radius2 * METER_TO_FEET + << " Equator = " << EQUATORIAL_RADIUS_FT ); + + set_Geocentric_Position( lat_geoc, lon, + sl_radius2 * METER_TO_FEET + alt ); + set_Geodetic_Position( lat_geod, lon, alt ); + + current_balloon.getHPR( temp ); + set_Euler_Angles( temp[0], temp[1], temp[2] ); + + + set_Alpha( 0.0/*FDMExec.GetTranslation()->Getalpha()*/ ); + set_Beta( 0.0/*FDMExec.GetTranslation()->Getbeta()*/ ); + + /* **FIXME*** */ set_Sea_level_radius( sl_radius2 * METER_TO_FEET ); + /* **FIXME*** */ set_Earth_position_angle( 0.0 ); + + /* ***FIXME*** */ set_Runway_altitude( 0.0 ); + + set_sin_lat_geocentric( lat_geoc ); + set_cos_lat_geocentric( lat_geoc ); + set_sin_cos_longitude( lon ); + set_sin_cos_latitude( lat_geod ); + + return 0; +} + + diff --git a/src/FDM/Balloon.h b/src/FDM/Balloon.h new file mode 100644 index 000000000..8ba627579 --- /dev/null +++ b/src/FDM/Balloon.h @@ -0,0 +1,95 @@ +/***************************************************************************** + + 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., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, 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 + +#include + +#include "flight.hxx" + +/****************************************************************************/ +/* DEFINES */ +/****************************************************************************/ + +/****************************************************************************/ +/* DECLARATIONS */ +/****************************************************************************/ + +// reset flight params to a specific position +// int fgBalloonSimInit(double dt, FGInterface& f); + +// update position based on inputs, positions, velocities, etc. +// int fgBalloonSimUpdate(FGInterface& f, int multiloop); + +// Convert from the FGInterface struct to the BalloonSim +// int FGInterface_2_fgBalloonSim (FGInterface& f); + +// Convert from the BalloonSim to the FGInterface struct +// int fgBalloonSim_2_FGInterface (FGInterface& f); + +class FGBalloonSim: public FGInterface { + + balloon current_balloon; + +public: + + // copy FDM state to BalloonSim structures + int copy_to_BalloonSim(); + + // copy FDM state from BalloonSim structures + int copy_from_BalloonSim(); + + // reset flight params to a specific position + int init( double dt ); + + // update position based on inputs, positions, velocities, etc. + int update( int multiloop ); +}; + + +/****************************************************************************/ +#endif /*BalloonSimInterface_H*/ + + + + diff --git a/src/FDM/Balloon/BalloonSim.cpp b/src/FDM/Balloon/BalloonSim.cpp new file mode 100644 index 000000000..c3443eec9 --- /dev/null +++ b/src/FDM/Balloon/BalloonSim.cpp @@ -0,0 +1,357 @@ +/***************************************************************************** + + 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., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, 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 */ +/****************************************************************************/ +#include +// #include +#include + +#include +#include +#include
+#include + +#include "BalloonSim.h" + +#include "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) * FG_PI; + balloon_envelope_volume = (4.0/3.0) * (8.8 * 8.8 * 8.8) * FG_PI; + + wind_facing_area_of_balloon = FG_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... */ + /************************************************************************/ + + sgVec3 v; + + //get the current wind velocity and store it in v + Point3D temp = WeatherDatabase->get(position).Wind; + sgSetVec3(v, temp.x(), temp.y(), temp.z()); + + sgSubVec3(v, velocity); + float speed = sgLengthVec3(v); + + // calculate the density of the gas inside + double rho = WeatherDatabase->get(position).AirPressure / (287.14 * T); + + // calculate the mass of the air + double mAir = rho * balloon_envelope_volume; + + // loss of energy by cooling down: + float k = 1.0 / (1.0/4.8 + 1.0/(4.8+3.4*speed) + l_of_the_envelope/lambda); + float Q = k * balloon_envelope_area * (dt/3600.0) * (WeatherDatabase->get(position).Temperature - T); //(dt/3600.0) = time since last call in hours + + // 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); + sgScaleVec3(fFriction, v, cw_envelope * wind_facing_area_of_balloon * WeatherDatabase->getAirDensity(position) * speed / 2.0); //wind resistance + sgScaleVec3(fLift, gravity_vector, -balloon_envelope_volume * WeatherDatabase->get(position).AirPressure / (287.14 * WeatherDatabase->get(position).Temperature)); + + sgAddVec3(fTotal, fLift); + sgAddVec3(fTotal, 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) ) + velocity[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); + } + + } +} +*/ diff --git a/src/FDM/Balloon/BalloonSim.h b/src/FDM/Balloon/BalloonSim.h new file mode 100644 index 000000000..c0966f850 --- /dev/null +++ b/src/FDM/Balloon/BalloonSim.h @@ -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., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, 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 + +/****************************************************************************/ +/* 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*/ diff --git a/src/FDM/Balloon/Makefile.am b/src/FDM/Balloon/Makefile.am new file mode 100644 index 000000000..d20022e7f --- /dev/null +++ b/src/FDM/Balloon/Makefile.am @@ -0,0 +1,5 @@ +noinst_LIBRARIES = libBalloon.a + +libBalloon_a_SOURCES = BalloonSim.cpp BalloonSim.h + +INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator diff --git a/src/FDM/Makefile.am b/src/FDM/Makefile.am index e44cd5bd8..a0c7e7a52 100644 --- a/src/FDM/Makefile.am +++ b/src/FDM/Makefile.am @@ -1,8 +1,10 @@ -SUBDIRS = External JSBsim LaRCsim Slew +SUBDIRS = Balloon External JSBsim LaRCsim Slew noinst_LIBRARIES = libFlight.a -libFlight_a_SOURCES = flight.cxx flight.hxx \ +libFlight_a_SOURCES = \ + Balloon.cxx Balloon.hxx \ + flight.cxx flight.hxx \ JSBsim.cxx JSBsim.hxx \ LaRCsim.cxx LaRCsim.hxx diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index 3f98f3bb7..57f73d937 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -34,6 +34,7 @@ #include "flight.hxx" #include "JSBsim.hxx" #include "LaRCsim.hxx" +#include "Balloon.h" // base_fdm_state is the internal state that is updated in integer diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx index 5bc8f0f91..d17ce874c 100644 --- a/src/FDM/flight.hxx +++ b/src/FDM/flight.hxx @@ -120,13 +120,15 @@ public: // Jon S. Berndt's new FDM written from the ground up in C++ FG_JSBSIM = 2, + // Christian's hot air balloon simulation + FG_BALLOONSIM = 3, + // The following aren't implemented but are here to spark // thoughts and discussions, and maybe even action. - FG_ACM = 3, - FG_SUPER_SONIC = 4, - FG_HELICOPTER = 5, - FG_AUTOGYRO = 6, - FG_BALLOON = 7, + FG_ACM = 4, + FG_SUPER_SONIC = 5, + FG_HELICOPTER = 6, + FG_AUTOGYRO = 7, FG_PARACHUTE = 8, // Driven externally via a serial port, net, file, etc.