Vivian Meazza:
I've added another parameter to the submodel - wind. It's activated by the entry <wind>true</wind> in the ../submodel.xml file. If true, the submodel is affected by the local wind, otherwise not. The parameter defaults to false. This is useful for exhausts and smoke, and possibly all objects.
This commit is contained in:
parent
30f3bd5096
commit
fed4a2c25a
8 changed files with 129 additions and 55 deletions
|
@ -33,8 +33,9 @@ FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
|
||||||
_otype = otBallistic;
|
_otype = otBallistic;
|
||||||
drag_area = 0.007;
|
drag_area = 0.007;
|
||||||
life_timer = 0.0;
|
life_timer = 0.0;
|
||||||
gravity = 32;
|
gravity = 32;
|
||||||
}
|
// buoyancy = 64;
|
||||||
|
}
|
||||||
|
|
||||||
FGAIBallistic::~FGAIBallistic() {
|
FGAIBallistic::~FGAIBallistic() {
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,17 @@ void FGAIBallistic::setBuoyancy(double fpss) {
|
||||||
buoyancy = fpss;
|
buoyancy = fpss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::setWind_from_east(double fps) {
|
||||||
|
wind_from_east = fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::setWind_from_north(double fps) {
|
||||||
|
wind_from_north = fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::setWind(bool val) {
|
||||||
|
wind = val;
|
||||||
|
}
|
||||||
void FGAIBallistic::Run(double dt) {
|
void FGAIBallistic::Run(double dt) {
|
||||||
|
|
||||||
life_timer += dt;
|
life_timer += dt;
|
||||||
|
@ -99,7 +110,9 @@ void FGAIBallistic::Run(double dt) {
|
||||||
|
|
||||||
double speed_north_deg_sec;
|
double speed_north_deg_sec;
|
||||||
double speed_east_deg_sec;
|
double speed_east_deg_sec;
|
||||||
|
double wind_speed_from_north_deg_sec;
|
||||||
|
double wind_speed_from_east_deg_sec;
|
||||||
|
|
||||||
// the two drag calculations below assume sea-level density,
|
// the two drag calculations below assume sea-level density,
|
||||||
// mass of 0.03 slugs, drag coeff of 0.295
|
// mass of 0.03 slugs, drag coeff of 0.295
|
||||||
// adjust speed due to drag
|
// adjust speed due to drag
|
||||||
|
@ -111,10 +124,27 @@ void FGAIBallistic::Run(double dt) {
|
||||||
// convert horizontal speed (fps) to degrees per second
|
// convert horizontal speed (fps) to degrees per second
|
||||||
speed_north_deg_sec = cos(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lat;
|
speed_north_deg_sec = cos(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lat;
|
||||||
speed_east_deg_sec = sin(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lon;
|
speed_east_deg_sec = sin(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lon;
|
||||||
|
|
||||||
|
// convert wind speed (fps) to degrees per second
|
||||||
|
|
||||||
|
if (!wind){
|
||||||
|
wind_from_north = 0;
|
||||||
|
wind_from_east = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wind_speed_from_north_deg_sec = wind_from_north / ft_per_deg_lat;
|
||||||
|
wind_speed_from_east_deg_sec = wind_from_east / ft_per_deg_lon;
|
||||||
|
|
||||||
|
|
||||||
// set new position
|
// set new position
|
||||||
pos.setlat( pos.lat() + speed_north_deg_sec * dt);
|
// pos.setlat( pos.lat() + (speed_north_deg_sec * dt) );
|
||||||
pos.setlon( pos.lon() + speed_east_deg_sec * dt);
|
// pos.setlon( pos.lon() + (speed_east_deg_sec * dt) );
|
||||||
|
|
||||||
|
|
||||||
|
// set new position
|
||||||
|
|
||||||
|
pos.setlat( pos.lat() + (speed_north_deg_sec - wind_speed_from_north_deg_sec) * dt );
|
||||||
|
pos.setlon( pos.lon() + (speed_east_deg_sec - wind_speed_from_east_deg_sec) * dt );
|
||||||
|
|
||||||
// adjust vertical speed for acceleration of gravity
|
// adjust vertical speed for acceleration of gravity
|
||||||
vs -= (gravity - buoyancy) * dt;
|
vs -= (gravity - buoyancy) * dt;
|
||||||
|
|
|
@ -41,7 +41,10 @@ public:
|
||||||
void setStabilization( bool val );
|
void setStabilization( bool val );
|
||||||
void setDragArea( double a );
|
void setDragArea( double a );
|
||||||
void setLife( double seconds );
|
void setLife( double seconds );
|
||||||
void setBuoyancy( double fps2 );
|
void setBuoyancy( double fpss );
|
||||||
|
void setWind_from_east( double fps );
|
||||||
|
void setWind_from_north( double fps );
|
||||||
|
void setWind( bool val );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -51,8 +54,11 @@ private:
|
||||||
bool aero_stabilized; // if true, object will point where it's going
|
bool aero_stabilized; // if true, object will point where it's going
|
||||||
double drag_area; // equivalent drag area in ft2
|
double drag_area; // equivalent drag area in ft2
|
||||||
double life_timer; // seconds
|
double life_timer; // seconds
|
||||||
double gravity; // fps2
|
double gravity; // fps2
|
||||||
double buoyancy; // fps2
|
double buoyancy; // fps2
|
||||||
|
double wind_from_east; // fps
|
||||||
|
double wind_from_north; // fps
|
||||||
|
bool wind; // if true, local wind will be applied to object
|
||||||
|
|
||||||
void Run(double dt);
|
void Run(double dt);
|
||||||
};
|
};
|
||||||
|
|
|
@ -253,7 +253,8 @@ int FGAIManager::createShip( string path, FGAIFlightPlan* flightplan ) {
|
||||||
|
|
||||||
int FGAIManager::createBallistic( string path, double latitude, double longitude,
|
int FGAIManager::createBallistic( string path, double latitude, double longitude,
|
||||||
double altitude, double azimuth, double elevation,
|
double altitude, double azimuth, double elevation,
|
||||||
double speed, double eda, double life, double buoyancy ) {
|
double speed, double eda, double life, double buoyancy,
|
||||||
|
double wind_from_east, double wind_from_north, bool wind ) {
|
||||||
|
|
||||||
FGAIBallistic* ai_ballistic = new FGAIBallistic(this);
|
FGAIBallistic* ai_ballistic = new FGAIBallistic(this);
|
||||||
ai_list.push_back(ai_ballistic);
|
ai_list.push_back(ai_ballistic);
|
||||||
|
@ -269,6 +270,9 @@ int FGAIManager::createBallistic( string path, double latitude, double longitude
|
||||||
ai_ballistic->setDragArea(eda);
|
ai_ballistic->setDragArea(eda);
|
||||||
ai_ballistic->setLife(life);
|
ai_ballistic->setLife(life);
|
||||||
ai_ballistic->setBuoyancy(buoyancy);
|
ai_ballistic->setBuoyancy(buoyancy);
|
||||||
|
ai_ballistic->setWind_from_east(wind_from_east);
|
||||||
|
ai_ballistic->setWind_from_north(wind_from_north);
|
||||||
|
ai_ballistic->setWind(wind);
|
||||||
ai_ballistic->init();
|
ai_ballistic->init();
|
||||||
ai_ballistic->bind();
|
ai_ballistic->bind();
|
||||||
return ai_ballistic->getID();
|
return ai_ballistic->getID();
|
||||||
|
@ -308,7 +312,6 @@ int FGAIManager::createThermal( double latitude, double longitude,
|
||||||
return ai_thermal->getID();
|
return ai_thermal->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FGAIManager::destroyObject( int ID ) {
|
void FGAIManager::destroyObject( int ID ) {
|
||||||
ai_list_itr = ai_list.begin();
|
ai_list_itr = ai_list.begin();
|
||||||
while(ai_list_itr != ai_list.end()) {
|
while(ai_list_itr != ai_list.end()) {
|
||||||
|
@ -387,7 +390,8 @@ void FGAIManager::processScenario( string filename ) {
|
||||||
} else if (en->aitype == "ballistic"){
|
} else if (en->aitype == "ballistic"){
|
||||||
createBallistic( en->model_path, en->latitude, en->longitude,
|
createBallistic( en->model_path, en->latitude, en->longitude,
|
||||||
en->altitude, en->azimuth, en->elevation, en->speed,
|
en->altitude, en->azimuth, en->elevation, en->speed,
|
||||||
en->eda, en->life, en->buoyancy );
|
en->eda, en->life, en->buoyancy, en->wind_from_east,
|
||||||
|
en-> wind_from_north, en->wind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,17 +91,20 @@ public:
|
||||||
int createShip( string path, // path to exterior model
|
int createShip( string path, // path to exterior model
|
||||||
FGAIFlightPlan *flightplan );
|
FGAIFlightPlan *flightplan );
|
||||||
|
|
||||||
int createBallistic( string path, // path to exterior model
|
int createBallistic( string path, // path to exterior model
|
||||||
double latitude, // in degrees -90 to 90
|
double latitude, // in degrees -90 to 90
|
||||||
double longitude, // in degrees -180 to 180
|
double longitude, // in degrees -180 to 180
|
||||||
double altitude, // in feet
|
double altitude, // in feet
|
||||||
double azimuth, // in degrees (same as heading)
|
double azimuth, // in degrees (same as heading)
|
||||||
double elevation, // in degrees (same as pitch)
|
double elevation, // in degrees (same as pitch)
|
||||||
double speed, // in feet per second
|
double speed, // in feet per second
|
||||||
double eda, // equivalent drag area, ft2
|
double eda, // equivalent drag area, ft2
|
||||||
double life, // life span in seconds
|
double life, // life span in seconds
|
||||||
double buoyancy // acceleration in ft per second2
|
double buoyancy, // acceleration due to buoyancy feet per second2
|
||||||
);
|
double wind_from_east, // in feet per second
|
||||||
|
double wind_from_north, // in feet per second
|
||||||
|
bool wind // val
|
||||||
|
);
|
||||||
|
|
||||||
int createStorm( string path, // path to exterior model
|
int createStorm( string path, // path to exterior model
|
||||||
double latitude, // in degrees -90 to 90
|
double latitude, // in degrees -90 to 90
|
||||||
|
@ -115,7 +118,19 @@ public:
|
||||||
double strength, // in feet per second
|
double strength, // in feet per second
|
||||||
double diameter ); // in feet
|
double diameter ); // in feet
|
||||||
|
|
||||||
|
int createSmoke ( string path, // path to exterior model
|
||||||
|
double latitude, // in degrees -90 to 90
|
||||||
|
double longitude, // in degrees -180 to 180
|
||||||
|
double altitude, // in feet
|
||||||
|
double azimuth, // in degrees (same as heading)
|
||||||
|
double elevation, // in degrees (same as pitch)
|
||||||
|
double speed, // in feet per second
|
||||||
|
double eda, // equivalent drag area, ft2
|
||||||
|
double life, // life span in seconds
|
||||||
|
double buoyancy // acceleration due to buoyancy feet per second2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
void destroyObject( int ID );
|
void destroyObject( int ID );
|
||||||
|
|
||||||
inline double get_user_latitude() { return user_latitude; }
|
inline double get_user_latitude() { return user_latitude; }
|
||||||
|
|
|
@ -71,7 +71,10 @@ FGAIScenario::FGAIScenario(string filename)
|
||||||
en->diameter = entry_node->getDoubleValue("diameter-ft", 0.0);
|
en->diameter = entry_node->getDoubleValue("diameter-ft", 0.0);
|
||||||
en->eda = entry_node->getDoubleValue("eda", 0.007);
|
en->eda = entry_node->getDoubleValue("eda", 0.007);
|
||||||
en->life = entry_node->getDoubleValue("life", 900.0);
|
en->life = entry_node->getDoubleValue("life", 900.0);
|
||||||
en->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
en->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
||||||
|
en->wind_from_east = entry_node->getDoubleValue("wind_from_east", 0);
|
||||||
|
en->wind_from_north = entry_node->getDoubleValue("wind_from_north", 0);
|
||||||
|
en->wind = entry_node->getBoolValue("wind", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_iterator = entries.begin();
|
entry_iterator = entries.begin();
|
||||||
|
|
|
@ -36,21 +36,24 @@ public:
|
||||||
string aircraft_class;
|
string aircraft_class;
|
||||||
string model_path;
|
string model_path;
|
||||||
string flightplan;
|
string flightplan;
|
||||||
double repeat; // in seconds
|
double repeat; // in seconds
|
||||||
double latitude; // used if no flightplan defined
|
double latitude; // used if no flightplan defined
|
||||||
double longitude; // used if no flightplan defined
|
double longitude; // used if no flightplan defined
|
||||||
double altitude; // used if no flightplan defined
|
double altitude; // used if no flightplan defined
|
||||||
double speed; // used if no flightplan defined
|
double speed; // used if no flightplan defined
|
||||||
double heading; // used if no flightplan defined
|
double heading; // used if no flightplan defined
|
||||||
double roll; // used if no flightplan defined
|
double roll; // used if no flightplan defined
|
||||||
double azimuth; // used by ballistic objects
|
double azimuth; // used by ballistic objects
|
||||||
double elevation; // used by ballistic objects
|
double elevation; // used by ballistic objects
|
||||||
double rudder; // used by ship objects
|
double rudder; // used by ship objects
|
||||||
double strength; // used by thermal objects
|
double strength; // used by thermal objects
|
||||||
double diameter; // used by thermal objects
|
double diameter; // used by thermal objects
|
||||||
double eda; // used by ballistic objects
|
double eda; // used by ballistic objects
|
||||||
double life; // life span in seconds
|
double life; // life span in seconds
|
||||||
double buoyancy; // acceleration in ft per sec2
|
double buoyancy; // acceleration in ft per sec2
|
||||||
|
double wind_from_east; // in feet per second
|
||||||
|
double wind_from_north; // in feet per second
|
||||||
|
bool wind;
|
||||||
} entry;
|
} entry;
|
||||||
|
|
||||||
FGAIScenario(string filename);
|
FGAIScenario(string filename);
|
||||||
|
|
|
@ -30,7 +30,7 @@ SubmodelSystem::init ()
|
||||||
{
|
{
|
||||||
load();
|
load();
|
||||||
_serviceable_node = fgGetNode("/sim/systems/submodels/serviceable", true);
|
_serviceable_node = fgGetNode("/sim/systems/submodels/serviceable", true);
|
||||||
|
|
||||||
_user_lat_node = fgGetNode("/position/latitude-deg", true);
|
_user_lat_node = fgGetNode("/position/latitude-deg", true);
|
||||||
_user_lon_node = fgGetNode("/position/longitude-deg", true);
|
_user_lon_node = fgGetNode("/position/longitude-deg", true);
|
||||||
_user_alt_node = fgGetNode("/position/altitude-ft", true);
|
_user_alt_node = fgGetNode("/position/altitude-ft", true);
|
||||||
|
@ -41,7 +41,9 @@ SubmodelSystem::init ()
|
||||||
_user_yaw_node = fgGetNode("/orientation/yaw-deg", true);
|
_user_yaw_node = fgGetNode("/orientation/yaw-deg", true);
|
||||||
|
|
||||||
_user_speed_node = fgGetNode("/velocities/uBody-fps", true);
|
_user_speed_node = fgGetNode("/velocities/uBody-fps", true);
|
||||||
|
|
||||||
|
_user_wind_from_east_node = fgGetNode("/environment/wind-from-east-fps",true);
|
||||||
|
_user_wind_from_north_node = fgGetNode("/environment/wind-from-north-fps",true);
|
||||||
|
|
||||||
ai = (FGAIManager*)globals->get_subsystem("ai_model");
|
ai = (FGAIManager*)globals->get_subsystem("ai_model");
|
||||||
}
|
}
|
||||||
|
@ -86,12 +88,15 @@ SubmodelSystem::release (submodel* sm, double dt)
|
||||||
if (sm->timer < sm->delay) return false;
|
if (sm->timer < sm->delay) return false;
|
||||||
sm->timer = 0.0;
|
sm->timer = 0.0;
|
||||||
|
|
||||||
transform(sm); // calculate submodel's initial conditions in world-coordinates
|
// calculate submodel's initial conditions in world-coordinates
|
||||||
|
transform(sm);
|
||||||
|
|
||||||
//cout << "Creating a submodel." << endl;
|
//cout << "Creating a submodel." << endl;
|
||||||
int rval = ai->createBallistic( sm->model, IC.lat, IC.lon, IC.alt, IC.azimuth,
|
int rval = ai->createBallistic( sm->model, IC.lat, IC.lon, IC.alt, IC.azimuth,
|
||||||
IC.elevation, IC.speed, sm->drag_area, sm->life,
|
IC.elevation, IC.speed,
|
||||||
sm-> buoyancy );
|
sm->drag_area, sm->life,
|
||||||
|
sm->buoyancy,
|
||||||
|
IC.wind_from_east, IC.wind_from_north, sm->wind);
|
||||||
//cout << "Submodel created." << endl;
|
//cout << "Submodel created." << endl;
|
||||||
if (sm->count > 0) (sm->count)--;
|
if (sm->count > 0) (sm->count)--;
|
||||||
|
|
||||||
|
@ -141,6 +146,7 @@ SubmodelSystem::load ()
|
||||||
sm->drag_area = entry_node->getDoubleValue("eda", 0.007);
|
sm->drag_area = entry_node->getDoubleValue("eda", 0.007);
|
||||||
sm->life = entry_node->getDoubleValue("life", 900.0);
|
sm->life = entry_node->getDoubleValue("life", 900.0);
|
||||||
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
||||||
|
sm->wind = entry_node->getBoolValue ("wind", false);
|
||||||
|
|
||||||
sm->trigger->setBoolValue(false);
|
sm->trigger->setBoolValue(false);
|
||||||
sm->timer = sm->delay;
|
sm->timer = sm->delay;
|
||||||
|
@ -159,15 +165,18 @@ SubmodelSystem::load ()
|
||||||
void
|
void
|
||||||
SubmodelSystem::transform( submodel* sm)
|
SubmodelSystem::transform( submodel* sm)
|
||||||
{
|
{
|
||||||
IC.lat = _user_lat_node->getDoubleValue();
|
IC.lat = _user_lat_node->getDoubleValue();
|
||||||
IC.lon = _user_lon_node->getDoubleValue();
|
IC.lon = _user_lon_node->getDoubleValue();
|
||||||
IC.alt = _user_alt_node->getDoubleValue();
|
IC.alt = _user_alt_node->getDoubleValue();
|
||||||
IC.azimuth = _user_heading_node->getDoubleValue() + sm->yaw_offset;
|
IC.azimuth = _user_heading_node->getDoubleValue() + sm->yaw_offset;
|
||||||
IC.elevation = _user_pitch_node->getDoubleValue() + sm->pitch_offset;
|
IC.elevation = _user_pitch_node->getDoubleValue() + sm->pitch_offset;
|
||||||
IC.speed = _user_speed_node->getDoubleValue() + sm->speed;
|
IC.speed = _user_speed_node->getDoubleValue() + sm->speed;
|
||||||
|
IC.wind_from_east = _user_wind_from_east_node->getDoubleValue();
|
||||||
}
|
IC.wind_from_north = _user_wind_from_north_node->getDoubleValue();
|
||||||
|
// IC.wind_from_east = 4;
|
||||||
|
// IC.wind_from_north = 5;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// end of submodel.cxx
|
// end of submodel.cxx
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ public:
|
||||||
double drag_area;
|
double drag_area;
|
||||||
double life;
|
double life;
|
||||||
double buoyancy;
|
double buoyancy;
|
||||||
|
bool wind;
|
||||||
|
|
||||||
} submodel;
|
} submodel;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -54,7 +55,9 @@ public:
|
||||||
double azimuth;
|
double azimuth;
|
||||||
double elevation;
|
double elevation;
|
||||||
double speed;
|
double speed;
|
||||||
|
double wind_from_east;
|
||||||
|
double wind_from_north;
|
||||||
|
|
||||||
} IC_struct;
|
} IC_struct;
|
||||||
|
|
||||||
SubmodelSystem ();
|
SubmodelSystem ();
|
||||||
|
@ -89,7 +92,8 @@ private:
|
||||||
SGPropertyNode_ptr _user_roll_node;
|
SGPropertyNode_ptr _user_roll_node;
|
||||||
SGPropertyNode_ptr _user_yaw_node;
|
SGPropertyNode_ptr _user_yaw_node;
|
||||||
SGPropertyNode_ptr _user_speed_node;
|
SGPropertyNode_ptr _user_speed_node;
|
||||||
|
SGPropertyNode_ptr _user_wind_from_east_node;
|
||||||
|
SGPropertyNode_ptr _user_wind_from_north_node;
|
||||||
FGAIManager* ai;
|
FGAIManager* ai;
|
||||||
IC_struct IC;
|
IC_struct IC;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue