X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FAIModel%2FAIGroundVehicle.cxx;h=08a47489b99302099492b9144064ed6ff8eefa39;hb=38226af24ec01e8f0a20d7fd73ef838a69f6ef25;hp=75f18b9c7844929ac08ccf02e34dcb7f20f439ac;hpb=acbcf94bde0ea73132a1dfadc0ebfd161d25f96d;p=flightgear.git diff --git a/src/AIModel/AIGroundVehicle.cxx b/src/AIModel/AIGroundVehicle.cxx index 75f18b9c7..08a47489b 100644 --- a/src/AIModel/AIGroundVehicle.cxx +++ b/src/AIModel/AIGroundVehicle.cxx @@ -26,7 +26,6 @@ #include
#include -#include #include #include "AIGroundVehicle.hxx" @@ -41,9 +40,15 @@ _range_ft(0), _relbrg (0), _parent_speed(0), _parent_x_offset(0), -_selected_ac(0) +_parent_y_offset(0), +_parent_z_offset(0), +_dt_count(0), +_next_run(0), +_break_count(0) + { invisible = false; + _parent = ""; } FGAIGroundVehicle::~FGAIGroundVehicle() {} @@ -54,20 +59,22 @@ void FGAIGroundVehicle::readFromScenario(SGPropertyNode* scFileNode) { FGAIShip::readFromScenario(scFileNode); - setNoRoll(scFileNode->getBoolValue("no-roll", true)); setName(scFileNode->getStringValue("name", "groundvehicle")); - setSMPath(scFileNode->getStringValue("submodel-path", "")); - setContactX1offset(scFileNode->getDoubleValue("contact_x1_offset", 0.0)); - setContactX2offset(scFileNode->getDoubleValue("contact_x2_offset", 0.0)); - setXOffset(scFileNode->getDoubleValue("hitch-x-offset", 38.55)); + setParentName(scFileNode->getStringValue("parent", "")); + setNoRoll(scFileNode->getBoolValue("no-roll", true)); + setContactX1offset(scFileNode->getDoubleValue("contact-x1-offset", 0.0)); + setContactX2offset(scFileNode->getDoubleValue("contact-x2-offset", 0.0)); + setXOffset(scFileNode->getDoubleValue("hitch-x-offset", 35.0)); + setYOffset(scFileNode->getDoubleValue("hitch-y-offset", 0.0)); + setZOffset(scFileNode->getDoubleValue("hitch-z-offset", 0.0)); setPitchoffset(scFileNode->getDoubleValue("pitch-offset", 0.0)); setRolloffset(scFileNode->getDoubleValue("roll-offset", 0.0)); setYawoffset(scFileNode->getDoubleValue("yaw-offset", 0.0)); - setPitchCoeff(scFileNode->getDoubleValue("pitch-coefficient", 0.5)); - setElevCoeff(scFileNode->getDoubleValue("elevation-coefficient", 0.5)); - setParentName(scFileNode->getStringValue("parent", "")); - setTowAngleGain(scFileNode->getDoubleValue("tow-angle-gain", 2.0)); + setPitchCoeff(scFileNode->getDoubleValue("pitch-coefficient", 0.1)); + setElevCoeff(scFileNode->getDoubleValue("elevation-coefficient", 0.25)); + setTowAngleGain(scFileNode->getDoubleValue("tow-angle-gain", 1.0)); setTowAngleLimit(scFileNode->getDoubleValue("tow-angle-limit-deg", 2.0)); + setInitialTunnel(scFileNode->getBoolValue("tunnel", false)); //we may need these later for towed vehicles // setSubID(scFileNode->getIntValue("SubID", 0)); // setGroundOffset(scFileNode->getDoubleValue("ground-offset", 0.0)); @@ -91,55 +98,45 @@ void FGAIGroundVehicle::bind() { SGRawValuePointer(&_range_ft)); props->tie("hitch/x-offset-ft", SGRawValuePointer(&_x_offset)); + props->tie("hitch/y-offset-ft", + SGRawValuePointer(&_y_offset)); + props->tie("hitch/z-offset-ft", + SGRawValuePointer(&_z_offset)); props->tie("hitch/parent-x-offset-ft", SGRawValuePointer(&_parent_x_offset)); + props->tie("hitch/parent-y-offset-ft", + SGRawValuePointer(&_parent_y_offset)); + props->tie("hitch/parent-z-offset-ft", + SGRawValuePointer(&_parent_z_offset)); props->tie("controls/constants/tow-angle/gain", SGRawValuePointer(&_tow_angle_gain)); props->tie("controls/constants/tow-angle/limit-deg", SGRawValuePointer(&_tow_angle_limit)); - - - //we may need these later for towed vehicles - - // (*this, &FGAIBallistic::getElevHitchToUser)); - //props->tie("position/x-offset", - // SGRawValueMethods(*this, &FGAIBase::_getXOffset, &FGAIBase::setXoffset)); - //props->tie("position/y-offset", - // SGRawValueMethods(*this, &FGAIBase::_getYOffset, &FGAIBase::setYoffset)); - //props->tie("position/z-offset", - // SGRawValueMethods(*this, &FGAIBase::_getZOffset, &FGAIBase::setZoffset)); - //props->tie("position/tgt-x-offset", - // SGRawValueMethods(*this, &FGAIWingman::getTgtXOffset, &FGAIWingman::setTgtXOffset)); - //props->tie("position/tgt-y-offset", - // SGRawValueMethods(*this, &FGAIWingman::getTgtYOffset, &FGAIWingman::setTgtYOffset)); - //props->tie("position/tgt-z-offset", - // SGRawValueMethods(*this, &FGAIWingman::getTgtZOffset, &FGAIWingman::setTgtZOffset)); + props->tie("controls/contact-x1-offset-ft", + SGRawValuePointer(&_contact_x1_offset)); + props->tie("controls/contact-x2-offset-ft", + SGRawValuePointer(&_contact_x2_offset)); } void FGAIGroundVehicle::unbind() { FGAIShip::unbind(); props->untie("controls/constants/elevation-coeff"); - props->untie("position/ht-AGL-ft"); props->untie("controls/constants/pitch-coeff"); + props->untie("position/ht-AGL-ft"); props->untie("hitch/rel-bearing-deg"); props->untie("hitch/tow-angle-deg"); props->untie("hitch/range-ft"); props->untie("hitch/x-offset-ft"); + props->untie("hitch/y-offset-ft"); + props->untie("hitch/z-offset-ft"); props->untie("hitch/parent-x-offset-ft"); + props->untie("hitch/parent-y-offset-ft"); + props->untie("hitch/parent-y-offset-ft"); props->untie("controls/constants/tow-angle/gain"); props->untie("controls/constants/tow-angle/limit-deg"); - - //we may need these later for towed vehicles - //props->untie("load/rel-brg-to-user-deg"); - //props->untie("load/elev-to-user-deg"); - //props->untie("velocities/vertical-speed-fps"); - //props->untie("position/x-offset"); - //props->untie("position/y-offset"); - //props->untie("position/z-offset"); - //props->untie("position/tgt-x-offset"); - //props->untie("position/tgt-y-offset"); - //props->untie("position/tgt-z-offset"); + props->untie("controls/contact-x1-offset-ft"); + props->untie("controls/contact-x2-offset-ft"); } bool FGAIGroundVehicle::init(bool search_in_AI_path) { @@ -147,87 +144,32 @@ bool FGAIGroundVehicle::init(bool search_in_AI_path) { return false; invisible = false; - _limit = 200; no_roll = true; + props->setStringValue("controls/parent-name", _parent.c_str()); + + if (setParentNode()){ + _parent_x_offset = _selected_ac->getDoubleValue("hitch/x-offset-ft"); + _parent_y_offset = _selected_ac->getDoubleValue("hitch/y-offset-ft"); + _parent_z_offset = _selected_ac->getDoubleValue("hitch/z-offset-ft"); + _hitch_x_offset_m = _selected_ac->getDoubleValue("hitch/x-offset-ft") + * SG_FEET_TO_METER; + _hitch_y_offset_m = _selected_ac->getDoubleValue("hitch/y-offset-ft") + * SG_FEET_TO_METER; + _hitch_z_offset_m = _selected_ac->getDoubleValue("hitch/z-offset-ft") + * SG_FEET_TO_METER; + setParent(); + } + return true; } void FGAIGroundVehicle::update(double dt) { // SG_LOG(SG_GENERAL, SG_ALERT, "updating GroundVehicle: " << _name ); - - if (getPitch()){ - setElevation(_elevation, dt, _elevation_coeff); - ClimbTo(_elevation_ft); - setPitch(_pitch, dt, _pitch_coeff); - PitchTo(_pitch_deg); - } - - if(_parent !=""){ - setParent(); - - string parent_next_name = _selected_ac->getStringValue("waypoint/name-next"); - bool parent_waiting = _selected_ac->getBoolValue("waypoint/waiting"); - _parent_speed = _selected_ac->getDoubleValue("velocities/true-airspeed-kt"); - - if (parent_next_name == "END" && fp->getNextWaypoint()->name != "END" ){ - SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name - << " setting END: getting new waypoints "); - AdvanceFP(); - setWPNames(); - /*} else if (parent_next_name == "WAIT" && fp->getNextWaypoint()->name != "WAIT" ){*/ - } else if (parent_waiting && !_waiting){ - SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name - << " setting WAIT/WAITUNTIL: getting new waypoints "); - AdvanceFP(); - setWPNames(); - _waiting = true; - } else if (parent_next_name != "WAIT" && fp->getNextWaypoint()->name == "WAIT"){ - SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name - << " wait done: getting new waypoints "); - _waiting = false; - _wait_count = 0; - fp->IncrementWaypoint(false); - next = fp->getNextWaypoint(); - - if (next->name == "WAITUNTIL" || next->name == "WAIT" - || next->name == "END"){ - } else { - prev = curr; - fp->IncrementWaypoint(false); - curr = fp->getCurrentWaypoint(); - next = fp->getNextWaypoint(); - } - - setWPNames(); - } else if (_range_ft > 1000){ - - SG_LOG(SG_GENERAL, SG_INFO, "AIGroundVeh1cle: " << _name - << " rescue: reforming train " << _range_ft << " " << _x_offset * 15); - - setTowAngle(0, dt, 1); - setSpeed(_parent_speed * 2); - - } else if (_parent_speed > 1){ - - setTowSpeed(); - setTowAngle(_relbrg, dt, 1); - - } else if (_parent_speed < -1){ - - setTowSpeed(); - - if (_relbrg < 0) - setTowAngle(-(180 - (360 + _relbrg)), dt, 1); - else - setTowAngle(-(180 - _relbrg), dt, 1); - - } else - setSpeed(_parent_speed); - } - FGAIShip::update(dt); + + RunGroundVehicle(dt); } void FGAIGroundVehicle::setNoRoll(bool nr) { @@ -246,6 +188,14 @@ void FGAIGroundVehicle::setXOffset(double x) { _x_offset = x; } +void FGAIGroundVehicle::setYOffset(double y) { + _y_offset = y; +} + +void FGAIGroundVehicle::setZOffset(double z) { + _z_offset = z; +} + void FGAIGroundVehicle::setPitchCoeff(double pc) { _pitch_coeff = pc; } @@ -272,167 +222,130 @@ void FGAIGroundVehicle::setPitch(double p, double dt, double coeff){ _pitch_deg = (p * c) + (_pitch_deg * (1 - c)); } -void FGAIGroundVehicle::setParentName(const string& p) { - _parent = p; -} - void FGAIGroundVehicle::setTowAngle(double ta, double dt, double coeff){ ta *= _tow_angle_gain; - //_tow_angle = pow(ta,2) * sign(ta); - //if (_tow_angle > _tow_angle_limit) _tow_angle = _tow_angle_limit; - //if (_tow_angle < -_tow_angle_limit) _tow_angle = -_tow_angle_limit; - SG_CLAMP_RANGE(_tow_angle, -_tow_angle_limit, _tow_angle_limit); -} - -bool FGAIGroundVehicle::getGroundElev(SGGeod inpos) { - - if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(inpos, 10000), - _elevation_m, &_material)){ - _ht_agl_ft = pos.getElevationFt() - _elevation_m * SG_METER_TO_FEET; - - if (_material) { - const vector& names = _material->get_names(); - - _solid = _material->get_solid(); - _load_resistance = _material->get_load_resistance(); - _frictionFactor =_material->get_friction_factor(); - _elevation = _elevation_m * SG_METER_TO_FEET; - - if (!names.empty()) - props->setStringValue("material/name", names[0].c_str()); - else - props->setStringValue("material/name", ""); - - //cout << "material " << names[0].c_str() - // << " _elevation_m " << _elevation_m - // << " solid " << _solid - // << " load " << _load_resistance - // << " frictionFactor " << _frictionFactor - // << endl; - - } - - return true; - } else { - return false; - } - + double factor = -0.0045 * speed + 1; + double limit = _tow_angle_limit * factor; +// cout << "speed "<< speed << " _factor " << _factor<<" " <<_tow_angle_limit<< endl; + _tow_angle = pow(ta,2) * sign(ta) * factor; + SG_CLAMP_RANGE(_tow_angle, -limit, limit); } bool FGAIGroundVehicle::getPitch() { - double vel = props->getDoubleValue("velocities/true-airspeed-kt", 0); - double contact_offset_x1_m = _contact_x1_offset * SG_FEET_TO_METER; - double contact_offset_x2_m = _contact_x2_offset * SG_FEET_TO_METER; - - SGVec3d front(-contact_offset_x1_m, 0, 0); - SGVec3d rear(-contact_offset_x2_m, 0, 0); - SGVec3d Front = getCartPosAt(front); - SGVec3d Rear = getCartPosAt(rear); - - SGGeod geodFront = SGGeod::fromCart(Front); - SGGeod geodRear = SGGeod::fromCart(Rear); + if (!_tunnel){ + double vel = props->getDoubleValue("velocities/true-airspeed-kt", 0); + double contact_offset_x1_m = _contact_x1_offset * SG_FEET_TO_METER; + double contact_offset_x2_m = _contact_x2_offset * SG_FEET_TO_METER; + double _z_offset_m = _parent_z_offset * SG_FEET_TO_METER; + + SGVec3d front(-contact_offset_x1_m, 0, 0); + SGVec3d rear(-contact_offset_x2_m, 0, 0); + SGVec3d Front = getCartPosAt(front); + SGVec3d Rear = getCartPosAt(rear); + + SGGeod geodFront = SGGeod::fromCart(Front); + SGGeod geodRear = SGGeod::fromCart(Rear); + + double front_elev_m = 0; + double rear_elev_m = 0; + double elev_front = 0; + double elev_rear = 0; + //double max_alt = 10000; + + if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(geodFront, 3000), + elev_front, &_material, 0)){ + front_elev_m = elev_front + _z_offset_m; + } else + return false; - double front_elev_m = 0; - double rear_elev_m = 0; - double elev_front = 0; - double elev_rear = 0; + if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(geodRear, 3000), + elev_rear, &_material, 0)){ + rear_elev_m = elev_rear; + } else + return false; - if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(geodFront, 10000), - elev_front, &_material)){ + if (vel >= 0){ + double diff = front_elev_m - rear_elev_m; + _pitch = atan2 (diff, + fabs(contact_offset_x1_m) + fabs(contact_offset_x2_m)) * SG_RADIANS_TO_DEGREES; + _elevation = (rear_elev_m + diff/2) * SG_METER_TO_FEET; + } else { + double diff = rear_elev_m - front_elev_m; + _pitch = atan2 (diff, + fabs(contact_offset_x1_m) + fabs(contact_offset_x2_m)) * SG_RADIANS_TO_DEGREES; + _elevation = (front_elev_m + diff/2) * SG_METER_TO_FEET; + _pitch = -_pitch; + } - front_elev_m = elev_front; + } else { - //if (_material) { - // - //} + if (prev->altitude == 0 || curr->altitude == 0) return false; + + static double distance; + static double d_alt; + static double curr_alt; + static double prev_alt; + + if (_new_waypoint){ + //cout << "new waypoint, calculating pitch " << endl; + curr_alt = curr->altitude; + prev_alt = prev->altitude; + //cout << "prev_alt" <altitude; + distance = SGGeodesy::distanceM(SGGeod::fromDeg(prev->longitude, prev->latitude), + SGGeod::fromDeg(curr->longitude, curr->latitude)); + _pitch = atan2(d_alt, distance * SG_METER_TO_FEET) * SG_RADIANS_TO_DEGREES; + //cout << "new waypoint, calculating pitch " << _pitch << + // " " << _pitch_offset << " " << _elevation <longitude, curr->latitude)); - if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(geodRear, 10000), - elev_rear, &_material)){ - rear_elev_m = elev_rear; - //if (_material) { - // rear_elev_m = elev_rear; - //} + /*cout << "tunnel " << _tunnel + << " distance prev & curr " << prev->name << " " << curr->name << " " << distance * SG_METER_TO_FEET + << " distance to go " << distance_to_go * SG_METER_TO_FEET + << " d_alt ft " << d_alt + << endl;*/ - } else - return false; + if (distance_to_go > distance) + _elevation = prev_alt; + else + _elevation = curr_alt - (tan(_pitch * SG_DEGREES_TO_RADIANS) * distance_to_go * SG_METER_TO_FEET); - if (vel >= 0){ - double diff = front_elev_m - rear_elev_m; - _pitch = atan2 (diff, - fabs(contact_offset_x1_m) + fabs(contact_offset_x2_m)) * SG_RADIANS_TO_DEGREES; - _elevation = (rear_elev_m + diff/2) * SG_METER_TO_FEET; - } else { - double diff = rear_elev_m - front_elev_m; - _pitch = atan2 (diff, - fabs(contact_offset_x1_m) + fabs(contact_offset_x2_m)) * SG_RADIANS_TO_DEGREES; - _elevation = (front_elev_m + diff/2) * SG_METER_TO_FEET; - _pitch = -_pitch; } return true; } -void FGAIGroundVehicle::setParent() { - - const SGPropertyNode *ai = fgGetNode("/ai/models", true); - - for (int i = ai->nChildren() - 1; i >= -1; i--) { - const SGPropertyNode *model; - - if (i < 0) { // last iteration: selected model - model = _selected_ac; - } else { - model = ai->getChild(i); - const string name = model->getStringValue("name"); - - if (!model->nChildren()){ - continue; - } - if (name == _parent) { - _selected_ac = model; // save selected model for last iteration - break; - } - - } - if (!model) - continue; +void FGAIGroundVehicle::setParent(){ - }// end for loop + double lat = _selected_ac->getDoubleValue("position/latitude-deg"); + double lon = _selected_ac->getDoubleValue("position/longitude-deg"); + double elevation = _selected_ac->getDoubleValue("position/altitude-ft"); - if (_selected_ac != 0){ - const string name = _selected_ac->getStringValue("name"); - double lat = _selected_ac->getDoubleValue("position/latitude-deg"); - double lon = _selected_ac->getDoubleValue("position/longitude-deg"); - double elevation = _selected_ac->getDoubleValue("position/altitude-ft"); - double hitch_offset_m = _x_offset * SG_FEET_TO_METER; - _selectedpos.setLatitudeDeg(lat); - _selectedpos.setLongitudeDeg(lon); - _selectedpos.setElevationFt(elevation); + _selectedpos.setLatitudeDeg(lat); + _selectedpos.setLongitudeDeg(lon); + _selectedpos.setElevationFt(elevation); - SGVec3d rear_hitch(-hitch_offset_m, 0, 0); - SGVec3d RearHitch = getCartHitchPosAt(rear_hitch); + _parent_speed = _selected_ac->getDoubleValue("velocities/true-airspeed-kt"); - SGGeod rearpos = SGGeod::fromCart(RearHitch); + SGVec3d rear_hitch(-_hitch_x_offset_m, _hitch_y_offset_m, 0); + SGVec3d RearHitch = getCartHitchPosAt(rear_hitch); - double user_lat = rearpos.getLatitudeDeg(); - double user_lon = rearpos.getLongitudeDeg(); + SGGeod rearpos = SGGeod::fromCart(RearHitch); - double range, bearing; + double user_lat = rearpos.getLatitudeDeg(); + double user_lon = rearpos.getLongitudeDeg(); - calcRangeBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), - user_lat, user_lon, range, bearing); - _range_ft = range * 6076.11549; - _relbrg = calcRelBearingDeg(bearing, hdg); - } else { - SG_LOG(SG_GENERAL, SG_ALERT, "AIGroundVeh1cle: " << _name - << " parent not found: dying "); - setDie(true); - } + double range, bearing; + calcRangeBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), + user_lat, user_lon, range, bearing); + _range_ft = range * 6076.11549; + _relbrg = calcRelBearingDeg(bearing, hdg); } void FGAIGroundVehicle::calcRangeBearing(double lat, double lon, double lat2, double lon2, @@ -441,17 +354,9 @@ void FGAIGroundVehicle::calcRangeBearing(double lat, double lon, double lat2, do // calculate the bearing and range of the second pos from the first double az2, distance; geo_inverse_wgs_84(lat, lon, lat2, lon2, &bearing, &az2, &distance); - range = distance *= SG_METER_TO_NM; + range = distance * SG_METER_TO_NM; } -double FGAIGroundVehicle::calcRelBearingDeg(double bearing, double heading) -{ - double angle = bearing - heading; - - SG_NORMALIZE_RANGE(angle, -180.0, 180.0); - - return angle; -} SGVec3d FGAIGroundVehicle::getCartHitchPosAt(const SGVec3d& _off) const { double hdg = _selected_ac->getDoubleValue("orientation/true-heading-deg"); @@ -535,9 +440,7 @@ void FGAIGroundVehicle::AdvanceFP(){ void FGAIGroundVehicle::setTowSpeed(){ - _parent_x_offset = _selected_ac->getDoubleValue("hitch/x-offset-ft"); - - // double diff = _range_ft - _parent_x_offset; + //double diff = _range_ft - _x_offset; double x = 0; if (_range_ft > _x_offset * 3) x = 50; @@ -545,11 +448,11 @@ void FGAIGroundVehicle::setTowSpeed(){ if (_relbrg < -90 || _relbrg > 90){ setSpeed(_parent_speed - 5 - x); //cout << _name << " case 1r _relbrg spd - 5 " << _relbrg << " " << diff << endl; - }else if (_range_ft > _parent_x_offset + 0.25 && _relbrg >= -90 && _relbrg <= 90){ + }else if (_range_ft > _x_offset + 0.25 && _relbrg >= -90 && _relbrg <= 90){ setSpeed(_parent_speed + 1 + x); //cout << _name << " case 2r _relbrg spd + 1 " << _relbrg << " " // << diff << " range " << _range_ft << endl; - } else if (_range_ft < _parent_x_offset - 0.25 && _relbrg >= -90 && _relbrg <= 90){ + } else if (_range_ft < _x_offset - 0.25 && _relbrg >= -90 && _relbrg <= 90){ setSpeed(_parent_speed - 1 - x); //cout << _name << " case 3r _relbrg spd - 2 " << _relbrg << " " // << diff << " " << _range_ft << endl; @@ -559,4 +462,104 @@ void FGAIGroundVehicle::setTowSpeed(){ } } + +void FGAIGroundVehicle::RunGroundVehicle(double dt){ + + _dt_count += dt; + + /////////////////////////////////////////////////////////////////////////// + // Check execution time (currently once every 0.05 sec or 20 fps) + // Add a bit of randomization to prevent the execution of all flight plans + // in synchrony, which can add significant periodic framerate flutter. + // Randomization removed to get better appearance + /////////////////////////////////////////////////////////////////////////// + + //cout << "_start_sec " << _start_sec << " time_sec " << time_sec << endl; + if (_dt_count < _next_run) + return; + + _next_run = 0.05 /*+ (0.015 * sg_random())*/; + + if (getPitch()){ + setElevation(_elevation, _dt_count, _elevation_coeff); + ClimbTo(_elevation_ft); + setPitch(_pitch, _dt_count, _pitch_coeff); + PitchTo(_pitch_deg); + } + + if(_parent == ""){ + AccelTo(prev->speed); + _dt_count = 0; + return; + } + + setParent(); + + string parent_next_name = _selected_ac->getStringValue("waypoint/name-next"); + bool parent_waiting = _selected_ac->getBoolValue("waypoint/waiting"); + //bool parent_restart = _selected_ac->getBoolValue("controls/restart"); + + if (parent_next_name == "END" && fp->getNextWaypoint()->name != "END" ){ + SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name + << " setting END: getting new waypoints "); + AdvanceFP(); + setWPNames(); + setTunnel(_initial_tunnel); + if(_restart) _missed_count = 200; + /*} else if (parent_next_name == "WAIT" && fp->getNextWaypoint()->name != "WAIT" ){*/ + } else if (parent_waiting && !_waiting){ + SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name + << " setting WAIT/WAITUNTIL: getting new waypoints "); + AdvanceFP(); + setWPNames(); + _waiting = true; + } else if (parent_next_name != "WAIT" && fp->getNextWaypoint()->name == "WAIT"){ + SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name + << " wait done: getting new waypoints "); + _waiting = false; + _wait_count = 0; + fp->IncrementWaypoint(false); + next = fp->getNextWaypoint(); + + if (next->name == "WAITUNTIL" || next->name == "WAIT" + || next->name == "END"){ + } else { + prev = curr; + fp->IncrementWaypoint(false); + curr = fp->getCurrentWaypoint(); + next = fp->getNextWaypoint(); + } + + setWPNames(); + } else if (_range_ft > (_x_offset +_parent_x_offset)* 4 + ){ + SG_LOG(SG_GENERAL, SG_ALERT, "AIGroundVeh1cle: " << _name + << " rescue: reforming train " << _range_ft + ); + + setTowAngle(0, dt, 1); + setSpeed(_parent_speed + (10 * sign(_parent_speed))); + + } else if (_parent_speed > 1){ + + setTowSpeed(); + setTowAngle(_relbrg, dt, 1); + + } else if (_parent_speed < -1){ + + setTowSpeed(); + + if (_relbrg < 0) + setTowAngle(-(180 - (360 + _relbrg)), dt, 1); + else + setTowAngle(-(180 - _relbrg), dt, 1); + + } else + setSpeed(_parent_speed); + +// FGAIShip::update(_dt_count); + _dt_count = 0; + +} + // end AIGroundvehicle