bool TaskAutoPilot::far_from_target(const TaskAccessor& task, const AircraftState& state) { // are we considered close to the target? if (task.is_empty() || !task.leg_stats().remaining.IsDefined()) return w[0].Distance(state.location)>state.ground_speed; bool d_far = (task.leg_stats().remaining.GetDistance() > fixed(100)); if (!task.is_ordered()) // cheat for non-ordered tasks return d_far; bool entered = awp >= task.size() || task.has_entered(awp); if (current_has_target(task)) return d_far || !entered; fixed dc = w[0].Distance(state.location); if (awp==0) { return (dc>state.ground_speed); } return (dc>state.ground_speed) || !entered; }
bool TaskAutoPilot::far_from_target(const TaskAccessor& task, const AIRCRAFT_STATE& state) { // are we considered close to the target? if (task.is_empty()) return w[0].distance(state.Location)>state.Speed; bool d_far = (task.leg_stats().remaining.get_distance() > fixed(100)); if (!task.is_ordered()) // cheat for non-ordered tasks return d_far; bool entered = task.has_entered(awp); if (current_has_target(task)) return d_far || !entered; fixed dc = w[0].distance(state.Location); if (awp==0) { return (dc>state.Speed); } return (dc>state.Speed) || !entered; }
bool TaskAutoPilot::has_finished(TaskAccessor& task) { if (task.is_finished()) return true; if (task.is_ordered()) { return awp>= task.size(); } else { return awp>= 1; } }
GeoPoint TaskAutoPilot::get_start_location(const TaskAccessor& task, bool previous) { if (!previous && (task.is_ordered())) { // set start location to 200 meters directly behind start // (otherwise start may fail to trigger) Angle brg = w[0].Bearing(w[1]); return GeoVector(fixed(200), brg).EndPoint(w[1]); } else { return w[0]; } }
bool TaskAutoPilot::do_advance(TaskAccessor& task) { if (task.is_ordered() && (awp==0)) { awp++; } awp++; if (has_finished(task)) return false; task.setActiveTaskPoint(awp); get_awp(task); return true; }
void TaskAutoPilot::Start(const TaskAccessor& task) { // construct list of places we will fly to. // we dont do this dynamically so it is remembered even if // the task is advanced/retreated. if (task.is_ordered()) { // construct list // this pilot is inaccurate, he flies to a random point in the OZ, // and starts in the start OZ. w[1] = task.random_oz_point(0, parms.target_noise); w[0] = task.random_oz_point(1, parms.target_noise); } else { // for non-ordered tasks, start at the default location w[1] = location_start; if (task.is_empty()) { // go somewhere nearby w[0] = location_previous; } else { // go directly to the target w[0] = task.random_oz_point(0, parms.target_noise); } } // pick up the locations from the task to be used to initialise // the aircraft simulator location_start = get_start_location(task); location_previous = get_start_location(task, false); awp= 0; // reset the heading heading = Angle::Zero(); heading_filt.Reset(fixed_zero); acstate = Cruise; }