David Culp:
1. Removed aircraft roll on ground. 2. Decreased descent pitch angle. 3. Updated flightplans to include <on-ground> 4. Fixed property indexing, so all AI aircraft have their own property branch The default value of <on-ground> is false, so you only need to specify it when on the ground. For takeoff you need to specify <on-ground>true</on-ground> for the first waypoint, and for the acceleration waypoint. For landing you need to specify it for the touchdown point and any taxi points. One problem. WARNING **** There is a bug in the way the property system works, which causes a segfault, but I don't know if the problem is in the property code, or in how I'm using it. After an AI object terminates, if you access the property tree through the property browser the sim will segfault.
This commit is contained in:
parent
b7352ead12
commit
22cd6dfb2a
7 changed files with 62 additions and 19 deletions
|
@ -132,7 +132,13 @@ void FGAIAircraft::Run(double dt) {
|
||||||
double speed_diff = tgt_speed - speed;
|
double speed_diff = tgt_speed - speed;
|
||||||
if (fabs(speed_diff) > 0.2) {
|
if (fabs(speed_diff) > 0.2) {
|
||||||
if (speed_diff > 0.0) speed += performance->accel * dt;
|
if (speed_diff > 0.0) speed += performance->accel * dt;
|
||||||
if (speed_diff < 0.0) speed -= performance->decel * dt;
|
if (speed_diff < 0.0) {
|
||||||
|
if (!no_roll) {
|
||||||
|
speed -= performance->decel * dt * 3;
|
||||||
|
} else {
|
||||||
|
speed -= performance->decel * dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert speed to degrees per second
|
// convert speed to degrees per second
|
||||||
|
@ -202,25 +208,32 @@ void FGAIAircraft::Run(double dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alt_lock && !use_perf_vs) {
|
if (alt_lock && !use_perf_vs) {
|
||||||
double max_vs = 2*(tgt_altitude - altitude);
|
double max_vs = 4*(tgt_altitude - altitude);
|
||||||
|
double min_vs = 100;
|
||||||
|
if (tgt_altitude < altitude) min_vs = -100.0;
|
||||||
if ((fabs(tgt_altitude - altitude) < 1500.0) &&
|
if ((fabs(tgt_altitude - altitude) < 1500.0) &&
|
||||||
(fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
|
(fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
|
||||||
|
if (fabs(tgt_vs) < fabs(min_vs)) tgt_vs = min_vs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust vertical speed
|
// adjust vertical speed
|
||||||
double vs_diff = tgt_vs - vs;
|
double vs_diff = tgt_vs - vs;
|
||||||
if (fabs(vs_diff) > 10.0) {
|
if (fabs(vs_diff) > 10.0) {
|
||||||
if (vs_diff > 0.0) {
|
if (vs_diff > 0.0) {
|
||||||
vs += 400.0 * dt;
|
vs += 900.0 * dt;
|
||||||
if (vs > tgt_vs) vs = tgt_vs;
|
if (vs > tgt_vs) vs = tgt_vs;
|
||||||
} else {
|
} else {
|
||||||
vs -= 300.0 * dt;
|
vs -= 400.0 * dt;
|
||||||
if (vs < tgt_vs) vs = tgt_vs;
|
if (vs < tgt_vs) vs = tgt_vs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// match pitch angle to vertical speed
|
// match pitch angle to vertical speed
|
||||||
pitch = vs * 0.005;
|
if (vs > 0){
|
||||||
|
pitch = vs * 0.005;
|
||||||
|
} else {
|
||||||
|
pitch = vs * 0.002;
|
||||||
|
}
|
||||||
|
|
||||||
//###########################//
|
//###########################//
|
||||||
// do calculations for radar //
|
// do calculations for radar //
|
||||||
|
@ -357,7 +370,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
|
||||||
setHeading(fp->getBearing(prev->latitude, prev->longitude, curr));
|
setHeading(fp->getBearing(prev->latitude, prev->longitude, curr));
|
||||||
if (next) fp->setLeadDistance(speed, hdg, curr, next);
|
if (next) fp->setLeadDistance(speed, hdg, curr, next);
|
||||||
|
|
||||||
if (curr->crossat > -1000.0) { //start descent/climb now
|
if (curr->crossat > -1000.0) { //use a calculated descent/climb rate
|
||||||
use_perf_vs = false;
|
use_perf_vs = false;
|
||||||
tgt_vs = (curr->crossat - prev->altitude)/
|
tgt_vs = (curr->crossat - prev->altitude)/
|
||||||
(fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/
|
(fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/
|
||||||
|
@ -368,6 +381,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
|
||||||
tgt_altitude = prev->altitude;
|
tgt_altitude = prev->altitude;
|
||||||
}
|
}
|
||||||
alt_lock = hdg_lock = true;
|
alt_lock = hdg_lock = true;
|
||||||
|
no_roll = prev->on_ground;
|
||||||
//cout << "First waypoint: " << prev->name << endl;
|
//cout << "First waypoint: " << prev->name << endl;
|
||||||
//cout << " Target speed: " << tgt_speed << endl;
|
//cout << " Target speed: " << tgt_speed << endl;
|
||||||
//cout << " Target altitude: " << tgt_altitude << endl;
|
//cout << " Target altitude: " << tgt_altitude << endl;
|
||||||
|
@ -410,6 +424,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
|
||||||
}
|
}
|
||||||
tgt_speed = prev->speed;
|
tgt_speed = prev->speed;
|
||||||
hdg_lock = alt_lock = true;
|
hdg_lock = alt_lock = true;
|
||||||
|
no_roll = prev->on_ground;
|
||||||
//cout << "Crossing waypoint: " << prev->name << endl;
|
//cout << "Crossing waypoint: " << prev->name << endl;
|
||||||
//cout << " Target speed: " << tgt_speed << endl;
|
//cout << " Target speed: " << tgt_speed << endl;
|
||||||
//cout << " Target altitude: " << tgt_altitude << endl;
|
//cout << " Target altitude: " << tgt_altitude << endl;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "AIBase.hxx"
|
#include "AIBase.hxx"
|
||||||
|
#include "AIManager.hxx"
|
||||||
|
|
||||||
FGAIBase *FGAIBase::_self = NULL;
|
FGAIBase *FGAIBase::_self = NULL;
|
||||||
|
|
||||||
|
@ -51,13 +52,18 @@ FGAIBase::FGAIBase() {
|
||||||
bearing = elevation = range = rdot = 0.0;
|
bearing = elevation = range = rdot = 0.0;
|
||||||
x_shift = y_shift = rotation = 0.0;
|
x_shift = y_shift = rotation = 0.0;
|
||||||
invisible = true;
|
invisible = true;
|
||||||
|
no_roll = true;
|
||||||
model_path = "";
|
model_path = "";
|
||||||
|
model = 0;
|
||||||
_otype = otNull;
|
_otype = otNull;
|
||||||
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGAIBase::~FGAIBase() {
|
FGAIBase::~FGAIBase() {
|
||||||
globals->get_scenery()->get_scene_graph()->removeKid(aip.getSceneGraph());
|
globals->get_scenery()->get_scene_graph()->removeKid(aip.getSceneGraph());
|
||||||
unbind();
|
unbind();
|
||||||
|
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
|
||||||
|
root->removeChild(_type_str.c_str(), index);
|
||||||
_self = NULL;
|
_self = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +74,11 @@ void FGAIBase::update(double dt) {
|
||||||
void FGAIBase::Transform() {
|
void FGAIBase::Transform() {
|
||||||
if (!invisible) {
|
if (!invisible) {
|
||||||
aip.setPosition(pos.lon(), pos.lat(), pos.elev() * SG_METER_TO_FEET);
|
aip.setPosition(pos.lon(), pos.lat(), pos.elev() * SG_METER_TO_FEET);
|
||||||
aip.setOrientation(roll, pitch, hdg);
|
if (no_roll) {
|
||||||
|
aip.setOrientation(0.0, pitch, hdg);
|
||||||
|
} else {
|
||||||
|
aip.setOrientation(roll, pitch, hdg);
|
||||||
|
}
|
||||||
aip.update( globals->get_scenery()->get_center() );
|
aip.update( globals->get_scenery()->get_center() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,12 +87,8 @@ void FGAIBase::Transform() {
|
||||||
bool FGAIBase::init() {
|
bool FGAIBase::init() {
|
||||||
|
|
||||||
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
|
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
|
||||||
vector<SGPropertyNode_ptr> p_vec = root->getChildren(_type_str);
|
index = manager->getNum(_otype) - 1;
|
||||||
unsigned num = p_vec.size();
|
props = root->getNode(_type_str.c_str(), index, true);
|
||||||
p_vec.clear();
|
|
||||||
|
|
||||||
props = root->getNode(_type_str, num, true);
|
|
||||||
ssgBranch *model = 0;
|
|
||||||
if (model_path != "") {
|
if (model_path != "") {
|
||||||
model = sgLoad3DModel( globals->get_fg_root(),
|
model = sgLoad3DModel( globals->get_fg_root(),
|
||||||
model_path.c_str(),
|
model_path.c_str(),
|
||||||
|
@ -135,7 +141,6 @@ void FGAIBase::bind() {
|
||||||
props->tie("radar/bearing-deg", SGRawValueFunctions<double>(FGAIBase::_getBearing));
|
props->tie("radar/bearing-deg", SGRawValueFunctions<double>(FGAIBase::_getBearing));
|
||||||
props->tie("radar/elevation-deg", SGRawValueFunctions<double>(FGAIBase::_getElevation));
|
props->tie("radar/elevation-deg", SGRawValueFunctions<double>(FGAIBase::_getElevation));
|
||||||
props->tie("radar/range-nm", SGRawValueFunctions<double>(FGAIBase::_getRange));
|
props->tie("radar/range-nm", SGRawValueFunctions<double>(FGAIBase::_getRange));
|
||||||
// props->tie("radar/rdot-kts", SGRawValueFunctions<double>(FGAIBase::_getRdot));
|
|
||||||
props->tie("radar/h-offset", SGRawValueFunctions<double>(FGAIBase::_getH_offset));
|
props->tie("radar/h-offset", SGRawValueFunctions<double>(FGAIBase::_getH_offset));
|
||||||
props->tie("radar/v-offset", SGRawValueFunctions<double>(FGAIBase::_getV_offset));
|
props->tie("radar/v-offset", SGRawValueFunctions<double>(FGAIBase::_getV_offset));
|
||||||
props->tie("radar/x-shift", SGRawValueFunctions<double>(FGAIBase::_getX_shift));
|
props->tie("radar/x-shift", SGRawValueFunctions<double>(FGAIBase::_getX_shift));
|
||||||
|
@ -164,13 +169,12 @@ void FGAIBase::unbind() {
|
||||||
props->untie("radar/bearing-deg");
|
props->untie("radar/bearing-deg");
|
||||||
props->untie("radar/elevation-deg");
|
props->untie("radar/elevation-deg");
|
||||||
props->untie("radar/range-nm");
|
props->untie("radar/range-nm");
|
||||||
// props->untie("radar/rdot-kts");
|
|
||||||
props->untie("radar/h-offset");
|
props->untie("radar/h-offset");
|
||||||
props->untie("radar/v-offset");
|
props->untie("radar/v-offset");
|
||||||
props->untie("radar/x-shift");
|
props->untie("radar/x-shift");
|
||||||
props->untie("radar/y-shift");
|
props->untie("radar/y-shift");
|
||||||
props->untie("radar/rotation");
|
props->untie("radar/rotation");
|
||||||
|
|
||||||
props->untie("controls/controls/lighting/nav-lights");
|
props->untie("controls/lighting/nav-lights");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,19 +97,25 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
string model_path; //Path to the 3D model
|
string model_path; //Path to the 3D model
|
||||||
|
ssgBranch * model; //The 3D model object
|
||||||
SGModelPlacement aip;
|
SGModelPlacement aip;
|
||||||
bool delete_me;
|
bool delete_me;
|
||||||
int id;
|
int id;
|
||||||
bool invisible;
|
bool invisible;
|
||||||
|
bool no_roll;
|
||||||
|
|
||||||
void Transform();
|
void Transform();
|
||||||
|
|
||||||
static FGAIBase *_self;
|
static FGAIBase *_self;
|
||||||
const char *_type_str;
|
string _type_str;
|
||||||
object_type _otype;
|
object_type _otype;
|
||||||
|
int index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
object_type getType();
|
||||||
|
bool isa( object_type otype );
|
||||||
|
|
||||||
static double _getVS_fps();
|
static double _getVS_fps();
|
||||||
static void _setVS_fps( double _vs );
|
static void _setVS_fps( double _vs );
|
||||||
|
|
||||||
|
@ -133,7 +139,6 @@ public:
|
||||||
static double _getRotation();
|
static double _getRotation();
|
||||||
|
|
||||||
static bool _isNight();
|
static bool _isNight();
|
||||||
bool isa( object_type otype );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,5 +210,7 @@ inline bool FGAIBase::_isNight() {
|
||||||
inline void FGAIBase::setID( int ID ) { id = ID; }
|
inline void FGAIBase::setID( int ID ) { id = ID; }
|
||||||
inline int FGAIBase::getID() { return id; }
|
inline int FGAIBase::getID() { return id; }
|
||||||
|
|
||||||
|
inline FGAIBase::object_type FGAIBase::getType() { return _otype; }
|
||||||
|
|
||||||
#endif // _FG_AIBASE_HXX
|
#endif // _FG_AIBASE_HXX
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ FGAIFlightPlan::FGAIFlightPlan(string filename)
|
||||||
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
|
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
|
||||||
wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
|
wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
|
||||||
wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
|
wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
|
||||||
|
wpt->on_ground = wpt_node->getBoolValue("on-ground", false);
|
||||||
|
|
||||||
if (wpt->name == "END") wpt->finished = true;
|
if (wpt->name == "END") wpt->finished = true;
|
||||||
else wpt->finished = false;
|
else wpt->finished = false;
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
bool finished;
|
bool finished;
|
||||||
bool gear_down;
|
bool gear_down;
|
||||||
bool flaps_down;
|
bool flaps_down;
|
||||||
|
bool on_ground;
|
||||||
} waypoint;
|
} waypoint;
|
||||||
|
|
||||||
FGAIFlightPlan(string filename);
|
FGAIFlightPlan(string filename);
|
||||||
|
|
|
@ -393,9 +393,23 @@ void FGAIManager::processScenario( string filename ) {
|
||||||
FGAIScenario::entry* en = s->getNextEntry();
|
FGAIScenario::entry* en = s->getNextEntry();
|
||||||
if (en) {
|
if (en) {
|
||||||
FGAIFlightPlan* f = new FGAIFlightPlan( en->flightplan );
|
FGAIFlightPlan* f = new FGAIFlightPlan( en->flightplan );
|
||||||
createAircraft("jet_transport", "Aircraft/737/Models/boeing733.xml", f);
|
if (en->aitype == "aircraft"){
|
||||||
|
createAircraft( en->aircraft_class, en->model_path, f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete s;
|
delete s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FGAIManager::getNum( FGAIBase::object_type ot ) {
|
||||||
|
ai_list_iterator itr = ai_list.begin();
|
||||||
|
int count = 0;
|
||||||
|
while(itr != ai_list.end()) {
|
||||||
|
if ((*itr)->getType() == ot) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ public:
|
||||||
inline double get_user_speed() {return user_speed; }
|
inline double get_user_speed() {return user_speed; }
|
||||||
|
|
||||||
void processScenario( string filename );
|
void processScenario( string filename );
|
||||||
|
int getNum( FGAIBase::object_type ot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue