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.
double speed_diff = tgt_speed - speed;
if (fabs(speed_diff) > 0.2) {
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
}
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) &&
(fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
+ if (fabs(tgt_vs) < fabs(min_vs)) tgt_vs = min_vs;
}
// adjust vertical speed
double vs_diff = tgt_vs - vs;
if (fabs(vs_diff) > 10.0) {
if (vs_diff > 0.0) {
- vs += 400.0 * dt;
+ vs += 900.0 * dt;
if (vs > tgt_vs) vs = tgt_vs;
} else {
- vs -= 300.0 * dt;
+ vs -= 400.0 * dt;
if (vs < tgt_vs) vs = tgt_vs;
}
}
// 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 //
setHeading(fp->getBearing(prev->latitude, prev->longitude, curr));
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;
tgt_vs = (curr->crossat - prev->altitude)/
(fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/
tgt_altitude = prev->altitude;
}
alt_lock = hdg_lock = true;
+ no_roll = prev->on_ground;
//cout << "First waypoint: " << prev->name << endl;
//cout << " Target speed: " << tgt_speed << endl;
//cout << " Target altitude: " << tgt_altitude << endl;
}
tgt_speed = prev->speed;
hdg_lock = alt_lock = true;
+ no_roll = prev->on_ground;
//cout << "Crossing waypoint: " << prev->name << endl;
//cout << " Target speed: " << tgt_speed << endl;
//cout << " Target altitude: " << tgt_altitude << endl;
#include "AIBase.hxx"
+#include "AIManager.hxx"
FGAIBase *FGAIBase::_self = NULL;
bearing = elevation = range = rdot = 0.0;
x_shift = y_shift = rotation = 0.0;
invisible = true;
+ no_roll = true;
model_path = "";
+ model = 0;
_otype = otNull;
+ index = 0;
}
FGAIBase::~FGAIBase() {
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);
_self = NULL;
}
void FGAIBase::Transform() {
if (!invisible) {
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() );
}
}
bool FGAIBase::init() {
SGPropertyNode *root = globals->get_props()->getNode("ai/models", true);
- vector<SGPropertyNode_ptr> p_vec = root->getChildren(_type_str);
- unsigned num = p_vec.size();
- p_vec.clear();
-
- props = root->getNode(_type_str, num, true);
- ssgBranch *model = 0;
+ index = manager->getNum(_otype) - 1;
+ props = root->getNode(_type_str.c_str(), index, true);
if (model_path != "") {
model = sgLoad3DModel( globals->get_fg_root(),
model_path.c_str(),
props->tie("radar/bearing-deg", SGRawValueFunctions<double>(FGAIBase::_getBearing));
props->tie("radar/elevation-deg", SGRawValueFunctions<double>(FGAIBase::_getElevation));
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/v-offset", SGRawValueFunctions<double>(FGAIBase::_getV_offset));
props->tie("radar/x-shift", SGRawValueFunctions<double>(FGAIBase::_getX_shift));
props->untie("radar/bearing-deg");
props->untie("radar/elevation-deg");
props->untie("radar/range-nm");
-// props->untie("radar/rdot-kts");
props->untie("radar/h-offset");
props->untie("radar/v-offset");
props->untie("radar/x-shift");
props->untie("radar/y-shift");
props->untie("radar/rotation");
- props->untie("controls/controls/lighting/nav-lights");
+ props->untie("controls/lighting/nav-lights");
}
string model_path; //Path to the 3D model
+ ssgBranch * model; //The 3D model object
SGModelPlacement aip;
bool delete_me;
int id;
bool invisible;
+ bool no_roll;
void Transform();
static FGAIBase *_self;
- const char *_type_str;
+ string _type_str;
object_type _otype;
+ int index;
public:
+ object_type getType();
+ bool isa( object_type otype );
+
static double _getVS_fps();
static void _setVS_fps( double _vs );
static double _getRotation();
static bool _isNight();
- bool isa( object_type otype );
};
inline void FGAIBase::setID( int ID ) { id = ID; }
inline int FGAIBase::getID() { return id; }
+inline FGAIBase::object_type FGAIBase::getType() { return _otype; }
+
#endif // _FG_AIBASE_HXX
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
wpt->gear_down = wpt_node->getBoolValue("gear-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;
else wpt->finished = false;
bool finished;
bool gear_down;
bool flaps_down;
+ bool on_ground;
} waypoint;
FGAIFlightPlan(string filename);
FGAIScenario::entry* en = s->getNextEntry();
if (en) {
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;
}
+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;
+}
+
inline double get_user_speed() {return user_speed; }
void processScenario( string filename );
+ int getNum( FGAIBase::object_type ot);
private: