1
0
Fork 0

Merge branch 'next' of git://gitorious.org/fg/flightgear into next

This commit is contained in:
ThorstenB 2010-10-29 20:05:54 +02:00
commit f2a817d137
88 changed files with 670 additions and 6190 deletions

View file

@ -192,6 +192,15 @@ texture-unit - has several child properties:
wrap-s wrap-s
wrap-t wrap-t
wrap-r wrap-r
mipmap-control - controls how the mipmap levels are computed.
Each color channel can be computed with different functions
among average, sum, product, min and max. For example :
<function-r>average</function-r>
<function-a>min</function-a>
function-r - function for red
function-g - function for green
function-b - function for blue
function-a - function for alpha
The following built-in types are supported: The following built-in types are supported:
white - 1 pixel white texture white - 1 pixel white texture
noise - a 3d noise texture noise - a 3d noise texture

View file

@ -1923,90 +1923,6 @@
<Filter <Filter
Name="Lib_Cockpit" Name="Lib_Cockpit"
> >
<File
RelativePath="..\..\..\src\Cockpit\cockpit.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\cockpit.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_card.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_dnst.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_gaug.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_inst.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_labl.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_ladr.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_rwy.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_scal.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Cockpit\hud_tbi.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\..\..\src\Cockpit\panel.cxx" RelativePath="..\..\..\src\Cockpit\panel.cxx"
> >
@ -2055,14 +1971,6 @@
RelativePath="..\..\..\src\FDM\JSBSim\FGJSBBase.h" RelativePath="..\..\..\src\FDM\JSBSim\FGJSBBase.h"
> >
</File> </File>
<File
RelativePath="..\..\..\src\FDM\JSBSim\FGState.cpp"
>
</File>
<File
RelativePath="..\..\..\src\FDM\JSBSim\FGState.h"
>
</File>
<File <File
RelativePath="..\..\..\src\FDM\JSBSim\JSBSim.cxx" RelativePath="..\..\..\src\FDM\JSBSim\JSBSim.cxx"
> >

View file

@ -43,6 +43,11 @@ FGSubmodelMgr::~FGSubmodelMgr()
{ {
} }
FGAIManager* FGSubmodelMgr::aiManager()
{
return (FGAIManager*)globals->get_subsystem("ai_model");
}
void FGSubmodelMgr::init() void FGSubmodelMgr::init()
{ {
index = 0; index = 0;
@ -74,8 +79,6 @@ void FGSubmodelMgr::init()
_contrail_trigger = fgGetNode("ai/submodels/contrails", true); _contrail_trigger = fgGetNode("ai/submodels/contrails", true);
_contrail_trigger->setBoolValue(false); _contrail_trigger->setBoolValue(false);
ai = (FGAIManager*)globals->get_subsystem("ai_model");
load(); load();
} }
@ -116,9 +119,9 @@ void FGSubmodelMgr::update(double dt)
_expiry = false; _expiry = false;
// check if the submodel hit an object or terrain // check if the submodel hit an object or terrain
sm_list = ai->get_ai_list(); FGAIManager::ai_list_type sm_list(aiManager()->get_ai_list());
sm_list_iterator sm_list_itr = sm_list.begin(); FGAIManager::ai_list_iterator sm_list_itr = sm_list.begin(),
sm_list_iterator end = sm_list.end(); end = sm_list.end();
for (; sm_list_itr != end; ++sm_list_itr) { for (; sm_list_itr != end; ++sm_list_itr) {
FGAIBase::object_type object_type =(*sm_list_itr)->getType(); FGAIBase::object_type object_type =(*sm_list_itr)->getType();
@ -300,7 +303,8 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
ballist->setParentNodes(_selected_ac); ballist->setParentNodes(_selected_ac);
ballist->setContentsNode(sm->contents_node); ballist->setContentsNode(sm->contents_node);
ballist->setWeight(sm->weight); ballist->setWeight(sm->weight);
ai->attach(ballist);
aiManager()->attach(ballist);
if (sm->count > 0) if (sm->count > 0)
sm->count--; sm->count--;
@ -383,8 +387,6 @@ void FGSubmodelMgr::transform(submodel *sm)
} else { } else {
// set the data for a submodel tied to an AI Object // set the data for a submodel tied to an AI Object
//cout << " set the data for a submodel tied to an AI Object " << id << endl; //cout << " set the data for a submodel tied to an AI Object " << id << endl;
sm_list_iterator sm_list_itr = sm_list.begin();
sm_list_iterator end = sm_list.end();
setParentNode(id); setParentNode(id);
} }
@ -477,15 +479,15 @@ void FGSubmodelMgr::loadAI()
{ {
SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading AI submodels "); SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading AI submodels ");
sm_list = ai->get_ai_list(); FGAIManager::ai_list_type sm_list(aiManager()->get_ai_list());
if (sm_list.empty()) { if (sm_list.empty()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Submodels: Unable to read AI submodel list"); SG_LOG(SG_GENERAL, SG_ALERT, "Submodels: Unable to read AI submodel list");
return; return;
} }
sm_list_iterator sm_list_itr = sm_list.begin(); FGAIManager::ai_list_iterator sm_list_itr = sm_list.begin(),
sm_list_iterator end = sm_list.end(); end = sm_list.end();
while (sm_list_itr != end) { while (sm_list_itr != end) {
string path = (*sm_list_itr)->_getSMPath(); string path = (*sm_list_itr)->_getSMPath();

View file

@ -13,17 +13,13 @@
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
#include <AIModel/AIBase.hxx> #include <simgear/math/SGMath.hxx>
#include <vector> #include <vector>
#include <string> #include <string>
#include <Main/fg_props.hxx>
using std::vector;
using std::string;
using std::list;
class FGAIBase; class FGAIBase;
class FGAIManager;
class FGSubmodelMgr : public SGSubsystem, public SGPropertyChangeListener class FGSubmodelMgr : public SGSubsystem, public SGPropertyChangeListener
{ {
@ -37,8 +33,8 @@ public:
SGPropertyNode_ptr submodel_node; SGPropertyNode_ptr submodel_node;
SGPropertyNode_ptr speed_node; SGPropertyNode_ptr speed_node;
string name; std::string name;
string model; std::string model;
double speed; double speed;
bool slaved; bool slaved;
bool repeat; bool repeat;
@ -68,13 +64,13 @@ public:
bool collision; bool collision;
bool expiry; bool expiry;
bool impact; bool impact;
string impact_report; std::string impact_report;
double fuse_range; double fuse_range;
string submodel; std::string submodel;
int sub_id; int sub_id;
bool force_stabilised; bool force_stabilised;
bool ext_force; bool ext_force;
string force_path; std::string force_path;
} submodel; } submodel;
typedef struct { typedef struct {
@ -112,7 +108,7 @@ public:
private: private:
typedef vector <submodel*> submodel_vector_type; typedef std::vector <submodel*> submodel_vector_type;
typedef submodel_vector_type::iterator submodel_vector_iterator; typedef submodel_vector_type::iterator submodel_vector_iterator;
submodel_vector_type submodels; submodel_vector_type submodels;
@ -186,22 +182,17 @@ private:
SGPropertyNode_ptr _path_node; SGPropertyNode_ptr _path_node;
SGPropertyNode_ptr _selected_ac; SGPropertyNode_ptr _selected_ac;
FGAIManager* ai;
IC_struct IC; IC_struct IC;
// A list of pointers to AI objects /**
typedef list <SGSharedPtr<FGAIBase> > sm_list_type; * Helper to retrieve the AI manager, if it currently exists
typedef sm_list_type::iterator sm_list_iterator; */
typedef sm_list_type::const_iterator sm_list_const_iterator; FGAIManager* aiManager();
sm_list_type sm_list;
void loadAI(); void loadAI();
void loadSubmodels(); void loadSubmodels();
void setData(int id, string& path, bool serviceable); void setData(int id, std::string& path, bool serviceable);
void setSubData(int id, string& path, bool serviceable); void setSubData(int id, std::string& path, bool serviceable);
void valueChanged (SGPropertyNode *); void valueChanged (SGPropertyNode *);
void transform(submodel *); void transform(submodel *);
void setParentNode(int parent_id); void setParentNode(int parent_id);

View file

@ -26,8 +26,6 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <plib/ul.h>
#include <Environment/environment_mgr.hxx> #include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx> #include <Environment/environment.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>

View file

@ -1,12 +1,6 @@
noinst_LIBRARIES = libCockpit.a noinst_LIBRARIES = libCockpit.a
libCockpit_a_SOURCES = \ libCockpit_a_SOURCES = \
cockpit.cxx cockpit.hxx \
hud.cxx hud.hxx \
hud_card.cxx hud_dnst.cxx hud_gaug.cxx hud_inst.cxx \
hud_labl.cxx hud_ladr.cxx \
hud_rwy.cxx \
hud_scal.cxx hud_tbi.cxx \
panel.cxx panel.hxx \ panel.cxx panel.hxx \
panel_io.cxx panel_io.hxx panel_io.cxx panel_io.hxx

View file

@ -1,465 +0,0 @@
// cockpit.cxx -- routines to draw a cockpit (initial draft)
//
// Written by Michele America, started September 1997.
//
// Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
//
// 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/compiler.h>
#include <simgear/sg_inlines.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/props/props.hxx>
#include <simgear/timing/sg_time.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Main/viewmgr.hxx>
#include <Main/viewer.hxx>
#include <Scenery/scenery.hxx>
#include <GUI/gui.h>
#include "cockpit.hxx"
#include "hud.hxx"
// The following routines obtain information concerntin the aircraft's
// current state and return it to calling instrument display routines.
// They should eventually be member functions of the aircraft.
//
float get_latitude( void )
{
return fgGetDouble("/position/latitude-deg");
}
float get_lat_min( void )
{
double a, d;
a = fgGetDouble("/position/latitude-deg");
if (a < 0.0) {
a = -a;
}
d = (double) ( (int) a);
float lat_min = (a - d) * 60.0;
return lat_min;
}
float get_longitude( void )
{
return fgGetDouble("/position/longitude-deg");
}
char*
get_formated_gmt_time( void )
{
static char buf[32];
const struct tm *p = globals->get_time_params()->getGmt();
sprintf( buf, "%d/%d/%4d %d:%02d:%02d",
p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
p->tm_hour, p->tm_min, p->tm_sec);
return buf;
}
float get_long_min( void )
{
double a, d;
a = fgGetDouble("/position/longitude-deg");
if (a < 0.0) {
a = -a;
}
d = (double) ( (int) a);
float lon_min = (a - d) * 60.0;
return lon_min;
}
float get_throttleval( void )
{
// Hack limiting to one engine
return globals->get_controls()->get_throttle( 0 );
}
float get_aileronval( void )
{
return globals->get_controls()->get_aileron();
}
float get_elevatorval( void )
{
return globals->get_controls()->get_elevator();
}
float get_elev_trimval( void )
{
return globals->get_controls()->get_elevator_trim();
}
float get_rudderval( void )
{
return globals->get_controls()->get_rudder();
}
float get_speed( void )
{
static const SGPropertyNode * speedup_node = fgGetNode("/sim/speed-up");
float speed = fgGetDouble("/velocities/airspeed-kt")
* speedup_node->getIntValue();
return speed;
}
float get_mach(void)
{
return fgGetDouble("/velocities/mach");
}
float get_aoa( void )
{
return fgGetDouble("/orientation/alpha-deg");
}
float get_roll( void )
{
return fgGetDouble("/orientation/roll-deg") * SG_DEGREES_TO_RADIANS;
}
float get_pitch( void )
{
return fgGetDouble("/orientation/pitch-deg") * SG_DEGREES_TO_RADIANS;
}
float get_heading( void )
{
return fgGetDouble("/orientation/heading-deg");
}
float get_altitude( void )
{
static const SGPropertyNode *startup_units_node
= fgGetNode("/sim/startup/units");
if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
return fgGetDouble("/position/altitude-ft");
} else {
return fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER;
}
}
float get_agl( void )
{
static const SGPropertyNode *startup_units_node
= fgGetNode("/sim/startup/units");
if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
return fgGetDouble("/position/altitude-agl-ft");
} else {
return fgGetDouble("/position/altitude-agl-ft") * SG_FEET_TO_METER;
}
}
float get_sideslip( void )
{
return fgGetDouble("/orientation/side-slip-rad");
}
float get_frame_rate( void )
{
return fgGetInt("/sim/frame-rate");
}
float get_fov( void )
{
return globals->get_current_view()->get_fov();
}
float get_vfc_ratio( void )
{
// float vfc = current_view.get_vfc_ratio();
// return (vfc);
return 0.0;
}
float get_vfc_tris_drawn ( void )
{
// float rendered = current_view.get_tris_rendered();
// return (rendered);
return 0.0;
}
float get_vfc_tris_culled ( void )
{
// float culled = current_view.get_tris_culled();
// return (culled);
return 0.0;
}
float get_climb_rate( void )
{
static const SGPropertyNode *startup_units_node
= fgGetNode("/sim/startup/units");
float climb_rate = fgGetDouble("/velocities/vertical-speed-fps", 0.0);
if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
climb_rate *= 60.0;
} else {
climb_rate *= SG_FEET_TO_METER * 60.0;
}
return climb_rate;
}
float get_view_direction( void )
{
double view_off = 360.0 - globals->get_current_view()->getHeadingOffset_deg();
double view = fgGetDouble("/orientation/heading-deg") + view_off;
SG_NORMALIZE_RANGE(view, 0.0, 360.0);
return view;
}
// Added by Markus Hof on 5. Jan 2004
float get_dme( void )
{
static const SGPropertyNode * dme_node =
fgGetNode("/instrumentation/dme/indicated-distance-nm");
return dme_node->getFloatValue();
}
float get_Ax ( void )
{
return fgGetDouble("/accelerations/ned/north-accel-fps_sec", 0.0);
}
float get_anzg ( void )
{
return fgGetDouble("/accelerations/n-z-cg-fps_sec", 0.0);
}
#ifdef ENABLE_SP_FDM
float get_aux1 (void)
{
return fgGetDouble("/fdm-ada/ship-lat", 0.0);
}
float get_aux2 (void)
{
return fgGetDouble("/fdm-ada/ship-lon", 0.0);
}
float get_aux3 (void)
{
return fgGetDouble("/fdm-ada/ship-alt", 0.0);
}
float get_aux4 (void)
{
return fgGetDouble("/fdm-ada/skijump-dist", 0.0);
}
float get_aux5 (void)
{
return fgGetDouble("/fdm-ada/aux5", 0.0);
}
float get_aux6 (void)
{
return fgGetDouble("/fdm-ada/aux6", 0.0);
}
float get_aux7 (void)
{
return fgGetDouble("/fdm-ada/aux7", 0.0);
}
float get_aux8 (void)
{
return fgGetDouble("/fdm-ada/aux8", 0.0);}
float get_aux9 (void)
{
return fgGetDouble("/fdm-ada/aux9", 0.0);}
float get_aux10 (void)
{
return fgGetDouble("/fdm-ada/aux10", 0.0);
}
float get_aux11 (void)
{
return fgGetDouble("/fdm-ada/aux11", 0.0);
}
float get_aux12 (void)
{
return fgGetDouble("/fdm-ada/aux12", 0.0);
}
float get_aux13 (void)
{
return fgGetDouble("/fdm-ada/aux13", 0.0);
}
float get_aux14 (void)
{
return fgGetDouble("/fdm-ada/aux14", 0.0);
}
float get_aux15 (void)
{
return fgGetDouble("/fdm-ada/aux15", 0.0);
}
float get_aux16 (void)
{
return fgGetDouble("/fdm-ada/aux16", 0.0);
}
float get_aux17 (void)
{
return fgGetDouble("/fdm-ada/aux17", 0.0);
}
float get_aux18 (void)
{
return fgGetDouble("/fdm-ada/aux18", 0.0);
}
#endif
bool fgCockpitInit()
{
SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
// cockpit->code = 1; /* It will be aircraft dependent */
// cockpit->status = 0;
// If aircraft has HUD specified we will get the specs from its def
// file. For now we will depend upon hard coding in hud?
// We must insure that the existing instrument link is purged.
// This is done by deleting the links in the list.
// HI_Head is now a null pointer so we can generate a new list from the
// current aircraft.
fgHUDInit();
return true;
}
void fgCockpitUpdate( osg::State* state ) {
static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
static const SGPropertyNode * hud_visibility_node
= fgGetNode("/sim/hud/visibility");
int iwidth = xsize_node->getIntValue();
int iheight = ysize_node->getIntValue();
// FIXME: inefficient
if ( hud_visibility_node->getBoolValue() ) {
// This will check the global hud linked list pointer.
// If there is anything to draw it will.
fgUpdateHUD( state );
}
glViewport( 0, 0, iwidth, iheight );
}
struct FuncTable {
const char *name;
FLTFNPTR func;
} fn_table[] = {
{ "agl", get_agl },
{ "aileronval", get_aileronval },
{ "altitude", get_altitude },
{ "anzg", get_anzg },
{ "aoa", get_aoa },
{ "ax", get_Ax },
{ "climb", get_climb_rate },
{ "elevatortrimval", get_elev_trimval },
{ "elevatorval", get_elevatorval },
{ "fov", get_fov },
{ "framerate", get_frame_rate },
{ "heading", get_heading },
{ "latitude", get_latitude },
{ "longitude", get_longitude },
{ "mach", get_mach },
{ "rudderval", get_rudderval },
{ "speed", get_speed },
{ "throttleval", get_throttleval },
{ "view_direction", get_view_direction },
{ "vfc_tris_culled", get_vfc_tris_culled },
{ "vfc_tris_drawn", get_vfc_tris_drawn },
#ifdef ENABLE_SP_FDM
{ "aux1", get_aux1 },
{ "aux2", get_aux2 },
{ "aux3", get_aux3 },
{ "aux4", get_aux4 },
{ "aux5", get_aux5 },
{ "aux6", get_aux6 },
{ "aux7", get_aux7 },
{ "aux8", get_aux8 },
{ "aux9", get_aux9 },
{ "aux10", get_aux10 },
{ "aux11", get_aux11 },
{ "aux12", get_aux12 },
{ "aux13", get_aux13 },
{ "aux14", get_aux14 },
{ "aux15", get_aux15 },
{ "aux16", get_aux16 },
{ "aux17", get_aux17 },
{ "aux18", get_aux18 },
#endif
{ 0, 0 },
};
FLTFNPTR get_func(const char *name)
{
for (int i = 0; fn_table[i].name; i++)
if (!strcmp(fn_table[i].name, name))
return fn_table[i].func;
return 0;
}

View file

@ -1,39 +0,0 @@
/**************************************************************************
* cockpit.hxx -- cockpit defines and prototypes (initial draft)
*
* Written by Michele America, started September 1997.
*
* Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
*
* 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 _COCKPIT_HXX
#define _COCKPIT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <osg/State>
bool fgCockpitInit();
void fgCockpitUpdate( osg::State* );
#endif /* _COCKPIT_HXX */

View file

@ -1,654 +0,0 @@
// hud.cxx -- hud defines and prototypes
//
// Written by Michele America, started September 1997.
//
// Copyright (C) 1997 Michele F. America - micheleamerica@geocities.com
//
// 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$
#include <simgear/compiler.h>
#include <simgear/structure/exception.hxx>
#include <string>
#include <fstream>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <math.h>
#include <stdlib.h>
#include <stdio.h> // char related functions
#include <string.h> // strcmp()
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props_io.hxx>
#include <osg/Matrixf>
#include <GUI/new_gui.hxx> // FGFontCache
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include <Airports/runways.hxx>
#include <Main/viewer.hxx>
#include "hud.hxx"
static HUD_Properties *HUDprop = 0;
static char units[5];
deque<SGSharedPtr<instr_item> > HUD_deque;
fgTextList HUD_TextList;
fgLineList HUD_LineList;
fgLineList HUD_StippleLineList;
fntRenderer *HUDtext = 0;
fntTexFont *HUD_Font = 0;
float HUD_TextSize = 0;
int HUD_style = 0;
float HUD_matrix[16];
int readHud( istream &input );
int readInstrument ( const SGPropertyNode * node);
static void drawHUD(osg::State*);
static void fgUpdateHUDVirtual(osg::State*);
class locRECT {
public:
RECT rect;
locRECT( UINT left, UINT top, UINT right, UINT bottom);
RECT get_rect(void) { return rect; }
};
locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
{
rect.left = left;
rect.top = top;
rect.right = right;
rect.bottom = bottom;
}
// #define DEBUG
int readInstrument(const SGPropertyNode * node)
{
static const SGPropertyNode *startup_units_node
= fgGetNode("/sim/startup/units");
instr_item *HIptr;
if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
strcpy(units, " ft");
} else {
strcpy(units, " m");
}
const SGPropertyNode * ladder_group = node->getNode("ladders");
if (ladder_group != 0) {
int nLadders = ladder_group->nChildren();
for (int j = 0; j < nLadders; j++) {
HIptr = static_cast<instr_item *>(new HudLadder(ladder_group->getChild(j)));
HUD_deque.insert(HUD_deque.begin(), HIptr);
}
}
const SGPropertyNode * card_group = node->getNode("cards");
if (card_group != 0) {
int nCards = card_group->nChildren();
for (int j = 0; j < nCards; j++) {
const char *type = card_group->getChild(j)->getStringValue("type", "gauge");
if (!strcmp(type, "gauge"))
HIptr = static_cast<instr_item *>(new gauge_instr(card_group->getChild(j)));
else if (!strcmp(type, "dial") || !strcmp(type, "tape"))
HIptr = static_cast<instr_item *>(new hud_card(card_group->getChild(j)));
else {
SG_LOG(SG_INPUT, SG_WARN, "HUD: unknown 'card' type: " << type);
continue;
}
HUD_deque.insert(HUD_deque.begin(), HIptr);
}
}
const SGPropertyNode * label_group = node->getNode("labels");
if (label_group != 0) {
int nLabels = label_group->nChildren();
for (int j = 0; j < nLabels; j++) {
HIptr = static_cast<instr_item *>(new instr_label(label_group->getChild(j)));
HUD_deque.insert(HUD_deque.begin(), HIptr);
}
}
const SGPropertyNode * tbi_group = node->getNode("tbis");
if (tbi_group != 0) {
int nTbis = tbi_group->nChildren();
for (int j = 0; j < nTbis; j++) {
HIptr = static_cast<instr_item *>(new fgTBI_instr(tbi_group->getChild(j)));
HUD_deque.insert(HUD_deque.begin(), HIptr);
}
}
const SGPropertyNode * rwy_group = node->getNode("runways");
if (rwy_group != 0) {
int nRwy = rwy_group->nChildren();
for (int j = 0; j < nRwy; j++) {
HIptr = static_cast<instr_item *>(new runway_instr(rwy_group->getChild(j)));
HUD_deque.insert(HUD_deque.begin(), HIptr);
}
}
return 0;
} //end readinstrument
int readHud( istream &input )
{
SGPropertyNode root;
try {
readProperties(input, &root);
} catch (const sg_exception &e) {
guiErrorMessage("Error reading HUD: ", e);
return 0;
}
SG_LOG(SG_INPUT, SG_DEBUG, "Read properties for " <<
root.getStringValue("name"));
if (!root.getNode("depreciated"))
SG_LOG(SG_INPUT, SG_ALERT, "WARNING: use of depreciated old HUD");
HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
SG_LOG(SG_INPUT, SG_DEBUG, "Reading Hud instruments");
const SGPropertyNode * instrument_group = root.getChild("instruments");
int nInstruments = instrument_group->nChildren();
for (int i = 0; i < nInstruments; i++) {
const SGPropertyNode * node = instrument_group->getChild(i);
SGPath path( globals->get_fg_root() );
path.append(node->getStringValue("path"));
SG_LOG(SG_INPUT, SG_DEBUG, "Reading Instrument "
<< node->getName()
<< " from "
<< path.str());
SGPropertyNode root2;
try {
readProperties(path.str(), &root2);
} catch (const sg_exception &e) {
guiErrorMessage("Error reading HUD instrument: ", e);
continue;
}
readInstrument(&root2);
}//for loop(i)
return 0;
}
// fgHUDInit
//
// Constructs a HUD object and then adds in instruments. At the present
// the instruments are hard coded into the routine. Ultimately these need
// to be defined by the aircraft's instrumentation records so that the
// display for a Piper Cub doesn't show the speed range of a North American
// mustange and the engine readouts of a B36!
//
int fgHUDInit()
{
HUD_style = 1;
SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
string hud_path =
fgGetString("/sim/hud/path", "Huds/Default/default.xml");
SGPath path(globals->get_fg_root());
path.append(hud_path);
ifstream input(path.c_str());
if (!input.good()) {
SG_LOG(SG_INPUT, SG_ALERT,
"Cannot read Hud configuration from " << path.str());
} else {
readHud(input);
input.close();
}
if ( HUDtext ) {
// this chunk of code is not necessarily thread safe if the
// compiler optimizer reorders these statements. Note that
// "delete ptr" does not set "ptr = NULL". We have to do that
// ourselves.
fntRenderer *tmp = HUDtext;
HUDtext = NULL;
delete tmp;
}
FGFontCache *fc = globals->get_fontcache();
const char* fileName = fgGetString("/sim/hud/font/name", "Helvetica.txf");
HUD_Font = fc->getTexFont(fileName);
if (!HUD_Font)
throw sg_io_exception("/sim/hud/font/name is not a texture font",
sg_location(fileName));
HUD_TextSize = fgGetFloat("/sim/hud/font/size", 10);
HUDtext = new fntRenderer();
HUDtext->setFont(HUD_Font);
HUDtext->setPointSize(HUD_TextSize);
HUD_TextList.setFont( HUDtext );
if (!HUDprop)
HUDprop = new HUD_Properties;
return 0; // For now. Later we may use this for an error code.
}
int fgHUDInit2()
{
HUD_style = 2;
SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
SGPath path(globals->get_fg_root());
path.append("Huds/Minimal/default.xml");
ifstream input(path.c_str());
if (!input.good()) {
SG_LOG(SG_INPUT, SG_ALERT,
"Cannot read Hud configuration from " << path.str());
} else {
readHud(input);
input.close();
}
if (!HUDprop)
HUDprop = new HUD_Properties;
return 0; // For now. Later we may use this for an error code.
}
//$$$ End - added, Neetha, 28 Nov 2k
// fgUpdateHUD
//
// Performs a once around the list of calls to instruments installed in
// the HUD object with requests for redraw. Kinda. It will when this is
// all C++.
//
void fgUpdateHUD( osg::State* state ) {
static const SGPropertyNode *enable3d_node = fgGetNode("/sim/hud/enable3d");
if ( HUD_style == 1 && enable3d_node->getBoolValue() ) {
fgUpdateHUDVirtual(state);
return;
}
static const float normal_aspect = float(640) / float(480);
// note: aspect_ratio is Y/X
float current_aspect = 1.0f/globals->get_current_view()->get_aspect_ratio();
if ( current_aspect > normal_aspect ) {
float aspect_adjust = current_aspect / normal_aspect;
float adjust = 320.0f*aspect_adjust - 320.0f;
fgUpdateHUD( state, -adjust, 0.0f, 640.0f+adjust, 480.0f );
} else {
float aspect_adjust = normal_aspect / current_aspect;
float adjust = 240.0f*aspect_adjust - 240.0f;
fgUpdateHUD( state, 0.0f, -adjust, 640.0f, 480.0f+adjust );
}
}
void fgUpdateHUDVirtual(osg::State* state)
{
using namespace osg;
FGViewer* view = globals->get_current_view();
// Standard fgfs projection, with essentially meaningless clip
// planes (we'll map the whole HUD plane to z=-1)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
Matrixf proj
= Matrixf::perspective(view->get_v_fov(), 1/view->get_aspect_ratio(),
0.1, 10);
glLoadMatrix(proj.ptr());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Standard fgfs view direction computation
Vec3f lookat;
lookat[0] = -sin(SG_DEGREES_TO_RADIANS * view->getHeadingOffset_deg());
lookat[1] = tan(SG_DEGREES_TO_RADIANS * view->getPitchOffset_deg());
lookat[2] = -cos(SG_DEGREES_TO_RADIANS * view->getHeadingOffset_deg());
if (fabs(lookat[1]) > 9999)
lookat[1] = 9999; // FPU sanity
Matrixf mv = Matrixf::lookAt(Vec3f(0.0, 0.0, 0.0), lookat,
Vec3f(0.0, 1.0, 0.0));
glLoadMatrix(mv.ptr());
// Map the -1:1 square to a 55.0x41.25 degree wide patch at z=1.
// This is the default fgfs field of view, which the HUD files are
// written to assume.
float dx = 0.52056705; // tan(55/2)
float dy = dx * 0.75; // assumes 4:3 aspect ratio
float m[16];
m[0] = dx; m[4] = 0; m[ 8] = 0; m[12] = 0;
m[1] = 0; m[5] = dy; m[ 9] = 0; m[13] = 0;
m[2] = 0; m[6] = 0; m[10] = 1; m[14] = 0;
m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;
glMultMatrixf(m);
// Convert the 640x480 "HUD standard" coordinate space to a square
// about the origin in the range [-1:1] at depth of -1
glScalef(1./320, 1./240, 1);
glTranslatef(-320, -240, -1);
// Do the deed
drawHUD(state);
// Clean up our mess
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void fgUpdateHUD( osg::State* state, GLfloat x_start, GLfloat y_start,
GLfloat x_end, GLfloat y_end )
{
using namespace osg;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
Matrixf proj = Matrixf::ortho2D(x_start, x_end, y_start, y_end);
glLoadMatrix(proj.ptr());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
drawHUD(state);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void drawHUD(osg::State* state)
{
if ( !HUD_deque.size() ) // Trust everyone, but ALWAYS cut the cards!
return;
HUD_TextList.erase();
HUD_LineList.erase();
// HUD_StippleLineList.erase();
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
static const SGPropertyNode *heading_enabled
= fgGetNode("/autopilot/locks/heading", true);
static const SGPropertyNode *altitude_enabled
= fgGetNode("/autopilot/locks/altitude", true);
static char hud_hdg_text[256];
static char hud_gps_text0[256];
static char hud_gps_text1[256];
static char hud_gps_text2[256];
static char hud_alt_text[256];
glEnable(GL_BLEND);
if (HUDprop->isTransparent())
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (HUDprop->isAntialiased()) {
glEnable(GL_LINE_SMOOTH);
glAlphaFunc(GL_GREATER, HUDprop->alphaClamp());
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
//glLineWidth(1.5);
} else {
//glLineWidth(1.0);
}
HUDprop->setColor();
for_each(HUD_deque.begin(), HUD_deque.end(), HUDdraw());
//HUD_TextList.add( fgText(40, 10, get_formated_gmt_time(), 0) );
int apY = 480 - 80;
if (strcmp( heading_enabled->getStringValue(), "dg-heading-hold") == 0 ) {
snprintf( hud_hdg_text, 256, "hdg = %.1f\n",
fgGetDouble("/autopilot/settings/heading-bug-deg") );
HUD_TextList.add( fgText( 40, apY, hud_hdg_text ) );
apY -= 15;
} else if ( strcmp(heading_enabled->getStringValue(), "true-heading-hold") == 0 ) {
snprintf( hud_hdg_text, 256, "hdg = %.1f\n",
fgGetDouble("/autopilot/settings/true-heading-deg") );
HUD_TextList.add( fgText( 40, apY, hud_hdg_text ) );
apY -= 15;
}
// GPS current waypoint information
SGPropertyNode_ptr gps = fgGetNode("/instrumentation/gps", true);
SGPropertyNode_ptr curWp = gps->getChild("wp")->getChild("wp",1);
if ((gps->getDoubleValue("raim") > 0.5) && curWp) {
// GPS is receiving a valid signal
snprintf(hud_gps_text0, 256, "WPT:%5s BRG:%03.0f %5.1fnm",
curWp->getStringValue("ID"),
curWp->getDoubleValue("bearing-mag-deg"),
curWp->getDoubleValue("distance-nm"));
HUD_TextList.add( fgText( 40, apY, hud_gps_text0 ) );
apY -= 15;
// curWp->getStringValue("TTW")
snprintf(hud_gps_text2, 256, "ETA %s", curWp->getStringValue("TTW"));
HUD_TextList.add( fgText( 40, apY, hud_gps_text2 ) );
apY -= 15;
double courseError = curWp->getDoubleValue("course-error-nm");
if (fabs(courseError) >= 0.01) {
// generate an arrow indicatinng if the pilot should turn left or right
char dir = (courseError < 0.0) ? '<' : '>';
snprintf(hud_gps_text1, 256, "GPS TRK:%03.0f XTRK:%c%4.2fnm",
gps->getDoubleValue("indicated-track-magnetic-deg"), dir, fabs(courseError));
} else { // on course, don't bother showing the XTRK error
snprintf(hud_gps_text1, 256, "GPS TRK:%03.0f",
gps->getDoubleValue("indicated-track-magnetic-deg"));
}
HUD_TextList.add( fgText( 40, apY, hud_gps_text1) );
apY -= 15;
} // of valid GPS output
////////////////////
if ( strcmp( altitude_enabled->getStringValue(), "altitude-hold" ) == 0 ) {
snprintf( hud_alt_text, 256, "alt = %.0f\n",
fgGetDouble("/autopilot/settings/target-altitude-ft") );
HUD_TextList.add( fgText( 40, apY, hud_alt_text ) );
apY -= 15;
} else if ( strcmp( altitude_enabled->getStringValue(), "agl-hold" ) == 0 ){
snprintf( hud_alt_text, 256, "agl = %.0f\n",
fgGetDouble("/autopilot/settings/target-agl-ft") );
HUD_TextList.add( fgText( 40, apY, hud_alt_text ) );
apY -= 15;
}
HUD_TextList.draw();
HUD_LineList.draw();
// glEnable(GL_LINE_STIPPLE);
// glLineStipple( 1, 0x00FF );
// HUD_StippleLineList.draw();
// glDisable(GL_LINE_STIPPLE);
if (HUDprop->isAntialiased()) {
glDisable(GL_ALPHA_TEST);
glDisable(GL_LINE_SMOOTH);
//glLineWidth(1.0);
}
if (HUDprop->isTransparent())
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}
void fgTextList::draw()
{
if (!Font)
return;
vector<fgText>::iterator curString = List.begin();
vector<fgText>::iterator lastString = List.end();
glPushAttrib(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
if (HUDprop->isTransparent())
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (HUDprop->isAntialiased()) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, HUDprop->alphaClamp());
}
Font->begin();
for (; curString != lastString; curString++)
curString->Draw(Font);
Font->end();
glDisable(GL_TEXTURE_2D);
glPopAttrib();
}
// HUD property listener class
//
HUD_Properties::HUD_Properties() :
_current(fgGetNode("/sim/hud/current-color", true)),
_visibility(fgGetNode("/sim/hud/visibility", true)),
_antialiasing(fgGetNode("/sim/hud/color/antialiased", true)),
_transparency(fgGetNode("/sim/hud/color/transparent", true)),
_red(fgGetNode("/sim/hud/color/red", true)),
_green(fgGetNode("/sim/hud/color/green", true)),
_blue(fgGetNode("/sim/hud/color/blue", true)),
_alpha(fgGetNode("/sim/hud/color/alpha", true)),
_alpha_clamp(fgGetNode("/sim/hud/color/alpha-clamp", true)),
_brightness(fgGetNode("/sim/hud/color/brightness", true)),
_visible(false),
_antialiased(false),
_transparent(false),
_a(0.67),
_cl(0.01)
{
_visibility->addChangeListener(this);
_antialiasing->addChangeListener(this);
_transparency->addChangeListener(this);
_red->addChangeListener(this);
_green->addChangeListener(this);
_blue->addChangeListener(this);
_alpha->addChangeListener(this);
_alpha_clamp->addChangeListener(this);
_brightness->addChangeListener(this);
_current->addChangeListener(this, true);
}
void HUD_Properties::valueChanged(SGPropertyNode *node)
{
if (!strcmp(node->getName(), "current-color")) {
int i = node->getIntValue();
if (i < 0)
i = 0;
SGPropertyNode *n = fgGetNode("/sim/hud/palette", true);
if ((n = n->getChild("color", i, false))) {
if (n->hasValue("red"))
_red->setFloatValue(n->getFloatValue("red", 1.0));
if (n->hasValue("green"))
_green->setFloatValue(n->getFloatValue("green", 1.0));
if (n->hasValue("blue"))
_blue->setFloatValue(n->getFloatValue("blue", 1.0));
if (n->hasValue("alpha"))
_alpha->setFloatValue(n->getFloatValue("alpha", 0.67));
if (n->hasValue("alpha-clamp"))
_alpha_clamp->setFloatValue(n->getFloatValue("alpha-clamp", 0.01));
if (n->hasValue("brightness"))
_brightness->setFloatValue(n->getFloatValue("brightness", 0.75));
if (n->hasValue("antialiased"))
_antialiasing->setBoolValue(n->getBoolValue("antialiased", false));
if (n->hasValue("transparent"))
_transparency->setBoolValue(n->getBoolValue("transparent", false));
}
}
_visible = _visibility->getBoolValue();
_transparent = _transparency->getBoolValue();
_antialiased = _antialiasing->getBoolValue();
float brt = _brightness->getFloatValue();
_r = clamp(brt * _red->getFloatValue());
_g = clamp(brt * _green->getFloatValue());
_b = clamp(brt * _blue->getFloatValue());
_a = clamp(_alpha->getFloatValue());
_cl = clamp(_alpha_clamp->getFloatValue());
}
void HUD_Properties::setColor() const
{
if (_antialiased)
glColor4f(_r, _g, _b, _a);
else
glColor3f(_r, _g, _b);
}

View file

@ -1,730 +0,0 @@
// hud.hxx -- hud defines and prototypes (initial draft)
//
// Written by Michele America, started September 1997.
//
// Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
//
// 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 _OLDHUD_HXX
#define _OLDHUD_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef __CYGWIN__
#include <ieeefp.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <algorithm> // for_each()
#include <vector> // STL vector
#include <deque> // STL double ended queue
#include <fstream>
namespace osg {
class State;
}
#include <simgear/math/SGMath.hxx>
#include <simgear/constants.h>
#include <Include/fg_typedefs.h>
#include <Aircraft/controls.hxx>
#include <FDM/flight.hxx>
#include <GUI/gui.h>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Main/viewmgr.hxx>
class FGRunway;
using std::deque;
using std::vector;
#define float_to_int(v) SGMiscf::roundToInt(v)
// some of Norman's crazy optimizations. :-)
#ifndef WIN32
typedef struct {
int x, y;
} POINT;
typedef struct {
int top, bottom, left, right;
} RECT;
#endif
// View mode definitions
enum VIEW_MODES{ HUD_VIEW, PANEL_VIEW, CHASE_VIEW, TOWER_VIEW };
// Label constants
#define HUD_FONT_SMALL 1
#define HUD_FONT_LARGE 2
enum fgLabelJust{ LEFT_JUST, CENTER_JUST, RIGHT_JUST } ;
#define HUDS_AUTOTICKS 0x0001
#define HUDS_VERT 0x0002
#define HUDS_HORZ 0x0000
#define HUDS_TOP 0x0004
#define HUDS_BOTTOM 0x0008
#define HUDS_LEFT HUDS_TOP
#define HUDS_RIGHT HUDS_BOTTOM
#define HUDS_BOTH (HUDS_LEFT | HUDS_RIGHT)
#define HUDS_NOTICKS 0x0010
#define HUDS_ARITHTIC 0x0020
#define HUDS_DECITICS 0x0040
#define HUDS_NOTEXT 0x0080
// in cockpit.cxx
extern float get_throttleval ( void );
extern float get_aileronval ( void );
extern float get_elevatorval ( void );
extern float get_elev_trimval( void );
extern float get_rudderval ( void );
extern float get_speed ( void );
extern float get_aoa ( void );
extern float get_nlf ( void );
extern float get_roll ( void );
extern float get_pitch ( void );
extern float get_heading ( void );
extern float get_view_direction( void );
extern float get_altitude ( void );
extern float get_agl ( void );
extern float get_sideslip ( void );
extern float get_frame_rate ( void );
extern float get_latitude ( void );
extern float get_lat_min ( void );
extern float get_longitude ( void );
extern float get_long_min ( void );
extern float get_fov ( void );
extern float get_vfc_ratio ( void );
extern float get_vfc_tris_drawn ( void );
extern float get_vfc_tris_culled ( void );
extern float get_climb_rate ( void );
extern float get_mach( void );
extern char *coord_format_lat(float);
extern char *coord_format_lon(float);
extern char *get_formated_gmt_time( void );
enum hudinstype{ HUDno_instr,
HUDscale,
HUDlabel,
HUDladder,
HUDcirc_ladder,
HUDhorizon,
HUDgauge,
HUDdual_inst,
HUDmoving_scale,
HUDtbi
};
typedef struct gltagRGBTRIPLE { // rgbt
GLfloat Blue;
GLfloat Green;
GLfloat Red;
} glRGBTRIPLE;
class fgLineSeg2D {
private:
GLfloat x0, y0, x1, y1;
public:
fgLineSeg2D( GLfloat a = 0, GLfloat b =0, GLfloat c = 0, GLfloat d =0 )
: x0(a), y0(b), x1(c), y1(d) {}
fgLineSeg2D( const fgLineSeg2D & image )
: x0(image.x0), y0(image.y0), x1(image.x1), y1(image.y1) {}
fgLineSeg2D& operator= ( const fgLineSeg2D & image ) { // seems unused
x0 = image.x0; y0 = image.y0; x1 = image.x1; y1 = image.y1; return *this;
}
void draw() const
{
glVertex2f(x0, y0);
glVertex2f(x1, y1);
}
};
class DrawLineSeg2D {
public:
void operator() (const fgLineSeg2D& elem) const {
elem.draw();
}
};
#define USE_HUD_TextList
extern fntTexFont *HUD_Font;
extern float HUD_TextSize;
extern fntRenderer *HUDtext;
extern float HUD_matrix[16];
class fgText {
private:
float x, y;
string msg;
bool digit;
// seems unused
public:
fgText(float x, float y, const string& c, bool digits=false): x(x), y(y), msg( c), digit( digits) {};
fgText( const fgText & image )
: x(image.x), y(image.y), msg(image.msg), digit(image.digit) { }
fgText& operator = ( const fgText & image ) {
x = image.x; y = image.y; msg= image.msg; digit = image.digit;
return *this;
}
static int getStringWidth ( const char *str )
{
if ( HUDtext && str ) {
float r, l ;
HUD_Font->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
return float_to_int( r - l );
}
return 0 ;
}
int StringWidth ()
{
if ( HUDtext && msg != "") {
float r, l ;
HUD_Font->getBBox ( msg.c_str(), HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
return float_to_int( r - l );
}
return 0 ;
}
// this code is changed to display Numbers with big/small digits
// according to MIL Standards for example Altitude above 10000 ft
// is shown as 10ooo.
void Draw(fntRenderer *fnt) {
if (digit) {
int c=0;
int p=4;
if (msg[0]=='-') {
//if negative value then increase the c and p values
//for '-' sign. c++;
p++;
}
for (string::size_type i = 0; i < msg.size(); i++) {
if ((msg[i]>='0') && (msg[i]<='9'))
c++;
}
float orig_size = fnt->getPointSize();
if (c>p) {
fnt->setPointSize(HUD_TextSize * 0.8);
int p2=(c-3)*8; //advance to the last 3 digits
fnt->start2f(x+p2,y);
fnt->puts(msg.c_str() + c - 3); // display last 3 digits
fnt->setPointSize(HUD_TextSize * 1.2);
fnt->start2f(x,y);
fnt->puts(msg.substr(0,c-3).c_str());
} else {
fnt->setPointSize(HUD_TextSize * 1.2);
fnt->start2f( x, y );
fnt->puts(msg.c_str());
}
fnt->setPointSize(orig_size);
} else {
//if digits not true
fnt->start2f( x, y );
fnt->puts( msg.c_str()) ;
}
}
void Draw()
{
guiFnt.drawString( msg.c_str(), float_to_int(x), float_to_int(y) );
}
};
class fgLineList {
vector < fgLineSeg2D > List;
public:
fgLineList( void ) {}
void add( const fgLineSeg2D& seg ) { List.push_back(seg); }
void erase( void ) { List.clear();}
void draw( void ) {
glBegin(GL_LINES);
for_each( List.begin(), List.end(), DrawLineSeg2D());
glEnd();
}
};
class fgTextList {
fntRenderer *Font;
vector< fgText > List;
public:
fgTextList ( void ) { Font = 0; }
void setFont( fntRenderer *Renderer ) { Font = Renderer; }
void add( const fgText& String ) { List.push_back(String); }
void erase( void ) { List.clear(); }
void draw( void );
};
inline void Text( fgTextList &List, float x, float y, char *s)
{
List.add( fgText( x, y, s) );
}
inline void Text( fgTextList &List, const fgText &me)
{
List.add(me);
}
inline void Line( fgLineList &List, float x1, float y1, float x2, float y2)
{
List.add(fgLineSeg2D(x1,y1,x2,y2));
}
// Declare our externals
extern fgTextList HUD_TextList;
extern fgLineList HUD_LineList;
extern fgLineList HUD_StippleLineList;
class instr_item : public SGReferenced { // An Abstract Base Class (ABC)
private:
static UINT instances; // More than 64K instruments? Nah!
static int brightness;
static glRGBTRIPLE color;
UINT handle;
RECT scrn_pos; // Framing - affects scale dimensions
// and orientation. Vert vs Horz, etc.
FLTFNPTR load_value_fn;
float disp_factor; // Multiply by to get numbers shown on scale.
UINT opts;
bool is_enabled;
bool broken;
UINT scr_span; // Working values for draw;
POINT mid_span; //
int digits;
public:
instr_item( int x,
int y,
UINT height,
UINT width,
FLTFNPTR data_source,
float data_scaling,
UINT options,
bool working = true,
int digit = 0);
virtual ~instr_item ();
void set_data_source ( FLTFNPTR fn ) { load_value_fn = fn; }
int get_brightness ( void ) { return brightness;}
RECT get_location ( void ) { return scrn_pos; }
bool is_broken ( void ) { return broken; }
bool enabled ( void ) { return is_enabled;}
bool data_available ( void ) { return !!load_value_fn; }
float get_value ( void ) { return load_value_fn(); }
float data_scaling ( void ) { return disp_factor; }
UINT get_span ( void ) { return scr_span; }
POINT get_centroid ( void ) { return mid_span; }
UINT get_options ( void ) { return opts; }
int get_digits ( void ) { return digits; }
inline int get_x() const { return scrn_pos.left; }
inline int get_y() const { return scrn_pos.top; }
inline int get_width() const { return scrn_pos.right; }
inline int get_height() const { return scrn_pos.bottom; }
UINT huds_vert (UINT options) { return (options & HUDS_VERT); }
UINT huds_left (UINT options) { return (options & HUDS_LEFT); }
UINT huds_right (UINT options) { return (options & HUDS_RIGHT); }
UINT huds_both (UINT options) {
return ((options & HUDS_BOTH) == HUDS_BOTH);
}
UINT huds_noticks (UINT options) { return (options & HUDS_NOTICKS); }
UINT huds_notext (UINT options) { return (options & HUDS_NOTEXT); }
UINT huds_top (UINT options) { return (options & HUDS_TOP); }
UINT huds_bottom (UINT options) { return (options & HUDS_BOTTOM); }
virtual void display_enable( bool working ) { is_enabled = working;}
virtual void break_display ( bool bad );
virtual void SetBrightness( int illumination_level ); // fgHUDSetBright...
void SetPosition ( int x, int y, UINT width, UINT height );
UINT get_Handle( void );
virtual void draw( void ) = 0; // Required method in derived classes
void drawOneLine( float x1, float y1, float x2, float y2)
{
HUD_LineList.add(fgLineSeg2D(x1,y1,x2,y2));
}
void drawOneStippleLine( float x1, float y1, float x2, float y2)
{
HUD_StippleLineList.add(fgLineSeg2D(x1,y1,x2,y2));
}
void TextString( char *msg, float x, float y, bool digit )
{
HUD_TextList.add(fgText(x, y, msg,digit));
}
int getStringWidth ( char *str )
{
if ( HUDtext && str ) {
float r, l ;
HUD_Font->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
return float_to_int( r - l );
}
return 0 ;
}
};
typedef instr_item *HIptr;
class HUDdraw {
public:
void operator() (HIptr elem) const {
if ( elem->enabled())
elem->draw();
}
};
extern int HUD_style;
// instr_item This class has no other purpose than to maintain
// a linked list of instrument and derived class
// object pointers.
class instr_label : public instr_item {
private:
const char *pformat;
fgLabelJust justify;
int fontSize;
int blink;
string format_buffer;
bool lat;
bool lon;
bool lbox;
SGPropertyNode_ptr lon_node;
SGPropertyNode_ptr lat_node;
public:
instr_label(const SGPropertyNode *);
virtual void draw(void);
};
//
// fgRunway_instr This class is responsible for rendering the active runway
// in the hud (if visible).
class runway_instr : public instr_item {
private:
void boundPoint(const sgdVec3& v, sgdVec3& m);
bool boundOutsidePoints(sgdVec3& v, sgdVec3& m);
bool drawLine(const sgdVec3& a1, const sgdVec3& a2,
const sgdVec3& p1, const sgdVec3& p2);
void drawArrow();
FGRunway* get_active_runway();
void get_rwy_points(sgdVec3 *points);
void setLineWidth(void);
sgdVec3 points3d[6], points2d[6];
double mm[16],pm[16], arrowScale, arrowRad, lnScale;
double scaleDist, default_pitch, default_heading;
GLint view[4];
FGRunway* runway;
FGViewer* cockpit_view;
unsigned short stippleOut, stippleCen;
bool drawIA, drawIAAlways;
RECT location;
POINT center;
public:
runway_instr(const SGPropertyNode *);
virtual void draw( void );
void setArrowRotationRadius(double radius);
// Scales the runway indication arrow
void setArrowScale(double scale);
// Draws arrow when runway is not visible in HUD if draw=true
void setDrawArrow(bool draw);
// Always draws arrow if draw=true;
void setDrawArrowAlways(bool draw);
// Sets the maximum line scale
void setLineScale(double scale);
// Sets the distance where to start scaling the lines
void setScaleDist(double dist_nm);
// Sets the stipple pattern of the outline of the runway
void setStippleOutline(unsigned short stipple);
// Sets the stipple patter of the center line of the runway
void setStippleCenterline(unsigned short stipple);
};
//
// instr_scale This class is an abstract base class for both moving
// scale and moving needle (fixed scale) indicators. It
// does not draw itself, but is not instanciable.
//
class instr_scale : public instr_item {
private:
float range_shown; // Width Units.
float Maximum_value; // ceiling.
float Minimum_value; // Representation floor.
float scale_factor; // factor => screen units/range values.
UINT Maj_div; // major division marker units
UINT Min_div; // minor division marker units
UINT Modulo; // Roll over point
int signif_digits; // digits to show to the right.
public:
instr_scale( int x,
int y,
UINT width,
UINT height,
FLTFNPTR load_fn,
UINT options,
float show_range,
float max_value,
float min_value,
float disp_scaling,
UINT major_divs,
UINT minor_divs,
UINT rollover,
int dp_showing,
bool working = true);
virtual void draw ( void ) {}; // No-op here. Defined in derived classes.
UINT div_min ( void ) { return Min_div;}
UINT div_max ( void ) { return Maj_div;}
float min_val ( void ) { return Minimum_value;}
float max_val ( void ) { return Maximum_value;}
UINT modulo ( void ) { return Modulo; }
float factor ( void ) { return scale_factor;}
float range_to_show ( void ) { return range_shown;}
};
// hud_card This class displays the indicated quantity on
// a scale that moves past the pointer. It may be
// horizontal or vertical, read above(left) or below(right) of the base
// line.
class hud_card : public instr_scale {
private:
float val_span;
string type;
float half_width_units;
bool draw_tick_bottom;
bool draw_tick_top;
bool draw_tick_right;
bool draw_tick_left;
bool draw_cap_bottom;
bool draw_cap_top;
bool draw_cap_right;
bool draw_cap_left;
float marker_offset;
bool pointer;
string pointer_type;
string tick_type;
string tick_length;
float radius;
float maxValue;
float minValue;
int divisions;
int zoom;
UINT Maj_div;
UINT Min_div;
public:
hud_card(const SGPropertyNode *);
// virtual void display_enable( bool setting ); // FIXME
virtual void draw(void);
void circles(float, float, float);
void fixed(float, float, float, float, float, float);
void zoomed_scale(int, int);
};
class gauge_instr : public instr_scale {
public:
gauge_instr(const SGPropertyNode *);
virtual void draw( void ); // Required method in base class
};
//
// dual_instr_item This class was created to form the base class
// for both panel and HUD Turn Bank Indicators.
class dual_instr_item : public instr_item {
private:
FLTFNPTR alt_data_source;
public:
dual_instr_item ( int x,
int y,
UINT width,
UINT height,
FLTFNPTR chn1_source,
FLTFNPTR chn2_source,
bool working,
UINT options );
float current_ch1( void ) { return (float)alt_data_source(); }
float current_ch2( void ) { return (float)get_value(); }
virtual void draw( void ) {}
};
class fgTBI_instr : public dual_instr_item {
private:
UINT BankLimit;
UINT SlewLimit;
UINT scr_hole;
bool tsi;
float rad;
public:
fgTBI_instr(const SGPropertyNode *);
UINT bank_limit(void) { return BankLimit; }
UINT slew_limit(void) { return SlewLimit; }
virtual void draw(void);
};
class HudLadder : public dual_instr_item {
private:
UINT width_units;
int div_units;
UINT minor_div;
UINT label_pos;
UINT scr_hole;
float vmax;
float vmin;
float factor;
string hudladder_type;
bool frl;
bool target_spot;
bool velocity_vector;
bool drift_marker;
bool alpha_bracket;
bool energy_marker;
bool climb_dive_marker;
bool glide_slope_marker;
float glide_slope;
bool energy_worm;
bool waypoint_marker;
int zenith;
int nadir;
int hat;
// The Ladder has it's own temporary display lists
fgTextList TextList;
fgLineList LineList;
fgLineList StippleLineList;
public:
HudLadder(const SGPropertyNode *);
virtual void draw(void);
void drawZenith(float, float, float);
void drawNadir(float, float, float);
void Text(float x, float y, char *s)
{
TextList.add(fgText(x, y, s));
}
void Line(float x1, float y1, float x2, float y2)
{
LineList.add(fgLineSeg2D(x1, y1, x2, y2));
}
void StippleLine(float x1, float y1, float x2, float y2)
{
StippleLineList.add(fgLineSeg2D(x1, y1, x2, y2));
}
};
extern int fgHUDInit();
extern int fgHUDInit2();
extern void fgUpdateHUD( osg::State* );
extern void fgUpdateHUD( osg::State*, GLfloat x_start, GLfloat y_start,
GLfloat x_end, GLfloat y_end );
class HUD_Properties : public SGPropertyChangeListener {
public:
HUD_Properties();
void valueChanged(SGPropertyNode *n);
void setColor() const;
bool isVisible() const { return _visible; }
bool isAntialiased() const { return _antialiased; }
bool isTransparent() const { return _transparent; }
float alphaClamp() const { return _cl; }
private:
float clamp(float f) { return f < 0.0f ? 0.0f : f > 1.0f ? 1.0f : f; }
SGPropertyNode_ptr _current;
SGPropertyNode_ptr _visibility;
SGPropertyNode_ptr _antialiasing;
SGPropertyNode_ptr _transparency;
SGPropertyNode_ptr _red, _green, _blue, _alpha;
SGPropertyNode_ptr _alpha_clamp;
SGPropertyNode_ptr _brightness;
bool _visible;
bool _antialiased;
bool _transparent;
float _r, _g, _b, _a, _cl;
};
#endif // _OLDHUD_H

File diff suppressed because it is too large Load diff

View file

@ -1,19 +0,0 @@
#include "hud.hxx"
dual_instr_item::dual_instr_item(
int x,
int y,
UINT width,
UINT height,
FLTFNPTR chn1_source,
FLTFNPTR chn2_source,
bool working,
UINT options) :
instr_item(x, y, width, height,
chn1_source, 1, options, working),
alt_data_source(chn2_source)
{
}

View file

@ -1,293 +0,0 @@
#include "hud.hxx"
#ifdef USE_HUD_TextList
#define textString(x, y, text, digit) TextString(text, x , y ,digit)
#else
#define textString(x, y, text, digit) puDrawString(guiFnt, text, x, y)
#endif
FLTFNPTR get_func(const char *name); // FIXME
gauge_instr::gauge_instr(const SGPropertyNode *node) :
instr_scale(
node->getIntValue("x"),
node->getIntValue("y"),
node->getIntValue("width"),
node->getIntValue("height"),
0 /*load_fn*/,
node->getIntValue("options"),
node->getFloatValue("maxValue") - node->getFloatValue("minValue"), // Always shows span?
node->getFloatValue("maxValue"),
node->getFloatValue("minValue"),
node->getFloatValue("disp_scaling"),
node->getIntValue("major_divs"),
node->getIntValue("minor_divs"),
node->getIntValue("modulator"), // "rollover"
0, /* hud.cxx: static int dp_shoing = 0; */ // FIXME
node->getBoolValue("working", true))
{
SG_LOG(SG_INPUT, SG_BULK, "Done reading gauge instrument "
<< node->getStringValue("name", "[unnamed]"));
set_data_source(get_func(node->getStringValue("loadfn")));
}
// As implemented, draw only correctly draws a horizontal or vertical
// scale. It should contain a variation that permits clock type displays.
// Now is supports "tickless" displays such as control surface indicators.
// This routine should be worked over before using. Current value would be
// fetched and not used if not commented out. Clearly that is intollerable.
void gauge_instr::draw(void)
{
float marker_xs, marker_xe;
float marker_ys, marker_ye;
int text_x, text_y;
int width, height, bottom_4;
int lenstr;
int i;
char TextScale[80];
bool condition;
int disp_val = 0;
float vmin = min_val();
float vmax = max_val();
POINT mid_scr = get_centroid();
float cur_value = get_value();
RECT scrn_rect = get_location();
UINT options = get_options();
width = scrn_rect.left + scrn_rect.right;
height = scrn_rect.top + scrn_rect.bottom;
bottom_4 = scrn_rect.bottom / 4;
// Draw the basic markings for the scale...
if (huds_vert(options)) { // Vertical scale
// Bottom tick bar
drawOneLine(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
// Top tick bar
drawOneLine( scrn_rect.left, height, width, height);
marker_xs = scrn_rect.left;
marker_xe = width;
if (huds_left(options)) { // Read left, so line down right side
drawOneLine(width, scrn_rect.top, width, height);
marker_xs = marker_xe - scrn_rect.right / 3.0; // Adjust tick
}
if (huds_right(options)) { // Read right, so down left sides
drawOneLine(scrn_rect.left, scrn_rect.top, scrn_rect.left, height);
marker_xe = scrn_rect.left + scrn_rect.right / 3.0; // Adjust tick
}
// At this point marker x_start and x_end values are transposed.
// To keep this from confusing things they are now interchanged.
if (huds_both(options)) {
marker_ye = marker_xs;
marker_xs = marker_xe;
marker_xe = marker_ye;
}
// Work through from bottom to top of scale. Calculating where to put
// minor and major ticks.
if (!huds_noticks(options)) { // If not no ticks...:)
// Calculate x marker offsets
int last = (int)vmax + 1; // float_to_int(vmax)+1;
i = (int)vmin; //float_to_int(vmin);
for (; i < last; i++) {
// Calculate the location of this tick
marker_ys = scrn_rect.top + (i - vmin) * factor()/* +.5f*/;
// We compute marker_ys even though we don't know if we will use
// either major or minor divisions. Simpler.
if (div_min()) { // Minor tick marks
if (!(i % (int)div_min())) {
if (huds_left(options) && huds_right(options)) {
drawOneLine(scrn_rect.left, marker_ys, marker_xs - 3, marker_ys);
drawOneLine(marker_xe + 3, marker_ys, width, marker_ys);
} else if (huds_left(options)) {
drawOneLine(marker_xs + 3, marker_ys, marker_xe, marker_ys);
} else {
drawOneLine(marker_xs, marker_ys, marker_xe - 3, marker_ys);
}
}
}
// Now we work on the major divisions. Since these are also labeled
// and no labels are drawn otherwise, we label inside this if
// statement.
if (div_max()) { // Major tick mark
if (!(i % (int)div_max())) {
if (huds_left(options) && huds_right(options)) {
drawOneLine(scrn_rect.left, marker_ys, marker_xs, marker_ys);
drawOneLine(marker_xe, marker_ys, width, marker_ys);
} else {
drawOneLine(marker_xs, marker_ys, marker_xe, marker_ys);
}
if (!huds_notext(options)) {
disp_val = i;
sprintf(TextScale, "%d",
float_to_int(disp_val * data_scaling()/*+.5*/));
lenstr = getStringWidth(TextScale);
if (huds_left(options) && huds_right(options)) {
text_x = mid_scr.x - lenstr/2 ;
} else if (huds_left(options)) {
text_x = float_to_int(marker_xs - lenstr);
} else {
text_x = float_to_int(marker_xe - lenstr);
}
// Now we know where to put the text.
text_y = float_to_int(marker_ys);
textString(text_x, text_y, TextScale, 0);
}
}
}
}
}
// Now that the scale is drawn, we draw in the pointer(s). Since labels
// have been drawn, text_x and text_y may be recycled. This is used
// with the marker start stops to produce a pointer for each side reading
text_y = scrn_rect.top + float_to_int((cur_value - vmin) * factor() /*+.5f*/);
// text_x = marker_xs - scrn_rect.left;
if (huds_right(options)) {
glBegin(GL_LINE_STRIP);
glVertex2f(scrn_rect.left, text_y + 5);
glVertex2f(float_to_int(marker_xe), text_y);
glVertex2f(scrn_rect.left, text_y - 5);
glEnd();
}
if (huds_left(options)) {
glBegin(GL_LINE_STRIP);
glVertex2f(width, text_y + 5);
glVertex2f(float_to_int(marker_xs), text_y);
glVertex2f(width, text_y - 5);
glEnd();
}
// End if VERTICAL SCALE TYPE
} else { // Horizontal scale by default
// left tick bar
drawOneLine(scrn_rect.left, scrn_rect.top, scrn_rect.left, height);
// right tick bar
drawOneLine(width, scrn_rect.top, width, height );
marker_ys = scrn_rect.top; // Starting point for
marker_ye = height; // tick y location calcs
marker_xs = scrn_rect.left + (cur_value - vmin) * factor() /*+ .5f*/;
if (huds_top(options)) {
// Bottom box line
drawOneLine(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
marker_ye = scrn_rect.top + scrn_rect.bottom / 2.0; // Tick point adjust
// Bottom arrow
glBegin(GL_LINE_STRIP);
glVertex2f(marker_xs - bottom_4, scrn_rect.top);
glVertex2f(marker_xs, marker_ye);
glVertex2f(marker_xs + bottom_4, scrn_rect.top);
glEnd();
}
if (huds_bottom(options)) {
// Top box line
drawOneLine(scrn_rect.left, height, width, height);
// Tick point adjust
marker_ys = height - scrn_rect.bottom / 2.0;
// Top arrow
glBegin(GL_LINE_STRIP);
glVertex2f(marker_xs + bottom_4, height);
glVertex2f(marker_xs, marker_ys );
glVertex2f(marker_xs - bottom_4, height);
glEnd();
}
int last = (int)vmax + 1; //float_to_int(vmax)+1;
i = (int)vmin; //float_to_int(vmin);
for (; i <last ; i++) {
condition = true;
if (!modulo() && i < min_val())
condition = false;
if (condition) {
marker_xs = scrn_rect.left + (i - vmin) * factor()/* +.5f*/;
// marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5f);
if (div_min()) {
if (!(i % (int)div_min())) {
// draw in ticks only if they aren't too close to the edge.
if (((marker_xs + 5) > scrn_rect.left)
|| ((marker_xs - 5) < (width))) {
if (huds_both(options)) {
drawOneLine(marker_xs, scrn_rect.top, marker_xs, marker_ys - 4);
drawOneLine(marker_xs, marker_ye + 4, marker_xs, height);
} else if (huds_top(options)) {
drawOneLine(marker_xs, marker_ys, marker_xs, marker_ye - 4);
} else {
drawOneLine(marker_xs, marker_ys + 4, marker_xs, marker_ye);
}
}
}
}
if (div_max()) {
if (!(i % (int)div_max())) {
if (modulo()) {
if (disp_val < 0) {
while (disp_val < 0)
disp_val += modulo();
}
disp_val = i % (int)modulo();
} else {
disp_val = i;
}
sprintf(TextScale, "%d",
float_to_int(disp_val * data_scaling()/* +.5*/));
lenstr = getStringWidth(TextScale);
// Draw major ticks and text only if far enough from the edge.
if (((marker_xs - 10) > scrn_rect.left)
&& ((marker_xs + 10) < width)) {
if (huds_both(options)) {
drawOneLine(marker_xs, scrn_rect.top, marker_xs, marker_ys);
drawOneLine(marker_xs, marker_ye, marker_xs, height);
if (!huds_notext(options))
textString(marker_xs - lenstr, marker_ys + 4, TextScale, 0);
} else {
drawOneLine(marker_xs, marker_ys, marker_xs, marker_ye);
if (!huds_notext(options)) {
if (huds_top(options))
textString(marker_xs - lenstr, height - 10, TextScale, 0);
else
textString(marker_xs - lenstr, scrn_rect.top, TextScale, 0);
}
}
}
}
}
}
}
}
}

View file

@ -1,93 +0,0 @@
#include "hud.hxx"
UINT instr_item :: instances = 0; // Initial value of zero
int instr_item :: brightness = 5;/*HUD_BRT_MEDIUM*/
//glRGBTRIPLE instr_item :: color = {0.1, 0.7, 0.0};
glRGBTRIPLE instr_item :: color = {0.0, 1.0, 0.0};
// constructor ( No default provided )
instr_item::instr_item(
int x,
int y,
UINT width,
UINT height,
FLTFNPTR data_source,
float data_scaling,
UINT options,
bool working,
int digit) :
handle ( ++instances ),
load_value_fn ( data_source ),
disp_factor ( data_scaling ),
opts ( options ),
is_enabled ( working ),
broken ( FALSE ),
digits ( digit )
{
scrn_pos.left = x;
scrn_pos.top = y;
scrn_pos.right = width;
scrn_pos.bottom = height;
// Set up convenience values for centroid of the box and
// the span values according to orientation
if (opts & HUDS_VERT) { // Vertical style
// Insure that the midpoint marker will fall exactly at the
// middle of the bar.
if (!(scrn_pos.bottom % 2))
scrn_pos.bottom++;
scr_span = scrn_pos.bottom;
} else {
// Insure that the midpoint marker will fall exactly at the
// middle of the bar.
if (!(scrn_pos.right % 2))
scrn_pos.right++;
scr_span = scrn_pos.right;
}
// Here we work out the centroid for the corrected box.
mid_span.x = scrn_pos.left + (scrn_pos.right >> 1);
mid_span.y = scrn_pos.top + (scrn_pos.bottom >> 1);
}
instr_item::~instr_item ()
{
if (instances)
instances--;
}
// break_display This is emplaced to provide hooks for making
// instruments unreliable. The default behavior is
// to simply not display, but more sophisticated behavior is available
// by over riding the function which is virtual in this class.
void instr_item::break_display ( bool bad )
{
broken = !!bad;
is_enabled = FALSE;
}
void instr_item::SetBrightness ( int level )
{
brightness = level; // This is all we will do for now. Later the
// brightness levels will be sensitive both to
// the control knob and the outside light levels
// to emulated night vision effects.
}
UINT instr_item::get_Handle( void )
{
return handle;
}

View file

@ -1,145 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "hud.hxx"
#ifdef USE_HUD_TextList
#define textString(x, y, text, digit) TextString(text, x , y ,digit)
#else
#define textString(x, y, text, digit) puDrawString(guiFnt, text, x, y)
#endif
FLTFNPTR get_func(const char *name); // FIXME
instr_label::instr_label(const SGPropertyNode *node) :
instr_item(
node->getIntValue("x"),
node->getIntValue("y"),
node->getIntValue("width"),
node->getIntValue("height"),
NULL /* node->getStringValue("data_source") */, // FIXME
node->getFloatValue("scale_data"),
node->getIntValue("options"),
node->getBoolValue("working", true),
node->getIntValue("digits")),
pformat(node->getStringValue("label_format")),
fontSize(fgGetInt("/sim/startup/xsize") > 1000 ? HUD_FONT_LARGE : HUD_FONT_SMALL), // FIXME
blink(node->getIntValue("blinking")),
lat(node->getBoolValue("latitude", false)),
lon(node->getBoolValue("longitude", false)),
lbox(node->getBoolValue("label_box", false)),
lon_node(fgGetNode("/position/longitude-string", true)),
lat_node(fgGetNode("/position/latitude-string", true))
{
SG_LOG(SG_INPUT, SG_BULK, "Done reading instr_label instrument "
<< node->getStringValue("name", "[unnamed]"));
set_data_source(get_func(node->getStringValue("data_source")));
int just = node->getIntValue("justification");
if (just == 0)
justify = LEFT_JUST;
else if (just == 1)
justify = CENTER_JUST;
else if (just == 2)
justify = RIGHT_JUST;
string pre_str(node->getStringValue("pre_label_string"));
if (pre_str== "NULL")
pre_str.clear();
else if (pre_str == "blank")
pre_str = " ";
const char *units = strcmp(fgGetString("/sim/startup/units"), "feet") ? " m" : " ft"; // FIXME
string post_str(node->getStringValue("post_label_string"));
if (post_str== "NULL")
post_str.clear();
else if (post_str == "blank")
post_str = " ";
else if (post_str == "units")
post_str = units;
format_buffer = pre_str + pformat;
format_buffer += post_str;
}
void instr_label::draw(void)
{
char label_buffer[80];
int posincr;
int lenstr;
RECT scrn_rect = get_location();
memset( label_buffer, 0, sizeof( label_buffer));
if (data_available()) {
if (lat)
snprintf(label_buffer, sizeof( label_buffer)-1, format_buffer.c_str(), lat_node->getStringValue());
else if (lon)
snprintf(label_buffer, sizeof( label_buffer)-1, format_buffer.c_str(), lon_node->getStringValue());
else {
if (lbox) {// Box for label
float x = scrn_rect.left;
float y = scrn_rect.top;
float w = scrn_rect.right;
float h = HUD_TextSize;
glPushMatrix();
glLoadIdentity();
glBegin(GL_LINES);
glVertex2f(x - 2.0, y - 2.0);
glVertex2f(x + w + 2.0, y - 2.0);
glVertex2f(x + w + 2.0, y + h + 2.0);
glVertex2f(x - 2.0, y + h + 2.0);
glEnd();
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0xAAAA);
glBegin(GL_LINES);
glVertex2f(x + w + 2.0, y - 2.0);
glVertex2f(x + w + 2.0, y + h + 2.0);
glVertex2f(x - 2.0, y + h + 2.0);
glVertex2f(x - 2.0, y - 2.0);
glEnd();
glDisable(GL_LINE_STIPPLE);
glPopMatrix();
}
snprintf(label_buffer, sizeof(label_buffer)-1, format_buffer.c_str(), get_value() * data_scaling());
}
} else {
snprintf(label_buffer, sizeof( label_buffer)-1, format_buffer.c_str(), 0);
}
lenstr = getStringWidth(label_buffer);
#ifdef DEBUGHUD
fgPrintf( SG_COCKPIT, SG_DEBUG, format_buffer);
fgPrintf( SG_COCKPIT, SG_DEBUG, "\n");
fgPrintf( SG_COCKPIT, SG_DEBUG, label_buffer);
fgPrintf( SG_COCKPIT, SG_DEBUG, "\n");
#endif
lenstr = strlen(label_buffer);
if (justify == RIGHT_JUST)
posincr = scrn_rect.right - lenstr;
else if (justify == CENTER_JUST)
posincr = get_span() - (lenstr / 2); // -lenstr*4;
else // justify == LEFT_JUST
posincr = 0;
if (fontSize == HUD_FONT_SMALL) {
textString(scrn_rect.left + posincr, scrn_rect.top,
label_buffer, get_digits());
} else if (fontSize == HUD_FONT_LARGE) {
textString(scrn_rect.left + posincr, scrn_rect.top,
label_buffer, get_digits());
}
}

View file

@ -1,785 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/constants.h>
#include "hud.hxx"
#include "panel.hxx"
#include <Main/viewer.hxx>
// FIXME
extern float get_roll(void);
extern float get_pitch(void);
HudLadder::HudLadder(const SGPropertyNode *node) :
dual_instr_item(
node->getIntValue("x"),
node->getIntValue("y"),
node->getIntValue("width"),
node->getIntValue("height"),
get_roll,
get_pitch, // FIXME getter functions from cockpit.cxx
node->getBoolValue("working", true),
HUDS_RIGHT),
width_units(int(node->getFloatValue("span_units"))),
div_units(int(fabs(node->getFloatValue("division_units")))),
minor_div(0 /* hud.cxx: static float minor_division = 0 */),
label_pos(node->getIntValue("lbl_pos")),
scr_hole(node->getIntValue("screen_hole")),
factor(node->getFloatValue("compression_factor")),
hudladder_type(node->getStringValue("name")),
frl(node->getBoolValue("enable_frl", false)),
target_spot(node->getBoolValue("enable_target_spot", false)),
velocity_vector(node->getBoolValue("enable_velocity_vector", false)),
drift_marker(node->getBoolValue("enable_drift_marker", false)),
alpha_bracket(node->getBoolValue("enable_alpha_bracket", false)),
energy_marker(node->getBoolValue("enable_energy_marker", false)),
climb_dive_marker(node->getBoolValue("enable_climb_dive_marker", false)),
glide_slope_marker(node->getBoolValue("enable_glide_slope_marker",false)),
glide_slope(node->getFloatValue("glide_slope", -4.0)),
energy_worm(node->getBoolValue("enable_energy_marker", false)),
waypoint_marker(node->getBoolValue("enable_waypoint_marker", false)),
zenith(node->getIntValue("zenith")),
nadir(node->getIntValue("nadir")),
hat(node->getIntValue("hat"))
{
// The factor assumes a base of 55 degrees per 640 pixels.
// Invert to convert the "compression" factor to a
// pixels-per-degree number.
if (fgGetBool("/sim/hud/enable3d", true) && HUD_style == 1)
factor = 640.0 / 55.0;
SG_LOG(SG_INPUT, SG_BULK, "Done reading HudLadder instrument"
<< node->getStringValue("name", "[unnamed]"));
if (!width_units)
width_units = 45;
vmax = width_units / 2;
vmin = -vmax;
}
//
// Draws a climb ladder in the center of the HUD
//
void HudLadder::draw(void)
{
float x_ini, x_ini2;
float x_end, x_end2;
float y = 0;
int count;
float cosine, sine, xvvr, yvvr, Vxx = 0.0, Vyy = 0.0, Vzz = 0.0;
float up_vel, ground_vel, actslope = 0.0;
float Axx = 0.0, Ayy = 0.0, Azz = 0.0, total_vel = 0.0, pot_slope, t1;
float t2 = 0.0, psi = 0.0, alpha, pla;
float vel_x = 0.0, vel_y = 0.0, drift;
bool pitch_ladder = false;
bool climb_dive_ladder = false;
bool clip_plane = false;
GLdouble eqn_top[4] = {0.0, -1.0, 0.0, 0.0};
GLdouble eqn_left[4] = {-1.0, 0.0, 0.0, 100.0};
GLdouble eqn_right[4] = {1.0, 0.0, 0.0, 100.0};
POINT centroid = get_centroid();
RECT box = get_location();
float half_span = box.right / 2.0;
float roll_value = current_ch2();
alpha = get_aoa();
pla = get_throttleval();
#ifdef ENABLE_SP_FDM
int lgear, wown, wowm, ilcanclaw, ihook;
ilcanclaw = fgGetInt("/fdm-ada/iaux2", 0);
lgear = fgGetInt("/fdm-ada/iaux3", 0);
wown = fgGetInt("/fdm-ada/iaux4", 0);
wowm = fgGetInt("/fdm-ada/iaux5", 0);;
ihook = fgGetInt("/fdm-ada/iaux6", 0);
#endif
float pitch_value = current_ch1() * SGD_RADIANS_TO_DEGREES;
if (hudladder_type == "Climb/Dive Ladder") {
pitch_ladder = false;
climb_dive_ladder = true;
clip_plane = true;
} else { // hudladder_type == "Pitch Ladder"
pitch_ladder = true;
climb_dive_ladder = false;
clip_plane = false;
}
//**************************************************************
glPushMatrix();
// define (0, 0) as center of screen
glTranslatef(centroid.x, centroid.y, 0);
// OBJECT STATIC RETICLE
// TYPE FRL
// ATTRIB - ALWAYS
// Draw the FRL spot and line
if (frl) {
#define FRL_DIAMOND_SIZE 2.0
glBegin(GL_LINE_LOOP);
glVertex2f(-FRL_DIAMOND_SIZE, 0.0);
glVertex2f(0.0, FRL_DIAMOND_SIZE);
glVertex2f(FRL_DIAMOND_SIZE, 0.0);
glVertex2f(0.0, -FRL_DIAMOND_SIZE);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(0, FRL_DIAMOND_SIZE);
glVertex2f(0, 8.0);
glEnd();
#undef FRL_DIAMOND_SIZE
}
// TYPE WATERLINE_MARK (W shaped _ _ )
// \/\/
//****************************************************************
// TYPE TARGET_SPOT
// Draw the target spot.
if (target_spot) {
#define CENTER_DIAMOND_SIZE 6.0
glBegin(GL_LINE_LOOP);
glVertex2f(-CENTER_DIAMOND_SIZE, 0.0);
glVertex2f(0.0, CENTER_DIAMOND_SIZE);
glVertex2f(CENTER_DIAMOND_SIZE, 0.0);
glVertex2f(0.0, -CENTER_DIAMOND_SIZE);
glEnd();
#undef CENTER_DIAMOND_SIZE
}
//****************************************************************
//velocity vector reticle - computations
if (velocity_vector) {
Vxx = fgGetDouble("/velocities/north-relground-fps", 0.0);
Vyy = fgGetDouble("/velocities/east-relground-fps", 0.0);
Vzz = fgGetDouble("/velocities/down-relground-fps", 0.0);
Axx = fgGetDouble("/accelerations/ned/north-accel-fps_sec", 0.0);
Ayy = fgGetDouble("/accelerations/ned/east-accel-fps_sec", 0.0);
Azz = fgGetDouble("/accelerations/ned/down-accel-fps_sec", 0.0);
psi = get_heading();
if (psi > 180.0)
psi = psi - 360;
total_vel = sqrt(Vxx * Vxx + Vyy * Vyy + Vzz * Vzz);
ground_vel = sqrt(Vxx * Vxx + Vyy * Vyy);
up_vel = Vzz;
if (ground_vel < 2.0) {
if (fabs(up_vel) < 2.0)
actslope = 0.0;
else
actslope = (up_vel / fabs(up_vel)) * 90.0;
} else {
actslope = atan(up_vel / ground_vel) * SGD_RADIANS_TO_DEGREES;
}
xvvr = (((atan2(Vyy, Vxx) * SGD_RADIANS_TO_DEGREES) - psi)
* (factor / globals->get_current_view()->get_aspect_ratio()));
drift = ((atan2(Vyy, Vxx) * SGD_RADIANS_TO_DEGREES) - psi);
yvvr = ((actslope - pitch_value) * factor);
vel_y = ((actslope - pitch_value) * cos(roll_value) + drift * sin(roll_value)) * factor;
vel_x = (-(actslope - pitch_value) * sin(roll_value) + drift * cos(roll_value))
* (factor/globals->get_current_view()->get_aspect_ratio());
// printf("%f %f %f %f\n",vel_x, vel_y, drift, psi);
//****************************************************************
// OBJECT MOVING RETICLE
// TYPE - DRIFT MARKER
// ATTRIB - ALWAYS
// drift marker
if (drift_marker) {
glBegin(GL_LINE_STRIP);
glVertex2f((xvvr * 25 / 120) - 6, -4);
glVertex2f(xvvr * 25 / 120, 8);
glVertex2f((xvvr * 25 / 120) + 6, -4);
glEnd();
}
//****************************************************************
// Clipping coordinates for ladder to be input from xml file
// Clip hud ladder
if (clip_plane) {
glClipPlane(GL_CLIP_PLANE0, eqn_top);
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE1, eqn_left);
glEnable(GL_CLIP_PLANE1);
glClipPlane(GL_CLIP_PLANE2, eqn_right);
glEnable(GL_CLIP_PLANE2);
// glScissor(-100,-240, 200, 240);
// glEnable(GL_SCISSOR_TEST);
}
//****************************************************************
// OBJECT MOVING RETICLE
// TYPE VELOCITY VECTOR
// ATTRIB - ALWAYS
// velocity vector
glBegin(GL_LINE_LOOP); // Use polygon to approximate a circle
for (count = 0; count < 50; count++) {
cosine = 6 * cos(count * SGD_2PI / 50.0);
sine = 6 * sin(count * SGD_2PI / 50.0);
glVertex2f(cosine + vel_x, sine + vel_y);
}
glEnd();
//velocity vector reticle orientation lines
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x - 12, vel_y);
glVertex2f(vel_x - 6, vel_y);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x + 12, vel_y);
glVertex2f(vel_x + 6, vel_y);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x, vel_y + 12);
glVertex2f(vel_x, vel_y + 6);
glEnd();
#ifdef ENABLE_SP_FDM
// OBJECT MOVING RETICLE
// TYPE LINE
// ATTRIB - ON CONDITION
if (lgear == 1) {
// undercarriage status
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x + 8, vel_y);
glVertex2f(vel_x + 8, vel_y - 4);
glEnd();
// OBJECT MOVING RETICLE
// TYPE LINE
// ATTRIB - ON CONDITION
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x - 8, vel_y);
glVertex2f(vel_x - 8, vel_y - 4);
glEnd();
// OBJECT MOVING RETICLE
// TYPE LINE
// ATTRIB - ON CONDITION
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x, vel_y - 6);
glVertex2f(vel_x, vel_y - 10);
glEnd();
}
// OBJECT MOVING RETICLE
// TYPE V
// ATTRIB - ON CONDITION
if (ihook == 1) {
// arrestor hook status
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x - 4, vel_y - 8);
glVertex2f(vel_x, vel_y - 10);
glVertex2f(vel_x + 4, vel_y - 8);
glEnd();
}
#endif
} // if velocity_vector
//***************************************************************
// OBJECT MOVING RETICLE
// TYPE - SQUARE_BRACKET
// ATTRIB - ON CONDITION
// alpha bracket
#ifdef ENABLE_SP_FDM
if (alpha_bracket && ihook == 1) {
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x - 20 , vel_y - (16 - alpha) * factor);
glVertex2f(vel_x - 17, vel_y - (16 - alpha) * factor);
glVertex2f(vel_x - 17, vel_y - (14 - alpha) * factor);
glVertex2f(vel_x - 20, vel_y - (14 - alpha) * factor);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x + 20 , vel_y - (16 - alpha) * factor);
glVertex2f(vel_x + 17, vel_y - (16 - alpha) * factor);
glVertex2f(vel_x + 17, vel_y - (14 - alpha) * factor);
glVertex2f(vel_x + 20, vel_y - (14 - alpha) * factor);
glEnd();
}
#endif
//printf("xvr=%f, yvr=%f, Vx=%f, Vy=%f, Vz=%f\n",xvvr, yvvr, Vx, Vy, Vz);
//printf("Ax=%f, Ay=%f, Az=%f\n",Ax, Ay, Az);
//****************************************************************
// OBJECT MOVING RETICLE
// TYPE ENERGY_MARKERS
// ATTRIB - ALWAYS
//energy markers - compute potential slope
if (energy_marker) {
if (total_vel < 5.0) {
t1 = 0;
t2 = 0;
} else {
t1 = up_vel / total_vel;
t2 = asin((Vxx * Axx + Vyy * Ayy + Vzz * Azz) / (9.81 * total_vel));
}
pot_slope = ((t2 / 3) * SGD_RADIANS_TO_DEGREES) * factor + vel_y;
// if (pot_slope < (vel_y - 45)) pot_slope = vel_y - 45;
// if (pot_slope > (vel_y + 45)) pot_slope = vel_y + 45;
//energy markers
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x - 20, pot_slope - 5);
glVertex2f(vel_x - 15, pot_slope);
glVertex2f(vel_x - 20, pot_slope + 5);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x + 20, pot_slope - 5);
glVertex2f(vel_x + 15, pot_slope);
glVertex2f(vel_x + 20, pot_slope + 5);
glEnd();
if (pla > (105.0 / 131.0)) {
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x - 24, pot_slope - 5);
glVertex2f(vel_x - 19, pot_slope);
glVertex2f(vel_x - 24, pot_slope + 5);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(vel_x + 24, pot_slope - 5);
glVertex2f(vel_x + 19, pot_slope);
glVertex2f(vel_x + 24, pot_slope + 5);
glEnd();
}
}
//**********************************************************
// ramp reticle
// OBJECT STATIC RETICLE
// TYPE LINE
// ATTRIB - ON CONDITION
#ifdef ENABLE_SP_FDM
if (energy_worm && ilcanclaw == 1) {
glBegin(GL_LINE_STRIP);
glVertex2f(-15, -134);
glVertex2f(15, -134);
glEnd();
// OBJECT MOVING RETICLE
// TYPE BOX
// ATTRIB - ON CONDITION
glBegin(GL_LINE_STRIP);
glVertex2f(-6, -134);
glVertex2f(-6, t2 * SGD_RADIANS_TO_DEGREES * 4.0 - 134);
glVertex2f(+6, t2 * SGD_RADIANS_TO_DEGREES * 4.0 - 134);
glVertex2f(6, -134);
glEnd();
// OBJECT MOVING RETICLE
// TYPE DIAMOND
// ATTRIB - ON CONDITION
glBegin(GL_LINE_LOOP);
glVertex2f(-6, actslope * 4.0 - 134);
glVertex2f(0, actslope * 4.0 -134 + 3);
glVertex2f(6, actslope * 4.0 - 134);
glVertex2f(0, actslope * 4.0 -134 -3);
glEnd();
}
#endif
//*************************************************************
// OBJECT MOVING RETICLE
// TYPE DIAMOND
// ATTRIB - ALWAYS
// Draw the locked velocity vector.
if (climb_dive_marker) {
glBegin(GL_LINE_LOOP);
glVertex2f(-3.0, 0.0 + vel_y);
glVertex2f(0.0, 6.0 + vel_y);
glVertex2f(3.0, 0.0 + vel_y);
glVertex2f(0.0, -6.0 + vel_y);
glEnd();
}
//****************************************************************
if (climb_dive_ladder) { // CONFORMAL_HUD
vmin = pitch_value - (float)width_units;
vmax = pitch_value + (float)width_units;
glTranslatef(vel_x, vel_y, 0);
} else { // pitch_ladder - Default Hud
vmin = pitch_value - (float)width_units * 0.5f;
vmax = pitch_value + (float)width_units * 0.5f;
}
glRotatef(roll_value * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
// FRL marker not rotated - this line shifted below
if (div_units) {
char TextLadder[8];
float label_length;
float label_height;
float left;
float right;
float bot;
float top;
float text_offset = 4.0f;
float zero_offset = 0.0;
if (climb_dive_ladder)
zero_offset = 50.0f; // horizon line is wider by this much (hard coded ??)
else
zero_offset = 10.0f;
fntFont *font = HUDtext->getFont(); // FIXME
float pointsize = HUDtext->getPointSize();
float italic = HUDtext->getSlant();
TextList.setFont(HUDtext);
TextList.erase();
LineList.erase();
StippleLineList.erase();
int last = float_to_int(vmax) + 1;
int i = float_to_int(vmin);
if (!scr_hole) {
x_end = half_span;
for (; i<last; i++) {
y = (((float)(i - pitch_value) * factor) + .5f);
if (!(i % div_units)) { // At integral multiple of div
sprintf(TextLadder, "%d", i);
font->getBBox(TextLadder, pointsize, italic,
&left, &right, &bot, &top);
label_length = right - left;
label_length += text_offset;
label_height = (top - bot) / 2.0f;
x_ini = -half_span;
if (i >= 0) {
// Make zero point wider on left
if (i == 0)
x_ini -= zero_offset;
// Zero or above draw solid lines
Line(x_ini, y, x_end, y);
if (i == 90 && zenith == 1)
drawZenith(x_ini, x_end, y);
} else {
// Below zero draw dashed lines.
StippleLine(x_ini, y, x_end, y);
if (i == -90 && nadir ==1)
drawNadir(x_ini, x_end, y);
}
// Calculate the position of the left text and write it.
Text(x_ini-label_length, y-label_height, TextLadder);
Text(x_end+text_offset, y-label_height, TextLadder);
}
}
} else { // if (scr_hole)
// Draw ladder with space in the middle of the lines
float hole = (float)((scr_hole) / 2.0f);
x_end = -half_span + hole;
x_ini2 = half_span - hole;
for (; i < last; i++) {
if (hudladder_type == "Pitch Ladder")
y = (((float)(i - pitch_value) * factor) + .5);
else if (hudladder_type == "Climb/Dive Ladder")
y = (((float)(i - actslope) * factor) + .5);
if (!(i % div_units)) { // At integral multiple of div
sprintf(TextLadder, "%d", i);
font->getBBox(TextLadder, pointsize, italic,
&left, &right, &bot, &top);
label_length = right - left;
label_length += text_offset;
label_height = (top - bot) / 2.0f;
// printf("l %f r %f b %f t %f\n",left, right, bot, top);
// Start by calculating the points and drawing the
// left side lines.
x_ini = -half_span;
x_end2 = half_span;
if (i >= 0) {
// Make zero point wider on left
if (i == 0) {
x_ini -= zero_offset;
x_end2 += zero_offset;
}
//draw climb bar vertical lines
if (climb_dive_ladder) {
// Zero or above draw solid lines
Line(x_end, y - 5.0, x_end, y);
Line(x_ini2, y - 5.0, x_ini2, y);
}
// draw pitch / climb bar
Line(x_ini, y, x_end, y);
Line(x_ini2, y, x_end2, y);
if (i == 90 && zenith == 1)
drawZenith(x_ini2, x_end, y);
} else { // i < 0
// draw dive bar vertical lines
if (climb_dive_ladder) {
Line(x_end, y + 5.0, x_end, y);
Line(x_ini2, y + 5.0, x_ini2, y);
}
// draw pitch / dive bars
StippleLine(x_ini, y, x_end, y);
StippleLine(x_ini2, y, x_end2, y);
if (i == -90 && nadir == 1)
drawNadir(x_ini2, x_end, y);
}
// Now calculate the location of the left side label using
Text(x_ini-label_length, y - label_height, TextLadder);
Text(x_end2+text_offset, y - label_height, TextLadder);
}
}
// OBJECT LADDER MARK
// TYPE LINE
// ATTRIB - ON CONDITION
// draw appraoch glide slope marker
#ifdef ENABLE_SP_FDM
if (glide_slope_marker && ihook) {
Line(-half_span + 15, (glide_slope-actslope) * factor,
-half_span + hole, (glide_slope - actslope) * factor);
Line(half_span - 15, (glide_slope-actslope) * factor,
half_span - hole, (glide_slope - actslope) * factor);
}
#endif
}
TextList.draw();
glLineWidth(0.2);
LineList.draw();
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0x00FF);
StippleLineList.draw();
glDisable(GL_LINE_STIPPLE);
}
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE2);
// glDisable(GL_SCISSOR_TEST);
glPopMatrix();
//*************************************************************
//*************************************************************
#ifdef ENABLE_SP_FDM
if (waypoint_marker) {
//waypoint marker computation
float fromwp_lat, towp_lat, fromwp_lon, towp_lon, dist, delx, dely, hyp, theta, brg;
fromwp_lon = get_longitude() * SGD_DEGREES_TO_RADIANS;
fromwp_lat = get_latitude() * SGD_DEGREES_TO_RADIANS;
towp_lon = fgGetDouble("/fdm-ada/ship-lon", 0.0) * SGD_DEGREES_TO_RADIANS;
towp_lat = fgGetDouble("/fdm-ada/ship-lat", 0.0) * SGD_DEGREES_TO_RADIANS;
dist = acos(sin(fromwp_lat) * sin(towp_lat) + cos(fromwp_lat)
* cos(towp_lat) * cos(fabs(fromwp_lon - towp_lon)));
delx= towp_lat - fromwp_lat;
dely = towp_lon - fromwp_lon;
hyp = sqrt(pow(delx, 2) + pow(dely, 2));
if (hyp != 0)
theta = asin(dely / hyp);
else
theta = 0.0;
brg = theta * SGD_RADIANS_TO_DEGREES;
if (brg > 360.0)
brg = 0.0;
if (delx < 0)
brg = 180 - brg;
// {Brg = asin(cos(towp_lat)*sin(fabs(fromwp_lon-towp_lon))/ sin(dist));
// Brg = Brg * SGD_RADIANS_TO_DEGREES; }
dist *= SGD_RADIANS_TO_DEGREES * 60.0 * 1852.0; //rad->deg->nm->m
// end waypoint marker computation
//*********************************************************
// OBJECT MOVING RETICLE
// TYPE ARROW
// waypoint marker
if (fabs(brg-psi) > 10.0) {
glPushMatrix();
glTranslatef(centroid.x, centroid.y, 0);
glTranslatef(vel_x, vel_y, 0);
glRotatef(brg - psi, 0.0, 0.0, -1.0);
glBegin(GL_LINE_LOOP);
glVertex2f(-2.5, 20.0);
glVertex2f(-2.5, 30.0);
glVertex2f(-5.0, 30.0);
glVertex2f(0.0, 35.0);
glVertex2f(5.0, 30.0);
glVertex2f(2.5, 30.0);
glVertex2f(2.5, 20.0);
glEnd();
glPopMatrix();
}
// waypoint marker on heading scale
if (fabs(brg-psi) < 12.0) {
if (hat == 0) {
glBegin(GL_LINE_LOOP);
glVertex2f(((brg - psi) * 60 / 25) + 320, 240.0);
glVertex2f(((brg - psi) * 60 / 25) + 326, 240.0 - 4);
glVertex2f(((brg - psi) * 60 / 25) + 323, 240.0 - 4);
glVertex2f(((brg - psi) * 60 / 25) + 323, 240.0 - 8);
glVertex2f(((brg - psi) * 60 / 25) + 317, 240.0 - 8);
glVertex2f(((brg - psi) * 60 / 25) + 317, 240.0 - 4);
glVertex2f(((brg - psi) * 60 / 25) + 314, 240.0 - 4);
glEnd();
} else { //if hat=0
float x = (brg - psi) * 60 / 25 + 320, y = 240.0, r = 5.0;
float x1, y1;
glEnable(GL_POINT_SMOOTH);
glBegin(GL_POINTS);
for (int count = 0; count <= 200; count++) {
float temp = count * 3.142 * 3 / (200.0 * 2.0);
float temp1 = temp - (45.0 * SGD_DEGREES_TO_RADIANS);
x1 = x + r * cos(temp1);
y1 = y + r * sin(temp1);
glVertex2f(x1, y1);
}
glEnd();
glDisable(GL_POINT_SMOOTH);
} //hat=0
} //brg<12
} // if waypoint_marker
#endif
}//draw
/******************************************************************/
// draws the zenith symbol for highest possible climb angle (i.e. 90 degree climb angle)
//
void HudLadder::drawZenith(float xfirst, float xlast, float yvalue)
{
float xcentre = (xfirst + xlast) / 2.0;
float ycentre = yvalue;
Line(xcentre - 9.0, ycentre, xcentre - 3.0, ycentre + 1.3);
Line(xcentre - 9.0, ycentre, xcentre - 3.0, ycentre - 1.3);
Line(xcentre + 9.0, ycentre, xcentre + 3.0, ycentre + 1.3);
Line(xcentre + 9.0, ycentre, xcentre + 3.0, ycentre - 1.3);
Line(xcentre, ycentre + 9.0, xcentre - 1.3, ycentre + 3.0);
Line(xcentre, ycentre + 9.0, xcentre + 1.3, ycentre + 3.0);
Line(xcentre - 3.9, ycentre + 3.9, xcentre - 3.0, ycentre + 1.3);
Line(xcentre - 3.9, ycentre + 3.9, xcentre - 1.3, ycentre + 3.0);
Line(xcentre + 3.9, ycentre + 3.9, xcentre + 1.3, ycentre+3.0);
Line(xcentre + 3.9, ycentre + 3.9, xcentre + 3.0, ycentre+1.3);
Line(xcentre - 3.9, ycentre - 3.9, xcentre - 3.0, ycentre-1.3);
Line(xcentre - 3.9, ycentre - 3.9, xcentre - 1.3, ycentre-2.6);
Line(xcentre + 3.9, ycentre - 3.9, xcentre + 3.0, ycentre-1.3);
Line(xcentre + 3.9, ycentre - 3.9, xcentre + 1.3, ycentre-2.6);
Line(xcentre - 1.3, ycentre - 2.6, xcentre, ycentre - 27.0);
Line(xcentre + 1.3, ycentre - 2.6, xcentre, ycentre - 27.0);
}
// draws the nadir symbol for lowest possible dive angle (i.e. 90 degree dive angle)
//
void HudLadder::drawNadir(float xfirst, float xlast, float yvalue)
{
float xcentre = (xfirst + xlast) / 2.0;
float ycentre = yvalue;
float r = 7.5;
float x1, y1, x2, y2;
// to draw a circle
float xcent1, xcent2, ycent1, ycent2;
xcent1 = xcentre + r;
ycent1 = ycentre;
for (int count = 1; count <= 400; count++) {
float temp = count * 2 * 3.142 / 400.0;
xcent2 = xcentre + r * cos(temp);
ycent2 = ycentre + r * sin(temp);
Line(xcent1, ycent1, xcent2, ycent2);
xcent1 = xcent2;
ycent1 = ycent2;
}
xcent2 = xcentre + r;
ycent2 = ycentre;
drawOneLine(xcent1, ycent1, xcent2, ycent2); //to connect last point to first point
//end circle
//to draw a line above the circle
Line(xcentre, ycentre + 7.5, xcentre, ycentre + 22.5);
//line in the middle of circle
Line(xcentre - 7.5, ycentre, xcentre + 7.5, ycentre);
float theta = asin (2.5 / 7.5);
float theta1 = asin(5.0 / 7.5);
x1 = xcentre + r * cos(theta);
y1 = ycentre + 2.5;
x2 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) - theta);
y2 = ycentre + 2.5;
Line(x1, y1, x2, y2);
x1 = xcentre + r * cos(theta1);
y1 = ycentre + 5.0;
x2 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) - theta1);
y2 = ycentre + 5.0;
Line(x1, y1, x2, y2);
x1 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) + theta);
y1 = ycentre - 2.5;
x2 = xcentre + r * cos((360.0 * SGD_DEGREES_TO_RADIANS) - theta);
y2 = ycentre - 2.5;
Line(x1, y1, x2, y2);
x1 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) + theta1);
y1 = ycentre - 5.0;
x2 = xcentre + r * cos((360.0 * SGD_DEGREES_TO_RADIANS) - theta1);
y2 = ycentre - 5.0;
Line(x1, y1, x2, y2);
}

View file

@ -1,437 +0,0 @@
// hud_rwy.cxx -- An instrument that renders a virtual runway on the HUD
//
// Written by Aaron Wilson & Phillip Merritt, Nov 2004.
//
// Copyright (C) 2004 Aaron Wilson, Aaron.I.Wilson@nasa.gov
// Copyright (C) 2004 Phillip Merritt, Phillip.M.Merritt@nasa.gov
//
// 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.
//
#include <simgear/compiler.h>
#include "hud.hxx"
#include <math.h>
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include <Environment/environment.hxx>
#include <Environment/environment_mgr.hxx>
#include <ATCDCL/ATCutils.hxx>
#include <Main/viewer.hxx>
#include <simgear/math/project.hxx>
// int x, int y, int width, int height, float scale_data, bool working)
runway_instr::runway_instr(const SGPropertyNode *node) :
instr_item(
node->getIntValue("x"),
node->getIntValue("y"),
node->getIntValue("width"),
node->getIntValue("height"),
NULL,
node->getDoubleValue("scale"),
0,
node->getBoolValue("working", true)),
arrowScale(node->getDoubleValue("arrow_scale", 1.0)),
arrowRad(node->getDoubleValue("arrow_radius")),
lnScale(node->getDoubleValue("line_scale", 1.0)),
scaleDist(node->getDoubleValue("scale_dist_nm")),
default_pitch(fgGetDouble("/sim/view[0]/config/pitch-pitch-deg", 0.0)),
default_heading(fgGetDouble("/sim/view[0]/config/pitch-heading-deg", 0.0)),
cockpit_view(globals->get_viewmgr()->get_view(0)),
stippleOut(node->getIntValue("outer_stipple", 0xFFFF)),
stippleCen(node->getIntValue("center_stipple", 0xFFFF)),
drawIA(arrowScale > 0 ? true : false),
drawIAAlways(arrowScale > 0 ? node->getBoolValue("arrow_always") : false)
{
SG_LOG(SG_INPUT, SG_BULK, "Done reading runway instrument "
<< node->getStringValue("name", "[unnamed]"));
view[0] = 0;
view[1] = 0;
view[2] = 640;
view[3] = 480;
center.x = view[2] >> 1;
center.y = view[3] >> 1;
location.left = center.x - (get_width() >> 1) + get_x();
location.right = center.x + (get_width() >>1) + get_x();
location.bottom = center.y - (get_height() >>1) + get_y();
location.top = center.y + (get_height() >> 1) + get_y();
}
void runway_instr::draw()
{
if (!is_broken() && (runway = get_active_runway())) {
glPushAttrib(GL_LINE_STIPPLE | GL_LINE_STIPPLE_PATTERN | GL_LINE_WIDTH);
float modelView[4][4], projMat[4][4];
bool anyLines;
//Get the current view
FGViewer* curr_view = globals->get_viewmgr()->get_current_view();
int curr_view_id = globals->get_viewmgr()->get_current();
double gpo = curr_view->getGoalPitchOffset_deg();
double gho = curr_view->getGoalHeadingOffset_deg();
double po = curr_view->getPitchOffset_deg();
double ho = curr_view->getHeadingOffset_deg();
double yaw = -(cockpit_view->getHeadingOffset_deg() - default_heading) * SG_DEGREES_TO_RADIANS;
double pitch = (cockpit_view->getPitchOffset_deg() - default_pitch) * SG_DEGREES_TO_RADIANS;
//double roll = fgGetDouble("/sim/view[0]/config/roll-offset-deg",0.0) //TODO: adjust for default roll offset
double sPitch = sin(pitch), cPitch = cos(pitch),
sYaw = sin(yaw), cYaw = cos(yaw);
//Set the camera to the cockpit view to get the view of the runway from the cockpit
// OSGFIXME
// ssgSetCamera((sgVec4 *)cockpit_view->get_VIEW());
get_rwy_points(points3d);
//Get the current project matrix
// OSGFIXME
// ssgGetProjectionMatrix(projMat);
// const sgVec4 *viewMat = globals->get_current_view()->get_VIEW();
//Get the current model view matrix (cockpit view)
// OSGFIXME
// ssgGetModelviewMatrix(modelView);
//Create a rotation matrix to correct for any offsets (other than default offsets) to the model view matrix
sgMat4 xy; //rotation about the Rxy, negate the sin's on Ry
xy[0][0] = cYaw; xy[1][0] = 0.0f; xy[2][0] = -sYaw; xy[3][0] = 0.0f;
xy[0][1] = sPitch*-sYaw; xy[1][1] = cPitch; xy[2][1] = -sPitch*cYaw; xy[3][1] = 0.0f;
xy[0][2] = cPitch*sYaw; xy[1][2] = sPitch; xy[2][2] = cPitch*cYaw; xy[3][2] = 0.0f;
xy[0][3] = 0.0f; xy[1][3] = 0.0f; xy[2][3] = 0.0f; xy[3][3] = 1.0f;
//Re-center the model view
sgPostMultMat4(modelView,xy);
//copy float matrices to double
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int idx = (i * 4) + j;
mm[idx] = (double)modelView[i][j];
pm[idx] = (double)projMat[i][j];
}
}
//Calculate the 2D points via gluProject
int result = GL_TRUE;
for (int i = 0; i < 6; i++) {
result = simgear::project(points3d[i][0], points3d[i][1], points3d[i][2],
mm, pm, view,
&points2d[i][0], &points2d[i][1], &points2d[i][2]);
}
//set the line width based on our distance from the runway
setLineWidth();
//Draw the runway lines on the HUD
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, stippleOut);
anyLines =
drawLine(points3d[0], points3d[1], points2d[0], points2d[1]) | //draw top
drawLine(points3d[2], points3d[1], points2d[2], points2d[1]) | //draw right
drawLine(points3d[2], points3d[3], points2d[2], points2d[3]) | //draw bottom
drawLine(points3d[3], points3d[0], points2d[3], points2d[0]); //draw left
glLineStipple(1, stippleCen);
anyLines |= drawLine(points3d[5], points3d[4], points2d[5], points2d[4]); //draw center
//Check to see if arrow needs drawn
if ((!anyLines && drawIA) || drawIAAlways) {
drawArrow(); //draw indication arrow
}
//Set the camera back to the current view
// OSGFIXME
// ssgSetCamera((sgVec4 *)curr_view);
glPopAttrib();
}//if not broken
}
FGRunway* runway_instr::get_active_runway()
{
const FGAirport* apt = fgFindAirportID(fgGetString("/sim/presets/airport-id"));
if (!apt) return NULL;
return apt->getActiveRunwayForUsage();
}
void runway_instr::get_rwy_points(sgdVec3 *points3d)
{
double alt = runway->geod().getElevationM();
double length = runway->lengthM() * 0.5;
double width = runway->widthM() * 0.5;
double frontLat = 0.0, frontLon = 0.0, backLat = 0.0, backLon = 0.0, az = 0.0, tempLat = 0.0, tempLon = 0.0;
double runwayLon = runway->geod().getLongitudeDeg(),
runwayLat = runway->geod().getLatitudeDeg();
double heading = runway->headingDeg();
geo_direct_wgs_84(alt, runwayLat, runwayLon, heading, length, &backLat, &backLon, &az);
sgGeodToCart(backLat * SG_DEGREES_TO_RADIANS, backLon * SG_DEGREES_TO_RADIANS, alt, points3d[4]);
geo_direct_wgs_84(alt, runwayLat, runwayLon, heading + 180, length, &frontLat, &frontLon, &az);
sgGeodToCart(frontLat * SG_DEGREES_TO_RADIANS, frontLon * SG_DEGREES_TO_RADIANS, alt, points3d[5]);
geo_direct_wgs_84(alt, backLat, backLon, heading + 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[0]);
geo_direct_wgs_84(alt, backLat, backLon, heading - 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[1]);
geo_direct_wgs_84(alt, frontLat, frontLon, heading - 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[2]);
geo_direct_wgs_84(alt, frontLat, frontLon, heading + 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[3]);
}
bool runway_instr::drawLine(const sgdVec3& a1, const sgdVec3& a2, const sgdVec3& point1, const sgdVec3& point2)
{
sgdVec3 p1, p2;
sgdCopyVec3(p1, point1);
sgdCopyVec3(p2, point2);
bool p1Inside = (p1[0] >= location.left && p1[0] <= location.right
&& p1[1] >= location.bottom && p1[1] <= location.top);
bool p1Insight = (p1[2] >= 0.0 && p1[2] < 1.0);
bool p1Valid = p1Insight && p1Inside;
bool p2Inside = (p2[0] >= location.left && p2[0] <= location.right
&& p2[1] >= location.bottom && p2[1] <= location.top);
bool p2Insight = (p2[2] >= 0.0 && p2[2] < 1.0);
bool p2Valid = p2Insight && p2Inside;
if (p1Valid && p2Valid) { //Both project points are valid, draw the line
glBegin(GL_LINES);
glVertex2d(p1[0],p1[1]);
glVertex2d(p2[0],p2[1]);
glEnd();
} else if (p1Valid) { //p1 is valid and p2 is not, calculate a new valid point
sgdVec3 vec = {a2[0] - a1[0], a2[1] - a1[1], a2[2] - a1[2]};
//create the unit vector
sgdScaleVec3(vec, 1.0 / sgdLengthVec3(vec));
sgdVec3 newPt;
sgdCopyVec3(newPt, a1);
sgdAddVec3(newPt, vec);
if (simgear::project(newPt[0], newPt[1], newPt[2], mm, pm, view,
&p2[0], &p2[1], &p2[2])
&& (p2[2] > 0 && p2[2] < 1.0)) {
boundPoint(p1, p2);
glBegin(GL_LINES);
glVertex2d(p1[0], p1[1]);
glVertex2d(p2[0], p2[1]);
glEnd();
}
} else if (p2Valid) { //p2 is valid and p1 is not, calculate a new valid point
sgdVec3 vec = {a1[0] - a2[0], a1[1] - a2[1], a1[2] - a2[2]};
//create the unit vector
sgdScaleVec3(vec, 1.0 / sgdLengthVec3(vec));
sgdVec3 newPt;
sgdCopyVec3(newPt, a2);
sgdAddVec3(newPt, vec);
if (simgear::project(newPt[0], newPt[1], newPt[2], mm, pm, view,
&p1[0], &p1[1], &p1[2])
&& (p1[2] > 0 && p1[2] < 1.0)) {
boundPoint(p2, p1);
glBegin(GL_LINES);
glVertex2d(p2[0], p2[1]);
glVertex2d(p1[0], p1[1]);
glEnd();
}
} else if (p1Insight && p2Insight) { //both points are insight, but not inside
bool v = boundOutsidePoints(p1, p2);
if (v) {
glBegin(GL_LINES);
glVertex2d(p1[0], p1[1]);
glVertex2d(p2[0], p2[1]);
glEnd();
}
return v;
}
//else both points are not insight, don't draw anything
return (p1Valid && p2Valid);
}
void runway_instr::boundPoint(const sgdVec3& v, sgdVec3& m)
{
double y = v[1];
if (m[1] < v[1])
y = location.bottom;
else if (m[1] > v[1])
y = location.top;
if (m[0] == v[0]) {
m[1] = y;
return; //prevent divide by zero
}
double slope = (m[1] - v[1]) / (m[0] - v[0]);
m[0] = (y - v[1]) / slope + v[0];
m[1] = y;
if (m[0] < location.left) {
m[0] = location.left;
m[1] = slope * (location.left - v[0]) + v[1];
} else if (m[0] > location.right) {
m[0] = location.right;
m[1] = slope * (location.right - v[0]) + v[1];
}
}
bool runway_instr::boundOutsidePoints(sgdVec3& v, sgdVec3& m)
{
bool pointsInvalid = (v[1] > location.top && m[1] > location.top) ||
(v[1] < location.bottom && m[1] < location.bottom) ||
(v[0] > location.right && m[0] > location.right) ||
(v[0] < location.left && m[0] < location.left);
if (pointsInvalid)
return false;
if (m[0] == v[0]) {//x's are equal, vertical line
if (m[1] > v[1]) {
m[1] = location.top;
v[1] = location.bottom;
} else {
v[1] = location.top;
m[1] = location.bottom;
}
return true;
}
if (m[1] == v[1]) { //y's are equal, horizontal line
if (m[0] > v[0]) {
m[0] = location.right;
v[0] = location.left;
} else {
v[0] = location.right;
m[0] = location.left;
}
return true;
}
double slope = (m[1] - v[1]) / (m[0] - v[0]);
double b = v[1] - (slope * v[0]);
double y1 = slope * location.left + b;
double y2 = slope * location.right + b;
double x1 = (location.bottom - b) / slope;
double x2 = (location.top - b) / slope;
int counter = 0;
if (y1 >= location.bottom && y1 <= location.top) {
v[0] = location.left;
v[1] = y1;
counter++;
}
if (y2 >= location.bottom && y2 <= location.top) {
if (counter > 0) {
m[0] = location.right;
m[1] = y2;
} else {
v[0] = location.right;
v[1] = y2;
}
counter++;
}
if (x1 >= location.left && x1 <= location.right) {
if (counter > 0) {
m[0] = x1;
m[1] = location.bottom;
} else {
v[0] = x1;
v[1] = location.bottom;
}
counter++;
}
if (x2 >= location.left && x2 <= location.right) {
m[0] = x1;
m[1] = location.bottom;
counter++;
}
return (counter == 2);
}
void runway_instr::drawArrow()
{
SGGeod acPos(SGGeod::fromDeg(
fgGetDouble("/position/longitude-deg"),
fgGetDouble("/position/latitude-deg")));
float theta = SGGeodesy::courseDeg(acPos, runway->geod());
theta -= fgGetDouble("/orientation/heading-deg");
theta = -theta;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslated((location.right + location.left) / 2.0,(location.top + location.bottom) / 2.0, 0.0);
glRotated(theta, 0.0, 0.0, 1.0);
glTranslated(0.0, arrowRad, 0.0);
glScaled(arrowScale, arrowScale, 0.0);
glBegin(GL_TRIANGLES);
glVertex2d(-5.0, 12.5);
glVertex2d(0.0, 25.0);
glVertex2d(5.0, 12.5);
glEnd();
glBegin(GL_QUADS);
glVertex2d(-2.5, 0.0);
glVertex2d(-2.5, 12.5);
glVertex2d(2.5, 12.5);
glVertex2d(2.5, 0.0);
glEnd();
glPopMatrix();
}
void runway_instr::setLineWidth()
{
//Calculate the distance from the runway, A
SGGeod acPos(SGGeod::fromDeg(
fgGetDouble("/position/longitude-deg"),
fgGetDouble("/position/latitude-deg")));
double distance = SGGeodesy::distanceNm(acPos, runway->geod());
//Get altitude above runway, B
double alt_nm = get_agl();
static const SGPropertyNode *startup_units_node = fgGetNode("/sim/startup/units");
if (!strcmp(startup_units_node->getStringValue(), "feet"))
alt_nm *= SG_FEET_TO_METER*SG_METER_TO_NM;
else
alt_nm *= SG_METER_TO_NM;
//Calculate distance away from runway, C = v(A≤+B≤)
distance = sqrt(alt_nm * alt_nm + distance*distance);
if (distance < scaleDist)
glLineWidth(1.0 + ((lnScale - 1) * ((scaleDist - distance) / scaleDist)));
else
glLineWidth(1.0);
}
void runway_instr::setArrowRotationRadius(double radius) { arrowRad = radius; }
void runway_instr::setArrowScale(double scale) { arrowScale = scale; }
void runway_instr::setDrawArrow(bool draw) {drawIA = draw;}
void runway_instr::setDrawArrowAlways(bool draw) {drawIAAlways = draw;}
void runway_instr::setLineScale(double scale) {lnScale = scale;}
void runway_instr::setScaleDist(double dist_m) {scaleDist = dist_m;}
void runway_instr::setStippleOutline(unsigned short stipple) {stippleOut = stipple;}
void runway_instr::setStippleCenterline(unsigned short stipple){stippleCen = stipple;}

View file

@ -1,53 +0,0 @@
#include "hud.hxx"
//============== Top of instr_scale class memeber definitions ===============
//
// Notes:
// 1. instr_scales divide the specified location into half and then
// the half opposite the read direction in half again. A bar is
// then drawn along the second divider. Scale ticks are drawn
// between the middle and quarter section lines (minor division
// markers) or just over the middle line.
//
// 2. This class was not intended to be instanciated. See moving_scale
// and gauge_instr classes.
//============================================================================
instr_scale::instr_scale(
int x,
int y,
UINT width,
UINT height,
FLTFNPTR load_fn,
UINT options,
float show_range,
float maxValue,
float minValue,
float disp_scale,
UINT major_divs,
UINT minor_divs,
UINT rollover,
int dp_showing,
bool working) :
instr_item( x, y, width, height, load_fn, disp_scale, options, working),
range_shown ( show_range ),
Maximum_value( maxValue ),
Minimum_value( minValue ),
Maj_div ( major_divs ),
Min_div ( minor_divs ),
Modulo ( rollover ),
signif_digits( dp_showing )
{
int temp;
scale_factor = (float)get_span() / range_shown;
if (show_range < 0)
range_shown = -range_shown;
temp = float_to_int(Maximum_value - Minimum_value) / 100;
if (range_shown < temp)
range_shown = temp;
}

View file

@ -1,241 +0,0 @@
//
// Turn Bank Indicator
//
#include <math.h>
#include "hud.hxx"
// FIXME
extern float get_roll(void);
extern float get_sideslip(void);
// x, y, width, height, get_roll, get_sideslip, maxBankAngle, maxSlipAngle, gap_width, working, tsi, rad
// int x, int y, UINT width, UINT height, FLTFNPTR chn1_source, FLTFNPTR chn2_source, float maxBankAngle,
// float maxSlipAngle, UINT gap_width, bool working, bool tsivalue, float radius) :
fgTBI_instr::fgTBI_instr(const SGPropertyNode *node) :
dual_instr_item(
node->getIntValue("x"),
node->getIntValue("y"),
node->getIntValue("width"),
node->getIntValue("height"),
get_roll, // FIXME
get_sideslip,
node->getBoolValue("working", true),
HUDS_TOP),
BankLimit(int(node->getFloatValue("maxBankAngle"))),
SlewLimit(int(node->getFloatValue("maxSlipAngle"))),
scr_hole(node->getIntValue("gap_width")),
tsi(node->getBoolValue("tsi")),
rad(node->getFloatValue("rad"))
{
SG_LOG(SG_INPUT, SG_BULK, "Done reading TBI instrument"
<< node->getStringValue("name", "[unnamed]"));
}
void fgTBI_instr::draw(void)
{
float bank_angle, sideslip_angle;
float ss_const; // sideslip angle pixels per rad
float cen_x, cen_y, bank, fspan, tee, hole;
int span = get_span();
float zero = 0.0;
RECT My_box = get_location();
POINT centroid = get_centroid();
int tee_height = My_box.bottom;
bank_angle = current_ch2(); // Roll limit +/- 30 degrees
if (bank_angle < -SGD_PI_2 / 3)
bank_angle = -SGD_PI_2 / 3;
else if (bank_angle > SGD_PI_2 / 3)
bank_angle = SGD_PI_2 / 3;
sideslip_angle = current_ch1(); // Sideslip limit +/- 20 degrees
if (sideslip_angle < -SGD_PI / 9)
sideslip_angle = -SGD_PI / 9;
else if ( sideslip_angle > SGD_PI / 9 )
sideslip_angle = SGD_PI / 9;
cen_x = centroid.x;
cen_y = centroid.y;
bank = bank_angle * SGD_RADIANS_TO_DEGREES;
tee = -tee_height;
fspan = span;
hole = scr_hole;
ss_const = 2 * sideslip_angle * fspan / (SGD_2PI / 9); // width represents 40 degrees
// printf("side_slip: %f fspan: %f\n", sideslip_angle, fspan);
// printf("ss_const: %f hole: %f\n", ss_const, hole);
glPushMatrix();
glTranslatef(cen_x, cen_y, zero);
glRotatef(-bank, zero, zero, 1.0);
if (!tsi) {
glBegin(GL_LINES);
if (!scr_hole) {
glVertex2f(-fspan, zero);
glVertex2f(fspan, zero);
} else {
glVertex2f(-fspan, zero);
glVertex2f(-hole, zero);
glVertex2f(hole, zero);
glVertex2f(fspan, zero);
}
// draw teemarks
glVertex2f(hole, zero);
glVertex2f(hole, tee);
glVertex2f(-hole, zero);
glVertex2f(-hole, tee);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(ss_const, -hole);
glVertex2f(ss_const + hole, zero);
glVertex2f(ss_const, hole);
glVertex2f(ss_const - hole, zero);
glEnd();
} else { //if tsi enabled
drawOneLine(cen_x-1.0, My_box.top, cen_x + 1.0, My_box.top);
drawOneLine(cen_x-1.0, My_box.top, cen_x - 1.0, My_box.top + 10.0);
drawOneLine(cen_x+1.0, My_box.top, cen_x + 1.0, My_box.top + 10.0);
drawOneLine(cen_x-1.0, My_box.top + 10.0, cen_x + 1.0, My_box.top + 10.0);
float x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
float xc, yc, r = rad, r1 = rad - 10.0, r2 = rad - 5.0;
xc = My_box.left + My_box.right / 2.0 ;
yc = My_box.top + r;
// first n last lines
x1 = xc + r * cos(255.0 * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin(255.0 * SGD_DEGREES_TO_RADIANS);
x2 = xc + r1 * cos(255.0 * SGD_DEGREES_TO_RADIANS);
y2 = yc + r1 * sin(255.0 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1,y1,x2,y2);
x1 = xc + r * cos(285.0 * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin(285.0 * SGD_DEGREES_TO_RADIANS);
x2 = xc + r1 * cos(285.0 * SGD_DEGREES_TO_RADIANS);
y2 = yc + r1 * sin(285.0 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1, y1, x2, y2);
// second n fifth lines
x1 = xc + r * cos(260.0 * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin(260.0 * SGD_DEGREES_TO_RADIANS);
x2 = xc + r2 * cos(260.0 * SGD_DEGREES_TO_RADIANS);
y2 = yc + r2 * sin(260.0 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1, y1, x2, y2);
x1 = xc + r * cos(280.0 * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin(280.0 * SGD_DEGREES_TO_RADIANS);
x2 = xc + r2 * cos(280.0 * SGD_DEGREES_TO_RADIANS);
y2 = yc + r2 * sin(280.0 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1, y1, x2, y2);
// third n fourth lines
x1 = xc + r * cos(265.0 * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin(265.0 * SGD_DEGREES_TO_RADIANS);
x2 = xc + r2 * cos(265.0 * SGD_DEGREES_TO_RADIANS);
y2 = yc + r2 * sin(265.0 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1, y1, x2, y2);
x1 = xc + r * cos(275.0 * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin(275.0 * SGD_DEGREES_TO_RADIANS);
x2 = xc + r2 * cos(275.0 * SGD_DEGREES_TO_RADIANS);
y2 = yc + r2 * sin(275.0 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1,y1,x2,y2);
// draw marker
float valbank, valsideslip, sideslip;
r = rad + 5.0; // add gap
// upper polygon
bank_angle = current_ch2();
bank = bank_angle * SGD_RADIANS_TO_DEGREES; // Roll limit +/- 30 degrees
if (bank > BankLimit)
bank = BankLimit;
if (bank < -1.0*BankLimit)
bank = -1.0*BankLimit;
valbank = bank * 15.0 / BankLimit; // total span of TSI is 30 degrees
sideslip_angle = current_ch1(); // Sideslip limit +/- 20 degrees
sideslip = sideslip_angle * SGD_RADIANS_TO_DEGREES;
if (sideslip > SlewLimit)
sideslip = SlewLimit;
if (sideslip < -1.0 * SlewLimit)
sideslip = -1.0 * SlewLimit;
valsideslip = sideslip * 15.0 / SlewLimit;
// values 270, 225 and 315 are angles in degrees...
x1 = xc + r * cos((valbank + 270.0) * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin((valbank + 270.0) * SGD_DEGREES_TO_RADIANS);
x2 = x1 + 6.0 * cos(225 * SGD_DEGREES_TO_RADIANS);
y2 = y1 + 6.0 * sin(225 * SGD_DEGREES_TO_RADIANS);
x3 = x1 + 6.0 * cos(315 * SGD_DEGREES_TO_RADIANS);
y3 = y1 + 6.0 * sin(315 * SGD_DEGREES_TO_RADIANS);
drawOneLine(x1, y1, x2, y2);
drawOneLine(x2, y2, x3, y3);
drawOneLine(x3, y3, x1, y1);
// lower polygon
x1 = xc + r * cos((valbank + 270.0) * SGD_DEGREES_TO_RADIANS);
y1 = yc + r * sin((valbank + 270.0) * SGD_DEGREES_TO_RADIANS);
x2 = x1 + 6.0 * cos(225 * SGD_DEGREES_TO_RADIANS);
y2 = y1 + 6.0 * sin(225 * SGD_DEGREES_TO_RADIANS);
x3 = x1 + 6.0 * cos(315 * SGD_DEGREES_TO_RADIANS);
y3 = y1 + 6.0 * sin(315 * SGD_DEGREES_TO_RADIANS);
x4 = x1 + 10.0 * cos(225 * SGD_DEGREES_TO_RADIANS);
y4 = y1 + 10.0 * sin(225 * SGD_DEGREES_TO_RADIANS);
x5 = x1 + 10.0 * cos(315 * SGD_DEGREES_TO_RADIANS);
y5 = y1 + 10.0 * sin(315 * SGD_DEGREES_TO_RADIANS);
x2 = x2 + cos(valsideslip * SGD_DEGREES_TO_RADIANS);
y2 = y2 + sin(valsideslip * SGD_DEGREES_TO_RADIANS);
x3 = x3 + cos(valsideslip * SGD_DEGREES_TO_RADIANS);
y3 = y3 + sin(valsideslip * SGD_DEGREES_TO_RADIANS);
x4 = x4 + cos(valsideslip * SGD_DEGREES_TO_RADIANS);
y4 = y4 + sin(valsideslip * SGD_DEGREES_TO_RADIANS);
x5 = x5 + cos(valsideslip * SGD_DEGREES_TO_RADIANS);
y5 = y5 + sin(valsideslip * SGD_DEGREES_TO_RADIANS);
drawOneLine(x2, y2, x3, y3);
drawOneLine(x3, y3, x5, y5);
drawOneLine(x5, y5, x4, y4);
drawOneLine(x4, y4, x2, y2);
}
glPopMatrix();
}

View file

@ -61,9 +61,6 @@
#include <Main/viewer.hxx> #include <Main/viewer.hxx>
#include <Instrumentation/dclgps.hxx> #include <Instrumentation/dclgps.hxx>
#include "hud.hxx"
#define WIN_X 0 #define WIN_X 0
#define WIN_Y 0 #define WIN_Y 0
#define WIN_W 1024 #define WIN_W 1024

View file

@ -24,8 +24,11 @@
# include <config.h> # include <config.h>
#endif #endif
#include <cstring>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/io/lowlevel.hxx> // endian tests #include <simgear/io/lowlevel.hxx> // endian tests
#include <simgear/io/sg_netBuffer.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include <Network/native_ctrls.hxx> #include <Network/native_ctrls.hxx>
@ -34,6 +37,49 @@
#include "ExternalNet.hxx" #include "ExternalNet.hxx"
class HTTPClient : public simgear::NetBufferChannel
{
bool done;
SGTimeStamp start;
public:
HTTPClient ( const char* host, int port, const char* path ) :
done( false )
{
open ();
connect (host, port);
char buffer[256];
::snprintf (buffer, 256, "GET %s HTTP/1.0\r\n\r\n", path );
bufferSend(buffer, strlen(buffer) ) ;
start.stamp();
}
virtual void handleBufferRead (simgear::NetBuffer& buffer)
{
const char* s = buffer.getData();
while (*s)
fputc(*s++,stdout);
printf("done\n");
buffer.remove();
printf("after buffer.remove()\n");
done = true;
}
bool isDone() const { return done; }
bool isDone( long usec ) const {
if ( start + SGTimeStamp::fromUSec(usec) < SGTimeStamp::now() ) {
return true;
} else {
return done;
}
}
};
FGExternalNet::FGExternalNet( double dt, string host, int dop, int dip, int cp ) FGExternalNet::FGExternalNet( double dt, string host, int dop, int dip, int cp )
{ {
// set_delta_t( dt ); // set_delta_t( dt );

View file

@ -23,59 +23,14 @@
#ifndef _EXTERNAL_NET_HXX #ifndef _EXTERNAL_NET_HXX
#define _EXTERNAL_NET_HXX #define _EXTERNAL_NET_HXX
#include <plib/netBuffer.h>
#include <plib/netSocket.h>
#include <simgear/timing/timestamp.hxx> // fine grained timing measurements #include <simgear/timing/timestamp.hxx> // fine grained timing measurements
#include <simgear/io/raw_socket.hxx>
#include <Network/net_ctrls.hxx> #include <Network/net_ctrls.hxx>
#include <Network/net_fdm.hxx> #include <Network/net_fdm.hxx>
#include <FDM/flight.hxx> #include <FDM/flight.hxx>
class HTTPClient : public netBufferChannel
{
bool done;
SGTimeStamp start;
public:
HTTPClient ( const char* host, int port, const char* path ) :
done( false )
{
open ();
connect (host, port);
const char* s = netFormat ( "GET %s HTTP/1.0\r\n\r\n", path );
bufferSend( s, strlen(s) ) ;
start.stamp();
}
virtual void handleBufferRead (netBuffer& buffer)
{
const char* s = buffer.getData();
while (*s)
fputc(*s++,stdout);
printf("done\n");
buffer.remove();
printf("after buffer.remove()\n");
done = true;
}
bool isDone() const { return done; }
bool isDone( long usec ) const {
if ( start + SGTimeStamp::fromUSec(usec) < SGTimeStamp::now() ) {
return true;
} else {
return done;
}
}
};
class FGExternalNet: public FGInterface { class FGExternalNet: public FGInterface {
private: private:
@ -85,8 +40,8 @@ private:
int cmd_port; int cmd_port;
string fdm_host; string fdm_host;
netSocket data_client; simgear::Socket data_client;
netSocket data_server; simgear::Socket data_server;
bool valid; bool valid;

View file

@ -71,16 +71,9 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.80 2010/08/21 22:56:10 jberndt Exp $"; static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.82 2010/10/07 03:17:29 jberndt Exp $";
static const char *IdHdr = ID_FDMEXEC; static const char *IdHdr = ID_FDMEXEC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GLOBAL DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
unsigned int FGFDMExec::FDMctr = 0;
FGPropertyManager* FGFDMExec::master=0;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@ -102,11 +95,21 @@ void checkTied ( FGPropertyManager *node )
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Constructor // Constructors
FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root), delete_root(false)
FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
{ {
FDMctr = new unsigned int;
*FDMctr = 0;
Initialize();
}
FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root), delete_root(false), FDMctr(fdmctr)
{
Initialize();
}
void FGFDMExec::Initialize()
{
Frame = 0; Frame = 0;
Error = 0; Error = 0;
GroundCallback = 0; GroundCallback = 0;
@ -138,9 +141,6 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
// run in standalone mode with no initialization file. // run in standalone mode with no initialization file.
IdFDM = FDMctr; // The main (parent) JSBSim instance is always the "zeroth"
FDMctr++; // instance. "child" instances are loaded last.
try { try {
char* num = getenv("JSBSIM_DEBUG"); char* num = getenv("JSBSIM_DEBUG");
if (num) debug_lvl = atoi(num); // set debug level if (num) debug_lvl = atoi(num); // set debug level
@ -148,12 +148,20 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
debug_lvl = 1; debug_lvl = 1;
} }
if (Root == 0) { if (Root == 0) { // Then this is the root FDM
if (master == 0) Root = new FGPropertyManager; // Create the property manager
master = new FGPropertyManager; delete_root = true;
Root = master;
FDMctr = new unsigned int; // Create and initialize the child FDM counter
(*FDMctr) = 0;
} }
// Store this FDM's ID
IdFDM = (*FDMctr); // The main (parent) JSBSim instance is always the "zeroth"
// Prepare FDMctr for the next child FDM id
(*FDMctr)++; // instance. "child" instances are loaded last.
instance = Root->GetNode("/fdm/jsbsim",IdFDM,true); instance = Root->GetNode("/fdm/jsbsim",IdFDM,true);
Debug(0); Debug(0);
// this is to catch errors in binding member functions to the property tree. // this is to catch errors in binding member functions to the property tree.
@ -186,7 +194,18 @@ FGFDMExec::~FGFDMExec()
try { try {
checkTied( instance ); checkTied( instance );
DeAllocate(); DeAllocate();
if (Root == 0) delete master;
if (IdFDM == 0) { // Meaning this is no child FDM
if(Root != 0) {
if (delete_root)
delete Root;
Root = 0;
}
if(FDMctr != 0) {
delete FDMctr;
FDMctr = 0;
}
}
} catch ( string msg ) { } catch ( string msg ) {
cout << "Caught error: " << msg << endl; cout << "Caught error: " << msg << endl;
} }
@ -439,7 +458,7 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::LoadScript(string script, double deltaT) bool FGFDMExec::LoadScript(const string& script, double deltaT)
{ {
bool result; bool result;
@ -451,8 +470,8 @@ bool FGFDMExec::LoadScript(string script, double deltaT)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string SystemsPath, bool FGFDMExec::LoadModel(const string& AircraftPath, const string& EnginePath, const string& SystemsPath,
string model, bool addModelToPath) const string& model, bool addModelToPath)
{ {
FGFDMExec::AircraftPath = RootDir + AircraftPath; FGFDMExec::AircraftPath = RootDir + AircraftPath;
FGFDMExec::EnginePath = RootDir + EnginePath; FGFDMExec::EnginePath = RootDir + EnginePath;
@ -463,7 +482,7 @@ bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string Systems
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::LoadModel(string model, bool addModelToPath) bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
{ {
string token; string token;
string aircraftCfgFileName; string aircraftCfgFileName;
@ -730,7 +749,7 @@ void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGFDMExec::QueryPropertyCatalog(string in) string FGFDMExec::QueryPropertyCatalog(const string& in)
{ {
string results=""; string results="";
for (unsigned i=0; i<PropertyCatalog.size(); i++) { for (unsigned i=0; i<PropertyCatalog.size(); i++) {
@ -852,7 +871,7 @@ bool FGFDMExec::ReadChild(Element* el)
struct childData* child = new childData; struct childData* child = new childData;
child->exec = new FGFDMExec(); child->exec = new FGFDMExec(Root, FDMctr);
child->exec->SetChild(true); child->exec->SetChild(true);
string childAircraft = el->GetAttributeValue("name"); string childAircraft = el->GetAttributeValue("name");
@ -922,7 +941,7 @@ void FGFDMExec::EnableOutput(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::SetOutputDirectives(string fname) bool FGFDMExec::SetOutputDirectives(const string& fname)
{ {
bool result; bool result;

View file

@ -60,7 +60,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.52 2010/07/04 13:50:21 jberndt Exp $" #define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.54 2010/10/07 03:17:29 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -169,7 +169,7 @@ CLASS DOCUMENTATION
property actually maps toa function call of DoTrim(). property actually maps toa function call of DoTrim().
@author Jon S. Berndt @author Jon S. Berndt
@version $Revision: 1.52 $ @version $Revision: 1.54 $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -206,8 +206,9 @@ class FGFDMExec : public FGJSBBase, public FGXMLFileRead
public: public:
/// Default constructor /// Default constructors
FGFDMExec(FGPropertyManager* root = 0); FGFDMExec(FGPropertyManager* root = 0);
FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr);
/// Default destructor /// Default destructor
~FGFDMExec(); ~FGFDMExec();
@ -252,8 +253,8 @@ public:
@param addModelToPath set to true to add the model name to the @param addModelToPath set to true to add the model name to the
AircraftPath, defaults to true AircraftPath, defaults to true
@return true if successful */ @return true if successful */
bool LoadModel(string AircraftPath, string EnginePath, string SystemsPath, bool LoadModel(const string& AircraftPath, const string& EnginePath, const string& SystemsPath,
string model, bool addModelToPath = true); const string& model, bool addModelToPath = true);
/** Loads an aircraft model. The paths to the aircraft and engine /** Loads an aircraft model. The paths to the aircraft and engine
config file directories must be set prior to calling this. See config file directories must be set prior to calling this. See
@ -265,28 +266,28 @@ public:
@param addModelToPath set to true to add the model name to the @param addModelToPath set to true to add the model name to the
AircraftPath, defaults to true AircraftPath, defaults to true
@return true if successful*/ @return true if successful*/
bool LoadModel(string model, bool addModelToPath = true); bool LoadModel(const string& model, bool addModelToPath = true);
/** Loads a script /** Loads a script
@param Script the full path name and file name for the script to be loaded. @param Script the full path name and file name for the script to be loaded.
@return true if successfully loadsd; false otherwise. */ @return true if successfully loadsd; false otherwise. */
bool LoadScript(string Script, double deltaT); bool LoadScript(const string& Script, double deltaT);
/** Sets the path to the engine config file directories. /** Sets the path to the engine config file directories.
@param path path to the directory under which engine config @param path path to the directory under which engine config
files are kept, for instance "engine" */ files are kept, for instance "engine" */
bool SetEnginePath(string path) { EnginePath = RootDir + path; return true; } bool SetEnginePath(const string& path) { EnginePath = RootDir + path; return true; }
/** Sets the path to the aircraft config file directories. /** Sets the path to the aircraft config file directories.
@param path path to the aircraft directory. For instance: @param path path to the aircraft directory. For instance:
"aircraft". Under aircraft, then, would be directories for various "aircraft". Under aircraft, then, would be directories for various
modeled aircraft such as C172/, x15/, etc. */ modeled aircraft such as C172/, x15/, etc. */
bool SetAircraftPath(string path) { AircraftPath = RootDir + path; return true; } bool SetAircraftPath(const string& path) { AircraftPath = RootDir + path; return true; }
/** Sets the path to the systems config file directories. /** Sets the path to the systems config file directories.
@param path path to the directory under which systems config @param path path to the directory under which systems config
files are kept, for instance "systems" */ files are kept, for instance "systems" */
bool SetSystemsPath(string path) { SystemsPath = RootDir + path; return true; } bool SetSystemsPath(const string& path) { SystemsPath = RootDir + path; return true; }
/// @name Top-level executive State and Model retrieval mechanism /// @name Top-level executive State and Model retrieval mechanism
//@{ //@{
@ -327,28 +328,28 @@ public:
//@} //@}
/// Retrieves the engine path. /// Retrieves the engine path.
inline string GetEnginePath(void) {return EnginePath;} inline const string& GetEnginePath(void) {return EnginePath;}
/// Retrieves the aircraft path. /// Retrieves the aircraft path.
inline string GetAircraftPath(void) {return AircraftPath;} inline const string& GetAircraftPath(void) {return AircraftPath;}
/// Retrieves the systems path. /// Retrieves the systems path.
inline string GetSystemsPath(void) {return SystemsPath;} inline const string& GetSystemsPath(void) {return SystemsPath;}
/// Retrieves the full aircraft path name. /// Retrieves the full aircraft path name.
inline string GetFullAircraftPath(void) {return FullAircraftPath;} inline const string& GetFullAircraftPath(void) {return FullAircraftPath;}
/** Retrieves the value of a property. /** Retrieves the value of a property.
@param property the name of the property @param property the name of the property
@result the value of the specified property */ @result the value of the specified property */
inline double GetPropertyValue(string property) {return instance->GetDouble(property);} inline double GetPropertyValue(const string& property) {return instance->GetDouble(property);}
/** Sets a property value. /** Sets a property value.
@param property the property to be set @param property the property to be set
@param value the value to set the property to */ @param value the value to set the property to */
inline void SetPropertyValue(string property, double value) { inline void SetPropertyValue(const string& property, double value) {
instance->SetDouble(property, value); instance->SetDouble(property, value);
} }
/// Returns the model name. /// Returns the model name.
string GetModelName(void) { return modelName; } const string& GetModelName(void) { return modelName; }
/* /*
/// Returns the current time. /// Returns the current time.
double GetSimTime(void); double GetSimTime(void);
@ -382,12 +383,12 @@ public:
be logged. be logged.
@param fname the filename of an output directives file. @param fname the filename of an output directives file.
*/ */
bool SetOutputDirectives(string fname); bool SetOutputDirectives(const string& fname);
/** Sets (or overrides) the output filename /** Sets (or overrides) the output filename
@param fname the name of the file to output data to @param fname the name of the file to output data to
@return true if successful, false if there is no output specified for the flight model */ @return true if successful, false if there is no output specified for the flight model */
bool SetOutputFileName(string fname) { bool SetOutputFileName(const string& fname) {
if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname); if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
else return false; else return false;
return true; return true;
@ -447,7 +448,7 @@ public:
* @param check The string to search for in the property catalog. * @param check The string to search for in the property catalog.
* @return the carriage-return-delimited string containing all matching strings * @return the carriage-return-delimited string containing all matching strings
* in the catalog. */ * in the catalog. */
string QueryPropertyCatalog(string check); string QueryPropertyCatalog(const string& check);
// Print the contents of the property catalog for the loaded aircraft. // Print the contents of the property catalog for the loaded aircraft.
void PrintPropertyCatalog(void); void PrintPropertyCatalog(void);
@ -495,11 +496,11 @@ public:
/** Sets the root directory where JSBSim starts looking for its system directories. /** Sets the root directory where JSBSim starts looking for its system directories.
@param rootDir the string containing the root directory. */ @param rootDir the string containing the root directory. */
void SetRootDir(string rootDir) {RootDir = rootDir;} void SetRootDir(const string& rootDir) {RootDir = rootDir;}
/** Retrieves teh Root Directory. /** Retrieves teh Root Directory.
@return the string representing the root (base) JSBSim directory. */ @return the string representing the root (base) JSBSim directory. */
string GetRootDir(void) const {return RootDir;} const string& GetRootDir(void) const {return RootDir;}
/** Increments the simulation time. /** Increments the simulation time.
@return the new simulation time. */ @return the new simulation time. */
@ -512,7 +513,6 @@ public:
int GetDebugLevel(void) const {return debug_lvl;}; int GetDebugLevel(void) const {return debug_lvl;};
private: private:
static unsigned int FDMctr;
int Error; int Error;
unsigned int Frame; unsigned int Frame;
unsigned int IdFDM; unsigned int IdFDM;
@ -536,8 +536,6 @@ private:
bool trim_status; bool trim_status;
int ta_mode; int ta_mode;
static FGPropertyManager *master;
FGGroundCallback* GroundCallback; FGGroundCallback* GroundCallback;
FGAtmosphere* Atmosphere; FGAtmosphere* Atmosphere;
FGFCS* FCS; FGFCS* FCS;
@ -557,13 +555,18 @@ private:
FGTrim* Trim; FGTrim* Trim;
FGPropertyManager* Root; FGPropertyManager* Root;
bool delete_root;
FGPropertyManager* instance; FGPropertyManager* instance;
// The FDM counter is used to give each child FDM an unique ID. The root FDM has the ID 0
unsigned int* FDMctr;
vector <string> PropertyCatalog; vector <string> PropertyCatalog;
vector <FGOutput*> Outputs; vector <FGOutput*> Outputs;
vector <childData*> ChildFDMList; vector <childData*> ChildFDMList;
vector <FGModel*> Models; vector <FGModel*> Models;
void Initialize();
bool ReadFileHeader(Element*); bool ReadFileHeader(Element*);
bool ReadChild(Element*); bool ReadChild(Element*);
bool ReadPrologue(Element*); bool ReadPrologue(Element*);

View file

@ -1,178 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGState.cpp
Author: Jon Berndt
Date started: 11/17/98
Called by: FGFDMExec and accessed by all models.
------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser 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 Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
See header file.
HISTORY
--------------------------------------------------------------------------------
11/17/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <cmath>
#include <iostream>
#include "FGState.h"
using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGState.cpp,v 1.15 2009/10/24 22:59:30 jberndt Exp $";
static const char *IdHdr = ID_STATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
MACROS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGState::FGState(FGFDMExec* fdex)
{
FDMExec = fdex;
sim_time = 0.0;
dt = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
// run in standalone mode with no initialization file.
Aircraft = FDMExec->GetAircraft();
Propagate = FDMExec->GetPropagate();
Auxiliary = FDMExec->GetAuxiliary();
FCS = FDMExec->GetFCS();
Atmosphere = FDMExec->GetAtmosphere();
Aerodynamics = FDMExec->GetAerodynamics();
GroundReactions = FDMExec->GetGroundReactions();
Propulsion = FDMExec->GetPropulsion();
PropertyManager = FDMExec->GetPropertyManager();
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGState::~FGState()
{
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGState::Initialize(FGInitialCondition *FGIC)
{
sim_time = 0.0;
Propagate->SetInitialState( FGIC );
Atmosphere->Run();
Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(),
FGIC->GetWindEFpsIC(),
FGIC->GetWindDFpsIC() );
FGColumnVector3 vAeroUVW;
vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
double alpha, beta;
if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
else
alpha = 0.0;
if (vAeroUVW(eV) != 0.0)
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
else
beta = 0.0;
Auxiliary->SetAB(alpha, beta);
double Vt = vAeroUVW.Magnitude();
Auxiliary->SetVt(Vt);
Auxiliary->SetMach(Vt/Atmosphere->GetSoundSpeed());
double qbar = 0.5*Vt*Vt*Atmosphere->GetDensity();
Auxiliary->Setqbar(qbar);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGState::bind(void)
{
PropertyManager->Tie("sim-time-sec", this, &FGState::Getsim_time);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGState::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGState" << endl;
if (from == 1) cout << "Destroyed: FGState" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,166 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGState.h
Author: Jon S. Berndt
Date started: 11/17/98
------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser 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 Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
11/17/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGSTATE_H
#define FGSTATE_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <fstream>
#include <string>
#include <map>
#include "FGJSBBase.h"
#include "initialization/FGInitialCondition.h"
#include "math/FGColumnVector3.h"
#include "math/FGQuaternion.h"
#include "FGFDMExec.h"
#include "models/FGAtmosphere.h"
#include "models/FGFCS.h"
#include "models/FGPropagate.h"
#include "models/FGAuxiliary.h"
#include "models/FGAerodynamics.h"
#include "models/FGAircraft.h"
#include "models/FGGroundReactions.h"
#include "models/FGPropulsion.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_STATE "$Id: FGState.h,v 1.15 2009/10/02 10:30:07 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates the calculation of aircraft state.
<h3>Properties</h3>
@property sim-time-sec (read only) cumulative simulation in seconds.
@author Jon S. Berndt
@version $Revision: 1.15 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGState : public FGJSBBase
{
public:
/** Constructor
@param Executive a pointer to the parent executive object */
FGState(FGFDMExec*);
/// Destructor
~FGState();
/** Initializes the simulation state based on parameters from an Initial Conditions object.
@param FGIC pointer to an initial conditions object.
@see FGInitialConditions. */
void Initialize(FGInitialCondition *FGIC);
/// Returns the cumulative simulation time in seconds.
inline double Getsim_time(void) const { return sim_time; }
/// Returns the simulation delta T.
inline double Getdt(void) {return dt;}
/// Suspends the simulation and sets the delta T to zero.
inline void SuspendIntegration(void) {saved_dt = dt; dt = 0.0;}
/// Resumes the simulation by resetting delta T to the correct value.
inline void ResumeIntegration(void) {dt = saved_dt;}
/** Returns the simulation suspension state.
@return true if suspended, false if executing */
bool IntegrationSuspended(void) {return dt == 0.0;}
/** Sets the current sim time.
@param cur_time the current time
@return the current simulation time. */
inline double Setsim_time(double cur_time) {
sim_time = cur_time;
return sim_time;
}
/** Sets the integration time step for the simulation executive.
@param delta_t the time step in seconds. */
inline void Setdt(double delta_t) { dt = delta_t; }
/** Increments the simulation time.
@return the new simulation time. */
inline double IncrTime(void) {
sim_time+=dt;
return sim_time;
}
/** Prints a summary of simulator state (speed, altitude,
configuration, etc.) */
// void ReportState(void);
private:
double sim_time, dt;
double saved_dt;
FGFDMExec* FDMExec;
FGAircraft* Aircraft;
FGPropagate* Propagate;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
FGAerodynamics* Aerodynamics;
FGGroundReactions* GroundReactions;
FGPropulsion* Propulsion;
FGAuxiliary* Auxiliary;
FGPropertyManager* PropertyManager;
void bind();
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -18,7 +18,7 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
// $Id: JSBSim.cxx,v 1.62 2010/07/14 05:50:40 ehofman Exp $ // $Id: JSBSim.cxx,v 1.63 2010/10/07 03:45:40 jberndt Exp $
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -97,14 +97,15 @@ public:
/** Compute the altitude above ground. */ /** Compute the altitude above ground. */
virtual double GetAGLevel(double t, const FGLocation& l, virtual double GetAGLevel(double t, const FGLocation& l,
FGLocation& cont, FGLocation& cont, FGColumnVector3& n,
FGColumnVector3& n, FGColumnVector3& v) const { FGColumnVector3& v, FGColumnVector3& w) const {
double loc_cart[3] = { l(eX), l(eY), l(eZ) }; double loc_cart[3] = { l(eX), l(eY), l(eZ) };
double contact[3], normal[3], vel[3], agl = 0; double contact[3], normal[3], vel[3], angularVel[3], agl = 0;
mInterface->get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, normal, mInterface->get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, normal,
vel, &agl); vel, angularVel, &agl);
n = FGColumnVector3( normal[0], normal[1], normal[2] ); n = FGColumnVector3( normal[0], normal[1], normal[2] );
v = FGColumnVector3( vel[0], vel[1], vel[2] ); v = FGColumnVector3( vel[0], vel[1], vel[2] );
w = FGColumnVector3( angularVel[0], angularVel[1], angularVel[2] );
cont = FGColumnVector3( contact[0], contact[1], contact[2] ); cont = FGColumnVector3( contact[0], contact[1], contact[2] );
return agl; return agl;
} }
@ -489,7 +490,7 @@ void FGJSBsim::update( double dt )
if ( startup_trim->getBoolValue() ) { if ( startup_trim->getBoolValue() ) {
double contact[3], d[3], agl; double contact[3], d[3], agl;
get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact, get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact,
d, d, &agl); d, d, d, &agl);
double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1] double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1]
+ contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC(); + contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC();
@ -743,7 +744,7 @@ bool FGJSBsim::copy_from_JSBsim()
double loc_cart[3] = { l(FGJSBBase::eX), l(FGJSBBase::eY), l(FGJSBBase::eZ) }; double loc_cart[3] = { l(FGJSBBase::eX), l(FGJSBBase::eY), l(FGJSBBase::eZ) };
double contact[3], d[3], sd, t; double contact[3], d[3], sd, t;
is_valid_m(&t, d, &sd); is_valid_m(&t, d, &sd);
get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, d, d, &sd); get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, d, d, d, &sd);
double rwrad double rwrad
= FGColumnVector3( contact[0], contact[1], contact[2] ).Magnitude(); = FGColumnVector3( contact[0], contact[1], contact[2] ).Magnitude();
_set_Runway_altitude( rwrad - get_Sea_level_radius() ); _set_Runway_altitude( rwrad - get_Sea_level_radius() );
@ -1204,9 +1205,8 @@ void FGJSBsim::update_ic(void)
bool bool
FGJSBsim::get_agl_ft(double t, const double pt[3], double alt_off, FGJSBsim::get_agl_ft(double t, const double pt[3], double alt_off,
double contact[3], double normal[3], double vel[3], double contact[3], double normal[3], double vel[3],
double *agl) double angularVel[3], double *agl)
{ {
double angularVel[3];
const SGMaterial* material; const SGMaterial* material;
simgear::BVHNode::Id id; simgear::BVHNode::Id id;
if (!FGInterface::get_agl_ft(t, pt, alt_off, contact, normal, vel, if (!FGInterface::get_agl_ft(t, pt, alt_off, contact, normal, vel,
@ -1289,10 +1289,12 @@ void FGJSBsim::update_external_forces(double t_off)
double contact[3]; double contact[3];
double ground_normal[3]; double ground_normal[3];
double ground_vel[3]; double ground_vel[3];
double ground_angular_vel[3];
double root_agl_ft; double root_agl_ft;
if (!got_wire) { if (!got_wire) {
bool got = get_agl_ft(t_off, hook_area[1], 0, contact, ground_normal, ground_vel, &root_agl_ft); bool got = get_agl_ft(t_off, hook_area[1], 0, contact, ground_normal,
ground_vel, ground_angular_vel, &root_agl_ft);
if (got && root_agl_ft > 0 && root_agl_ft < hook_length) { if (got && root_agl_ft > 0 && root_agl_ft < hook_length) {
FGColumnVector3 ground_normal_body = Tl2b * (Tec2l * FGColumnVector3(ground_normal[0], ground_normal[1], ground_normal[2])); FGColumnVector3 ground_normal_body = Tl2b * (Tec2l * FGColumnVector3(ground_normal[0], ground_normal[1], ground_normal[2]));
FGColumnVector3 contact_body = Tl2b * Location.LocationToLocal(FGColumnVector3(contact[0], contact[1], contact[2])); FGColumnVector3 contact_body = Tl2b * Location.LocationToLocal(FGColumnVector3(contact[0], contact[1], contact[2]));

View file

@ -58,7 +58,6 @@ FORWARD DECLARATIONS
#include <FDM/JSBSim/FGFDMExec.h> #include <FDM/JSBSim/FGFDMExec.h>
namespace JSBSim { namespace JSBSim {
class FGState;
class FGAtmosphere; class FGAtmosphere;
class FGFCS; class FGFCS;
class FGPropulsion; class FGPropulsion;
@ -86,7 +85,7 @@ CLASS DOCUMENTATION
documentation for main for direction on running JSBSim apart from FlightGear. documentation for main for direction on running JSBSim apart from FlightGear.
@author Curtis L. Olson (original) @author Curtis L. Olson (original)
@author Tony Peden (Maintained and refined) @author Tony Peden (Maintained and refined)
@version $Id: JSBSim.hxx,v 1.13 2010/07/07 20:46:36 andgi Exp $ @version $Id: JSBSim.hxx,v 1.15 2010/10/07 03:45:40 jberndt Exp $
@see main in file JSBSim.cpp (use main() wrapper for standalone usage) @see main in file JSBSim.cpp (use main() wrapper for standalone usage)
*/ */
@ -208,13 +207,12 @@ public:
bool get_agl_ft(double t, const double pt[3], double alt_off, bool get_agl_ft(double t, const double pt[3], double alt_off,
double contact[3], double normal[3], double vel[3], double contact[3], double normal[3], double vel[3],
double *agl); double angularVel[3], double *agl);
private: private:
JSBSim::FGFDMExec *fdmex; JSBSim::FGFDMExec *fdmex;
JSBSim::FGInitialCondition *fgic; JSBSim::FGInitialCondition *fgic;
bool needTrim; bool needTrim;
JSBSim::FGState* State;
JSBSim::FGAtmosphere* Atmosphere; JSBSim::FGAtmosphere* Atmosphere;
JSBSim::FGFCS* FCS; JSBSim::FGFCS* FCS;
JSBSim::FGPropulsion* Propulsion; JSBSim::FGPropulsion* Propulsion;

View file

@ -2,8 +2,8 @@ SUBDIRS = initialization models input_output math
noinst_LIBRARIES = libJSBSim.a noinst_LIBRARIES = libJSBSim.a
libJSBSim_a_SOURCES = FGFDMExec.cpp FGJSBBase.cpp FGState.cpp JSBSim.cxx libJSBSim_a_SOURCES = FGFDMExec.cpp FGJSBBase.cpp JSBSim.cxx
noinst_HEADERS = FGFDMExec.h FGJSBBase.h FGState.h JSBSim.hxx noinst_HEADERS = FGFDMExec.h FGJSBBase.h JSBSim.hxx
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim

View file

@ -62,7 +62,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.44 2010/09/18 22:48:12 jberndt Exp $"; static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.46 2010/09/29 02:19:05 jberndt Exp $";
static const char *IdHdr = ID_INITIALCONDITION; static const char *IdHdr = ID_INITIALCONDITION;
//****************************************************************************** //******************************************************************************
@ -120,7 +120,7 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
FGQuaternion Quat( phi, theta, psi ); FGQuaternion Quat( phi, theta, psi );
Quat.Normalize(); Quat.Normalize();
const FGMatrix33& _Tl2b = Quat.GetT(); // local to body frame // const FGMatrix33& _Tl2b = Quat.GetT(); // local to body frame
const FGMatrix33& _Tb2l = Quat.GetTInv(); // body to local const FGMatrix33& _Tb2l = Quat.GetTInv(); // body to local
FGColumnVector3 _vUVW_BODY(u,v,w); FGColumnVector3 _vUVW_BODY(u,v,w);
@ -863,17 +863,22 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
} }
double version = document->GetAttributeValueAsNumber("version"); double version = document->GetAttributeValueAsNumber("version");
bool result = false;
if (version == HUGE_VAL) { if (version == HUGE_VAL) {
return Load_v1(); // Default to the old version result = Load_v1(); // Default to the old version
} else if (version >= 3.0) { } else if (version >= 3.0) {
cerr << "Only initialization file formats 1 and 2 are currently supported" << endl; cerr << "Only initialization file formats 1 and 2 are currently supported" << endl;
exit (-1); exit (-1);
} else if (version >= 2.0) { } else if (version >= 2.0) {
return Load_v2(); result = Load_v2();
} else if (version >= 1.0) { } else if (version >= 1.0) {
return Load_v1(); result = Load_v1();
} }
fdmex->GetPropagate()->DumpState();
return result;
} }
//****************************************************************************** //******************************************************************************
@ -962,6 +967,7 @@ bool FGInitialCondition::Load_v1(void)
bool FGInitialCondition::Load_v2(void) bool FGInitialCondition::Load_v2(void)
{ {
int n; int n;
double epa = 0.0;
FGColumnVector3 vLoc, vOrient; FGColumnVector3 vLoc, vOrient;
bool result = true; bool result = true;
FGInertial* Inertial = fdmex->GetInertial(); FGInertial* Inertial = fdmex->GetInertial();
@ -969,10 +975,10 @@ bool FGInitialCondition::Load_v2(void)
FGColumnVector3 vOmegaEarth = FGColumnVector3(0.0, 0.0, Inertial->omega()); FGColumnVector3 vOmegaEarth = FGColumnVector3(0.0, 0.0, Inertial->omega());
if (document->FindElement("earth_position_angle")) { if (document->FindElement("earth_position_angle")) {
double epa = document->FindElementValueAsNumberConvertTo("earth_position_angle", "RAD"); epa = document->FindElementValueAsNumberConvertTo("earth_position_angle", "RAD");
}
Inertial->SetEarthPositionAngle(epa); Inertial->SetEarthPositionAngle(epa);
Propagate->GetVState()->vLocation.SetEarthPositionAngle(epa); Propagate->GetVState()->vLocation.SetEarthPositionAngle(epa);
}
Propagate->SetSeaLevelRadius(GetSeaLevelRadiusFtIC()); Propagate->SetSeaLevelRadius(GetSeaLevelRadiusFtIC());
@ -989,15 +995,15 @@ bool FGInitialCondition::Load_v2(void)
Element* position = document->FindElement("position"); Element* position = document->FindElement("position");
if (position) { if (position) {
vLoc = position->FindElementTripletConvertTo("FT");
string frame = position->GetAttributeValue("frame"); string frame = position->GetAttributeValue("frame");
frame = to_lower(frame); frame = to_lower(frame);
if (frame == "eci") { // Need to transform vLoc to ECEF for storage and use in FGLocation. if (frame == "eci") { // Need to transform vLoc to ECEF for storage and use in FGLocation.
vLoc = position->FindElementTripletConvertTo("FT");
vLoc = Propagate->GetTi2ec()*vLoc; vLoc = Propagate->GetTi2ec()*vLoc;
Propagate->SetLocation(vLoc); Propagate->SetLocation(vLoc);
} else if (frame == "ecef") { } else if (frame == "ecef") {
double AltitudeASL = 0.0; double AltitudeASL = 0.0;
if (vLoc.Magnitude() == 0.0) { if (!position->FindElement("x") && !position->FindElement("y") && !position->FindElement("z")) {
if (position->FindElement("radius")) { if (position->FindElement("radius")) {
AltitudeASL = position->FindElementValueAsNumberConvertTo("radius", "FT") - sea_level_radius; AltitudeASL = position->FindElementValueAsNumberConvertTo("radius", "FT") - sea_level_radius;
} else if (position->FindElement("altitudeAGL")) { } else if (position->FindElement("altitudeAGL")) {
@ -1008,11 +1014,15 @@ bool FGInitialCondition::Load_v2(void)
cerr << endl << " No altitude or radius initial condition is given." << endl; cerr << endl << " No altitude or radius initial condition is given." << endl;
result = false; result = false;
} }
Propagate->SetPosition( double lat_rad=0.0;
position->FindElementValueAsNumberConvertTo("longitude", "RAD"), double long_rad = 0.0;
position->FindElementValueAsNumberConvertTo("latitude", "RAD"), if (position->FindElement("longitude"))
AltitudeASL + GetSeaLevelRadiusFtIC()); long_rad = position->FindElementValueAsNumberConvertTo("longitude", "RAD");
if (position->FindElement("latitude"))
lat_rad = position->FindElementValueAsNumberConvertTo("latitude", "RAD");
Propagate->SetPosition(long_rad, lat_rad, AltitudeASL + GetSeaLevelRadiusFtIC());
} else { } else {
vLoc = position->FindElementTripletConvertTo("FT");
Propagate->SetLocation(vLoc); Propagate->SetLocation(vLoc);
} }
} else { } else {
@ -1072,7 +1082,9 @@ bool FGInitialCondition::Load_v2(void)
// Q_b/i = Q_e/i * Q_b/e // Q_b/i = Q_e/i * Q_b/e
FGQuaternion QuatEC2Body(vOrient); // Store relationship of Body frame wrt ECEF frame, Q_b/e FGQuaternion QuatEC2Body(vOrient); // Store relationship of Body frame wrt ECEF frame, Q_b/e
QuatEC2Body.Normalize();
FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix
QuatI2EC.Normalize();
QuatI2Body = QuatI2EC * QuatEC2Body; // Q_b/i = Q_e/i * Q_b/e QuatI2Body = QuatI2EC * QuatEC2Body; // Q_b/i = Q_e/i * Q_b/e
} else if (frame == "local") { } else if (frame == "local") {
@ -1089,8 +1101,11 @@ bool FGInitialCondition::Load_v2(void)
// Q_b/i = Q_e/i * Q_n/e * Q_b/n // Q_b/i = Q_e/i * Q_n/e * Q_b/n
FGQuaternion QuatLocal2Body = FGQuaternion(vOrient); // Store relationship of Body frame wrt local (NED) frame, Q_b/n FGQuaternion QuatLocal2Body = FGQuaternion(vOrient); // Store relationship of Body frame wrt local (NED) frame, Q_b/n
QuatLocal2Body.Normalize();
FGQuaternion QuatEC2Local = Propagate->GetTec2l(); // Get Q_n/e from matrix FGQuaternion QuatEC2Local = Propagate->GetTec2l(); // Get Q_n/e from matrix
QuatEC2Local.Normalize();
FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix
QuatI2EC.Normalize();
QuatI2Body = QuatI2EC * QuatEC2Local * QuatLocal2Body; // Q_b/i = Q_e/i * Q_n/e * Q_b/n QuatI2Body = QuatI2EC * QuatEC2Local * QuatLocal2Body; // Q_b/i = Q_e/i * Q_n/e * Q_b/n
} else { } else {
@ -1102,6 +1117,7 @@ bool FGInitialCondition::Load_v2(void)
} }
} }
QuatI2Body.Normalize();
Propagate->SetInertialOrientation(QuatI2Body); Propagate->SetInertialOrientation(QuatI2Body);
// Initialize vehicle velocity // Initialize vehicle velocity
@ -1201,7 +1217,9 @@ bool FGInitialCondition::Load_v2(void)
running_elements = document->FindNextElement("running"); running_elements = document->FindNextElement("running");
} }
// fdmex->RunIC(); fdmex->SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0.
fdmex->Run();
fdmex->ResumeIntegration(); // Restores the integration rate to what it was.
return result; return result;
} }

View file

@ -68,9 +68,10 @@ double FGGroundCallback::GetAltitude(const FGLocation& loc) const
double FGGroundCallback::GetAGLevel(double t, const FGLocation& loc, double FGGroundCallback::GetAGLevel(double t, const FGLocation& loc,
FGLocation& contact, FGColumnVector3& normal, FGLocation& contact, FGColumnVector3& normal,
FGColumnVector3& vel) const FGColumnVector3& vel, FGColumnVector3& angularVel) const
{ {
vel = FGColumnVector3(0.0, 0.0, 0.0); vel = FGColumnVector3(0.0, 0.0, 0.0);
angularVel = FGColumnVector3(0.0, 0.0, 0.0);
normal = FGColumnVector3(loc).Normalize(); normal = FGColumnVector3(loc).Normalize();
double loc_radius = loc.GetRadius(); // Get the radius of the given location double loc_radius = loc.GetRadius(); // Get the radius of the given location
// (e.g. the CG) // (e.g. the CG)

View file

@ -45,7 +45,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_GROUNDCALLBACK "$Id: FGGroundCallback.h,v 1.8 2009/10/02 10:30:09 jberndt Exp $" #define ID_GROUNDCALLBACK "$Id: FGGroundCallback.h,v 1.9 2010/10/07 03:45:40 jberndt Exp $"
namespace JSBSim { namespace JSBSim {
@ -59,7 +59,7 @@ CLASS DOCUMENTATION
ball formed earth. ball formed earth.
@author Mathias Froehlich @author Mathias Froehlich
@version $Id: FGGroundCallback.h,v 1.8 2009/10/02 10:30:09 jberndt Exp $ @version $Id: FGGroundCallback.h,v 1.9 2010/10/07 03:45:40 jberndt Exp $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -85,7 +85,8 @@ public:
virtual double GetAltitude(const FGLocation& l) const; virtual double GetAltitude(const FGLocation& l) const;
/** Compute the altitude above ground. Defaults to sealevel altitude. */ /** Compute the altitude above ground. Defaults to sealevel altitude. */
virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont, virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont,
FGColumnVector3& n, FGColumnVector3& v) const; FGColumnVector3& n, FGColumnVector3& v,
FGColumnVector3& w) const;
virtual void SetTerrainGeoCentRadius(double radius) {mReferenceRadius = radius;} virtual void SetTerrainGeoCentRadius(double radius) {mReferenceRadius = radius;}
virtual double GetTerrainGeoCentRadius(void) const {return mReferenceRadius;} virtual double GetTerrainGeoCentRadius(void) const {return mReferenceRadius;}
private: private:

View file

@ -42,7 +42,7 @@ FORWARD DECLARATIONS
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.30 2010/09/04 14:15:15 jberndt Exp $"; static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.31 2010/09/29 02:22:03 jberndt Exp $";
static const char *IdHdr = ID_XMLELEMENT; static const char *IdHdr = ID_XMLELEMENT;
bool Element::converterIsInitialized = false; bool Element::converterIsInitialized = false;
@ -93,10 +93,10 @@ Element::Element(const string& nm)
convert["SLUG*FT2"]["KG*M2"] = 1.35594; convert["SLUG*FT2"]["KG*M2"] = 1.35594;
convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"]; convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
// Angles // Angles
convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926); convert["RAD"]["DEG"] = 180.0/M_PI;
convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"]; convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
// Angular rates // Angular rates
convert["RAD/SEC"]["DEG/SEC"] = 360.0/(2.0*3.1415926); convert["RAD/SEC"]["DEG/SEC"] = convert["RAD"]["DEG"];
convert["DEG/SEC"]["RAD/SEC"] = 1.0/convert["RAD/SEC"]["DEG/SEC"]; convert["DEG/SEC"]["RAD/SEC"] = 1.0/convert["RAD/SEC"]["DEG/SEC"];
// Spring force // Spring force
convert["LBS/FT"]["N/M"] = 14.5939; convert["LBS/FT"]["N/M"] = 14.5939;
@ -478,7 +478,6 @@ FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units
if (!supplied_units.empty()) value *= convert[supplied_units][target_units]; if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
} else { } else {
value = 0.0; value = 0.0;
cerr << "Could not find an X triplet item for this column vector." << endl;
} }
triplet(1) = value; triplet(1) = value;
@ -489,7 +488,6 @@ FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units
if (!supplied_units.empty()) value *= convert[supplied_units][target_units]; if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
} else { } else {
value = 0.0; value = 0.0;
cerr << "Could not find a Y triplet item for this column vector." << endl;
} }
triplet(2) = value; triplet(2) = value;
@ -500,7 +498,6 @@ FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units
if (!supplied_units.empty()) value *= convert[supplied_units][target_units]; if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
} else { } else {
value = 0.0; value = 0.0;
cerr << "Could not find a Z triplet item for this column vector." << endl;
} }
triplet(3) = value; triplet(3) = value;

View file

@ -40,7 +40,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGXMLParse.cpp,v 1.10 2009/10/24 22:59:30 jberndt Exp $"; static const char *IdSrc = "$Id: FGXMLParse.cpp,v 1.11 2010/09/28 02:54:03 jberndt Exp $";
static const char *IdHdr = ID_XMLPARSE; static const char *IdHdr = ID_XMLPARSE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -122,7 +122,7 @@ void FGXMLParse::endElement (const char * name)
{ {
if (!working_string.empty()) { if (!working_string.empty()) {
vector <string> work_strings = split(working_string, '\n'); vector <string> work_strings = split(working_string, '\n');
for (int i=0; i<work_strings.size(); i++) current_element->AddData(work_strings[i]); for (unsigned int i=0; i<work_strings.size(); i++) current_element->AddData(work_strings[i]);
} }
current_element = current_element->GetParent(); current_element = current_element->GetParent();

View file

@ -65,7 +65,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.19 2010/05/13 03:07:59 jberndt Exp $" #define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.20 2010/10/15 11:30:28 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -107,7 +107,7 @@ public:
void Close(void); void Close(void);
bool GetConnectStatus(void) {return connected;} bool GetConnectStatus(void) {return connected;}
enum {ptUDP, ptTCP}; enum ProtocolType {ptUDP, ptTCP} ;
private: private:
int sckt; int sckt;

View file

@ -45,7 +45,7 @@ INCLUDES
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGLocation.cpp,v 1.22 2010/09/18 22:47:17 jberndt Exp $"; static const char *IdSrc = "$Id: FGLocation.cpp,v 1.23 2010/09/22 11:34:09 jberndt Exp $";
static const char *IdHdr = ID_LOCATION; static const char *IdHdr = ID_LOCATION;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
@ -319,7 +319,7 @@ void FGLocation::ComputeDerivedUnconditional(void) const
if (a != 0.0 && b != 0.0) { if (a != 0.0 && b != 0.0) {
double c, p, q, s, t, u, v, w, z, p2, u2, r0; double c, p, q, s, t, u, v, w, z, p2, u2, r0;
double Ne, P, Q0, Q, signz0, sqrt_q; double Ne, P, Q0, Q, signz0, sqrt_q, z_term;
p = fabs(mECLoc(eZ))/eps2; p = fabs(mECLoc(eZ))/eps2;
s = r02/(e2*eps2); s = r02/(e2*eps2);
p2 = p*p; p2 = p*p;
@ -328,8 +328,7 @@ void FGLocation::ComputeDerivedUnconditional(void) const
if (q>0) if (q>0)
{ {
u = p/sqrt_q; u = p/sqrt_q;
// u2 = p2/q; u2 = p2/q;
u2 = u*u;
v = b2*u2/q; v = b2*u2/q;
P = 27.0*v*s/q; P = 27.0*v*s/q;
Q0 = sqrt(P+1) + sqrt(P); Q0 = sqrt(P+1) + sqrt(P);
@ -338,10 +337,11 @@ void FGLocation::ComputeDerivedUnconditional(void) const
c = sqrt(u2 - 1 + 2.0*t); c = sqrt(u2 - 1 + 2.0*t);
w = (c - u)/2.0; w = (c - u)/2.0;
signz0 = mECLoc(eZ)>=0?1.0:-1.0; signz0 = mECLoc(eZ)>=0?1.0:-1.0;
if ((sqrt(t*t+v)-u*w-0.5*t-0.25) < 0.0) { z_term = sqrt(t*t+v)-u*w-0.5*t-0.25;
if (z_term < 0.0) {
z = 0.0; z = 0.0;
} else { } else {
z = signz0*sqrt_q*(w+sqrt(sqrt(t*t+v)-u*w-0.5*t-0.25)); z = signz0*sqrt_q*(w+sqrt(z_term));
} }
Ne = a*sqrt(1+eps2*z*z/b2); Ne = a*sqrt(1+eps2*z*z/b2);
mGeodLat = asin((eps2+1.0)*(z/Ne)); mGeodLat = asin((eps2+1.0)*(z/Ne));

View file

@ -47,7 +47,7 @@ SENTRY
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_QUATERNION "$Id: FGQuaternion.h,v 1.17 2010/06/30 03:13:40 jberndt Exp $" #define ID_QUATERNION "$Id: FGQuaternion.h,v 1.18 2010/09/29 02:19:05 jberndt Exp $"
namespace JSBSim { namespace JSBSim {
@ -177,7 +177,7 @@ public:
const FGMatrix33& GetTInv(void) const { ComputeDerived(); return mTInv; } const FGMatrix33& GetTInv(void) const { ComputeDerived(); return mTInv; }
/** Retrieves the Euler angles. /** Retrieves the Euler angles.
@return a reference to the triad of euler angles corresponding @return a reference to the triad of Euler angles corresponding
to this quaternion rotation. to this quaternion rotation.
units radians */ units radians */
const FGColumnVector3& GetEuler(void) const { const FGColumnVector3& GetEuler(void) const {
@ -186,7 +186,7 @@ public:
} }
/** Retrieves the Euler angles. /** Retrieves the Euler angles.
@param i the euler angle index. @param i the Euler angle index.
units radians. units radians.
@return a reference to the i-th euler angles corresponding @return a reference to the i-th euler angles corresponding
to this quaternion rotation. to this quaternion rotation.
@ -197,7 +197,7 @@ public:
} }
/** Retrieves the Euler angles. /** Retrieves the Euler angles.
@param i the euler angle index. @param i the Euler angle index.
@return a reference to the i-th euler angles corresponding @return a reference to the i-th euler angles corresponding
to this quaternion rotation. to this quaternion rotation.
units degrees */ units degrees */
@ -206,6 +206,15 @@ public:
return radtodeg*mEulerAngles(i); return radtodeg*mEulerAngles(i);
} }
/** Retrieves the Euler angle vector.
@return an Euler angle column vector corresponding
to this quaternion rotation.
units degrees */
FGColumnVector3 const GetEulerDeg(void) const {
ComputeDerived();
return radtodeg*mEulerAngles;
}
/** Retrieves sine of the given euler angle. /** Retrieves sine of the given euler angle.
@return the sine of the Euler angle theta (pitch attitude) corresponding @return the sine of the Euler angle theta (pitch attitude) corresponding
to this quaternion rotation. */ to this quaternion rotation. */

View file

@ -47,7 +47,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGTable.cpp,v 1.23 2010/09/16 11:01:24 jberndt Exp $"; static const char *IdSrc = "$Id: FGTable.cpp,v 1.27 2010/10/21 11:09:56 jberndt Exp $";
static const char *IdHdr = ID_TABLE; static const char *IdHdr = ID_TABLE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -143,13 +143,12 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
internal = true; internal = true;
} else { } else {
// internal table is a child element of a restricted type // internal table is a child element of a restricted type
cerr << endl << fgred << " An internal table cannot be nested within another type," << endl; throw(" An internal table cannot be nested within another type,"
cerr << " such as a function. The 'internal' keyword is ignored." << fgdef << endl << endl; " such as a function. The 'internal' keyword is ignored.");
} }
} else if (!call_type.empty()) { } else if (!call_type.empty()) {
cerr << endl << fgred << " An unknown table type attribute is listed: " << call_type throw(" An unknown table type attribute is listed: "
<< ". Execution cannot continue." << fgdef << endl << endl; ". Execution cannot continue.");
abort();
} }
// Determine and store the lookup properties for this table unless this table // Determine and store the lookup properties for this table unless this table
@ -218,8 +217,7 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
brkpt_string = el->GetAttributeValue("breakPoint"); brkpt_string = el->GetAttributeValue("breakPoint");
if (brkpt_string.empty()) { if (brkpt_string.empty()) {
// no independentVars found, and table is not marked as internal, nor is it a 3D table // no independentVars found, and table is not marked as internal, nor is it a 3D table
cerr << endl << fgred << "No independent variable found for table." << fgdef << endl << endl; throw("No independent variable found for table.");
abort();
} }
} }
// end lookup property code // end lookup property code
@ -249,10 +247,11 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
case 2: case 2:
nRows = tableData->GetNumDataLines()-1; nRows = tableData->GetNumDataLines()-1;
if (nRows >= 2) nCols = FindNumColumns(tableData->GetDataLine(0)); if (nRows >= 2) {
else { nCols = FindNumColumns(tableData->GetDataLine(0));
cerr << endl << fgred << "Not enough rows in this table." << fgdef << endl; if (nCols < 2) throw(string("Not enough columns in table data."));
abort(); } else {
throw(string("Not enough rows in the table data."));
} }
Type = tt2D; Type = tt2D;
@ -290,6 +289,63 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
break; break;
} }
// Sanity checks: lookup indices must be increasing monotonically
unsigned int r,c,b;
// find next xml element containing a name attribute
// to indicate where the error occured
Element* nameel = el;
while (nameel != 0 && nameel->GetAttributeValue("name") == "")
nameel=nameel->GetParent();
// check breakpoints, if applicable
if (dimension > 2) {
for (b=2; b<=nTables; ++b) {
if (Data[b][1] <= Data[b-1][1]) {
stringstream errormsg;
errormsg << fgred << highint << endl
<< " FGTable: breakpoint lookup is not monotonically increasing" << endl
<< " in breakpoint " << b;
if (nameel != 0) errormsg << " of table in " << nameel->GetAttributeValue("name");
errormsg << ":" << reset << endl
<< " " << Data[b][1] << "<=" << Data[b-1][1] << endl;
throw(errormsg.str());
}
}
}
// check columns, if applicable
if (dimension > 1) {
for (c=2; c<=nCols; ++c) {
if (Data[0][c] <= Data[0][c-1]) {
stringstream errormsg;
errormsg << fgred << highint << endl
<< " FGTable: column lookup is not monotonically increasing" << endl
<< " in column " << c;
if (nameel != 0) errormsg << " of table in " << nameel->GetAttributeValue("name");
errormsg << ":" << reset << endl
<< " " << Data[0][c] << "<=" << Data[0][c-1] << endl;
throw(errormsg.str());
}
}
}
// check rows
if (dimension < 3) { // in 3D tables, check only rows of subtables
for (r=2; r<=nRows; ++r) {
if (Data[r][0]<=Data[r-1][0]) {
stringstream errormsg;
errormsg << fgred << highint << endl
<< " FGTable: row lookup is not monotonically increasing" << endl
<< " in row " << r;
if (nameel != 0) errormsg << " of table in " << nameel->GetAttributeValue("name");
errormsg << ":" << reset << endl
<< " " << Data[r][0] << "<=" << Data[r-1][0] << endl;
throw(errormsg.str());
}
}
}
bind(); bind();
if (debug_lvl & 1) Print(); if (debug_lvl & 1) Print();

View file

@ -52,7 +52,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.32 2010/09/07 00:40:03 jberndt Exp $"; static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.34 2010/10/15 11:32:41 jberndt Exp $";
static const char *IdHdr = ID_AERODYNAMICS; static const char *IdHdr = ID_AERODYNAMICS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -349,7 +349,14 @@ bool FGAerodynamics::Load(Element *element)
axis = axis_element->GetAttributeValue("name"); axis = axis_element->GetAttributeValue("name");
function_element = axis_element->FindElement("function"); function_element = axis_element->FindElement("function");
while (function_element) { while (function_element) {
string current_func_name = function_element->GetAttributeValue("name");
try {
ca.push_back( new FGFunction(PropertyManager, function_element) ); ca.push_back( new FGFunction(PropertyManager, function_element) );
} catch (string const str) {
cerr << endl << fgred << "Error loading aerodynamic function in "
<< current_func_name << ":" << str << " Aborting." << reset << endl;
return false;
}
function_element = axis_element->FindNextElement("function"); function_element = axis_element->FindNextElement("function");
} }
Coeff[AxisIdx[axis]] = ca; Coeff[AxisIdx[axis]] = ca;

View file

@ -59,7 +59,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.42 2010/07/27 23:18:19 jberndt Exp $"; static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.44 2010/10/10 15:10:15 jberndt Exp $";
static const char *IdHdr = ID_AUXILIARY; static const char *IdHdr = ID_AUXILIARY;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -173,7 +173,7 @@ bool FGAuxiliary::Run()
vAeroUVW = vUVW - wind; vAeroUVW = vUVW - wind;
Vt = vAeroUVW.Magnitude(); Vt = vAeroUVW.Magnitude();
if ( Vt > 0.05) { if ( Vt > 1.0 ) {
if (vAeroUVW(eW) != 0.0) if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0; alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
if (vAeroUVW(eV) != 0.0) if (vAeroUVW(eV) != 0.0)
@ -182,10 +182,9 @@ bool FGAuxiliary::Run()
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW)); double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
double signU=1; double signU=1;
if (vAeroUVW(eU) != 0.0) if (vAeroUVW(eU) < 0.0) signU=-1;
signU = vAeroUVW(eU)/fabs(vAeroUVW(eU));
if ( (mUW == 0.0) || (Vt == 0.0) ) { if ( mUW < 1.0 ) {
adot = 0.0; adot = 0.0;
bdot = 0.0; bdot = 0.0;
} else { } else {

View file

@ -63,7 +63,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGFCS.cpp,v 1.70 2010/08/21 22:56:11 jberndt Exp $"; static const char *IdSrc = "$Id: FGFCS.cpp,v 1.71 2010/09/28 02:54:03 jberndt Exp $";
static const char *IdHdr = ID_FCS; static const char *IdHdr = ID_FCS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -187,7 +187,7 @@ bool FGFCS::InitModel(void)
void FGFCS::LateBind(void) void FGFCS::LateBind(void)
{ {
int i; unsigned int i;
for (i=0; i<Systems.size(); i++) Systems[i]->LateBind(); for (i=0; i<Systems.size(); i++) Systems[i]->LateBind();
for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind(); for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind();

View file

@ -51,7 +51,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FCS "$Id: FGFCS.h,v 1.30 2010/09/05 17:31:40 jberndt Exp $" #define ID_FCS "$Id: FGFCS.h,v 1.31 2010/09/22 11:33:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -168,7 +168,7 @@ CLASS DOCUMENTATION
@property gear/tailhook-pos-norm @property gear/tailhook-pos-norm
@author Jon S. Berndt @author Jon S. Berndt
@version $Revision: 1.30 $ @version $Revision: 1.31 $
@see FGActuator @see FGActuator
@see FGDeadBand @see FGDeadBand
@see FGFCSFunction @see FGFCSFunction
@ -345,11 +345,6 @@ public:
bool GetPropFeather(int engine) const { return PropFeather[engine]; } bool GetPropFeather(int engine) const { return PropFeather[engine]; }
//@} //@}
/** Retrieves the State object pointer.
This is used by the FGFCS-owned components.
@return pointer to the State object */
FGState* GetState(void) { return State; }
/** Retrieves all component names for inclusion in output stream /** Retrieves all component names for inclusion in output stream
@param delimiter either a tab or comma string depending on output type @param delimiter either a tab or comma string depending on output type
@return a string containing the descriptive names for all components */ @return a string containing the descriptive names for all components */

View file

@ -45,7 +45,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGInertial.cpp,v 1.18 2010/03/28 05:57:00 jberndt Exp $"; static const char *IdSrc = "$Id: FGInertial.cpp,v 1.19 2010/10/10 15:06:38 jberndt Exp $";
static const char *IdHdr = ID_INERTIAL; static const char *IdHdr = ID_INERTIAL;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -148,7 +148,8 @@ FGColumnVector3 FGInertial::GetGravityJ2(FGColumnVector3 position) const
double lat = Propagate->GetLatitude(); double lat = Propagate->GetLatitude();
double sinLat = sin(lat); double sinLat = sin(lat);
double preCommon = 1.5*J2*(a/r)*(a/r); double adivr = a/r;
double preCommon = 1.5*J2*adivr*adivr;
double xy = 1.0 - 5.0*(sinLat*sinLat); double xy = 1.0 - 5.0*(sinLat*sinLat);
double z = 3.0 - 5.0*(sinLat*sinLat); double z = 3.0 - 5.0*(sinLat*sinLat);
double GMOverr2 = GM/(r*r); double GMOverr2 = GM/(r*r);

View file

@ -48,6 +48,7 @@ INCLUDES
#include "FGMassBalance.h" #include "FGMassBalance.h"
#include "math/FGTable.h" #include "math/FGTable.h"
#include <cstdlib> #include <cstdlib>
#include <cstring>
using namespace std; using namespace std;
@ -61,7 +62,7 @@ DEFINITIONS
GLOBAL DATA GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
static const char *IdSrc = "$Id: FGLGear.cpp,v 1.76 2010/07/30 11:50:01 jberndt Exp $"; static const char *IdSrc = "$Id: FGLGear.cpp,v 1.78 2010/10/07 03:45:40 jberndt Exp $";
static const char *IdHdr = ID_LGEAR; static const char *IdHdr = ID_LGEAR;
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@ -76,7 +77,8 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
FGForce(fdmex), FGForce(fdmex),
GearNumber(number), GearNumber(number),
SteerAngle(0.0), SteerAngle(0.0),
Castered(false) Castered(false),
StaticFriction(false)
{ {
Element *force_table=0; Element *force_table=0;
Element *dampCoeff=0; Element *dampCoeff=0;
@ -254,9 +256,7 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
Curvature = 1.03; Curvature = 1.03;
// Initialize Lagrange multipliers // Initialize Lagrange multipliers
LMultiplier[ftRoll].value = 0.; memset(LMultiplier, 0, sizeof(LMultiplier));
LMultiplier[ftSide].value = 0.;
LMultiplier[ftRoll].value = 0.;
Debug(0); Debug(0);
} }
@ -281,13 +281,15 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
if (isRetractable) ComputeRetractionState(); if (isRetractable) ComputeRetractionState();
if (GearDown) { if (GearDown) {
FGColumnVector3 angularVel;
vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear); gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
// Compute the height of the theoretical location of the wheel (if strut is // Compute the height of the theoretical location of the wheel (if strut is
// not compressed) with respect to the ground level // not compressed) with respect to the ground level
double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel); double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel, angularVel);
vGroundNormal = Propagate->GetTec2b() * normal; vGroundNormal = Propagate->GetTec2b() * normal;
// The height returned above is the AGL and is expressed in the Z direction // The height returned above is the AGL and is expressed in the Z direction

View file

@ -47,7 +47,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_LGEAR "$Id: FGLGear.h,v 1.40 2010/07/30 11:50:01 jberndt Exp $" #define ID_LGEAR "$Id: FGLGear.h,v 1.41 2010/09/22 11:33:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -58,7 +58,6 @@ namespace JSBSim {
class FGAircraft; class FGAircraft;
class FGPropagate; class FGPropagate;
class FGFCS; class FGFCS;
class FGState;
class FGMassBalance; class FGMassBalance;
class FGAuxiliary; class FGAuxiliary;
class FGTable; class FGTable;
@ -181,7 +180,7 @@ CLASS DOCUMENTATION
</contact> </contact>
@endcode @endcode
@author Jon S. Berndt @author Jon S. Berndt
@version $Id: FGLGear.h,v 1.40 2010/07/30 11:50:01 jberndt Exp $ @version $Id: FGLGear.h,v 1.41 2010/09/22 11:33:40 jberndt Exp $
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at @see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975 NASA-Ames", NASA CR-2497, January 1975
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics", @see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",

View file

@ -48,7 +48,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_MODEL "$Id: FGModel.h,v 1.15 2010/09/07 00:19:46 jberndt Exp $" #define ID_MODEL "$Id: FGModel.h,v 1.16 2010/09/22 11:33:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -57,7 +57,6 @@ FORWARD DECLARATIONS
namespace JSBSim { namespace JSBSim {
class FGFDMExec; class FGFDMExec;
class FGState;
class FGAtmosphere; class FGAtmosphere;
class FGFCS; class FGFCS;
class FGPropulsion; class FGPropulsion;
@ -119,7 +118,6 @@ protected:
virtual void Debug(int from); virtual void Debug(int from);
FGFDMExec* FDMExec; FGFDMExec* FDMExec;
FGState* State;
FGAtmosphere* Atmosphere; FGAtmosphere* Atmosphere;
FGFCS* FCS; FGFCS* FCS;
FGPropulsion* Propulsion; FGPropulsion* Propulsion;

View file

@ -61,9 +61,6 @@ INCLUDES
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include "input_output/net_fdm.hxx"
#include "input_output/FGfdmSocket.h"
#if defined(WIN32) && !defined(__CYGWIN__) #if defined(WIN32) && !defined(__CYGWIN__)
# include <windows.h> # include <windows.h>
#else #else
@ -77,7 +74,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGOutput.cpp,v 1.48 2010/04/12 12:25:19 jberndt Exp $"; static const char *IdSrc = "$Id: FGOutput.cpp,v 1.49 2010/10/15 11:30:29 jberndt Exp $";
static const char *IdHdr = ID_OUTPUT; static const char *IdHdr = ID_OUTPUT;
// (stolen from FGFS native_fdm.cxx) // (stolen from FGFS native_fdm.cxx)
@ -132,7 +129,6 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
Name = "FGOutput"; Name = "FGOutput";
sFirstPass = dFirstPass = true; sFirstPass = dFirstPass = true;
socket = 0; socket = 0;
flightGearSocket = 0;
runID_postfix = 0; runID_postfix = 0;
Type = otNone; Type = otNone;
SubSystems = 0; SubSystems = 0;
@ -153,7 +149,6 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
FGOutput::~FGOutput() FGOutput::~FGOutput()
{ {
delete socket; delete socket;
delete flightGearSocket;
OutputProperties.clear(); OutputProperties.clear();
Debug(1); Debug(1);
} }
@ -231,6 +226,15 @@ void FGOutput::SetType(const string& type)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGOutput::SetProtocol(const string& protocol)
{
if (protocol == "UDP") Protocol = FGfdmSocket::ptUDP;
else if (protocol == "TCP") Protocol = FGfdmSocket::ptTCP;
else Protocol = FGfdmSocket::ptTCP; // Default to TCP
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGOutput::DelimitedOutput(const string& fname) void FGOutput::DelimitedOutput(const string& fname)
{ {
streambuf* buffer; streambuf* buffer;
@ -566,7 +570,6 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
} }
} }
// Consumables // Consumables
net->num_tanks = Propulsion->GetNumTanks(); // Max number of fuel tanks net->num_tanks = Propulsion->GetNumTanks(); // Max number of fuel tanks
@ -574,7 +577,6 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
net->fuel_quantity[i] = (float)(((FGTank *)Propulsion->GetTank(i))->GetContents()); net->fuel_quantity[i] = (float)(((FGTank *)Propulsion->GetTank(i))->GetContents());
} }
// Gear status // Gear status
net->num_wheels = GroundReactions->GetNumGearUnits(); net->num_wheels = GroundReactions->GetNumGearUnits();
@ -588,13 +590,11 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
net->gear_compression[i] = (float)(GroundReactions->GetGearUnit(i)->GetCompLen()); net->gear_compression[i] = (float)(GroundReactions->GetGearUnit(i)->GetCompLen());
} }
// Environment // Environment
net->cur_time = (long int)1234567890; // Friday, Feb 13, 2009, 23:31:30 UTC (not processed by FGFS anyway) net->cur_time = (long int)1234567890; // Friday, Feb 13, 2009, 23:31:30 UTC (not processed by FGFS anyway)
net->warp = 0; // offset in seconds to unix time net->warp = 0; // offset in seconds to unix time
net->visibility = 25000.0; // visibility in meters (for env. effects) net->visibility = 25000.0; // visibility in meters (for env. effects)
// Control surface positions (normalized values) // Control surface positions (normalized values)
net->elevator = (float)(FCS->GetDePos(ofNorm)); // Norm Elevator Pos, -- net->elevator = (float)(FCS->GetDePos(ofNorm)); // Norm Elevator Pos, --
net->elevator_trim_tab = (float)(FCS->GetPitchTrimCmd()); // Norm Elev Trim Tab Pos, -- net->elevator_trim_tab = (float)(FCS->GetPitchTrimCmd()); // Norm Elev Trim Tab Pos, --
@ -607,7 +607,6 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
net->speedbrake = (float)(FCS->GetDsbPos(ofNorm)); // Norm Speedbrake Pos, -- net->speedbrake = (float)(FCS->GetDsbPos(ofNorm)); // Norm Speedbrake Pos, --
net->spoilers = (float)(FCS->GetDspPos(ofNorm)); // Norm Spoiler Pos, -- net->spoilers = (float)(FCS->GetDspPos(ofNorm)); // Norm Spoiler Pos, --
// Convert the net buffer to network format // Convert the net buffer to network format
if ( isLittleEndian ) { if ( isLittleEndian ) {
net->version = htonl(net->version); net->version = htonl(net->version);
@ -691,12 +690,11 @@ void FGOutput::FlightGearSocketOutput(void)
{ {
int length = sizeof(fgSockBuf); int length = sizeof(fgSockBuf);
if (socket == NULL) return;
if (flightGearSocket == NULL) return; if (!socket->GetConnectStatus()) return;
if (!flightGearSocket->GetConnectStatus()) return;
SocketDataFill(&fgSockBuf); SocketDataFill(&fgSockBuf);
flightGearSocket->Send((char *)&fgSockBuf, length); socket->Send((char *)&fgSockBuf, length);
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -944,11 +942,9 @@ void FGOutput::SocketStatusOutput(const string& out_str)
bool FGOutput::Load(Element* element) bool FGOutput::Load(Element* element)
{ {
string type="", parameter=""; string parameter="";
string name=""; string name="";
string protocol="tcp";
int OutRate = 0; int OutRate = 0;
string property;
unsigned int port; unsigned int port;
Element *property_element; Element *property_element;
@ -967,19 +963,12 @@ bool FGOutput::Load(Element* element)
if (!document) return false; if (!document) return false;
name = FDMExec->GetRootDir() + document->GetAttributeValue("name"); name = FDMExec->GetRootDir() + document->GetAttributeValue("name");
type = document->GetAttributeValue("type"); SetType(document->GetAttributeValue("type"));
SetType(type); Port = document->GetAttributeValue("port");
if (!document->GetAttributeValue("port").empty() && type == string("SOCKET")) { if (!Port.empty() && (Type == otSocket || Type == otFlightGear)) {
port = atoi(document->GetAttributeValue("port").c_str()); port = atoi(Port.c_str());
socket = new FGfdmSocket(name, port); SetProtocol(document->GetAttributeValue("protocol"));
} else if (!document->GetAttributeValue("port").empty() && type == string("FLIGHTGEAR")) { socket = new FGfdmSocket(name, port, Protocol);
port = atoi(document->GetAttributeValue("port").c_str());
if (!document->GetAttributeValue("protocol").empty())
protocol = document->GetAttributeValue("protocol");
if (protocol == "udp")
flightGearSocket = new FGfdmSocket(name, port, FGfdmSocket::ptUDP); // create udp socket
else
flightGearSocket = new FGfdmSocket(name, port, FGfdmSocket::ptTCP); // create tcp socket (default)
} else { } else {
BaseFilename = Filename = name; BaseFilename = Filename = name;
} }

View file

@ -45,12 +45,13 @@ INCLUDES
#include "input_output/FGXMLFileRead.h" #include "input_output/FGXMLFileRead.h"
#include "input_output/net_fdm.hxx" #include "input_output/net_fdm.hxx"
#include "input_output/FGfdmSocket.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_OUTPUT "$Id: FGOutput.h,v 1.17 2009/10/24 22:59:30 jberndt Exp $" #define ID_OUTPUT "$Id: FGOutput.h,v 1.18 2010/10/15 11:30:29 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -123,7 +124,7 @@ CLASS DOCUMENTATION
propulsion ON|OFF propulsion ON|OFF
</pre> </pre>
NOTE that Time is always output with the data. NOTE that Time is always output with the data.
@version $Id: FGOutput.h,v 1.17 2009/10/24 22:59:30 jberndt Exp $ @version $Id: FGOutput.h,v 1.18 2010/10/15 11:30:29 jberndt Exp $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -145,17 +146,19 @@ public:
void SocketStatusOutput(const std::string&); void SocketStatusOutput(const std::string&);
void SocketDataFill(FGNetFDM* net); void SocketDataFill(FGNetFDM* net);
void SetType(const std::string& type); void SetType(const std::string& type);
void SetProtocol(const std::string& protocol);
void SetPort(const std::string& port);
void SetStartNewFile(bool tt) {StartNewFile = tt;} void SetStartNewFile(bool tt) {StartNewFile = tt;}
void SetSubsystems(int tt) {SubSystems = tt;} void SetSubsystems(int tt) {SubSystems = tt;}
void Enable(void) { enabled = true; }
void Disable(void) { enabled = false; }
bool Toggle(void) {enabled = !enabled; return enabled;}
bool Load(Element* el);
void SetOutputFileName(const std::string& fname) {Filename = fname;} void SetOutputFileName(const std::string& fname) {Filename = fname;}
void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;} void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;}
void SetRate(int rt); void SetRate(int rt);
void Enable(void) { enabled = true; }
void Disable(void) { enabled = false; }
bool Toggle(void) {enabled = !enabled; return enabled;}
bool Load(Element* el);
string GetOutputFileName(void) const {return Filename;} string GetOutputFileName(void) const {return Filename;}
/// Subsystem types for specifying which will be output in the FDM data logging /// Subsystem types for specifying which will be output in the FDM data logging
@ -180,14 +183,15 @@ public:
private: private:
enum {otNone, otCSV, otTab, otSocket, otTerminal, otFlightGear, otUnknown} Type; enum {otNone, otCSV, otTab, otSocket, otTerminal, otFlightGear, otUnknown} Type;
FGfdmSocket::ProtocolType Protocol;
bool sFirstPass, dFirstPass, enabled; bool sFirstPass, dFirstPass, enabled;
int SubSystems; int SubSystems;
int runID_postfix; int runID_postfix;
bool StartNewFile; bool StartNewFile;
std::string output_file_name, delimeter, BaseFilename, Filename, DirectivesFile; std::string output_file_name, delimeter, BaseFilename, Filename, DirectivesFile;
std::string Port;
std::ofstream datafile; std::ofstream datafile;
FGfdmSocket* socket; FGfdmSocket* socket;
FGfdmSocket* flightGearSocket;
std::vector <FGPropertyManager*> OutputProperties; std::vector <FGPropertyManager*> OutputProperties;
void Debug(int from); void Debug(int from);

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.65 2010/09/18 22:48:12 jberndt Exp $"; static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.71 2010/10/15 11:34:09 jberndt Exp $";
static const char *IdHdr = ID_PROPAGATE; static const char *IdHdr = ID_PROPAGATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -82,7 +82,7 @@ FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex)
{ {
Debug(0); Debug(0);
Name = "FGPropagate"; Name = "FGPropagate";
gravType = gtStandard; gravType = gtWGS84;
vPQRdot.InitMatrix(); vPQRdot.InitMatrix();
vQtrndot = FGQuaternion(0,0,0); vQtrndot = FGQuaternion(0,0,0);
@ -95,6 +95,7 @@ FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex)
integrator_translational_position = eTrapezoidal; integrator_translational_position = eTrapezoidal;
VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqQtrndot.resize(4, FGQuaternion(0.0,0.0,0.0)); VState.dqQtrndot.resize(4, FGQuaternion(0.0,0.0,0.0));
@ -129,6 +130,7 @@ bool FGPropagate::InitModel(void)
vInertialVelocity.InitMatrix(); vInertialVelocity.InitMatrix();
VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0));
@ -204,6 +206,7 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal; FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal;
VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth; VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
VState.vPQRi_i = Tb2i * VState.vPQRi;
// Make an initial run and set past values // Make an initial run and set past values
InitializeDerivatives(); InitializeDerivatives();
@ -246,10 +249,11 @@ bool FGPropagate::Run(void)
CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame) CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame)
// Propagate rotational / translational velocity, angular /translational position, respectively. // Propagate rotational / translational velocity, angular /translational position, respectively.
Integrate(VState.vPQRi, vPQRdot, VState.dqPQRdot, dt, integrator_rotational_rate);
Integrate(VState.vInertialVelocity, vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate); Integrate(VState.vPQRi_i, vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate); // ECI integration
Integrate(VState.qAttitudeECI, vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position); Integrate(VState.qAttitudeECI, vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position); Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
Integrate(VState.vInertialVelocity, vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
// CAUTION : the order of the operations below is very important to get transformation // CAUTION : the order of the operations below is very important to get transformation
// matrices that are consistent with the new state of the vehicle // matrices that are consistent with the new state of the vehicle
@ -280,6 +284,7 @@ bool FGPropagate::Run(void)
VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet
VState.vPQRi = Ti2b * VState.vPQRi_i;
VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth; VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
VState.qAttitudeLocal = Tl2b.GetQuaternion(); VState.qAttitudeLocal = Tl2b.GetQuaternion();
@ -318,6 +323,7 @@ void FGPropagate::CalculatePQRdot(void)
// frame. // frame.
vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi)); vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
vPQRidot = Tb2i * vPQRdot;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -502,7 +508,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
// Instruct the algorithm to zero out the relative movement between the // Instruct the algorithm to zero out the relative movement between the
// aircraft and the ground. // aircraft and the ground.
vdot += (VState.vUVW - Tec2b * LocalTerrainVelocity) / dt; vdot += (VState.vUVW - Tec2b * LocalTerrainVelocity) / dt;
wdot += VState.vPQR / dt; wdot += (VState.vPQR - Tec2b * LocalTerrainAngularVelocity) / dt;
} }
// Assemble the linear system of equations // Assemble the linear system of equations
@ -557,6 +563,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
vUVWdot += invMass * Fc; vUVWdot += invMass * Fc;
vUVWidot += invMass * Tb2i * Fc; vUVWidot += invMass * Tb2i * Fc;
vPQRdot += Jinv * Mc; vPQRdot += Jinv * Mc;
vPQRidot += Tb2i* Jinv * Mc;
// Save the value of the Lagrange multipliers to accelerate the convergence // Save the value of the Lagrange multipliers to accelerate the convergence
// of the Gauss-Seidel algorithm at next iteration. // of the Gauss-Seidel algorithm at next iteration.
@ -609,7 +616,8 @@ void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::SetInertialRates(FGColumnVector3 vRates) { void FGPropagate::SetInertialRates(FGColumnVector3 vRates) {
VState.vPQRi = Ti2b * vRates; VState.vPQRi_i = vRates;
VState.vPQRi = Ti2b * VState.vPQRi_i;
VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth; VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
} }
@ -626,11 +634,13 @@ void FGPropagate::InitializeDerivatives(void)
// Initialize past values deques // Initialize past values deques
VState.dqPQRdot.clear(); VState.dqPQRdot.clear();
VState.dqPQRidot.clear();
VState.dqUVWidot.clear(); VState.dqUVWidot.clear();
VState.dqInertialVelocity.clear(); VState.dqInertialVelocity.clear();
VState.dqQtrndot.clear(); VState.dqQtrndot.clear();
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
VState.dqPQRdot.push_front(vPQRdot); VState.dqPQRdot.push_front(vPQRdot);
VState.dqPQRidot.push_front(vPQRidot);
VState.dqUVWidot.push_front(vUVWdot); VState.dqUVWidot.push_front(vUVWdot);
VState.dqInertialVelocity.push_front(VState.vInertialVelocity); VState.dqInertialVelocity.push_front(VState.vInertialVelocity);
VState.dqQtrndot.push_front(vQtrndot); VState.dqQtrndot.push_front(vQtrndot);
@ -647,7 +657,7 @@ void FGPropagate::RecomputeLocalTerrainRadius(void)
// Get the LocalTerrain radius. // Get the LocalTerrain radius.
FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv, FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv,
LocalTerrainVelocity); LocalTerrainVelocity, LocalTerrainAngularVelocity);
LocalTerrainRadius = contactloc.GetRadius(); LocalTerrainRadius = contactloc.GetRadius();
} }
@ -712,6 +722,41 @@ void FGPropagate::SetDistanceAGL(double tt)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::DumpState(void)
{
cout << endl;
cout << fgblue
<< "------------------------------------------------------------------" << reset << endl;
cout << highint
<< "State Report at sim time: " << FDMExec->GetSimTime() << " seconds" << reset << endl;
cout << " " << underon
<< "Position" << underoff << endl;
cout << " ECI: " << VState.vInertialPosition.Dump(", ") << " (x,y,z, in ft)" << endl;
cout << " ECEF: " << VState.vLocation << " (x,y,z, in ft)" << endl;
cout << " Local: " << VState.vLocation.GetLatitudeDeg()
<< ", " << VState.vLocation.GetLongitudeDeg()
<< ", " << GetAltitudeASL() << " (lat, lon, alt in deg and ft)" << endl;
cout << endl << " " << underon
<< "Orientation" << underoff << endl;
cout << " ECI: " << VState.qAttitudeECI.GetEulerDeg().Dump(", ") << " (phi, theta, psi in deg)" << endl;
cout << " Local: " << VState.qAttitudeLocal.GetEulerDeg().Dump(", ") << " (phi, theta, psi in deg)" << endl;
cout << endl << " " << underon
<< "Velocity" << underoff << endl;
cout << " ECI: " << VState.vInertialVelocity.Dump(", ") << " (x,y,z in ft/s)" << endl;
cout << " ECEF: " << (GetTb2ec() * VState.vUVW).Dump(", ") << " (x,y,z in ft/s)" << endl;
cout << " Local: " << GetVel() << " (n,e,d in ft/sec)" << endl;
cout << " Body: " << GetUVW() << " (u,v,w in ft/sec)" << endl;
cout << endl << " " << underon
<< "Body Rates (relative to given frame, expressed in body frame)" << underoff << endl;
cout << " ECI: " << (VState.vPQRi*radtodeg).Dump(", ") << " (p,q,r in deg/s)" << endl;
cout << " ECEF: " << (VState.vPQR*radtodeg).Dump(", ") << " (p,q,r in deg/s)" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::bind(void) void FGPropagate::bind(void)
{ {
typedef double (FGPropagate::*PMF)(int) const; typedef double (FGPropagate::*PMF)(int) const;

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.48 2010/09/18 22:48:12 jberndt Exp $" #define ID_PROPAGATE "$Id: FGPropagate.h,v 1.51 2010/10/07 03:45:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -102,7 +102,7 @@ CLASS DOCUMENTATION
@endcode @endcode
@author Jon S. Berndt, Mathias Froehlich @author Jon S. Berndt, Mathias Froehlich
@version $Id: FGPropagate.h,v 1.48 2010/09/18 22:48:12 jberndt Exp $ @version $Id: FGPropagate.h,v 1.51 2010/10/07 03:45:40 jberndt Exp $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -135,6 +135,11 @@ public:
units rad/sec */ units rad/sec */
FGColumnVector3 vPQRi; FGColumnVector3 vPQRi;
/** The angular velocity vector for the vehicle body frame relative to the
ECI frame, expressed in the ECI frame.
units rad/sec */
FGColumnVector3 vPQRi_i;
/** The current orientation of the vehicle, that is, the orientation of the /** The current orientation of the vehicle, that is, the orientation of the
body frame relative to the local, NED frame. */ body frame relative to the local, NED frame. */
FGQuaternion qAttitudeLocal; FGQuaternion qAttitudeLocal;
@ -148,6 +153,7 @@ public:
FGColumnVector3 vInertialPosition; FGColumnVector3 vInertialPosition;
deque <FGColumnVector3> dqPQRdot; deque <FGColumnVector3> dqPQRdot;
deque <FGColumnVector3> dqPQRidot;
deque <FGColumnVector3> dqUVWidot; deque <FGColumnVector3> dqUVWidot;
deque <FGColumnVector3> dqInertialVelocity; deque <FGColumnVector3> dqInertialVelocity;
deque <FGQuaternion> dqQtrndot; deque <FGQuaternion> dqQtrndot;
@ -566,16 +572,6 @@ public:
VState.vInertialPosition = GetTec2i() * VState.vLocation; VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices(); UpdateLocationMatrices();
} }
void SetLocation(const FGLocation& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void SetLocation(const FGColumnVector3& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void SetAltitudeASL(double altASL); void SetAltitudeASL(double altASL);
void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);} void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);}
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; } void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
@ -588,6 +584,16 @@ public:
VehicleRadius = GetRadius(); VehicleRadius = GetRadius();
UpdateLocationMatrices(); UpdateLocationMatrices();
} }
void SetLocation(const FGLocation& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void SetLocation(const FGColumnVector3& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void RecomputeLocalTerrainRadius(void); void RecomputeLocalTerrainRadius(void);
@ -604,6 +610,8 @@ public:
double value; double value;
}; };
void DumpState(void);
private: private:
// state vector // state vector
@ -612,6 +620,7 @@ private:
FGColumnVector3 vVel; FGColumnVector3 vVel;
FGColumnVector3 vPQRdot; FGColumnVector3 vPQRdot;
FGColumnVector3 vPQRidot;
FGColumnVector3 vUVWdot, vUVWidot; FGColumnVector3 vUVWdot, vUVWidot;
FGColumnVector3 vInertialVelocity; FGColumnVector3 vInertialVelocity;
FGColumnVector3 vLocation; FGColumnVector3 vLocation;
@ -633,7 +642,7 @@ private:
FGMatrix33 Tl2i; FGMatrix33 Tl2i;
double LocalTerrainRadius, SeaLevelRadius, VehicleRadius; double LocalTerrainRadius, SeaLevelRadius, VehicleRadius;
FGColumnVector3 LocalTerrainVelocity; FGColumnVector3 LocalTerrainVelocity, LocalTerrainAngularVelocity;
eIntegrateType integrator_rotational_rate; eIntegrateType integrator_rotational_rate;
eIntegrateType integrator_translational_rate; eIntegrateType integrator_translational_rate;
eIntegrateType integrator_rotational_position; eIntegrateType integrator_rotational_position;

View file

@ -65,7 +65,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.40 2010/09/07 00:40:03 jberndt Exp $"; static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.41 2010/10/15 11:32:41 jberndt Exp $";
static const char *IdHdr = ID_PROPULSION; static const char *IdHdr = ID_PROPULSION;
extern short debug_lvl; extern short debug_lvl;
@ -295,6 +295,7 @@ bool FGPropulsion::Load(Element* el)
document->SetParent(engine_element); document->SetParent(engine_element);
type = document->GetName(); type = document->GetName();
try {
if (type == "piston_engine") { if (type == "piston_engine") {
HavePistonEngine = true; HavePistonEngine = true;
if (!IsBound) bind(); if (!IsBound) bind();
@ -319,6 +320,10 @@ bool FGPropulsion::Load(Element* el)
cerr << "Unknown engine type: " << type << endl; cerr << "Unknown engine type: " << type << endl;
exit(-5); exit(-5);
} }
} catch (std::string str) {
cerr << endl << fgred << str << reset << endl;
return false;
}
FCS->AddThrottle(); FCS->AddThrottle();
ThrottleAdded = true; ThrottleAdded = true;

View file

@ -54,7 +54,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGEngine.cpp,v 1.39 2010/08/21 17:13:48 jberndt Exp $"; static const char *IdSrc = "$Id: FGEngine.cpp,v 1.40 2010/10/15 11:32:41 jberndt Exp $";
static const char *IdHdr = ID_ENGINE; static const char *IdHdr = ID_ENGINE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -109,7 +109,11 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
// Load thruster // Load thruster
local_element = engine_element->GetParent()->FindElement("thruster"); local_element = engine_element->GetParent()->FindElement("thruster");
if (local_element) { if (local_element) {
try {
if (!LoadThruster(local_element)) exit(-1); if (!LoadThruster(local_element)) exit(-1);
} catch (std::string str) {
throw("Error loading engine " + Name + ". " + str);
}
} else { } else {
cerr << "No thruster definition supplied with engine definition." << endl; cerr << "No thruster definition supplied with engine definition." << endl;
} }

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.30 2010/05/02 15:10:07 jberndt Exp $"; static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.32 2010/10/21 03:27:40 jberndt Exp $";
static const char *IdHdr = ID_PROPELLER; static const char *IdHdr = ID_PROPELLER;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -105,6 +105,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
table_element = prop_element->FindNextElement("table"); table_element = prop_element->FindNextElement("table");
name = table_element->GetAttributeValue("name"); name = table_element->GetAttributeValue("name");
try {
if (name == "C_THRUST") { if (name == "C_THRUST") {
cThrust = new FGTable(PropertyManager, table_element); cThrust = new FGTable(PropertyManager, table_element);
} else if (name == "C_POWER") { } else if (name == "C_POWER") {
@ -116,6 +117,9 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
} else { } else {
cerr << "Unknown table type: " << name << " in propeller definition." << endl; cerr << "Unknown table type: " << name << " in propeller definition." << endl;
} }
} catch (std::string str) {
throw("Error loading propeller table:" + name + ". " + str);
}
} }
local_element = prop_element->GetParent()->FindElement("sense"); local_element = prop_element->GetParent()->FindElement("sense");
@ -334,7 +338,7 @@ double FGPropeller::GetPowerRequired(void)
if (CL > 1.5) CL = 1.5; if (CL > 1.5) CL = 1.5;
double BladeArea = Diameter * Diameter / 32.0 * numBlades; double BladeArea = Diameter * Diameter / 32.0 * numBlades;
vTorque(eX) = -Sense*BladeArea*Diameter*Vel*Vel*rho*0.19*CL; vTorque(eX) = -Sense*BladeArea*Diameter*Vel*Vel*rho*0.19*CL;
PowerRequired = vTorque(eX)*0.2*M_PI; PowerRequired = fabs(vTorque(eX))*0.2*M_PI;
} }
return PowerRequired; return PowerRequired;

View file

@ -24,6 +24,7 @@
# include <config.h> # include <config.h>
#endif #endif
#include <cassert>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
#include <FDM/fdm_shell.hxx> #include <FDM/fdm_shell.hxx>

View file

@ -10,14 +10,13 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <sys/types.h> #include <sys/types.h>
#include <plib/ul.h>
#include <plib/pu.h> #include <plib/pu.h>
#include <plib/ul.h>
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
@ -56,11 +55,8 @@ void
NewGUI::init () NewGUI::init ()
{ {
setStyle(); setStyle();
char path1[1024]; SGPath p(globals->get_fg_root(), "gui/dialogs");
char path2[1024]; readDir(p);
ulMakePath(path1, globals->get_fg_root().c_str(), "gui");
ulMakePath(path2, path1, "dialogs");
readDir(path2);
_menubar->init(); _menubar->init();
} }
@ -233,19 +229,6 @@ NewGUI::setMenuBarVisible (bool visible)
_menubar->hide(); _menubar->hide();
} }
static bool
test_extension (const char * path, const char * ext)
{
int pathlen = strlen(path);
int extlen = strlen(ext);
for (int i = 1; i <= pathlen && i <= extlen; i++) {
if (path[pathlen-i] != ext[extlen-i])
return false;
}
return true;
}
void void
NewGUI::newDialog (SGPropertyNode* props) NewGUI::newDialog (SGPropertyNode* props)
{ {
@ -260,50 +243,32 @@ NewGUI::newDialog (SGPropertyNode* props)
} }
void void
NewGUI::readDir (const char * path) NewGUI::readDir (const SGPath& path)
{ {
ulDir * dir = ulOpenDir(path); simgear::Dir dir(path);
simgear::PathList xmls = dir.children(simgear::Dir::TYPE_FILE, ".xml");
if (dir == 0) { for (unsigned int i=0; i<xmls.size(); ++i) {
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to read GUI files from "
<< path);
return;
}
for (ulDirEnt * dirEnt = ulReadDir(dir);
dirEnt != 0;
dirEnt = ulReadDir(dir)) {
char subpath[1024];
ulMakePath(subpath, path, dirEnt->d_name);
if (!dirEnt->d_isdir && test_extension(subpath, ".xml")) {
SGPropertyNode * props = new SGPropertyNode; SGPropertyNode * props = new SGPropertyNode;
try { try {
readProperties(subpath, props); readProperties(xmls[i].str(), props);
} catch (const sg_exception &) { } catch (const sg_exception &) {
SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog "
<< subpath); << xmls[i].str());
delete props; delete props;
continue; continue;
} }
SGPropertyNode *nameprop = props->getNode("name"); SGPropertyNode *nameprop = props->getNode("name");
if (!nameprop) { if (!nameprop) {
SG_LOG(SG_INPUT, SG_WARN, "dialog " << subpath SG_LOG(SG_INPUT, SG_WARN, "dialog " << xmls[i].str()
<< " has no name; skipping."); << " has no name; skipping.");
delete props; delete props;
continue; continue;
} }
string name = nameprop->getStringValue(); string name = nameprop->getStringValue();
if (_dialog_props[name])
delete (SGPropertyNode *)_dialog_props[name];
_dialog_props[name] = props; _dialog_props[name] = props;
} }
} }
ulCloseDir(dir);
}

View file

@ -219,7 +219,7 @@ private:
void clear_colors(); void clear_colors();
// Read all the configuration files in a directory. // Read all the configuration files in a directory.
void readDir (const char * path); void readDir (const SGPath& path);
FGMenuBar * _menubar; FGMenuBar * _menubar;
FGDialog * _active_dialog; FGDialog * _active_dialog;

View file

@ -27,7 +27,6 @@
#include <vector> #include <vector>
#include <simgear/structure/SGBinding.hxx> #include <simgear/structure/SGBinding.hxx>
#include <plib/ul.h>
#if defined( UL_WIN32 ) #if defined( UL_WIN32 )
#define TGT_PLATFORM "windows" #define TGT_PLATFORM "windows"

View file

@ -30,8 +30,7 @@
#include "FGDeviceConfigurationMap.hxx" #include "FGDeviceConfigurationMap.hxx"
#include <plib/ul.h> #include <simgear/misc/sg_dir.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <Main/globals.hxx> #include <Main/globals.hxx>
@ -41,11 +40,8 @@ FGDeviceConfigurationMap::FGDeviceConfigurationMap( const char * relative_path,
base(aBase), base(aBase),
childname(aChildname) childname(aChildname)
{ {
SGPath path(globals->get_fg_root());
path.append( relative_path );
int index = 1000; int index = 1000;
scan_dir( path, &index); scan_dir( SGPath(globals->get_fg_root(), relative_path), &index);
PropertyList childNodes = base->getChildren(childname); PropertyList childNodes = base->getChildren(childname);
for (int k = (int)childNodes.size() - 1; k >= 0; k--) { for (int k = (int)childNodes.size() - 1; k >= 0; k--) {
@ -62,21 +58,16 @@ FGDeviceConfigurationMap::~FGDeviceConfigurationMap()
base->removeChildren( childname ); base->removeChildren( childname );
} }
void FGDeviceConfigurationMap::scan_dir( SGPath & path, int *index) void FGDeviceConfigurationMap::scan_dir(const SGPath & path, int *index)
{ {
ulDir *dir = ulOpenDir(path.c_str()); simgear::Dir dir(path);
if (dir) { simgear::PathList children = dir.children(simgear::Dir::TYPE_FILE |
ulDirEnt* dent; simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
while ((dent = ulReadDir(dir)) != 0) {
if (dent->d_name[0] == '.')
continue;
SGPath p(path.str());
p.append(dent->d_name);
scan_dir(p, index);
}
ulCloseDir(dir);
for (unsigned int c=0; c<children.size(); ++c) {
SGPath path(children[c]);
if (path.isDir()) {
scan_dir(path, index);
} else if (path.extension() == "xml") { } else if (path.extension() == "xml") {
SG_LOG(SG_INPUT, SG_DEBUG, "Reading joystick file " << path.str()); SG_LOG(SG_INPUT, SG_DEBUG, "Reading joystick file " << path.str());
SGPropertyNode_ptr n = base->getChild(childname, (*index)++, true); SGPropertyNode_ptr n = base->getChild(childname, (*index)++, true);
@ -84,5 +75,6 @@ void FGDeviceConfigurationMap::scan_dir( SGPath & path, int *index)
n->setStringValue("source", path.c_str()); n->setStringValue("source", path.c_str());
} }
} }
}

View file

@ -30,16 +30,17 @@
#endif #endif
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/misc/sg_path.hxx>
#include <map> #include <map>
class SGPath;
class FGDeviceConfigurationMap : public std::map<std::string,SGPropertyNode_ptr> { class FGDeviceConfigurationMap : public std::map<std::string,SGPropertyNode_ptr> {
public: public:
FGDeviceConfigurationMap ( const char * relative_path, SGPropertyNode_ptr base, const char * childname ); FGDeviceConfigurationMap ( const char * relative_path, SGPropertyNode_ptr base, const char * childname );
virtual ~FGDeviceConfigurationMap(); virtual ~FGDeviceConfigurationMap();
private: private:
void scan_dir( SGPath & path, int *index); void scan_dir(const SGPath & path, int *index);
SGPropertyNode_ptr base; SGPropertyNode_ptr base;
const char * childname; const char * childname;
}; };

View file

@ -66,7 +66,7 @@ bool FGEventSetting::Test()
static inline bool StartsWith( string & s, const char * cp ) static inline bool StartsWith( string & s, const char * cp )
{ {
return s.compare( 0, strlen(cp), cp ) == 0; return s.find( cp ) == 0;
} }
FGInputEvent * FGInputEvent::NewObject( FGInputDevice * device, SGPropertyNode_ptr node ) FGInputEvent * FGInputEvent::NewObject( FGInputDevice * device, SGPropertyNode_ptr node )
@ -223,8 +223,8 @@ FGInputDevice::~FGInputDevice()
if( nasal ) { if( nasal ) {
SGPropertyNode_ptr nasalClose = nasal->getNode("close"); SGPropertyNode_ptr nasalClose = nasal->getNode("close");
if (nasalClose) { if (nasalClose) {
const char *s = nasalClose->getStringValue(); const string s = nasalClose->getStringValue();
nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s, strlen(s), deviceNode ); nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s.c_str(), s.length(), deviceNode );
} }
} }
nas->deleteModule(nasalModule.c_str()); nas->deleteModule(nasalModule.c_str());
@ -253,10 +253,10 @@ void FGInputDevice::Configure( SGPropertyNode_ptr aDeviceNode )
if (nasal) { if (nasal) {
SGPropertyNode_ptr open = nasal->getNode("open"); SGPropertyNode_ptr open = nasal->getNode("open");
if (open) { if (open) {
const char *s = open->getStringValue(); const string s = open->getStringValue();
FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal"); FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
if (nas) if (nas)
nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s, strlen(s), deviceNode ); nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s.c_str(), s.length(), deviceNode );
} }
} }

View file

@ -29,6 +29,8 @@
#include <poll.h> #include <poll.h>
#include <linux/input.h> #include <linux/input.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <fcntl.h>
struct TypeCode { struct TypeCode {
unsigned type; unsigned type;
@ -238,7 +240,7 @@ static EventNameByType EVENT_NAME_BY_TYPE;
struct ltstr { struct ltstr {
bool operator()(const char * s1, const char * s2 ) const { bool operator()(const char * s1, const char * s2 ) const {
return strcmp( s1, s2 ) < 0; return string(s1).compare( s2 ) < 0;
} }
}; };

View file

@ -599,7 +599,6 @@ private:
double _default_heading; double _default_heading;
GLint _view[4]; GLint _view[4];
FGRunway* _runway; FGRunway* _runway;
FGViewer* _cockpit_view;
unsigned short _stipple_out; // stipple pattern of the outline of the runway unsigned short _stipple_out; // stipple pattern of the outline of the runway
unsigned short _stipple_center; // stipple pattern of the center line of the runway unsigned short _stipple_center; // stipple pattern of the center line of the runway
bool _draw_arrow; // draw arrow when runway is not visible in HUD bool _draw_arrow; // draw arrow when runway is not visible in HUD

View file

@ -49,7 +49,6 @@ HUD::Runway::Runway(HUD *hud, const SGPropertyNode *node, float x, float y) :
_scale_dist(node->getDoubleValue("scale-dist-nm")), _scale_dist(node->getDoubleValue("scale-dist-nm")),
_default_pitch(fgGetDouble("/sim/view[0]/config/pitch-pitch-deg", 0.0)), _default_pitch(fgGetDouble("/sim/view[0]/config/pitch-pitch-deg", 0.0)),
_default_heading(fgGetDouble("/sim/view[0]/config/pitch-heading-deg", 0.0)), _default_heading(fgGetDouble("/sim/view[0]/config/pitch-heading-deg", 0.0)),
_cockpit_view(globals->get_viewmgr()->get_view(0)),
_stipple_out(node->getIntValue("outer_stipple", 0xFFFF)), _stipple_out(node->getIntValue("outer_stipple", 0xFFFF)),
_stipple_center(node->getIntValue("center-stipple", 0xFFFF)), _stipple_center(node->getIntValue("center-stipple", 0xFFFF)),
_draw_arrow(_arrow_scale > 0 ? true : false), _draw_arrow(_arrow_scale > 0 ? true : false),
@ -69,7 +68,6 @@ HUD::Runway::Runway(HUD *hud, const SGPropertyNode *node, float x, float y) :
_top = _center_y + (_h / 2) + _y; _top = _center_y + (_h / 2) + _y;
} }
void HUD::Runway::draw() void HUD::Runway::draw()
{ {
_runway = get_active_runway(); _runway = get_active_runway();
@ -87,8 +85,10 @@ void HUD::Runway::draw()
double po = curr_view->getPitchOffset_deg(); double po = curr_view->getPitchOffset_deg();
double ho = curr_view->getHeadingOffset_deg(); double ho = curr_view->getHeadingOffset_deg();
double yaw = -(_cockpit_view->getHeadingOffset_deg() - _default_heading) * SG_DEGREES_TO_RADIANS; FGViewer* cockpitView = globals->get_viewmgr()->get_view(0);
double pitch = (_cockpit_view->getPitchOffset_deg() - _default_pitch) * SG_DEGREES_TO_RADIANS;
double yaw = -(cockpitView->getHeadingOffset_deg() - _default_heading) * SG_DEGREES_TO_RADIANS;
double pitch = (cockpitView->getPitchOffset_deg() - _default_pitch) * SG_DEGREES_TO_RADIANS;
//double roll = fgGetDouble("/sim/view[0]/config/roll-offset-deg",0.0) //TODO: adjust for default roll offset //double roll = fgGetDouble("/sim/view[0]/config/roll-offset-deg",0.0) //TODO: adjust for default roll offset
double sPitch = sin(pitch), cPitch = cos(pitch), double sPitch = sin(pitch), cPitch = cos(pitch),
sYaw = sin(yaw), cYaw = cos(yaw); sYaw = sin(yaw), cYaw = cos(yaw);

View file

@ -55,7 +55,8 @@ FGInstrumentMgr::FGInstrumentMgr () :
_explicitGps(false) _explicitGps(false)
{ {
set_subsystem("od_gauge", new FGODGauge); set_subsystem("od_gauge", new FGODGauge);
set_subsystem("hud", new HUD);
globals->add_subsystem("hud", new HUD, SGSubsystemMgr::DISPLAY);
} }
FGInstrumentMgr::~FGInstrumentMgr () FGInstrumentMgr::~FGInstrumentMgr ()

View file

@ -56,7 +56,6 @@ using std::setfill;
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <Cockpit/panel.hxx> #include <Cockpit/panel.hxx>
#include <Cockpit/hud.hxx>
#include "instrument_mgr.hxx" #include "instrument_mgr.hxx"
#include "od_gauge.hxx" #include "od_gauge.hxx"
@ -331,7 +330,7 @@ wxRadarBg::update (double delta_time_sec)
} }
_radar_ref_rng = _radar_ref_rng_node->getDoubleValue(); _radar_ref_rng = _radar_ref_rng_node->getDoubleValue();
_view_heading = get_heading() * SG_DEGREES_TO_RADIANS; _view_heading = fgGetDouble("/orientation/heading-deg") * SG_DEGREES_TO_RADIANS;
_centerTrans.makeTranslate(0.0f, 0.0f, 0.0f); _centerTrans.makeTranslate(0.0f, 0.0f, 0.0f);
_scale = 200.0 / _range_nm; _scale = 200.0 / _range_nm;
@ -500,7 +499,7 @@ wxRadarBg::update_weather()
if (iradarEcho->lightning || lwc < LWClevel[level]) if (iradarEcho->lightning || lwc < LWClevel[level])
continue; continue;
float radius = sgSqrt(iradarEcho->dist) * SG_METER_TO_NM * _scale; float radius = sqrt(iradarEcho->dist) * SG_METER_TO_NM * _scale;
float size = iradarEcho->radius * 2.0 * SG_METER_TO_NM * _scale; float size = iradarEcho->radius * 2.0 * SG_METER_TO_NM * _scale;
if (radius - size > 180) if (radius - size > 180)
@ -617,7 +616,7 @@ wxRadarBg::update_aircraft()
// double bearing = test_brg * SG_DEGREES_TO_RADIANS; // double bearing = test_brg * SG_DEGREES_TO_RADIANS;
// float angle = calcRelBearing(bearing, _view_heading); // float angle = calcRelBearing(bearing, _view_heading);
double bumpinessFactor = (*ground_echoes_iterator)->bumpiness; double bumpinessFactor = (*ground_echoes_iterator)->bumpiness;
float heading = get_heading(); float heading = fgGetDouble("/orientation/heading-deg");
if ( _display_mode == BSCAN ){ if ( _display_mode == BSCAN ){
test_rng = (*ground_echoes_iterator)->elevation * 6; test_rng = (*ground_echoes_iterator)->elevation * 6;
test_brg = (*ground_echoes_iterator)->bearing; test_brg = (*ground_echoes_iterator)->bearing;

View file

@ -24,11 +24,9 @@ endif
if HAVE_FRAMEWORK_PLIB if HAVE_FRAMEWORK_PLIB
fgfs_PLIB_FW = $(plib_FRAMEWORK) fgfs_PLIB_FW = $(plib_FRAMEWORK)
metar_PLIB_FW = $(plib_FRAMEWORK)
else else
fgfs_PLIB_LIBS = -lplibpuaux -lplibpu -lplibfnt -lplibjs -lplibnet \ fgfs_PLIB_LIBS = -lplibpuaux -lplibpu -lplibfnt -lplibjs \
-lplibsg -lplibul -lplibsg -lplibul
metar_PLIB_LIBS = -lplibnet -lplibul
endif endif
if HAVE_FRAMEWORK_OSG if HAVE_FRAMEWORK_OSG
@ -133,9 +131,8 @@ metar_SOURCES = metar_main.cxx
metar_LDADD = \ metar_LDADD = \
-lsgenvironment -lsgio -lsgbucket -lsgmisc -lsgstructure -lsgdebug \ -lsgenvironment -lsgio -lsgbucket -lsgmisc -lsgstructure -lsgdebug \
$(metar_PLIB_LIBS) $(network_LIBS) \ $(network_LIBS) \
-lz $(base_LIBS) -lz $(base_LIBS)
metar_LDFLAGS = $(metar_PLIB_FW)
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src

View file

@ -25,7 +25,6 @@
#include <Cockpit/panel.hxx> #include <Cockpit/panel.hxx>
#include <Cockpit/panel_io.hxx> #include <Cockpit/panel_io.hxx>
#include <Cockpit/hud.hxx>
#include <Environment/environment.hxx> #include <Environment/environment.hxx>
#include <FDM/flight.hxx> #include <FDM/flight.hxx>
#include <GUI/gui.h> #include <GUI/gui.h>
@ -392,9 +391,11 @@ static bool
do_panel_load (const SGPropertyNode * arg) do_panel_load (const SGPropertyNode * arg)
{ {
string panel_path = string panel_path =
arg->getStringValue("path", arg->getStringValue("path", fgGetString("/sim/panel/path"));
fgGetString("/sim/panel/path", if (panel_path.empty()) {
"Panels/Default/default.xml")); return false;
}
FGPanel * new_panel = fgReadPanel(panel_path); FGPanel * new_panel = fgReadPanel(panel_path);
if (new_panel == 0) { if (new_panel == 0) {
SG_LOG(SG_INPUT, SG_ALERT, SG_LOG(SG_INPUT, SG_ALERT,
@ -452,24 +453,11 @@ do_preferences_load (const SGPropertyNode * arg)
return true; return true;
} }
static void
fix_hud_visibility()
{
if ( !strcmp(fgGetString("/sim/flight-model"), "ada") ) {
globals->get_props()->setBoolValue( "/sim/hud/visibility", true );
if ( globals->get_viewmgr()->get_current() == 1 ) {
globals->get_props()->setBoolValue( "/sim/hud/visibility", false );
}
}
}
static void static void
do_view_next( bool ) do_view_next( bool )
{ {
globals->get_current_view()->setHeadingOffset_deg(0.0); globals->get_current_view()->setHeadingOffset_deg(0.0);
globals->get_viewmgr()->next_view(); globals->get_viewmgr()->next_view();
fix_hud_visibility();
} }
static void static void
@ -477,7 +465,6 @@ do_view_prev( bool )
{ {
globals->get_current_view()->setHeadingOffset_deg(0.0); globals->get_current_view()->setHeadingOffset_deg(0.0);
globals->get_viewmgr()->prev_view(); globals->get_viewmgr()->prev_view();
fix_hud_visibility();
} }
/** /**
@ -488,7 +475,6 @@ do_view_cycle (const SGPropertyNode * arg)
{ {
globals->get_current_view()->setHeadingOffset_deg(0.0); globals->get_current_view()->setHeadingOffset_deg(0.0);
globals->get_viewmgr()->next_view(); globals->get_viewmgr()->next_view();
fix_hud_visibility();
return true; return true;
} }
@ -1305,21 +1291,6 @@ do_increase_visibility (const SGPropertyNode * arg)
return true; return true;
} }
static bool
do_hud_init(const SGPropertyNode *)
{
fgHUDInit(); // minimal HUD
return true;
}
static bool
do_hud_init2(const SGPropertyNode *)
{
fgHUDInit2(); // normal HUD
return true;
}
/** /**
* An fgcommand to allow loading of xml files via nasal, * An fgcommand to allow loading of xml files via nasal,
* the xml file's structure will be made available within * the xml file's structure will be made available within
@ -1519,8 +1490,6 @@ static struct {
{ "replay", do_replay }, { "replay", do_replay },
{ "decrease-visibility", do_decrease_visibility }, { "decrease-visibility", do_decrease_visibility },
{ "increase-visibility", do_increase_visibility }, { "increase-visibility", do_increase_visibility },
{ "hud-init", do_hud_init },
{ "hud-init2", do_hud_init2 },
{ "loadxml", do_load_xml_to_proptree}, { "loadxml", do_load_xml_to_proptree},
{ "savexml", do_save_xml_from_proptree }, { "savexml", do_save_xml_from_proptree },
{ "press-cockpit-button", do_press_cockpit_button }, { "press-cockpit-button", do_press_cockpit_button },

View file

@ -85,7 +85,6 @@
#include <Autopilot/route_mgr.hxx> #include <Autopilot/route_mgr.hxx>
#include <Autopilot/autopilotgroup.hxx> #include <Autopilot/autopilotgroup.hxx>
#include <Cockpit/cockpit.hxx>
#include <Cockpit/panel.hxx> #include <Cockpit/panel.hxx>
#include <Cockpit/panel_io.hxx> #include <Cockpit/panel_io.hxx>
@ -1401,32 +1400,23 @@ bool fgInitSubsystems() {
// AI Traffic manager // AI Traffic manager
globals->add_subsystem("Traffic Manager", new FGTrafficManager, SGSubsystemMgr::POST_FDM); globals->add_subsystem("Traffic Manager", new FGTrafficManager, SGSubsystemMgr::POST_FDM);
if( fgCockpitInit()) {
// Cockpit initialized ok.
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Error in Cockpit initialization!" );
exit(-1);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Add a new 2D panel. // Add a new 2D panel.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
string panel_path = fgGetString("/sim/panel/path", string panel_path(fgGetString("/sim/panel/path"));
"Panels/Default/default.xml"); if (!panel_path.empty()) {
FGPanel* p = fgReadPanel(panel_path);
globals->set_current_panel( fgReadPanel(panel_path) ); if (p) {
if (globals->get_current_panel() == 0) { globals->set_current_panel(p);
p->init();
p->bind();
SG_LOG( SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path );
} else {
SG_LOG( SG_INPUT, SG_ALERT, SG_LOG( SG_INPUT, SG_ALERT,
"Error reading new panel from " << panel_path ); "Error reading new panel from " << panel_path );
} else {
SG_LOG( SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path );
globals->get_current_panel()->init();
globals->get_current_panel()->bind();
} }
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Initialize the controls subsystem. // Initialize the controls subsystem.

View file

@ -167,6 +167,7 @@ FGGlobals::~FGGlobals()
// shut down all subsystems, make sure we take down the // shut down all subsystems, make sure we take down the
// AIModels system first. // AIModels system first.
SGSubsystem* ai = subsystem_mgr->remove("ai_model"); SGSubsystem* ai = subsystem_mgr->remove("ai_model");
ai->unbind();
delete ai; delete ai;
subsystem_mgr->unbind(); subsystem_mgr->unbind();

View file

@ -48,11 +48,11 @@
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/timing/sg_time.hxx> #include <simgear/timing/sg_time.hxx>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
#include <simgear/io/raw_socket.hxx>
#include <Time/light.hxx> #include <Time/light.hxx>
#include <Aircraft/replay.hxx> #include <Aircraft/replay.hxx>
#include <Cockpit/cockpit.hxx> #include <Aircraft/controls.hxx>
#include <Cockpit/hud.hxx>
#include <Model/panelnode.hxx> #include <Model/panelnode.hxx>
#include <Model/acmodel.hxx> #include <Model/acmodel.hxx>
#include <Scenery/scenery.hxx> #include <Scenery/scenery.hxx>
@ -588,8 +588,8 @@ int fgMainInit( int argc, char **argv ) {
fgRegisterIdleHandler( &fgIdleFunction ); fgRegisterIdleHandler( &fgIdleFunction );
fgRegisterDrawHandler( &FGRenderer::update ); fgRegisterDrawHandler( &FGRenderer::update );
// Initialize plib net interface // Initialize sockets (WinSock needs this)
netInit( &argc, argv ); simgear::Socket::initSockets();
// Clouds3D requires an alpha channel // Clouds3D requires an alpha channel
fgOSOpenWindow(true /* request stencil buffer */); fgOSOpenWindow(true /* request stencil buffer */);

View file

@ -80,8 +80,6 @@
#include <Time/light.hxx> #include <Time/light.hxx>
#include <Time/light.hxx> #include <Time/light.hxx>
#include <Cockpit/panel.hxx> #include <Cockpit/panel.hxx>
#include <Cockpit/cockpit.hxx>
#include <Cockpit/hud.hxx>
#include <Model/panelnode.hxx> #include <Model/panelnode.hxx>
#include <Model/modelmgr.hxx> #include <Model/modelmgr.hxx>
#include <Model/acmodel.hxx> #include <Model/acmodel.hxx>
@ -89,7 +87,6 @@
#include <Scenery/redout.hxx> #include <Scenery/redout.hxx>
#include <Scenery/tilemgr.hxx> #include <Scenery/tilemgr.hxx>
#include <GUI/new_gui.hxx> #include <GUI/new_gui.hxx>
#include <Instrumentation/instrument_mgr.hxx>
#include <Instrumentation/HUD/HUD.hxx> #include <Instrumentation/HUD/HUD.hxx>
#include <Environment/precipitation_mgr.hxx> #include <Environment/precipitation_mgr.hxx>
@ -99,6 +96,7 @@
#include "CameraGroup.hxx" #include "CameraGroup.hxx"
#include "FGEventHandler.hxx" #include "FGEventHandler.hxx"
#include <Main/viewer.hxx> #include <Main/viewer.hxx>
#include <Main/viewmgr.hxx>
using namespace osg; using namespace osg;
using namespace simgear; using namespace simgear;
@ -207,10 +205,7 @@ public:
glPushAttrib(GL_ALL_ATTRIB_BITS); glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(~0u); glPushClientAttrib(~0u);
fgCockpitUpdate(&state); HUD *hud = static_cast<HUD*>(globals->get_subsystem("hud"));
FGInstrumentMgr *instr = static_cast<FGInstrumentMgr*>(globals->get_subsystem("instrumentation"));
HUD *hud = static_cast<HUD*>(instr->get_subsystem("hud"));
hud->draw(state); hud->draw(state);
// update the panel subsystem // update the panel subsystem

View file

@ -651,6 +651,8 @@ FGViewer::update (double dt)
} }
} }
recalc(); recalc();
if( fgGetBool( "/sim/rendering/draw-otw", true ) ) {
_cameraGroup->update(toOsg(_absolute_view_pos), toOsg(mViewOrientation)); _cameraGroup->update(toOsg(_absolute_view_pos), toOsg(mViewOrientation));
_cameraGroup->setCameraParameters(get_v_fov(), get_aspect_ratio()); _cameraGroup->setCameraParameters(get_v_fov(), get_aspect_ratio());
} }
}

View file

@ -35,7 +35,6 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <osg/Math> // isNaN #include <osg/Math> // isNaN
#include <plib/netSocket.h>
#include <simgear/misc/stdint.hxx> #include <simgear/misc/stdint.hxx>
#include <simgear/timing/timestamp.hxx> #include <simgear/timing/timestamp.hxx>
@ -411,7 +410,7 @@ FGMultiplayMgr::init (void)
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<mCallsign); SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<mCallsign);
Close(); // Should Init be called twice, close Socket first Close(); // Should Init be called twice, close Socket first
// A memory leak was reported here by valgrind // A memory leak was reported here by valgrind
mSocket = new netSocket(); mSocket = new simgear::Socket();
if (!mSocket->open(false)) { if (!mSocket->open(false)) {
SG_LOG( SG_NETWORK, SG_DEBUG, SG_LOG( SG_NETWORK, SG_DEBUG,
"FGMultiplayMgr::init - Failed to create data socket" ); "FGMultiplayMgr::init - Failed to create data socket" );
@ -731,7 +730,7 @@ FGMultiplayMgr::update(double)
// returned will only be that of the next // returned will only be that of the next
// packet waiting to be processed. // packet waiting to be processed.
////////////////////////////////////////////////// //////////////////////////////////////////////////
netAddress SenderAddress; simgear::IPAddress SenderAddress;
bytes = mSocket->recvfrom(msgBuf.Msg, sizeof(msgBuf.Msg), 0, bytes = mSocket->recvfrom(msgBuf.Msg, sizeof(msgBuf.Msg), 0,
&SenderAddress); &SenderAddress);
////////////////////////////////////////////////// //////////////////////////////////////////////////
@ -815,7 +814,7 @@ FGMultiplayMgr::update(double)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
void void
FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg, FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
const netAddress& SenderAddress, long stamp) const simgear::IPAddress& SenderAddress, long stamp)
{ {
const T_MsgHdr* MsgHdr = Msg.msgHdr(); const T_MsgHdr* MsgHdr = Msg.msgHdr();
if (MsgHdr->MsgLen < sizeof(T_MsgHdr) + sizeof(T_PositionMsg)) { if (MsgHdr->MsgLen < sizeof(T_MsgHdr) + sizeof(T_PositionMsg)) {
@ -965,7 +964,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
void void
FGMultiplayMgr::ProcessChatMsg(const MsgBuf& Msg, FGMultiplayMgr::ProcessChatMsg(const MsgBuf& Msg,
const netAddress& SenderAddress) const simgear::IPAddress& SenderAddress)
{ {
const T_MsgHdr* MsgHdr = Msg.msgHdr(); const T_MsgHdr* MsgHdr = Msg.msgHdr();
if (MsgHdr->MsgLen < sizeof(T_MsgHdr) + 1) { if (MsgHdr->MsgLen < sizeof(T_MsgHdr) + 1) {

View file

@ -38,8 +38,8 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <plib/netSocket.h>
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <simgear/io/raw_socket.hxx>
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
#include <AIModel/AIMultiplayer.hxx> #include <AIModel/AIMultiplayer.hxx>
@ -78,16 +78,16 @@ private:
const std::string& modelName); const std::string& modelName);
FGAIMultiplayer* getMultiplayer(const std::string& callsign); FGAIMultiplayer* getMultiplayer(const std::string& callsign);
void FillMsgHdr(T_MsgHdr *MsgHdr, int iMsgId, unsigned _len = 0u); void FillMsgHdr(T_MsgHdr *MsgHdr, int iMsgId, unsigned _len = 0u);
void ProcessPosMsg(const MsgBuf& Msg, const netAddress& SenderAddress, void ProcessPosMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress,
long stamp); long stamp);
void ProcessChatMsg(const MsgBuf& Msg, const netAddress& SenderAddress); void ProcessChatMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress);
/// maps from the callsign string to the FGAIMultiplayer /// maps from the callsign string to the FGAIMultiplayer
typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap; typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;
MultiPlayerMap mMultiPlayerMap; MultiPlayerMap mMultiPlayerMap;
netSocket* mSocket; simgear::Socket* mSocket;
netAddress mServer; simgear::IPAddress mServer;
bool mHaveServer; bool mHaveServer;
bool mInitialised; bool mInitialised;
std::string mCallsign; std::string mCallsign;

View file

@ -13,9 +13,6 @@
#include <string> #include <string>
#include <plib/ul.h>
#include <plib/netSocket.h>
#include "tiny_xdr.hxx" #include "tiny_xdr.hxx"
/* XDR 8bit integers */ /* XDR 8bit integers */

View file

@ -31,6 +31,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include <stdio.h> //snprintf #include <stdio.h> //snprintf
#ifdef _WIN32 #ifdef _WIN32
# include <io.h> //lseek, read, write # include <io.h> //lseek, read, write
@ -38,8 +40,6 @@
#include <string> #include <string>
#include <plib/ul.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/io/iochannel.hxx> #include <simgear/io/iochannel.hxx>

View file

@ -28,8 +28,6 @@
# include <config.h> # include <config.h>
#endif #endif
#include <plib/netChat.h>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>

View file

@ -32,8 +32,8 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <algorithm> // sort() #include <algorithm> // sort()
#include <stdlib.h> // atoi() atof() #include <cstdlib> // atoi() atof()
#include <cstring>
#include <string> #include <string>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
@ -66,7 +66,7 @@ bool FGHttpd::open() {
bool FGHttpd::process() { bool FGHttpd::process() {
netChannel::poll(); simgear::NetChannel::poll();
return true; return true;
} }

View file

@ -32,7 +32,7 @@
# include <config.h> # include <config.h>
#endif #endif
#include <plib/netChat.h> #include <simgear/io/sg_netChat.hxx>
#include "protocol.hxx" #include "protocol.hxx"
@ -40,10 +40,10 @@
/* simple httpd server that makes an hasty stab at following the http /* simple httpd server that makes an hasty stab at following the http
1.1 rfc. */ 1.1 rfc. */
class HttpdChannel : public netChat class HttpdChannel : public simgear::NetChat
{ {
netBuffer buffer ; simgear::NetBuffer buffer ;
string urlEncode(string); string urlEncode(string);
string urlDecode(string); string urlDecode(string);
@ -61,12 +61,12 @@ public:
} ; } ;
class HttpdServer : private netChannel class HttpdServer : private simgear::NetChannel
{ {
virtual bool writable (void) { return false ; } virtual bool writable (void) { return false ; }
virtual void handleAccept (void) { virtual void handleAccept (void) {
netAddress addr ; simgear::IPAddress addr ;
int handle = accept ( &addr ) ; int handle = accept ( &addr ) ;
SG_LOG( SG_IO, SG_INFO, "Client " << addr.getHost() << ":" << addr.getPort() << " connected" ); SG_LOG( SG_IO, SG_INFO, "Client " << addr.getHost() << ":" << addr.getPort() << " connected" );

View file

@ -31,9 +31,9 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <stdlib.h> // atoi() atof() #include <cstdlib> // atoi() atof()
#include <string> #include <cstring>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/io/iochannel.hxx> #include <simgear/io/iochannel.hxx>
@ -75,7 +75,7 @@ bool FGJpegHttpd::open() {
bool FGJpegHttpd::process() { bool FGJpegHttpd::process() {
netChannel::poll(); simgear::NetChannel::poll();
return true; return true;
} }

View file

@ -32,7 +32,7 @@
# include <config.h> # include <config.h>
#endif #endif
#include <plib/netChat.h> #include <simgear/io/sg_netChat.hxx>
#ifdef FG_JPEG_SERVER #ifdef FG_JPEG_SERVER
# include <simgear/screen/jpgfactory.hxx> # include <simgear/screen/jpgfactory.hxx>
@ -57,10 +57,10 @@ class trJpgFactory;
/* simple httpd server that makes an hasty stab at following the http /* simple httpd server that makes an hasty stab at following the http
1.1 rfc. */ 1.1 rfc. */
class HttpdImageChannel : public netChat class HttpdImageChannel : public simgear::NetChat
{ {
netBuffer buffer ; simgear::NetBuffer buffer ;
trJpgFactory *JpgFactory; trJpgFactory *JpgFactory;
public: public:
@ -89,12 +89,12 @@ public:
}; };
class HttpdImageServer : private netChannel class HttpdImageServer : private simgear::NetChannel
{ {
virtual bool writable (void) { return false ; } virtual bool writable (void) { return false ; }
virtual void handleAccept (void) { virtual void handleAccept (void) {
netAddress addr ; simgear::IPAddress addr ;
int handle = accept ( &addr ) ; int handle = accept ( &addr ) ;
SG_LOG( SG_IO, SG_INFO, "Client " << addr.getHost() << ":" << addr.getPort() << " connected" ); SG_LOG( SG_IO, SG_INFO, "Client " << addr.getHost() << ":" << addr.getPort() << " connected" );

View file

@ -28,8 +28,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <string> #include <cstring>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <string> #include <string>

View file

@ -40,7 +40,7 @@
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <Main/viewmgr.hxx> #include <Main/viewmgr.hxx>
#include <plib/netChat.h> #include <simgear/io/sg_netChat.hxx>
#include "props.hxx" #include "props.hxx"
@ -54,9 +54,9 @@ using std::endl;
* Props connection class. * Props connection class.
* This class represents a connection to props client. * This class represents a connection to props client.
*/ */
class PropsChannel : public netChat class PropsChannel : public simgear::NetChat
{ {
netBuffer buffer; simgear::NetBuffer buffer;
/** /**
* Current property node name. * Current property node name.
@ -471,9 +471,9 @@ FGProps::open()
return false; return false;
} }
netChannel::open(); simgear::NetChannel::open();
netChannel::bind( "", port ); simgear::NetChannel::bind( "", port );
netChannel::listen( 5 ); simgear::NetChannel::listen( 5 );
SG_LOG( SG_IO, SG_INFO, "Props server started on port " << port ); SG_LOG( SG_IO, SG_INFO, "Props server started on port " << port );
set_enabled( true ); set_enabled( true );
@ -496,7 +496,7 @@ FGProps::close()
bool bool
FGProps::process() FGProps::process()
{ {
netChannel::poll(); simgear::NetChannel::poll();
return true; return true;
} }
@ -506,7 +506,7 @@ FGProps::process()
void void
FGProps::handleAccept() FGProps::handleAccept()
{ {
netAddress addr; simgear::IPAddress addr;
int handle = accept( &addr ); int handle = accept( &addr );
SG_LOG( SG_IO, SG_INFO, "Props server accepted connection from " SG_LOG( SG_IO, SG_INFO, "Props server accepted connection from "
<< addr.getHost() << ":" << addr.getPort() ); << addr.getHost() << ":" << addr.getPort() );

View file

@ -30,10 +30,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
using std::string; #include <simgear/io/sg_netChannel.hxx>
using std::vector;
#include <plib/netChannel.h>
#include "protocol.hxx" #include "protocol.hxx"
@ -43,7 +40,7 @@ using std::vector;
* FlightGear properties. * FlightGear properties.
*/ */
class FGProps : public FGProtocol, class FGProps : public FGProtocol,
public netChannel public simgear::NetChannel
{ {
private: private:
@ -58,7 +55,7 @@ public:
* *
* @param tokens Tokenized configuration parameters * @param tokens Tokenized configuration parameters
*/ */
FGProps( const vector<string>& tokens ); FGProps( const std::vector<std::string>& tokens );
/** /**
* Destructor. * Destructor.

View file

@ -14,12 +14,11 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <plib/ul.h>
#include <simgear/nasal/nasal.h> #include <simgear/nasal/nasal.h>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/misc/interpolator.hxx> #include <simgear/misc/interpolator.hxx>
#include <simgear/scene/material/mat.hxx> #include <simgear/scene/material/mat.hxx>
#include <simgear/structure/commands.hxx> #include <simgear/structure/commands.hxx>
@ -364,15 +363,17 @@ static naRef f_directory(naContext c, naRef me, int argc, naRef* args)
{ {
if(argc != 1 || !naIsString(args[0])) if(argc != 1 || !naIsString(args[0]))
naRuntimeError(c, "bad arguments to directory()"); naRuntimeError(c, "bad arguments to directory()");
naRef ldir = args[0];
ulDir* dir = ulOpenDir(naStr_data(args[0])); simgear::Dir d(SGPath(naStr_data(args[0])));
if(!dir) return naNil(); if(!d.exists()) return naNil();
naRef result = naNewVector(c); naRef result = naNewVector(c);
ulDirEnt* dent;
while((dent = ulReadDir(dir))) simgear::PathList paths = d.children(simgear::Dir::TYPE_FILE | simgear::Dir::TYPE_DIR);
naVec_append(result, naStr_fromdata(naNewString(c), dent->d_name, for (unsigned int i=0; i<paths.size(); ++i) {
strlen(dent->d_name))); std::string p = paths[i].file();
ulCloseDir(dir); naVec_append(result, naStr_fromdata(naNewString(c), p.c_str(), p.size()));
}
return result; return result;
} }
@ -722,18 +723,14 @@ void FGNasalSys::init()
hashset(_globals, "__gcsave", _gcHash); hashset(_globals, "__gcsave", _gcHash);
// Now load the various source files in the Nasal directory // Now load the various source files in the Nasal directory
SGPath p(globals->get_fg_root()); simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
p.append("Nasal"); simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
ulDirEnt* dent;
ulDir* dir = ulOpenDir(p.c_str()); for (unsigned int i=0; i<scripts.size(); ++i) {
while(dir && (dent = ulReadDir(dir)) != 0) { SGPath fullpath(scripts[i]);
SGPath fullpath(p); SGPath file = fullpath.file();
fullpath.append(dent->d_name);
SGPath file(dent->d_name);
if(file.extension() != "nas") continue;
loadModule(fullpath, file.base().c_str()); loadModule(fullpath, file.base().c_str());
} }
ulCloseDir(dir);
// set signal and remove node to avoid restoring at reinit // set signal and remove node to avoid restoring at reinit
const char *s = "nasal-dir-initialized"; const char *s = "nasal-dir-initialized";

View file

@ -51,10 +51,9 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <plib/ul.h>
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/route/waypoint.hxx> #include <simgear/route/waypoint.hxx>
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
@ -126,42 +125,23 @@ FGTrafficManager::~FGTrafficManager()
void FGTrafficManager::init() void FGTrafficManager::init()
{ {
ulDir *d, *d2;
ulDirEnt *dent, *dent2;
heuristicsVector heuristics; heuristicsVector heuristics;
HeuristicMap heurMap; HeuristicMap heurMap;
if (string(fgGetString("/sim/traffic-manager/datafile")) == string("")) { if (string(fgGetString("/sim/traffic-manager/datafile")) == string("")) {
SGPath aircraftDir = globals->get_fg_root(); simgear::Dir trafficDir(SGPath(globals->get_fg_root(), "AI/Traffic"));
SGPath path = aircraftDir; simgear::PathList d = trafficDir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
aircraftDir.append("AI/Traffic"); for (unsigned int i=0; i<d.size(); ++i) {
if ((d = ulOpenDir(aircraftDir.c_str())) != NULL) { simgear::Dir d2(d[i]);
while ((dent = ulReadDir(d)) != NULL) { simgear::PathList trafficFiles = d2.children(simgear::Dir::TYPE_FILE, ".xml");
if (string(dent->d_name) != string(".") && for (unsigned int j=0; j<trafficFiles.size(); ++j) {
string(dent->d_name) != string("..") && dent->d_isdir) { SGPath curFile = trafficFiles[j];
SGPath currACDir = aircraftDir;
currACDir.append(dent->d_name);
if ((d2 = ulOpenDir(currACDir.c_str())) == NULL)
return;
while ((dent2 = ulReadDir(d2)) != NULL) {
SGPath currFile = currACDir;
currFile.append(dent2->d_name);
if (currFile.extension() == string("xml")) {
SGPath currFile = currACDir;
currFile.append(dent2->d_name);
SG_LOG(SG_GENERAL, SG_DEBUG, SG_LOG(SG_GENERAL, SG_DEBUG,
"Scanning " << currFile. "Scanning " << curFile.str() << " for traffic");
str() << " for traffic"); readXML(curFile.str(), *this);
readXML(currFile.str(), *this);
} }
} }
ulCloseDir(d2);
}
}
ulCloseDir(d);
}
} else { } else {
fgSetBool("/sim/traffic-manager/heuristics", false); fgSetBool("/sim/traffic-manager/heuristics", false);
SGPath path = string(fgGetString("/sim/traffic-manager/datafile")); SGPath path = string(fgGetString("/sim/traffic-manager/datafile"));

View file

@ -6,10 +6,4 @@ terrasync_SOURCES = terrasync.cxx
AM_CPPFLAGS = $(svn_CPPFLAGS) AM_CPPFLAGS = $(svn_CPPFLAGS)
if HAVE_FRAMEWORK_PLIB terrasync_LDADD = -lsgio -lsgstructure -lsgmisc -lsgdebug $(network_LIBS) $(svn_LIBS)
terrasync_LDFLAGS = $(plib_FRAMEWORK)
else
terrasync_PLIB_LIBS = -lplibnet -lplibul
endif
terrasync_LDADD = $(terrasync_PLIB_LIBS) -lsgmisc -lsgdebug $(network_LIBS) $(svn_LIBS)

View file

@ -47,9 +47,7 @@
#include <deque> #include <deque>
#include <map> #include <map>
#include <plib/netSocket.h> #include <simgear/io/raw_socket.hxx>
#include <plib/ul.h>
#include <simgear/bucket/newbucket.hxx> #include <simgear/bucket/newbucket.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
@ -115,7 +113,7 @@ static void usage( const string& prog ) {
deque<string> waitingTiles; deque<string> waitingTiles;
typedef map<string,time_t> CompletedTiles; typedef map<string,time_t> CompletedTiles;
CompletedTiles completedTiles; CompletedTiles completedTiles;
netSocket theSocket; simgear::Socket theSocket;
#ifdef HAVE_SVN_CLIENT_H #ifdef HAVE_SVN_CLIENT_H
@ -513,7 +511,7 @@ int main( int argc, char **argv ) {
} }
// Must call this before any other net stuff // Must call this before any other net stuff
netInit( &argc,argv ); simgear::Socket::initSockets();
if ( ! theSocket.open( false ) ) { // open a UDP socket if ( ! theSocket.open( false ) ) { // open a UDP socket
printf("error opening socket\n"); printf("error opening socket\n");
@ -624,7 +622,11 @@ int main( int argc, char **argv ) {
terminating = true; terminating = true;
} else } else
ulSleep( 1 ); #ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
} // while !terminating } // while !terminating
return 0; return 0;