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.
_otype = otBallistic;
drag_area = 0.007;
life_timer = 0.0;
- gravity = 32;
- }
+ gravity = 32;
+// buoyancy = 64;
+ }
FGAIBallistic::~FGAIBallistic() {
}
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) {
life_timer += dt;
double speed_north_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,
// mass of 0.03 slugs, drag coeff of 0.295
// adjust speed due to drag
// convert horizontal speed (fps) to degrees per second
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;
+
+ // 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
- pos.setlat( pos.lat() + speed_north_deg_sec * dt);
- pos.setlon( pos.lon() + speed_east_deg_sec * dt);
+// pos.setlat( pos.lat() + (speed_north_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
vs -= (gravity - buoyancy) * dt;
void setStabilization( bool val );
void setDragArea( double a );
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:
bool aero_stabilized; // if true, object will point where it's going
double drag_area; // equivalent drag area in ft2
double life_timer; // seconds
- double gravity; // fps2
- double buoyancy; // fps2
+ double gravity; // 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);
};
int FGAIManager::createBallistic( string path, double latitude, double longitude,
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);
ai_list.push_back(ai_ballistic);
ai_ballistic->setDragArea(eda);
ai_ballistic->setLife(life);
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->bind();
return ai_ballistic->getID();
return ai_thermal->getID();
}
-
void FGAIManager::destroyObject( int ID ) {
ai_list_itr = ai_list.begin();
while(ai_list_itr != ai_list.end()) {
} else if (en->aitype == "ballistic"){
createBallistic( en->model_path, en->latitude, en->longitude,
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);
}
}
}
int createShip( string path, // path to exterior model
FGAIFlightPlan *flightplan );
- int createBallistic( 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 in ft per second2
- );
+ int createBallistic( 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
+ 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
double latitude, // in degrees -90 to 90
double strength, // in feet per second
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 );
inline double get_user_latitude() { return user_latitude; }
en->diameter = entry_node->getDoubleValue("diameter-ft", 0.0);
en->eda = entry_node->getDoubleValue("eda", 0.007);
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();
string aircraft_class;
string model_path;
string flightplan;
- double repeat; // in seconds
- double latitude; // used if no flightplan defined
- double longitude; // used if no flightplan defined
- double altitude; // used if no flightplan defined
- double speed; // used if no flightplan defined
- double heading; // used if no flightplan defined
- double roll; // used if no flightplan defined
- double azimuth; // used by ballistic objects
- double elevation; // used by ballistic objects
- double rudder; // used by ship objects
- double strength; // used by thermal objects
- double diameter; // used by thermal objects
- double eda; // used by ballistic objects
- double life; // life span in seconds
- double buoyancy; // acceleration in ft per sec2
+ double repeat; // in seconds
+ double latitude; // used if no flightplan defined
+ double longitude; // used if no flightplan defined
+ double altitude; // used if no flightplan defined
+ double speed; // used if no flightplan defined
+ double heading; // used if no flightplan defined
+ double roll; // used if no flightplan defined
+ double azimuth; // used by ballistic objects
+ double elevation; // used by ballistic objects
+ double rudder; // used by ship objects
+ double strength; // used by thermal objects
+ double diameter; // used by thermal objects
+ double eda; // used by ballistic objects
+ double life; // life span in seconds
+ 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;
FGAIScenario(string filename);
{
load();
_serviceable_node = fgGetNode("/sim/systems/submodels/serviceable", true);
-
+
_user_lat_node = fgGetNode("/position/latitude-deg", true);
_user_lon_node = fgGetNode("/position/longitude-deg", true);
_user_alt_node = fgGetNode("/position/altitude-ft", true);
_user_yaw_node = fgGetNode("/orientation/yaw-deg", 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");
}
if (sm->timer < sm->delay) return false;
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;
int rval = ai->createBallistic( sm->model, IC.lat, IC.lon, IC.alt, IC.azimuth,
- IC.elevation, IC.speed, sm->drag_area, sm->life,
- sm-> buoyancy );
+ IC.elevation, IC.speed,
+ sm->drag_area, sm->life,
+ sm->buoyancy,
+ IC.wind_from_east, IC.wind_from_north, sm->wind);
//cout << "Submodel created." << endl;
if (sm->count > 0) (sm->count)--;
sm->drag_area = entry_node->getDoubleValue("eda", 0.007);
sm->life = entry_node->getDoubleValue("life", 900.0);
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
+ sm->wind = entry_node->getBoolValue ("wind", false);
sm->trigger->setBoolValue(false);
sm->timer = sm->delay;
void
SubmodelSystem::transform( submodel* sm)
{
- IC.lat = _user_lat_node->getDoubleValue();
- IC.lon = _user_lon_node->getDoubleValue();
- IC.alt = _user_alt_node->getDoubleValue();
- IC.azimuth = _user_heading_node->getDoubleValue() + sm->yaw_offset;
- IC.elevation = _user_pitch_node->getDoubleValue() + sm->pitch_offset;
- IC.speed = _user_speed_node->getDoubleValue() + sm->speed;
-
-}
+ IC.lat = _user_lat_node->getDoubleValue();
+ IC.lon = _user_lon_node->getDoubleValue();
+ IC.alt = _user_alt_node->getDoubleValue();
+ IC.azimuth = _user_heading_node->getDoubleValue() + sm->yaw_offset;
+ IC.elevation = _user_pitch_node->getDoubleValue() + sm->pitch_offset;
+ 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
double drag_area;
double life;
double buoyancy;
-
+ bool wind;
+
} submodel;
typedef struct {
double azimuth;
double elevation;
double speed;
-
+ double wind_from_east;
+ double wind_from_north;
+
} IC_struct;
SubmodelSystem ();
SGPropertyNode_ptr _user_roll_node;
SGPropertyNode_ptr _user_yaw_node;
SGPropertyNode_ptr _user_speed_node;
-
+ SGPropertyNode_ptr _user_wind_from_east_node;
+ SGPropertyNode_ptr _user_wind_from_north_node;
FGAIManager* ai;
IC_struct IC;
};