};
-FGAIAircraft::FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref) {
+FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
+ FGAIBase(otAircraft) {
trafficRef = ref;
if (trafficRef)
groundOffset = trafficRef->getGroundOffset();
else
groundOffset = 0;
- manager = mgr;
- _type_str = "aircraft";
- _otype = otAircraft;
fp = 0;
dt_count = 0;
dt_elev_count = 0;
FGAIAircraft::~FGAIAircraft() {
+ delete fp;
}
+void FGAIAircraft::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIBase::readFromScenario(scFileNode);
+
+ setPerformance(scFileNode->getStringValue("class", "jet_transport"));
+ setFlightPlan(scFileNode->getStringValue("flightplan"),
+ scFileNode->getBoolValue("repeat", false));
+}
bool FGAIAircraft::init() {
refuel_node = fgGetNode("systems/refuel/contact", true);
props->tie("controls/gear/gear-down",
SGRawValueMethods<FGAIAircraft,bool>(*this,
&FGAIAircraft::_getGearDown));
-#if 0
- props->getNode("controls/lighting/landing-lights", true)
- ->alias("controls/gear/gear-down");
-#endif
}
void FGAIAircraft::unbind() {
FGAIBase::unbind();
props->untie("controls/gear/gear-down");
-#if 0
- props->getNode("controls/lighting/landing-lights")->unalias();
-#endif
}
Transform();
}
+void FGAIAircraft::setPerformance(const std::string& acclass)
+{
+ if (acclass == "light") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::LIGHT]);
+ } else if (acclass == "ww2_fighter") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::WW2_FIGHTER]);
+ } else if (acclass == "jet_transport") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+ } else if (acclass == "jet_fighter") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_FIGHTER]);
+ } else if (acclass == "tanker") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+ SetTanker(true);
+ } else {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+ }
+}
+
void FGAIAircraft::SetPerformance(const PERF_STRUCT *ps) {
performance = ps;
else { return 1.0; }
}
+void FGAIAircraft::setFlightPlan(const std::string& flightplan, bool repeat)
+{
+ if (!flightplan.empty()){
+ FGAIFlightPlan* fp = new FGAIFlightPlan(flightplan);
+ fp->setRepeat(repeat);
+ SetFlightPlan(fp);
+ }
+}
+
void FGAIAircraft::SetFlightPlan(FGAIFlightPlan *f) {
+ delete fp;
fp = f;
}
enum aircraft_e {LIGHT=0, WW2_FIGHTER, JET_TRANSPORT, JET_FIGHTER, TANKER};
static const PERF_STRUCT settings[];
- FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref=0);
+ FGAIAircraft(FGAISchedule *ref=0);
~FGAIAircraft();
-
- bool init();
+
+ virtual void readFromScenario(SGPropertyNode* scFileNode);
+
+ virtual bool init();
virtual void bind();
virtual void unbind();
- void update(double dt);
+ virtual void update(double dt);
+ void setPerformance(const std::string& perfString);
void SetPerformance(const PERF_STRUCT *ps);
+ void setFlightPlan(const std::string& fp, bool repat = false);
void SetFlightPlan(FGAIFlightPlan *f);
FGAIFlightPlan* GetFlightPlan() const { return fp; };
void AccelTo(double speed);
void doGroundAltitude();
void loadNextLeg ();
- void setAcType(string ac) { acType = ac; };
- void setCompany(string comp) { company = comp;};
- //void setSchedule(FGAISchedule *ref) { trafficRef = ref;};
+ void setAcType(const string& ac) { acType = ac; };
+ void setCompany(const string& comp) { company = comp;};
inline void SetTanker(bool setting) { isTanker = setting; };
+ virtual const char* getTypeString(void) const { return "aircraft"; }
+
private:
FGAISchedule *trafficRef;
#include "AIBallistic.hxx"
-FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
- manager = mgr;
- _type_str = "ballistic";
- _otype = otBallistic;
+FGAIBallistic::FGAIBallistic() : FGAIBase(otBallistic) {
drag_area = 0.007;
life_timer = 0.0;
gravity = 32;
// buoyancy = 64;
no_roll = false;
+ aero_stabilised = false;
}
FGAIBallistic::~FGAIBallistic() {
}
+void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIBase::readFromScenario(scFileNode);
+
+ setAzimuth(scFileNode->getDoubleValue("azimuth", 0.0));
+ setElevation(scFileNode->getDoubleValue("elevation", 0.0));
+ setDragArea(scFileNode->getDoubleValue("eda", 0.007));
+ setLife(scFileNode->getDoubleValue("life", 900.0));
+ setBuoyancy(scFileNode->getDoubleValue("buoyancy", 0));
+ setWind_from_east(scFileNode->getDoubleValue("wind_from_east", 0));
+ setWind_from_north(scFileNode->getDoubleValue("wind_from_north", 0));
+ setWind(scFileNode->getBoolValue("wind", false));
+ setRoll(scFileNode->getDoubleValue("roll", 0.0));
+ setCd(scFileNode->getDoubleValue("cd", 0.029));
+ setMass(scFileNode->getDoubleValue("mass", 0.007));
+ setStabilisation(scFileNode->getBoolValue("aero_stabilized", false));
+}
bool FGAIBallistic::init() {
FGAIBase::init();
public:
- FGAIBallistic(FGAIManager* mgr);
+ FGAIBallistic();
~FGAIBallistic();
+ void readFromScenario(SGPropertyNode* scFileNode);
+
bool init();
virtual void bind();
virtual void unbind();
double _getTime() const;
+ virtual const char* getTypeString(void) const { return "ballistic"; }
+
private:
double azimuth; // degrees true
const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor
-FGAIBase::FGAIBase()
+FGAIBase::FGAIBase(object_type ot)
: fp( NULL ),
props( NULL ),
manager( NULL ),
- _refID( _newAIModelID() )
+ _refID( _newAIModelID() ),
+ _otype(ot)
{
- _type_str = "model";
tgt_heading = hdg = tgt_altitude = tgt_speed = 0.0;
tgt_roll = roll = tgt_pitch = tgt_yaw = tgt_vs = vs = pitch = 0.0;
bearing = elevation = range = rdot = 0.0;
invisible = true;
no_roll = true;
life = 900;
- model_path = "";
- _otype = otNull;
index = 0;
delete_me = false;
}
globals->get_scenery()->unregister_placement_transform(aip.getTransform());
globals->get_scenery()->get_scene_graph()->removeKid(aip.getSceneGraph());
}
- // unbind();
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
- root->removeChild(_type_str.c_str(), index);
+ root->removeChild(getTypeString(), index);
delete fp;
fp = NULL;
}
+
+void FGAIBase::readFromScenario(SGPropertyNode* scFileNode)
+{
+ if (!scFileNode)
+ return;
+
+ setPath(scFileNode->getStringValue("model", "Models/Geometry/glider.ac"));
+
+ setHeading(scFileNode->getDoubleValue("heading", 0.0));
+ setSpeed(scFileNode->getDoubleValue("speed", 0.0));
+ setAltitude(scFileNode->getDoubleValue("altitude", 0.0));
+ setLongitude(scFileNode->getDoubleValue("longitude", 0.0));
+ setLatitude(scFileNode->getDoubleValue("latitude", 0.0));
+ setBank(scFileNode->getDoubleValue("roll", 0.0));
+}
+
void FGAIBase::update(double dt) {
if (_otype == otStatic) return;
if (_otype == otBallistic) CalculateMach();
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
index = manager->getNum(_otype) - 1;
- props = root->getNode(_type_str.c_str(), index, true);
-
- if (model_path != "") {
- try {
- model = load3DModel( globals->get_fg_root(),
- SGPath(model_path).c_str(),
- props,
- globals->get_sim_time_sec() );
- } catch (const sg_exception &e) {
+ props = root->getNode(getTypeString(), index, true);
+
+ if (!model_path.empty()) {
+ try {
+ model = load3DModel( globals->get_fg_root(), model_path, props,
+ globals->get_sim_time_sec() );
+ } catch (const sg_exception &e) {
model = NULL;
- }
+ }
}
if (model) {
aip.init( model );
// Register that one at the scenery manager
globals->get_scenery()->register_placement_transform(aip.getTransform());
} else {
- if (model_path != "") {
+ if (!model_path.empty()) {
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
}
}
#include <simgear/scene/model/placement.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/structure/ssgSharedPtr.hxx>
+#include <simgear/structure/SGReferenced.hxx>
#include <Main/fg_props.hxx>
class FGAIManager;
class FGAIFlightPlan;
-
-struct ParkPosition {
- ParkPosition(const ParkPosition& pp)
- : name(pp.name), offset(pp.offset), heading_deg(pp.heading_deg)
- {}
- ParkPosition(const string& n, const Point3D& off = Point3D(), double heading = 0)
- : name(n), offset(off), heading_deg(heading)
- {}
- string name;
- Point3D offset;
- double heading_deg;
-};
-
-typedef struct {
- string callsign;
-
- // can be aircraft, ship, storm, thermal, static or ballistic
- string m_type;
- string m_class;
- string path;
- string flightplan;
-
- FGAIFlightPlan *fp;
-
- 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
- double turb_strength; // used by storm objects
- double diameter; // used by thermal and storm objects
- double height_msl; // used by thermal and storm 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
- double cd; // coefficient of drag
- bool wind; // if true, model reacts to parent wind
- double mass; // in slugs
- bool aero_stabilised; // if true, ballistic object aligns with trajectory
- list<string> solid_objects; // List of solid object names
- list<string> wire_objects; // List of wire object names
- list<string> catapult_objects; // List of catapult object names
- list<ParkPosition> ppositions; // List of positions on a carrier where an aircraft can start.
- Point3D flols_offset; // used by carrier objects, in meters
- double radius; // used by ship objects, in feet
- string name; // used by carrier objects
- string pennant_number; // used by carrier objects
- string acType; // used by aircraft objects
- string company; // used by aircraft objects
- string TACAN_channel_ID; // used by carrier objects
- double max_lat; // used by carrier objects
- double min_lat; // used by carrier objects
- double max_long; // used by carrier objects
- double min_long; // used by carrier objects
-
-} FGAIModelEntity;
-
-
-class FGAIBase {
+class FGAIBase : public SGReferenced {
public:
+ enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
+ otRocket, otStorm, otThermal, otStatic, otMultiplayer,
+ MAX_OBJECTS }; // Needs to be last!!!
- FGAIBase();
+ FGAIBase(object_type ot);
virtual ~FGAIBase();
- virtual void update(double dt);
inline const Point3D& GetPos() const { return(pos); }
- enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
- otRocket, otStorm, otThermal, otStatic, otMultiplayer,
- MAX_OBJECTS }; // Needs to be last!!!
+ virtual void readFromScenario(SGPropertyNode* scFileNode);
virtual bool init();
+ virtual void update(double dt);
virtual void bind();
virtual void unbind();
+ void setManager(FGAIManager* mgr);
void setPath( const char* model );
void setSpeed( double speed_KTAS );
void setAltitude( double altitude_ft );
void CalculateMach();
double UpdateRadar(FGAIManager* manager);
- string _type_str;
- object_type _otype;
int index;
static int _newAIModelID();
private:
const int _refID;
+ object_type _otype;
public:
object_type getType();
+ virtual const char* getTypeString(void) const { return "null"; }
bool isa( object_type otype );
double _getVS_fps() const;
static bool _isNight();
};
+inline void FGAIBase::setManager(FGAIManager* mgr) {
+ manager = mgr;
+}
-inline void FGAIBase::setPath( const char* model ) {
+inline void FGAIBase::setPath(const char* model ) {
model_path.append(model);
}
#include "AICarrier.hxx"
-#include "AIScenario.hxx"
-
/** Value of earth radius (meters) */
#define RADIUS_M SG_EQUATORIAL_RADIUS_M
-FGAICarrier::FGAICarrier(FGAIManager* mgr) : FGAIShip(mgr) {
- _type_str = "carrier";
- _otype = otCarrier;
+FGAICarrier::FGAICarrier() : FGAIShip(otCarrier) {
}
FGAICarrier::~FGAICarrier() {
}
+void FGAICarrier::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIShip::readFromScenario(scFileNode);
+
+ setRadius(scFileNode->getDoubleValue("turn-radius-ft", 2000));
+ setSign(scFileNode->getStringValue("pennant-number"));
+ setWind_from_east(scFileNode->getDoubleValue("wind_from_east", 0));
+ setWind_from_north(scFileNode->getDoubleValue("wind_from_north", 0));
+ setTACANChannelID(scFileNode->getStringValue("TACAN-channel-ID", "029Y"));
+ setMaxLat(scFileNode->getDoubleValue("max-lat", 0));
+ setMinLat(scFileNode->getDoubleValue("min-lat", 0));
+ setMaxLong(scFileNode->getDoubleValue("max-long", 0));
+ setMinLong(scFileNode->getDoubleValue("min-long", 0));
+
+ SGPropertyNode* flols = scFileNode->getChild("flols-pos");
+ if (flols) {
+ flols_off[0] = flols->getDoubleValue("x-offset-m", 0);
+ flols_off[1] = flols->getDoubleValue("y-offset-m", 0);
+ flols_off[2] = flols->getDoubleValue("z-offset-m", 0);
+ } else
+ flols_off = Point3D(0, 0, 0);
+
+ std::vector<SGPropertyNode_ptr> props = scFileNode->getChildren("wire");
+ std::vector<SGPropertyNode_ptr>::const_iterator it;
+ for (it = props.begin(); it != props.end(); ++it) {
+ std::string s = (*it)->getStringValue();
+ if (!s.empty())
+ wire_objects.push_back(s);
+ }
+
+ props = scFileNode->getChildren("catapult");
+ for (it = props.begin(); it != props.end(); ++it) {
+ std::string s = (*it)->getStringValue();
+ if (!s.empty())
+ catapult_objects.push_back(s);
+ }
+
+ props = scFileNode->getChildren("solid");
+ for (it = props.begin(); it != props.end(); ++it) {
+ std::string s = (*it)->getStringValue();
+ if (!s.empty())
+ solid_objects.push_back(s);
+ }
+
+ props = scFileNode->getChildren("parking-pos");
+ for (it = props.begin(); it != props.end(); ++it) {
+ string name = (*it)->getStringValue("name", "unnamed");
+ double offset_x = (*it)->getDoubleValue("x-offset-m", 0);
+ double offset_y = (*it)->getDoubleValue("y-offset-m", 0);
+ double offset_z = (*it)->getDoubleValue("z-offset-m", 0);
+ double hd = (*it)->getDoubleValue("heading-offset-deg", 0);
+ ParkPosition pp(name, Point3D(offset_x, offset_y, offset_z), hd);
+ ppositions.push_back(pp);
+ }
+}
+
void FGAICarrier::setWind_from_east(double fps) {
wind_from_east = fps;
}
min_long = fabs(deg);
}
-void FGAICarrier::setSolidObjects(const list<string>& so) {
- solid_objects = so;
-}
-
-void FGAICarrier::setWireObjects(const list<string>& wo) {
- wire_objects = wo;
-}
-
-void FGAICarrier::setCatapultObjects(const list<string>& co) {
- catapult_objects = co;
-}
-
-void FGAICarrier::setParkingPositions(const list<ParkPosition>& p) {
- ppositions = p;
-}
-
void FGAICarrier::setSign(const string& s) {
sign = s;
}
TACAN_channel_id = id;
}
-void FGAICarrier::setFlolsOffset(const Point3D& off) {
- flols_off = off;
-}
-
void FGAICarrier::getVelocityWrtEarth(sgdVec3& v, sgdVec3& omega, sgdVec3& pivot) {
sgdCopyVec3(v, vel_wrt_earth );
sgdCopyVec3(omega, rot_wrt_earth );
}
void FGAICarrier::update(double dt) {
-
// For computation of rotation speeds we just use finite differences her.
// That is perfectly valid since this thing is not driven by accelerations
// but by just apply discrete changes at its velocity variables.
class FGAICarrier : public FGAIShip {
public:
- FGAICarrier(FGAIManager* mgr);
- ~FGAICarrier();
+ FGAICarrier();
+ virtual ~FGAICarrier();
+
+ virtual void readFromScenario(SGPropertyNode* scFileNode);
- void setSolidObjects(const list<string>& solid_objects);
- void setWireObjects(const list<string>& wire_objects);
- void setCatapultObjects(const list<string>& catapult_objects);
- void setParkingPositions(const list<ParkPosition>& p);
void setSign(const string& );
- void setFlolsOffset(const Point3D& off);
void setTACANChannelID(const string &);
void getVelocityWrtEarth(sgdVec3& v, sgdVec3& omega, sgdVec3& pivot);
bool init();
+ virtual const char* getTypeString(void) const { return "carrier"; }
+
bool getParkPosition(const string& id, Point3D& geodPos,
double& hdng, sgdVec3 uvw);
private:
+ /// Is sufficient to be private, stores a possible position to place an
+ /// aircraft on start
+ struct ParkPosition {
+ ParkPosition(const ParkPosition& pp)
+ : name(pp.name), offset(pp.offset), heading_deg(pp.heading_deg)
+ {}
+ ParkPosition(const string& n, const Point3D& off = Point3D(), double heading = 0)
+ : name(n), offset(off), heading_deg(heading)
+ {}
+ string name;
+ Point3D offset;
+ double heading_deg;
+ };
+
void update(double dt);
void mark_nohot(ssgEntity*);
leg = 10;
gateId = 0;
SGPath path( globals->get_fg_root() );
- path.append( ("/Data/AI/FlightPlans/" + filename).c_str() );
+ path.append( ("/AI/FlightPlans/" + filename).c_str() );
SGPropertyNode root;
repeat = false;
// Position computed by the traffic manager, as well
// as setting speeds and altitude computed by the
// traffic manager.
-FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
+FGAIFlightPlan::FGAIFlightPlan(const std::string& p,
double course,
time_t start,
FGAirport *dep,
FGAirport *arr,
bool firstLeg,
double radius,
+ double alt,
+ double lat,
+ double lon,
+ double speed,
const string& fltType,
const string& acType,
const string& airline)
bool useInitialWayPoint = true;
bool useCurrentWayPoint = false;
SGPath path( globals->get_fg_root() );
- path.append( "/Data/AI/FlightPlans" );
- path.append( entity->path );
+ path.append( "/AI/FlightPlans" );
+ path.append( p );
SGPropertyNode root;
// This is a bit of a hack:
//cerr << "Set leg to : " << leg << endl;
wpt_iterator = waypoints.begin();
- create(dep,arr, leg, entity->altitude, entity->speed, entity->latitude, entity->longitude,
+ create(dep,arr, leg, alt, speed, lat, lon,
firstLeg, radius, fltType, acType, airline);
wpt_iterator = waypoints.begin();
//cerr << "after create: " << (*wpt_iterator)->name << endl;
} waypoint;
FGAIFlightPlan(const string& filename);
- FGAIFlightPlan(FGAIModelEntity *entity,
+ FGAIFlightPlan(const std::string& p,
double course,
time_t start,
FGAirport *dep,
FGAirport *arr,
bool firstLeg,
double radius,
+ double alt,
+ double lat,
+ double lon,
+ double speed,
const string& fltType,
const string& acType,
const string& airline);
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#include <simgear/misc/sg_path.hxx>
-#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Airports/simple.hxx>
-#include <Traffic/SchedFlight.hxx>
-#include <Traffic/Schedule.hxx>
#include <Traffic/TrafficMgr.hxx>
-#include <list>
-
#include "AIManager.hxx"
#include "AIAircraft.hxx"
#include "AIShip.hxx"
#include "AIStatic.hxx"
#include "AIMultiplayer.hxx"
-SG_USING_STD(list);
-
-
FGAIManager::FGAIManager() {
- initDone = false;
for (int i=0; i < FGAIBase::MAX_OBJECTS; i++)
numObjects[i] = 0;
_dt = 0.0;
- dt_count = 9;
scenario_filename = "";
- ai_list.clear();
}
FGAIManager::~FGAIManager() {
ai_list_iterator ai_list_itr = ai_list.begin();
while(ai_list_itr != ai_list.end()) {
(*ai_list_itr)->unbind();
- delete (*ai_list_itr);
++ai_list_itr;
- }
- ai_list.clear();
+ }
}
user_yaw_node = fgGetNode("/orientation/side-slip-deg", true);
user_speed_node = fgGetNode("/velocities/uBody-fps", true);
+
+ /// Move that into the constructor
for(int i = 0 ; i < root->nChildren() ; i++) {
SGPropertyNode *aiEntry = root->getChild( i );
- if( !strcmp( aiEntry->getName(), "scenario" ) ) {
+ if( !strcmp( aiEntry->getName(), "scenario" ) ) {
scenario_filename = aiEntry->getStringValue();
- if (scenario_filename != "") processScenario( scenario_filename );
- }
+ if (!scenario_filename.empty())
+ processScenario( scenario_filename );
+ }
}
- initDone = true;
}
--numObjects[(*ai_list_itr)->getType()];
--numObjects[0];
(*ai_list_itr)->unbind();
- delete (*ai_list_itr);
if ( ai_list_itr == ai_list.begin() ) {
ai_list.erase(ai_list_itr);
ai_list_itr = ai_list.begin();
} else {
fetchUserState();
if ((*ai_list_itr)->isa(FGAIBase::otThermal)) {
- processThermal((FGAIThermal*)*ai_list_itr);
+ FGAIBase *base = *ai_list_itr;
+ processThermal((FGAIThermal*)base);
} else {
(*ai_list_itr)->update(_dt);
}
++ai_list_itr;
}
wind_from_down_node->setDoubleValue( strength ); // for thermals
-
-}
-
-
-void*
-FGAIManager::createAircraft( FGAIModelEntity *entity, FGAISchedule *ref) {
-
- FGAIAircraft* ai_plane = new FGAIAircraft(this, ref);
- ai_list.push_back(ai_plane);
- ++numObjects[0];
- ++numObjects[FGAIBase::otAircraft];
- if (entity->m_class == "light") {
- ai_plane->SetPerformance(&FGAIAircraft::settings[FGAIAircraft::LIGHT]);
- } else if (entity->m_class == "ww2_fighter") {
- ai_plane->SetPerformance(&FGAIAircraft::settings[FGAIAircraft::WW2_FIGHTER]);
- } else if (entity->m_class == "jet_transport") {
- ai_plane->SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
- } else if (entity->m_class == "jet_fighter") {
- ai_plane->SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_FIGHTER]);
- } else if (entity->m_class == "tanker") {
- ai_plane->SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
- ai_plane->SetTanker(true);
- } else {
- ai_plane->SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
- }
- ai_plane->setAcType(entity->acType);
- ai_plane->setCompany(entity->company);
- ai_plane->setHeading(entity->heading);
- ai_plane->setSpeed(entity->speed);
- ai_plane->setPath(entity->path.c_str());
- ai_plane->setAltitude(entity->altitude);
- ai_plane->setLongitude(entity->longitude);
- ai_plane->setLatitude(entity->latitude);
- ai_plane->setBank(entity->roll);
-
- if ( entity->fp ) {
- ai_plane->SetFlightPlan(entity->fp);
- }
- if (entity->repeat) {
- ai_plane->GetFlightPlan()->setRepeat(true);
- }
- ai_plane->init();
- ai_plane->bind();
- return ai_plane;
-}
-
-void*
-FGAIManager::createMultiplayer( FGAIModelEntity *entity ) {
-
- FGAIMultiplayer* ai_plane = new FGAIMultiplayer(this);
- ai_list.push_back(ai_plane);
- ++numObjects[0];
- ++numObjects[FGAIBase::otMultiplayer];
- ai_plane->setAcType(entity->acType);
- ai_plane->setCompany(entity->company);
- ai_plane->setPath(entity->path.c_str());
-
- ai_plane->init();
- ai_plane->bind();
- return ai_plane;
}
-
-void*
-FGAIManager::createShip( FGAIModelEntity *entity ) {
-
- // cout << "creating ship" << endl;
-
- FGAIShip* ai_ship = new FGAIShip(this);
- ai_list.push_back(ai_ship);
- ++numObjects[0];
- ++numObjects[FGAIBase::otShip];
- ai_ship->setHeading(entity->heading);
- ai_ship->setSpeed(entity->speed);
- ai_ship->setPath(entity->path.c_str());
- ai_ship->setAltitude(entity->altitude);
- ai_ship->setLongitude(entity->longitude);
- ai_ship->setLatitude(entity->latitude);
- ai_ship->setRudder(entity->rudder);
- ai_ship->setName(entity->name);
-
- if ( entity->fp ) {
- ai_ship->setFlightPlan(entity->fp);
- }
-
- ai_ship->init();
- ai_ship->bind();
- return ai_ship;
-}
-
-void*
-FGAIManager::createCarrier( FGAIModelEntity *entity ) {
-
- // cout << "creating carrier" << endl;
-
- FGAICarrier* ai_carrier = new FGAICarrier(this);
- ai_list.push_back(ai_carrier);
- ++numObjects[0];
- ++numObjects[FGAIBase::otCarrier];
- ai_carrier->setHeading(entity->heading);
- ai_carrier->setSpeed(entity->speed);
- ai_carrier->setPath(entity->path.c_str());
- ai_carrier->setAltitude(entity->altitude);
- ai_carrier->setLongitude(entity->longitude);
- ai_carrier->setLatitude(entity->latitude);
- ai_carrier->setRudder(entity->rudder);
- ai_carrier->setSolidObjects(entity->solid_objects);
- ai_carrier->setWireObjects(entity->wire_objects);
- ai_carrier->setCatapultObjects(entity->catapult_objects);
- ai_carrier->setParkingPositions(entity->ppositions);
- ai_carrier->setRadius(entity->radius);
- ai_carrier->setSign(entity->pennant_number);
- ai_carrier->setName(entity->name);
- ai_carrier->setFlolsOffset(entity->flols_offset);
- ai_carrier->setWind_from_east(entity->wind_from_east);
- ai_carrier->setWind_from_north(entity->wind_from_north);
- ai_carrier->setTACANChannelID(entity->TACAN_channel_ID);
- ai_carrier->setMaxLat(entity->max_lat);
- ai_carrier->setMinLat(entity->min_lat);
- ai_carrier->setMaxLong(entity->max_long);
- ai_carrier->setMinLong(entity->min_long);
-
-
- if ( entity->fp ) {
- ai_carrier->setFlightPlan(entity->fp);
- }
-
- ai_carrier->init();
- ai_carrier->bind();
- return ai_carrier;
-}
-
-void*
-FGAIManager::createBallistic( FGAIModelEntity *entity ) {
-
- FGAIBallistic* ai_ballistic = new FGAIBallistic(this);
- ai_list.push_back(ai_ballistic);
- ++numObjects[0];
- ++numObjects[FGAIBase::otBallistic];
- ai_ballistic->setAzimuth(entity->azimuth);
- ai_ballistic->setElevation(entity->elevation);
- ai_ballistic->setSpeed(entity->speed);
- ai_ballistic->setPath(entity->path.c_str());
- ai_ballistic->setAltitude(entity->altitude);
- ai_ballistic->setLongitude(entity->longitude);
- ai_ballistic->setLatitude(entity->latitude);
- ai_ballistic->setDragArea(entity->eda);
- ai_ballistic->setLife(entity->life);
- ai_ballistic->setBuoyancy(entity->buoyancy);
- ai_ballistic->setWind_from_east(entity->wind_from_east);
- ai_ballistic->setWind_from_north(entity->wind_from_north);
- ai_ballistic->setWind(entity->wind);
- ai_ballistic->setRoll(entity->roll);
- ai_ballistic->setCd(entity->cd);
- ai_ballistic->setMass(entity->mass);
- ai_ballistic->setStabilisation(entity->aero_stabilised);
- ai_ballistic->init();
- ai_ballistic->bind();
- return ai_ballistic;
-}
-
-void*
-FGAIManager::createStorm( FGAIModelEntity *entity ) {
-
- FGAIStorm* ai_storm = new FGAIStorm(this);
- ++numObjects[0];
- ++numObjects[FGAIBase::otStorm];
- ai_storm->setHeading(entity->heading);
- ai_storm->setSpeed(entity->speed);
- ai_storm->setPath(entity->path.c_str());
- ai_storm->setAltitude(entity->altitude);
- ai_storm->setDiameter(entity->diameter / 6076.11549);
- ai_storm->setHeight(entity->height_msl);
- ai_storm->setStrengthNorm(entity->turb_strength);
- ai_storm->setLongitude(entity->longitude);
- ai_storm->setLatitude(entity->latitude);
- ai_storm->init();
- ai_storm->bind();
- ai_list.push_back(ai_storm);
- return ai_storm;
-}
-
-void*
-FGAIManager::createThermal( FGAIModelEntity *entity ) {
-
- FGAIThermal* ai_thermal = new FGAIThermal(this);
- ++numObjects[0];
- ++numObjects[FGAIBase::otThermal];
- ai_thermal->setLongitude(entity->longitude);
- ai_thermal->setLatitude(entity->latitude);
- ai_thermal->setMaxStrength(entity->strength);
- ai_thermal->setDiameter(entity->diameter / 6076.11549);
- ai_thermal->setHeight(entity->height_msl);
- ai_thermal->init();
- ai_thermal->bind();
- ai_list.push_back(ai_thermal);
- return ai_thermal;
+void
+FGAIManager::attach(SGSharedPtr<FGAIBase> model)
+{
+ model->setManager(this);
+ ai_list.push_back(model);
+ ++numObjects[0];
+ ++numObjects[model->getType()];
+ model->init();
+ model->bind();
}
-void*
-FGAIManager::createStatic( FGAIModelEntity *entity ) {
-
- // cout << "creating static object" << endl;
-
- FGAIStatic* ai_static = new FGAIStatic(this);
- ai_list.push_back(ai_static);
- ++numObjects[0];
- ++numObjects[FGAIBase::otStatic];
- ai_static->setHeading(entity->heading);
- ai_static->setPath(entity->path.c_str());
- ai_static->setAltitude(entity->altitude);
- ai_static->setLongitude(entity->longitude);
- ai_static->setLatitude(entity->latitude);
- ai_static->init();
- ai_static->bind();
- return ai_static;
-}
void FGAIManager::destroyObject( int ID ) {
ai_list_iterator ai_list_itr = ai_list.begin();
--numObjects[0];
--numObjects[(*ai_list_itr)->getType()];
(*ai_list_itr)->unbind();
- delete (*ai_list_itr);
ai_list.erase(ai_list_itr);
-
break;
}
++ai_list_itr;
void FGAIManager::processScenario( const string &filename ) {
- FGAIScenario* s = new FGAIScenario( filename );
- for (int i=0;i<s->nEntries();i++) {
- FGAIModelEntity* const en = s->getNextEntry();
-
- if (en) {
- if ( en->m_type == "aircraft") {
- createAircraft( en );
- } else if ( en->m_type == "ship") {
- createShip( en );
-
- } else if ( en->m_type == "carrier") {
- createCarrier( en );
-
- } else if ( en->m_type == "thunderstorm") {
- createStorm( en );
-
- } else if ( en->m_type == "thermal") {
- createThermal( en );
-
- } else if ( en->m_type == "ballistic") {
- createBallistic( en );
-
- } else if ( en->m_type == "static") {
- createStatic( en );
- }
+ SGPropertyNode_ptr scenarioTop = loadScenarioFile(filename);
+ if (!scenarioTop)
+ return;
+ SGPropertyNode* scenarios = scenarioTop->getChild("scenario");
+ if (!scenarios)
+ return;
+
+ for (int i = 0; i < scenarios->nChildren(); i++) {
+ SGPropertyNode* scEntry = scenarios->getChild(i);
+ std::string type = scEntry->getStringValue("type", "aircraft");
+
+ if (type == "aircraft") {
+ FGAIAircraft* aircraft = new FGAIAircraft;
+ aircraft->readFromScenario(scEntry);
+ attach(aircraft);
+
+ } else if (type == "ship") {
+ FGAIShip* ship = new FGAIShip;
+ ship->readFromScenario(scEntry);
+ attach(ship);
+
+ } else if (type == "carrier") {
+ FGAICarrier* carrier = new FGAICarrier;
+ carrier->readFromScenario(scEntry);
+ attach(carrier);
+
+ } else if (type == "thunderstorm") {
+ FGAIStorm* storm = new FGAIStorm;
+ storm->readFromScenario(scEntry);
+ attach(storm);
+
+ } else if (type == "thermal") {
+ FGAIThermal* thermal = new FGAIThermal;
+ thermal->readFromScenario(scEntry);
+ attach(thermal);
+
+ } else if (type == "ballistic") {
+ FGAIBallistic* ballistic = new FGAIBallistic;
+ ballistic->readFromScenario(scEntry);
+ attach(ballistic);
+
+ } else if (type == "static") {
+ FGAIStatic* aistatic = new FGAIStatic;
+ aistatic->readFromScenario(scEntry);
+ attach(aistatic);
+
}
}
+}
- delete s;
+SGPropertyNode_ptr
+FGAIManager::loadScenarioFile(const std::string& filename)
+{
+ SGPath path(globals->get_fg_root());
+ path.append("AI/" + filename + ".xml");
+ try {
+ SGPropertyNode_ptr root = new SGPropertyNode;
+ readProperties(path.str(), root);
+ return root;
+ } catch (const sg_exception &e) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path specified for AI "
+ "scenario: \"" << path.str() << "\"");
+ return 0;
+ }
}
// This code keeps track of models that have already been loaded
Point3D& geodPos, double& heading,
sgdVec3 uvw)
{
+ bool found = false;
SGPropertyNode* root = fgGetNode("sim/ai", true);
if (!root->getNode("enabled", true)->getBoolValue())
- return 0;
+ return found;
- bool found = false;
for(int i = 0 ; (!found) && i < root->nChildren() ; i++) {
SGPropertyNode *aiEntry = root->getChild( i );
- if( !strcmp( aiEntry->getName(), "scenario" ) ) {
- string filename = aiEntry->getStringValue();
- FGAIScenario* s = new FGAIScenario( filename );
- for (int i=0; i<s->nEntries(); i++) {
- FGAIModelEntity* en = s->getNextEntry();
- if (en && en->m_type == "carrier" &&
- (en->pennant_number == id || en->name == id)) {
- FGAICarrier* ai_carrier = new FGAICarrier(0);
- ai_carrier->setHeading(en->heading);
- ai_carrier->setSpeed(en->speed);
- ai_carrier->setAltitude(en->altitude);
- ai_carrier->setLongitude(en->longitude);
- ai_carrier->setLatitude(en->latitude);
- ai_carrier->setBank(en->rudder);
- ai_carrier->setParkingPositions(en->ppositions);
- ai_carrier->setWind_from_east(en->wind_from_east);
- ai_carrier->setWind_from_north(en->wind_from_north);
- //ai_carrier->setTACANFreq(en->TACAN_freq);
-
- if (ai_carrier->getParkPosition(pid, geodPos, heading, uvw)) {
- delete ai_carrier;
+ if( !strcmp( aiEntry->getName(), "scenario" ) ) {
+ string filename = aiEntry->getStringValue();
+ SGPropertyNode_ptr scenarioTop = loadScenarioFile(filename);
+ if (scenarioTop) {
+ SGPropertyNode* scenarios = scenarioTop->getChild("scenario");
+ if (scenarios) {
+ for (int i = 0; i < scenarios->nChildren(); i++) {
+ SGPropertyNode* scEntry = scenarios->getChild(i);
+ std::string type = scEntry->getStringValue("type");
+ std::string pnumber = scEntry->getStringValue("pennant-number");
+ std::string name = scEntry->getStringValue("name");
+ if (type == "carrier" && (pnumber == id || name == id)) {
+ SGSharedPtr<FGAICarrier> carrier = new FGAICarrier;
+ carrier->readFromScenario(scEntry);
+
+ if (carrier->getParkPosition(pid, geodPos, heading, uvw)) {
found = true;
break;
+ }
}
-
- delete ai_carrier;
+ }
}
}
- delete s;
}
}
return found;
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/structure/ssgSharedPtr.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
#include <Main/fg_props.hxx>
#include <AIModel/AIBase.hxx>
-#include <AIModel/AIScenario.hxx>
#include <AIModel/AIFlightPlan.hxx>
#include <Traffic/SchedFlight.hxx>
private:
// A list of pointers to AI objects
- typedef list <FGAIBase*> ai_list_type;
+ typedef list <SGSharedPtr<FGAIBase> > ai_list_type;
typedef ai_list_type::iterator ai_list_iterator;
typedef ai_list_type::const_iterator ai_list_const_iterator;
- // Everything put in this list should be created dynamically
- // on the heap and ***DELETED WHEN REMOVED!!!!!***
ai_list_type ai_list;
ModelVec loadedModels;
void unbind();
void update(double dt);
- void* createBallistic( FGAIModelEntity *entity );
- void* createAircraft( FGAIModelEntity *entity, FGAISchedule *ref=0 );
- void* createMultiplayer( FGAIModelEntity *entity );
- void* createThermal( FGAIModelEntity *entity );
- void* createStorm( FGAIModelEntity *entity );
- void* createShip( FGAIModelEntity *entity );
- void* createCarrier( FGAIModelEntity *entity );
- void* createStatic( FGAIModelEntity *entity );
+ void attach(SGSharedPtr<FGAIBase> model);
void destroyObject( int ID );
ssgBranch * getModel(const string& path) const;
void setModel(const string& path, ssgBranch *model);
+ static SGPropertyNode_ptr loadScenarioFile(const std::string& filename);
+
static bool getStartPosition(const string& id, const string& pid,
Point3D& geodPos, double& hdng, sgdVec3 uvw);
private:
- bool initDone;
bool enabled;
int numObjects[FGAIBase::MAX_OBJECTS];
SGPropertyNode* root;
double wind_from_east;
double wind_from_north;
double _dt;
- int dt_count;
void fetchUserState( void );
// used by thermals
static string tempReg;
-FGAIMultiplayer::FGAIMultiplayer(FGAIManager* mgr) {
- manager = mgr;
- _type_str = "multiplayer";
- _otype = otMultiplayer;
-
+FGAIMultiplayer::FGAIMultiplayer() : FGAIBase(otMultiplayer) {
_time_node = fgGetNode("/sim/time/elapsed-sec", true);
//initialise values
FGAIMultiplayer::~FGAIMultiplayer() {
}
-
bool FGAIMultiplayer::init() {
return FGAIBase::init();
}
//###########################//
//double range_ft2 = UpdateRadar(manager);
}
+
void FGAIMultiplayer::setTimeStamp()
{
// this function sets the timestamp as the sim elapsed time
class FGAIMultiplayer : public FGAIBase {
public:
- FGAIMultiplayer(FGAIManager* mgr);
+ FGAIMultiplayer();
~FGAIMultiplayer();
bool init();
void setAcType(string ac) { acType = ac; };
void setCompany(string comp);
+ virtual const char* getTypeString(void) const { return "multiplayer"; }
+
double dt;
double speedN, speedE, speedD;
double rateH, rateR, rateP;
-// FGAIScenario.cxx - class for loading an AI scenario
-// Written by David Culp, started May 2004
-// - davidculp2@comcast.net
-//
-// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#include <cstdio>
-
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/structure/exception.hxx>
-#include <simgear/constants.h>
-#ifdef __BORLANDC__
-# define exception c_exception
-#endif
-#include <simgear/props/props.hxx>
-
-#include <Main/globals.hxx>
-#include <Main/fg_props.hxx>
-
-#include "AIScenario.hxx"
-#include "AIFlightPlan.hxx"
-
-static list<string>
-getAllStringNodeVals(const char* name, SGPropertyNode * entry_node);
-static list<ParkPosition>
-getAllOffsetNodeVals(const char* name, SGPropertyNode * entry_node);
-
-FGAIScenario::FGAIScenario(const string &filename)
-{
- int i;
- SGPath path( globals->get_fg_root() );
-
-// cout << "/Data/AI/" << filename << endl;
-
- path.append( ("/Data/AI/" + filename + ".xml").c_str() );
- SGPropertyNode root;
- readProperties(path.str(), &root);
-
-// cout <<"path " << path.str() << endl;
-
- try {
- readProperties(path.str(), &root);
- } catch (const sg_exception &e) {
- SG_LOG(SG_GENERAL, SG_ALERT,
- "Incorrect path specified for AI scenario: ");
-
- cout << path.str() << endl;
-
- return;
- }
-
- entries.clear();
- SGPropertyNode * node = root.getNode("scenario");
- for (i = 0; i < node->nChildren(); i++) {
-
-// cout << "Reading entity data entry " << i << endl;
-
- SGPropertyNode * entry_node = node->getChild(i);
-
- FGAIModelEntity* en = new FGAIModelEntity;
- en->callsign = entry_node->getStringValue("callsign", "none");
- en->m_type = entry_node->getStringValue("type", "aircraft");
- en->m_class = entry_node->getStringValue("class", "jet_transport");
- en->path = entry_node->getStringValue("model", "Models/Geometry/glider.ac");
- en->flightplan = entry_node->getStringValue("flightplan", "");
- en->repeat = entry_node->getBoolValue("repeat", false);
- en->latitude = entry_node->getDoubleValue("latitude", 0.0);
- en->longitude = entry_node->getDoubleValue("longitude", 0.0);
- en->altitude = entry_node->getDoubleValue("altitude", 0.0);
- en->speed = entry_node->getDoubleValue("speed", 0.0);
- en->heading = entry_node->getDoubleValue("heading", 0.0);
- en->roll = entry_node->getDoubleValue("roll", 0.0);
- en->azimuth = entry_node->getDoubleValue("azimuth", 0.0);
- en->elevation = entry_node->getDoubleValue("elevation", 0.0);
- en->rudder = entry_node->getFloatValue("rudder", 0.0);
- en->strength = entry_node->getDoubleValue("strength-fps", 8.0);
- en->turb_strength = entry_node->getDoubleValue("strength-norm", 1.0);
- en->diameter = entry_node->getDoubleValue("diameter-ft", 0.0);
- en->height_msl = entry_node->getDoubleValue("height-msl", 5000.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->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);
- en->cd = entry_node->getDoubleValue("cd", 0.029);
- en->mass = entry_node->getDoubleValue("mass", 0.007);
- en->radius = entry_node->getDoubleValue("turn-radius-ft", 2000);
- en->TACAN_channel_ID= entry_node->getStringValue("TACAN-channel-ID", "029Y");
- en->name = entry_node->getStringValue("name", "Nimitz");
- en->pennant_number = entry_node->getStringValue("pennant-number", "");
- en->wire_objects = getAllStringNodeVals("wire", entry_node);
- en->catapult_objects = getAllStringNodeVals("catapult", entry_node);
- en->solid_objects = getAllStringNodeVals("solid", entry_node);
- en->ppositions = getAllOffsetNodeVals("parking-pos", entry_node);
- en->max_lat = entry_node->getDoubleValue("max-lat", 0);
- en->min_lat = entry_node->getDoubleValue("min-lat",0);
- en->max_long = entry_node->getDoubleValue("max-long", 0);
- en->min_long = entry_node->getDoubleValue("min-long", 0);
- list<ParkPosition> flolspos = getAllOffsetNodeVals("flols-pos", entry_node);
- en->flols_offset = flolspos.front().offset;
-
- en->fp = NULL;
- if (en->flightplan != ""){
- en->fp = new FGAIFlightPlan( en->flightplan );
- }
- entries.push_back( en );
- }
-
- entry_iterator = entries.begin();
- //cout << entries.size() << " entries read." << endl;
-}
-
-
-FGAIScenario::~FGAIScenario()
-{
- entries.clear();
-}
-
-
-FGAIModelEntity* const
-FGAIScenario::getNextEntry( void )
-{
- if (entries.size() == 0) return 0;
- if (entry_iterator != entries.end()) {
- return *entry_iterator++;
- } else {
- return 0;
- }
-}
-
-int FGAIScenario::nEntries( void )
-{
- return entries.size();
-}
-
-static list<string>
-getAllStringNodeVals(const char* name, SGPropertyNode * entry_node)
-{
- list<string> retval;
- int i=0;
- do {
- char nodename[100];
- snprintf(nodename, sizeof(nodename), "%s[%d]", name, i);
- const char* objname = entry_node->getStringValue(nodename, 0);
- if (objname == 0)
- return retval;
-
- retval.push_back(string(objname));
- ++i;
- } while (1);
-
- return retval;
-}
-
-static list<ParkPosition>
-getAllOffsetNodeVals(const char* name, SGPropertyNode * entry_node)
-{
- list<ParkPosition> retval;
-
- vector<SGPropertyNode_ptr>::const_iterator it;
- vector<SGPropertyNode_ptr> children = entry_node->getChildren(name);
- for (it = children.begin(); it != children.end(); ++it) {
- string name = (*it)->getStringValue("name", "unnamed");
- double offset_x = (*it)->getDoubleValue("x-offset-m", 0);
- double offset_y = (*it)->getDoubleValue("y-offset-m", 0);
- double offset_z = (*it)->getDoubleValue("z-offset-m", 0);
- double hd = (*it)->getDoubleValue("heading-offset-deg", 0);
- ParkPosition pp(name, Point3D(offset_x, offset_y, offset_z), hd);
- retval.push_back(pp);
- }
-
- return retval;
-}
-
-// end scenario.cxx
-
-// FGAIScenario - class for loading an AI scenario
-// Written by David Culp, started May 2004
-// - davidculp2@comcast.net
-//
-// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#ifndef _FG_AISCENARIO_HXX
-#define _FG_AISCENARIO_HXX
-
-#include <simgear/compiler.h>
-
-#include <vector>
-#include <string>
-
-#include "AIBase.hxx"
-
-SG_USING_STD(vector);
-SG_USING_STD(string);
-
-
-class FGAIScenario {
-
-public:
-
- FGAIScenario(const string &filename);
- ~FGAIScenario();
-
- FGAIModelEntity* const getNextEntry( void );
- int nEntries( void );
-
-private:
-
- typedef vector <FGAIModelEntity*> entry_vector_type;
- typedef entry_vector_type::const_iterator entry_vector_iterator;
-
- entry_vector_type entries;
- entry_vector_iterator entry_iterator;
-
-
-};
-
-
-#endif // _FG_AISCENARIO_HXX
-
#include <simgear/math/point3d.hxx>
#include <math.h>
+#include "AIFlightPlan.hxx"
#include "AIShip.hxx"
-FGAIShip::FGAIShip(FGAIManager* mgr) {
- manager = mgr;
- _type_str = "ship";
- _otype = otShip;
-
+FGAIShip::FGAIShip(object_type ot) : FGAIBase(ot) {
}
FGAIShip::~FGAIShip() {
}
+void FGAIShip::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIBase::readFromScenario(scFileNode);
+
+ setRudder(scFileNode->getFloatValue("rudder", 0.0));
+ setName(scFileNode->getStringValue("name", "Titanic"));
+
+ std::string flightplan = scFileNode->getStringValue("flightplan");
+ if (!flightplan.empty()){
+ FGAIFlightPlan* fp = new FGAIFlightPlan(flightplan);
+ setFlightPlan(fp);
+ }
+}
bool FGAIShip::init() {
public:
- FGAIShip(FGAIManager* mgr);
- ~FGAIShip();
+ FGAIShip(object_type ot = otShip);
+ virtual ~FGAIShip();
- bool init();
+ virtual void readFromScenario(SGPropertyNode* scFileNode);
+
+ virtual bool init();
virtual void bind();
virtual void unbind();
- void update(double dt);
+ virtual void update(double dt);
void setFlightPlan(FGAIFlightPlan* f);
void setName(const string&);
void setRudder(float r);
void ClimbTo(double altitude);
void TurnTo(double heading);
bool hdg_lock;
+
+ virtual const char* getTypeString(void) const { return "ship"; }
protected:
#include "AIStatic.hxx"
-FGAIStatic::FGAIStatic(FGAIManager* mgr) {
- manager = mgr;
- _type_str = "static";
- _otype = otStatic;
+FGAIStatic::FGAIStatic() : FGAIBase(otStatic) {
}
FGAIStatic::~FGAIStatic() {
}
-
bool FGAIStatic::init() {
return FGAIBase::init();
}
public:
- FGAIStatic(FGAIManager* mgr);
+ FGAIStatic();
~FGAIStatic();
-
- bool init();
+
+ virtual bool init();
virtual void bind();
virtual void unbind();
- void update(double dt);
-
-private:
+ virtual void update(double dt);
- double dt;
-
+ virtual const char* getTypeString(void) const { return "static"; }
};
#include "AIStorm.hxx"
-FGAIStorm::FGAIStorm(FGAIManager* mgr) {
- manager = mgr;
- _type_str = "thunderstorm";
- _otype = otStorm;
+FGAIStorm::FGAIStorm() : FGAIBase(otStorm) {
delay = 3.6;
subflashes = 1;
timer = 0.0;
FGAIStorm::~FGAIStorm() {
}
+void FGAIStorm::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIBase::readFromScenario(scFileNode);
+
+ setDiameter(scFileNode->getDoubleValue("diameter-ft", 0.0)/6076.11549);
+ setHeight(scFileNode->getDoubleValue("height-msl", 5000.0));
+ setStrengthNorm(scFileNode->getDoubleValue("strength-norm", 1.0));
+}
bool FGAIStorm::init() {
return FGAIBase::init();
void FGAIStorm::Run(double dt) {
- FGAIStorm::dt = dt;
-
double speed_north_deg_sec;
double speed_east_deg_sec;
public:
- FGAIStorm(FGAIManager* mgr);
+ FGAIStorm();
~FGAIStorm();
- bool init();
+ void readFromScenario(SGPropertyNode* scFileNode);
+
+ virtual bool init();
virtual void bind();
virtual void unbind();
- void update(double dt);
+ virtual void update(double dt);
inline void setStrengthNorm( double s ) { strength_norm = s; };
inline void setDiameter( double d ) { diameter = d; };
inline void setHeight( double h ) { height = h; };
inline double getDiameter() const { return diameter; };
inline double getHeight() const { return height; };
+ virtual const char* getTypeString(void) const { return "thunderstorm"; }
+
private:
- double dt;
double diameter; // diameter of turbulence zone, in nm
double height; // top of turbulence zone, in feet MSL
double strength_norm; // strength of turbulence
#include "AIThermal.hxx"
-FGAIThermal::FGAIThermal(FGAIManager* mgr) {
- manager = mgr;
- _type_str = "thermal";
- _otype = otThermal;
+FGAIThermal::FGAIThermal() : FGAIBase(otThermal) {
max_strength = 6.0;
diameter = 0.5;
strength = factor = 0.0;
}
-
FGAIThermal::~FGAIThermal() {
}
+void FGAIThermal::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIBase::readFromScenario(scFileNode);
+
+ setMaxStrength(scFileNode->getDoubleValue("strength-fps", 8.0));
+ setDiameter(scFileNode->getDoubleValue("diameter-ft", 0.0)/6076.11549);
+ setHeight(scFileNode->getDoubleValue("height-msl", 5000.0));
+}
bool FGAIThermal::init() {
factor = 8.0 * max_strength / (diameter * diameter * diameter);
void FGAIThermal::Run(double dt) {
- FGAIThermal::dt = dt;
-
//###########################//
// do calculations for range //
//###########################//
public:
- FGAIThermal(FGAIManager* mgr);
+ FGAIThermal();
~FGAIThermal();
- bool init();
+ void readFromScenario(SGPropertyNode* scFileNode);
+
+ virtual bool init();
virtual void bind();
virtual void unbind();
- void update(double dt);
+ virtual void update(double dt);
inline void setMaxStrength( double s ) { max_strength = s; };
inline void setDiameter( double d ) { diameter = d; };
inline double getDiameter() const { return diameter; };
inline double getHeight() const { return height; };
+ virtual const char* getTypeString(void) const { return "thermal"; }
private:
- double dt;
void Run(double dt);
double max_strength;
double strength;
AIStorm.hxx AIStorm.cxx \
AIThermal.hxx AIThermal.cxx \
AIFlightPlan.hxx AIFlightPlan.cxx AIFlightPlanCreate.cxx \
- AIScenario.hxx AIScenario.cxx \
AICarrier.hxx AICarrier.cxx \
AIStatic.hxx AIStatic.cxx
#include <Main/fg_props.hxx>
#include <Main/util.hxx>
#include <AIModel/AIManager.hxx>
+#include <AIModel/AIBallistic.hxx>
const double FGSubmodelMgr::lbs_to_slugs = 0.031080950172;
transform(sm); // calculate submodel's initial conditions in world-coordinates
- FGAIModelEntity entity;
-
- entity.path = sm->model.c_str();
- entity.latitude = IC.lat;
- entity.longitude = IC.lon;
- entity.altitude = IC.alt;
- entity.azimuth = IC.azimuth;
- entity.elevation = IC.elevation;
- entity.roll = IC.roll;
- entity.speed = IC.speed;
- entity.eda = sm->drag_area;
- entity.life = sm->life;
- entity.buoyancy = sm->buoyancy;
- entity.wind_from_east = IC.wind_from_east;
- entity.wind_from_north = IC.wind_from_north;
- entity.wind = sm->wind;
- entity.cd = sm->cd;
- entity.mass = IC.mass;
- entity.aero_stabilised = sm->aero_stabilised;
- ai->createBallistic( &entity );
+ FGAIBallistic* ballist = new FGAIBallistic;
+ ballist->setPath(sm->model.c_str());
+ ballist->setLatitude(IC.lat);
+ ballist->setLongitude(IC.lon);
+ ballist->setAltitude(IC.alt);
+ ballist->setAzimuth(IC.azimuth);
+ ballist->setElevation(IC.elevation);
+ ballist->setRoll(IC.roll);
+ ballist->setSpeed(IC.speed);
+ ballist->setDragArea(sm->drag_area);
+ ballist->setLife(sm->life);
+ ballist->setBuoyancy(sm->buoyancy);
+ ballist->setWind_from_east(IC.wind_from_east);
+ ballist->setWind_from_north(IC.wind_from_north);
+ ballist->setWind(sm->wind);
+ ballist->setCd(sm->cd);
+ ballist->setMass(IC.mass);
+ ballist->setStabilisation(sm->aero_stabilised);
+ ai->attach(ballist);
if (sm->count > 0) (sm->count)--;
vector<SGPropertyNode_ptr> children = root.getChildren("submodel");
vector<SGPropertyNode_ptr>::iterator it = children.begin();
vector<SGPropertyNode_ptr>::iterator end = children.end();
- for (int i = 0; it < end; ++it, i++) {
+ for (int i = 0; it != end; ++it, i++) {
// cout << "Reading submodel " << (*it)->getPath() << endl;
submodel* sm = new submodel;
$(top_builddir)/src/Instrumentation/KLN89/libKLN89.a \
$(top_builddir)/src/Instrumentation/libInstrumentation.a \
$(top_builddir)/src/Model/libModel.a \
- $(top_builddir)/src/AIModel/libAIModel.a \
$(top_builddir)/src/Network/libNetwork.a \
$(top_builddir)/src/Navaids/libNavaids.a \
$(top_builddir)/src/Scenery/libScenery.a \
$(top_builddir)/src/Sound/libSound.a \
$(top_builddir)/src/Airports/libAirports.a \
$(MPLAYER_LIBS) \
+ $(top_builddir)/src/AIModel/libAIModel.a \
$(VOICE_LIBS) \
$(top_builddir)/src/Systems/libSystems.a \
$(top_builddir)/src/Time/libTime.a \
-lsgmagvar -lsgmisc -lsgnasal -lsgxml -lsgsound -lsgserial \
-lsgstructure -lsgenvironment \
$(THREAD_LIBS) \
- -lplibpu -lplibfnt -lplibjs -lplibnet -lplibssg -lplibsg -lplibul \
+ -lplibpu -lplibfnt -lplibjs -lplibnet -lplibssgaux -lplibssg -lplibsg -lplibul \
$(network_LIBS) \
-lz \
$(opengl_LIBS) \
#include "mpplayer.hxx"
-
#include <stdlib.h>
#if !(defined(_MSC_VER) || defined(__MINGW32__))
# include <netdb.h>
const double left_aileron, const double right_aileron, const double elevator, const double rudder,
//const double rpms[6],
const double rateH, const double rateR, const double rateP,
- const double accN, const double accE, const double accD
+ const double accN, const double accE, const double accD
)
{
int toff, utoff;
m_speedN = speedN;
m_speedE = speedE;
m_speedD = speedD;
- m_accN = accN;
- m_accE = accE;
- m_accD = accD;
+ m_accN = accN;
+ m_accE = accE;
+ m_accD = accD;
m_left_aileron = left_aileron;
- m_right_aileron = right_aileron;
+ m_right_aileron = right_aileron;
m_elevator = elevator;
- m_rudder = rudder;
+ m_rudder = rudder;
/*for (int i = 0; i < 6; i++) {
m_rpms[i] = rpms[i];
// set properties
SGPropertyNode *root = m_AIModel->getProps();
root->getNode("surface-positions/left-aileron-pos-norm", true)->setDoubleValue(m_left_aileron);
- root->getNode("surface-positions/right-aileron-pos-norm", true)->setDoubleValue(m_right_aileron);
+ root->getNode("surface-positions/right-aileron-pos-norm", true)->setDoubleValue(m_right_aileron);
root->getNode("surface-positions/elevator-pos-norm", true)->setDoubleValue(m_elevator);
root->getNode("surface-positions/rudder-pos-norm", true)->setDoubleValue(m_rudder);
/*root->getNode("engines/engine/rpm", true)->setDoubleValue(m_rpms[0]);
// Adjust by the last offset
//cout << "OFFSET: " << (m_LastOffset - m_TimeOffset) << endl;
- //m_AIModel->timewarp(m_LastOffset - m_TimeOffset);
+ //m_AIModel->timewarp(m_LastOffset - m_TimeOffset);
- // set the timestamp for the data update (sim elapsed time (secs))
- m_AIModel->setTimeStamp();
+ // set the timestamp for the data update (sim elapsed time (secs))
+ m_AIModel->setTimeStamp();
}
time(&m_LastUpdate);
void
MPPlayer::LoadAI(void)
{
- // set up the model info
- FGAIModelEntity aiModel;
- aiModel.m_type = "aircraft";
- aiModel.path = m_ModelName;
- aiModel.acType = "Multiplayer";
- aiModel.company = m_Callsign;
-
// then get the model manager
FGAIManager *aiModelMgr = (FGAIManager *) globals->get_subsystem("ai_model");
if (!aiModelMgr) {
// then get the model
fgSetBool("/sim/freeze/clock", true);
- m_AIModel = (FGAIMultiplayer *) aiModelMgr->createMultiplayer(&aiModel);
+ m_AIModel = new FGAIMultiplayer;
+ m_AIModel->setAcType("Multiplayer");
+ m_AIModel->setCompany(m_Callsign);
+ m_AIModel->setPath(m_ModelName.c_str());
+ aiModelMgr->attach(m_AIModel);
fgSetBool("/sim/freeze/clock", false);
}
PosMsg->rateH = XDR_encode_float ((float) m_rateH);
PosMsg->rateR = XDR_encode_float ((float) m_rateR);
PosMsg->rateP = XDR_encode_float ((float) m_rateP);
- PosMsg->accN = XDR_encode_float ((float) m_accN);
+ PosMsg->accN = XDR_encode_float ((float) m_accN);
PosMsg->accE = XDR_encode_float ((float) m_accE);
PosMsg->accD = XDR_encode_float ((float) m_accD);
}
const double left_aileron, const double right_aileron, const double elevator, const double rudder,
//const double rpms[6],
const double rateH, const double rateR, const double rateP,
- const double accN, const double accE, const double accD);
+ const double accN, const double accE, const double accD);
/** Sets a property for this player
*/
void SetProperty(string property, SGPropertyNode::Type type, double val);
double m_accE; // ...
double m_accD; // ...
double m_left_aileron; // ...
- double m_right_aileron; // ...
+ double m_right_aileron; // ...
double m_elevator; // ...
double m_rudder; // ...
//double m_rpms[6]; // ...
double m_rateH; // ...
double m_rateR; // ...
double m_rateP; // ...
-
+
time_t m_LastUpdate; // last time update data received
int m_LastTime; // last seconds according to the packet
int m_LastUTime; // last microseconds according to the packet
#include <AIModel/AIFlightPlan.hxx>
#include <AIModel/AIManager.hxx>
+#include <AIModel/AIAircraft.hxx>
#include <Airports/simple.hxx>
#include <Main/fg_init.hxx> // That's pretty ugly, but I need fgFindAirportID
// alt = dep->_elevation+19;
// }
- FGAIModelEntity entity;
-
- entity.m_class = m_class; //"jet_transport";
- entity.company = airline; //i->getAirline();
- entity.acType = acType; //i->getAcType();
- entity.path = modelPath.c_str();
- entity.flightplan = flightPlanName.c_str();
- entity.latitude = lat;
- entity.longitude = lon;
- entity.altitude = i->getCruiseAlt() *100; // convert from FL to feet
- entity.speed = speed;
- entity.roll = 0.0;
- entity.fp = new FGAIFlightPlan(&entity, courseToDest, i->getDepartureTime(), dep,
- arr,true, radius, flightType, acType, airline);
-
// Fixme: A non-existent model path results in an
// abort, due to an unhandled exeption, in fg main loop.
- FGAIBase *aircraft = (FGAIBase*)aimgr->createAircraft( &entity, this);
+ FGAIAircraft *aircraft = new FGAIAircraft(this);
+ aircraft->setPerformance(m_class); //"jet_transport";
+ aircraft->setCompany(airline); //i->getAirline();
+ aircraft->setAcType(acType); //i->getAcType();
+ aircraft->setPath(modelPath.c_str());
+ aircraft->setFlightPlan(flightPlanName);
+ aircraft->setLatitude(lat);
+ aircraft->setLongitude(lon);
+ aircraft->setAltitude(i->getCruiseAlt()*100); // convert from FL to feet
+ aircraft->setSpeed(speed);
+ aircraft->setBank(0);
+ aircraft->SetFlightPlan(new FGAIFlightPlan(modelPath, courseToDest, i->getDepartureTime(), dep,
+ arr,true, radius, i->getCruiseAlt()*100, lat, lon, speed, flightType, acType, airline));
+ aimgr->attach(aircraft);
+
+
AIManagerRef = aircraft->getID();
//cerr << "Class: " << m_class << ". acType: " << acType << ". Airline: " << airline << ". Speed = " << speed << ". From " << dep->getId() << " to " << arr->getId() << ". Time Fraction = " << (remainingTimeEnroute/(double) totalTimeEnroute) << endl;
//cerr << "Latitude : " << lat << ". Longitude : " << lon << endl;