David Culp:
Here's some new AI stuff. 1) AI objects must now be defined in a scenario file, not in preferences.xml or a *-set file. (Of course this doesn't prevent objects from being created dynamically, as with Durk's traffic manager). 2) A new demo_scenario file is attached. It creates 3 aircraft, a sailboat, and a thunderstorm. 3) Objects without flightplans live forever. 4) FGAIShip::ProcessFlightplan() is not yet implemented. 5) preferences.xml should now define only <enabled> and <scenario>
This commit is contained in:
parent
d1944b338b
commit
3c1a7174fb
10 changed files with 90 additions and 73 deletions
|
@ -64,7 +64,6 @@ FGAIAircraft::FGAIAircraft(FGAIManager* mgr) {
|
||||||
|
|
||||||
|
|
||||||
FGAIAircraft::~FGAIAircraft() {
|
FGAIAircraft::~FGAIAircraft() {
|
||||||
if (fp) delete fp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
#include "AIManager.hxx"
|
#include "AIManager.hxx"
|
||||||
#include "AIBase.hxx"
|
#include "AIBase.hxx"
|
||||||
#include "AIFlightPlan.hxx"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
|
@ -67,13 +66,11 @@ public:
|
||||||
void ClimbTo(double altitude);
|
void ClimbTo(double altitude);
|
||||||
void TurnTo(double heading);
|
void TurnTo(double heading);
|
||||||
void ProcessFlightPlan( double dt );
|
void ProcessFlightPlan( double dt );
|
||||||
//double getHeading(double lat1, double lon1, double lat2, double lon2);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool hdg_lock;
|
bool hdg_lock;
|
||||||
bool alt_lock;
|
bool alt_lock;
|
||||||
FGAIFlightPlan *fp;
|
|
||||||
double dt_count;
|
double dt_count;
|
||||||
double dt;
|
double dt;
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ FGAIBase::~FGAIBase() {
|
||||||
// unbind();
|
// unbind();
|
||||||
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
|
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
|
||||||
root->removeChild(_type_str.c_str(), index);
|
root->removeChild(_type_str.c_str(), index);
|
||||||
|
if (fp) delete fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBase::update(double dt) {
|
void FGAIBase::update(double dt) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <simgear/scene/model/placement.hxx>
|
#include <simgear/scene/model/placement.hxx>
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
#include "AIFlightPlan.hxx"
|
||||||
|
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ protected:
|
||||||
int id;
|
int id;
|
||||||
bool invisible;
|
bool invisible;
|
||||||
bool no_roll;
|
bool no_roll;
|
||||||
|
FGAIFlightPlan *fp;
|
||||||
|
|
||||||
void Transform();
|
void Transform();
|
||||||
|
|
||||||
|
|
|
@ -54,75 +54,15 @@ FGAIManager::~FGAIManager() {
|
||||||
|
|
||||||
|
|
||||||
void FGAIManager::init() {
|
void FGAIManager::init() {
|
||||||
int rval;
|
|
||||||
root = fgGetNode("sim/ai", true);
|
root = fgGetNode("sim/ai", true);
|
||||||
|
|
||||||
enabled = root->getNode("enabled", true)->getBoolValue();
|
enabled = root->getNode("enabled", true)->getBoolValue();
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
wind_from_down = fgGetNode("/environment/wind-from-down-fps", true);
|
wind_from_down = fgGetNode("/environment/wind-from-down-fps", true);
|
||||||
|
|
||||||
for (int i = 0; i < root->nChildren(); i++) {
|
scenario_filename = root->getNode("scenario", true)->getStringValue();
|
||||||
const SGPropertyNode * entry = root->getChild(i);
|
|
||||||
|
|
||||||
if (!strcmp(entry->getName(), "scenario")){
|
|
||||||
scenario_filename = entry->getStringValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(entry->getName(), "entry")) {
|
|
||||||
if (!strcmp(entry->getStringValue("type", ""), "aircraft")) {
|
|
||||||
|
|
||||||
rval = createAircraft( entry->getStringValue("class", ""),
|
|
||||||
entry->getStringValue("path"),
|
|
||||||
entry->getDoubleValue("latitude"),
|
|
||||||
entry->getDoubleValue("longitude"),
|
|
||||||
entry->getDoubleValue("altitude-ft"),
|
|
||||||
entry->getDoubleValue("heading"),
|
|
||||||
entry->getDoubleValue("speed-KTAS"),
|
|
||||||
0.0,
|
|
||||||
entry->getDoubleValue("bank") );
|
|
||||||
|
|
||||||
} else if (!strcmp(entry->getStringValue("type", ""), "ship")) {
|
|
||||||
|
|
||||||
rval = createShip( entry->getStringValue("path"),
|
|
||||||
entry->getDoubleValue("latitude"),
|
|
||||||
entry->getDoubleValue("longitude"),
|
|
||||||
entry->getDoubleValue("altitude-ft"),
|
|
||||||
entry->getDoubleValue("heading"),
|
|
||||||
entry->getDoubleValue("speed-KTAS"),
|
|
||||||
entry->getDoubleValue("rudder") );
|
|
||||||
|
|
||||||
} else if (!strcmp(entry->getStringValue("type", ""), "ballistic")) {
|
|
||||||
|
|
||||||
rval = createBallistic( entry->getStringValue("path"),
|
|
||||||
entry->getDoubleValue("latitude"),
|
|
||||||
entry->getDoubleValue("longitude"),
|
|
||||||
entry->getDoubleValue("altitude-ft"),
|
|
||||||
entry->getDoubleValue("azimuth"),
|
|
||||||
entry->getDoubleValue("elevation"),
|
|
||||||
entry->getDoubleValue("speed") );
|
|
||||||
|
|
||||||
} else if (!strcmp(entry->getStringValue("type", ""), "storm")) {
|
|
||||||
|
|
||||||
rval = createStorm( entry->getStringValue("path"),
|
|
||||||
entry->getDoubleValue("latitude"),
|
|
||||||
entry->getDoubleValue("longitude"),
|
|
||||||
entry->getDoubleValue("altitude-ft"),
|
|
||||||
entry->getDoubleValue("heading"),
|
|
||||||
entry->getDoubleValue("speed-KTAS") );
|
|
||||||
|
|
||||||
} else if (!strcmp(entry->getStringValue("type", ""), "thermal")) {
|
|
||||||
|
|
||||||
rval = createThermal( entry->getDoubleValue("latitude"),
|
|
||||||
entry->getDoubleValue("longitude"),
|
|
||||||
entry->getDoubleValue("strength-fps"),
|
|
||||||
entry->getDoubleValue("diameter-ft") );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scenario_filename != "") processScenario( scenario_filename );
|
if (scenario_filename != "") processScenario( scenario_filename );
|
||||||
initDone = true;
|
initDone = true;
|
||||||
|
@ -214,7 +154,7 @@ void FGAIManager::freeID( int ID ) {
|
||||||
|
|
||||||
int FGAIManager::createAircraft( string model_class, string path,
|
int FGAIManager::createAircraft( string model_class, string path,
|
||||||
double latitude, double longitude, double altitude,
|
double latitude, double longitude, double altitude,
|
||||||
double heading, double speed, double pitch, double roll ) {
|
double heading, double speed, double roll ) {
|
||||||
|
|
||||||
FGAIAircraft* ai_plane = new FGAIAircraft(this);
|
FGAIAircraft* ai_plane = new FGAIAircraft(this);
|
||||||
ai_list.push_back(ai_plane);
|
ai_list.push_back(ai_plane);
|
||||||
|
@ -290,6 +230,19 @@ int FGAIManager::createShip( string path, double latitude, double longitude,
|
||||||
return ai_ship->getID();
|
return ai_ship->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FGAIManager::createShip( string path, FGAIFlightPlan* flightplan ) {
|
||||||
|
|
||||||
|
FGAIShip* ai_ship = new FGAIShip(this);
|
||||||
|
ai_list.push_back(ai_ship);
|
||||||
|
ai_ship->setID( assignID() );
|
||||||
|
++numObjects;
|
||||||
|
ai_ship->setPath(path.c_str());
|
||||||
|
ai_ship->setFlightPlan(flightplan);
|
||||||
|
ai_ship->init();
|
||||||
|
ai_ship->bind();
|
||||||
|
return ai_ship->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
@ -387,17 +340,46 @@ void FGAIManager::processThermal( FGAIThermal* thermal ) {
|
||||||
|
|
||||||
|
|
||||||
void FGAIManager::processScenario( string filename ) {
|
void FGAIManager::processScenario( string filename ) {
|
||||||
//cout << "AIManager: creating a scenario." << endl;
|
|
||||||
FGAIScenario* s = new FGAIScenario( filename );
|
FGAIScenario* s = new FGAIScenario( filename );
|
||||||
|
FGAIFlightPlan* f;
|
||||||
|
|
||||||
for (int i=0;i<s->nEntries();i++) {
|
for (int i=0;i<s->nEntries();i++) {
|
||||||
FGAIScenario::entry* en = s->getNextEntry();
|
FGAIScenario::entry* en = s->getNextEntry();
|
||||||
|
f = 0;
|
||||||
if (en) {
|
if (en) {
|
||||||
FGAIFlightPlan* f = new FGAIFlightPlan( en->flightplan );
|
if (en->flightplan != ""){
|
||||||
|
f = new FGAIFlightPlan( en->flightplan );
|
||||||
|
}
|
||||||
if (en->aitype == "aircraft"){
|
if (en->aitype == "aircraft"){
|
||||||
createAircraft( en->aircraft_class, en->model_path, f);
|
if (f){
|
||||||
|
createAircraft( en->aircraft_class, en->model_path, f );
|
||||||
|
} else {
|
||||||
|
createAircraft( en->aircraft_class, en->model_path, en->latitude,
|
||||||
|
en->longitude, en->altitude, en->heading,
|
||||||
|
en->speed, en->roll );
|
||||||
|
}
|
||||||
|
} else if (en->aitype == "ship"){
|
||||||
|
if (f){
|
||||||
|
createShip( en->model_path, f );
|
||||||
|
} else {
|
||||||
|
createShip( en->model_path, en->latitude,
|
||||||
|
en->longitude, en->altitude, en->heading,
|
||||||
|
en->speed, en->rudder );
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (en->aitype == "storm"){
|
||||||
|
createStorm( en->model_path, en->latitude, en->longitude,
|
||||||
|
en->altitude, en->heading, en->speed );
|
||||||
|
} else if (en->aitype == "thermal"){
|
||||||
|
createThermal( en->latitude, en->longitude, en->strength,
|
||||||
|
en->diameter );
|
||||||
|
} else if (en->aitype == "ballistic"){
|
||||||
|
createBallistic( en->model_path, en->latitude, en->longitude,
|
||||||
|
en->altitude, en->azimuth, en->elevation, en->speed );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete s;
|
delete s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,6 @@ public:
|
||||||
double altitude, // in feet
|
double altitude, // in feet
|
||||||
double heading, // true heading in degrees
|
double heading, // true heading in degrees
|
||||||
double speed, // in knots true airspeed (KTAS)
|
double speed, // in knots true airspeed (KTAS)
|
||||||
double pitch = 0, // in degrees
|
|
||||||
double roll = 0 ); // in degrees
|
double roll = 0 ); // in degrees
|
||||||
|
|
||||||
int createAircraft( string model_class, // see FGAIAircraft.hxx for possible classes
|
int createAircraft( string model_class, // see FGAIAircraft.hxx for possible classes
|
||||||
|
@ -87,8 +86,10 @@ public:
|
||||||
double altitude, // in feet (ex. for a lake!)
|
double altitude, // in feet (ex. for a lake!)
|
||||||
double heading, // true heading in degrees
|
double heading, // true heading in degrees
|
||||||
double speed, // in knots true
|
double speed, // in knots true
|
||||||
double rudder ); // in degrees (between 0 and 5 works best)
|
double rudder ); // in degrees (right is positive)(0 to 5 works best)
|
||||||
|
|
||||||
|
int createShip( string path, // path to exterior model
|
||||||
|
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
|
||||||
|
|
|
@ -58,6 +58,17 @@ FGAIScenario::FGAIScenario(string filename)
|
||||||
en->model_path = entry_node->getStringValue("model", "Models/Geometry/glider.ac");
|
en->model_path = entry_node->getStringValue("model", "Models/Geometry/glider.ac");
|
||||||
en->flightplan = entry_node->getStringValue("flightplan", "");
|
en->flightplan = entry_node->getStringValue("flightplan", "");
|
||||||
en->repeat = entry_node->getDoubleValue("repeat", 0.0);
|
en->repeat = entry_node->getDoubleValue("repeat", 0.0);
|
||||||
|
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->getDoubleValue("rudder", 0.0);
|
||||||
|
en->strength = entry_node->getDoubleValue("strength", 0.0);
|
||||||
|
en->diameter = entry_node->getDoubleValue("diameter", 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_iterator = entries.begin();
|
entry_iterator = entries.begin();
|
||||||
|
|
|
@ -37,6 +37,17 @@ public:
|
||||||
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 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
|
||||||
} entry;
|
} entry;
|
||||||
|
|
||||||
FGAIScenario(string filename);
|
FGAIScenario(string filename);
|
||||||
|
|
|
@ -66,6 +66,8 @@ void FGAIShip::update(double dt) {
|
||||||
|
|
||||||
void FGAIShip::Run(double dt) {
|
void FGAIShip::Run(double dt) {
|
||||||
|
|
||||||
|
if (fp) ProcessFlightPlan(dt);
|
||||||
|
|
||||||
double turn_radius_ft;
|
double turn_radius_ft;
|
||||||
double turn_circum_ft;
|
double turn_circum_ft;
|
||||||
double speed_north_deg_sec;
|
double speed_north_deg_sec;
|
||||||
|
@ -167,3 +169,12 @@ double FGAIShip::sign(double x) {
|
||||||
if ( x < 0.0 ) { return -1.0; }
|
if ( x < 0.0 ) { return -1.0; }
|
||||||
else { return 1.0; }
|
else { return 1.0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIShip::setFlightPlan(FGAIFlightPlan* f) {
|
||||||
|
fp = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAIShip::ProcessFlightPlan(double dt) {
|
||||||
|
// not implemented yet
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ public:
|
||||||
virtual void bind();
|
virtual void bind();
|
||||||
virtual void unbind();
|
virtual void unbind();
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
|
void setFlightPlan(FGAIFlightPlan* f);
|
||||||
|
void ProcessFlightPlan( double dt );
|
||||||
|
|
||||||
void AccelTo(double speed);
|
void AccelTo(double speed);
|
||||||
void PitchTo(double angle);
|
void PitchTo(double angle);
|
||||||
|
|
Loading…
Add table
Reference in a new issue