]> git.mxchange.org Git - flightgear.git/commitdiff
Add the BalloonSim and MagicCarpet fdm's back in (i seriously thought this had been...
authorehofman <ehofman>
Sat, 26 Jul 2008 07:19:13 +0000 (07:19 +0000)
committerehofman <ehofman>
Sat, 26 Jul 2008 07:19:13 +0000 (07:19 +0000)
src/FDM/SP/Balloon.cxx [new file with mode: 0644]
src/FDM/SP/Balloon.h [new file with mode: 0644]
src/FDM/SP/BalloonSim.cpp [new file with mode: 0644]
src/FDM/SP/BalloonSim.h [new file with mode: 0644]
src/FDM/SP/MagicCarpet.cxx [new file with mode: 0644]
src/FDM/SP/MagicCarpet.hxx [new file with mode: 0644]

diff --git a/src/FDM/SP/Balloon.cxx b/src/FDM/SP/Balloon.cxx
new file mode 100644 (file)
index 0000000..62e4903
--- /dev/null
@@ -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;
+}
+
+
diff --git a/src/FDM/SP/Balloon.h b/src/FDM/SP/Balloon.h
new file mode 100644 (file)
index 0000000..869b20a
--- /dev/null
@@ -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*/
+
+
+
+
diff --git a/src/FDM/SP/BalloonSim.cpp b/src/FDM/SP/BalloonSim.cpp
new file mode 100644 (file)
index 0000000..a966d6c
--- /dev/null
@@ -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);
+       }
+
+    }
+}
+*/
diff --git a/src/FDM/SP/BalloonSim.h b/src/FDM/SP/BalloonSim.h
new file mode 100644 (file)
index 0000000..d424fc6
--- /dev/null
@@ -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*/
diff --git a/src/FDM/SP/MagicCarpet.cxx b/src/FDM/SP/MagicCarpet.cxx
new file mode 100644 (file)
index 0000000..f11573e
--- /dev/null
@@ -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 );
+}
diff --git a/src/FDM/SP/MagicCarpet.hxx b/src/FDM/SP/MagicCarpet.hxx
new file mode 100644 (file)
index 0000000..8124c81
--- /dev/null
@@ -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