Added the computation of the wake of all AI aircrafts.
Wake computations are now performed for all AI aircrafts within a range lower or equal to the value indicated by the property /fdm/ai-wake/max-radius-nm. These computations are triggered by the property /fdm/ai-wake/enabled (it is disabled by default). The result of the wake computations is not yet used by the FDMs so do not expect the user aircraft to react to the AI wake.
This commit is contained in:
parent
b5fe38c1eb
commit
96df6689e6
4 changed files with 52 additions and 5 deletions
|
@ -34,6 +34,8 @@
|
|||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
#include "AIModel/AIManager.hxx"
|
||||
#include "AIModel/AIAircraft.hxx"
|
||||
|
||||
// all the FDMs, since we are the factory method
|
||||
#ifdef ENABLE_SP_FDM
|
||||
|
@ -88,6 +90,10 @@ void FDMShell::init()
|
|||
_data_logging = _props->getNode("/sim/temp/fdm-data-logging", true);
|
||||
_replay_master = _props->getNode("/sim/freeze/replay-state", true);
|
||||
|
||||
// AI aerodynamic wake interaction
|
||||
_max_radius_nm = _props->getNode("fdm/ai-wake/max-radius-nm", true);
|
||||
_ai_wake_enabled = _props->getNode("fdm/ai-wake/enabled", true);
|
||||
|
||||
createImplementation();
|
||||
}
|
||||
|
||||
|
@ -100,6 +106,12 @@ void FDMShell::postinit()
|
|||
{
|
||||
SG_LOG(SG_FLIGHT, SG_ALERT, "Failed to save initial FDM property state");
|
||||
}
|
||||
|
||||
_ai_mgr = dynamic_cast<FGAIManager*>(globals->get_subsystem("ai-model"));
|
||||
if (_ai_mgr)
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "FDM connection to the AI manager: SUCCESS");
|
||||
else
|
||||
SG_LOG(SG_FLIGHT, SG_DEV_ALERT, "FDM connection to the AI manager: FAILED");
|
||||
}
|
||||
|
||||
void FDMShell::shutdown()
|
||||
|
@ -184,7 +196,30 @@ void FDMShell::update(double dt)
|
|||
return; // still waiting
|
||||
}
|
||||
|
||||
// pull environmental data in, since the FDMs are lazy
|
||||
// AI aerodynamic wake interaction
|
||||
if (_ai_wake_enabled->getBoolValue()) {
|
||||
for (FGAIBase* base : _ai_mgr->get_ai_list()) {
|
||||
try {
|
||||
if (base->isa(FGAIBase::otAircraft) ) {
|
||||
SGVec3d pos = _impl->getCartPosition();
|
||||
const SGSharedPtr<FGAIAircraft> aircraft = dynamic_cast<FGAIAircraft*>(base);
|
||||
double range = _ai_mgr->calcRangeFt(pos, aircraft)*SG_FEET_TO_METER;
|
||||
|
||||
if (!aircraft->onGround() && aircraft->getSpeed() > 0.0
|
||||
&& range < _max_radius_nm->getDoubleValue()*SG_NM_TO_METER) {
|
||||
_impl->add_ai_wake(aircraft);
|
||||
}
|
||||
}
|
||||
} catch (sg_exception& e) {
|
||||
SG_LOG(SG_FLIGHT, SG_WARN, "caught exception updating AI model:"
|
||||
<< base->_getName()<< ", which will be killed."
|
||||
"\n\tError:" << e.getFormattedMessage());
|
||||
base->setDie(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pull environmental data in, since the FDMs are lazy
|
||||
_impl->set_Velocities_Local_Airmass(
|
||||
_wind_north->getDoubleValue(),
|
||||
_wind_east->getDoubleValue(),
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
// forward decls
|
||||
class FGInterface;
|
||||
class FGAIManager;
|
||||
|
||||
/**
|
||||
* Wrap an FDM implementation in a subsystem with standard semantics
|
||||
|
@ -68,6 +69,10 @@ private:
|
|||
SGPropertyNode_ptr _density_slugft, _data_logging, _replay_master;
|
||||
|
||||
SGPropertyNode_ptr _initialFdmProperties;
|
||||
|
||||
SGSharedPtr<FGAIManager> _ai_mgr;
|
||||
SGPropertyNode_ptr _max_radius_nm;
|
||||
SGPropertyNode_ptr _ai_wake_enabled;
|
||||
};
|
||||
|
||||
#endif // of FG_FDM_SHELL_HXX
|
||||
|
|
|
@ -228,6 +228,8 @@ FGInterface::common_init ()
|
|||
set_Climb_Rate( fgGetDouble("/sim/presets/vertical-speed-fps") );
|
||||
}
|
||||
|
||||
reset_wake_group();
|
||||
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "End common FDM init" );
|
||||
}
|
||||
|
||||
|
@ -927,4 +929,3 @@ FGInterface::release_wire(void)
|
|||
{
|
||||
ground_cache.release_wire();
|
||||
}
|
||||
|
||||
|
|
|
@ -80,12 +80,14 @@
|
|||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/props/tiedpropertylist.hxx>
|
||||
#include <FDM/groundcache.hxx>
|
||||
#include <FDM/AIWake/AIWakeGroup.hxx>
|
||||
|
||||
namespace simgear {
|
||||
class BVHMaterial;
|
||||
}
|
||||
|
||||
class SGIOChannel;
|
||||
class FGAIAircraft;
|
||||
|
||||
/**
|
||||
* A little helper class to update the track if
|
||||
|
@ -125,8 +127,6 @@ private:
|
|||
|
||||
// This is based heavily on LaRCsim/ls_generic.h
|
||||
class FGInterface : public SGSubsystem {
|
||||
|
||||
private:
|
||||
|
||||
// Has the init() method been called. This is used to delay
|
||||
// initialization until scenery can be loaded and we know the true
|
||||
|
@ -210,6 +210,8 @@ private:
|
|||
// the ground cache object itself.
|
||||
FGGroundCache ground_cache;
|
||||
|
||||
AIWakeGroup wake_group;
|
||||
|
||||
void set_A_X_pilot(double x)
|
||||
{ _set_Accels_Pilot_Body(x, _state.a_pilot_body_v[1], _state.a_pilot_body_v[2]); }
|
||||
|
||||
|
@ -224,7 +226,6 @@ protected:
|
|||
|
||||
int _calc_multiloop (double dt);
|
||||
|
||||
public:
|
||||
|
||||
// deliberately not virtual so that
|
||||
// FGInterface constructor will call
|
||||
|
@ -751,6 +752,11 @@ public:
|
|||
// Tell the cache code that it does no longer need to care for
|
||||
// the wire end position.
|
||||
void release_wire(void);
|
||||
|
||||
// Manages the AI wake computations.
|
||||
void add_ai_wake(FGAIAircraft* ai) { wake_group.AddAI(ai); }
|
||||
void reset_wake_group(void) { wake_group.gc(); }
|
||||
const AIWakeGroup& get_wake_group(void) { return wake_group; }
|
||||
};
|
||||
|
||||
#endif // _FLIGHT_HXX
|
||||
|
|
Loading…
Add table
Reference in a new issue