/// <summary>
        /// Check whether we reached the end of a straight segment
        /// </summary>
        protected void CheckStraightEnd()
        {
            var currentPoint = new Point3D(_x, _y, 0, CoordinateUnit.metric);

            // At the last straight segment, quit the optimisation when we reach the endpoint
            if (_segmentIndex == _numberOfSegments)
            {
                if (currentPoint.DistanceTo(_segmentStartPoint) >= _endPoint.DistanceTo(_segmentStartPoint))
                {
                    Log("Reached end of segment" + _segmentIndex + " (straight) X:" + _x + " Y:" + _y + " Heading:" + _heading * 180 / Math.PI);
                    _vertical_state = VERTICAL_STATE.END;
                }
            }
            else
            {
                // At the second last straight segment,
                // continue flying as long as we cannot reach the endpoint with a minimum radius turn in less than a 180degree turn
                if (_segmentIndex == _numberOfSegments - 2 &&
                    currentPoint.DistanceTo(_endPoint) / 2 < _aircraft.MinimumTurnRadius(_aircraft.VMax))
                {
                    Log("Continue X:" + _x);
                    return;
                }

                // Switch from flying straight to a turn if we reach beyond the given segment length
                if (currentPoint.DistanceTo(_segmentStartPoint) >= Interpolate(0, MAX_SEGMENT_LENGTH, Setting(2)))
                {
                    Log("Reached end of segment" + _segmentIndex + " (straight) X:" + _x + " Y:" + _y + " Heading:" + _heading * 180 / Math.PI);
                    _horizontal_state    = HORIZONTAL_STATE.TURN;
                    _segmentStartHeading = _heading;
                    _segmentIndex++;
                }
            }
        }
        /// <summary>
        /// Create a new FlightSimulator object
        /// </summary>
        /// <param name="aircraft">The aircraft that will be used in the simulation</param>
        /// <param name="endPoint">The position the aircraft will fly towards</param>
        /// <param name="numberOfSegments">The number of segments used in the simulation. The simulation starts and ends with a straight segment, so the number of segments should be odd.</param>
        /// <param name="settings">The control parameters, which are a list of doubles between 0 and 1. The number of controls needed for any number of segments can be calculated by calling TrajectoryChromosome.ChromosomeLength().</param>
        public FlightSimulator(ISimulatorModel aircraft, Point3D endPoint, int numberOfSegments, List <double> settings, TrajectoryGenerator trajectoryGenerator)
        {
            _trajectoryGenerator = trajectoryGenerator;
            _settings            = settings;

            _vertical_state = VERTICAL_STATE.TAKEOFF;
            _aircraft       = aircraft;
            _speed          = 160;
            _x       = 0;
            _y       = 0;
            _heading = Math.PI / 2;

            _endPoint         = endPoint;
            _numberOfSegments = numberOfSegments;
            _segmentIndex     = 1;
        }
        /// <summary>
        /// Switch to a different vertical state if needed
        /// </summary>
        protected void updateVerticalState()
        {
            switch (_vertical_state)
            {
            case VERTICAL_STATE.TAKEOFF:
                if (_height >= 1500)
                {
                    _vertical_state = VERTICAL_STATE.CLIMB;
                }
                break;

            case VERTICAL_STATE.CLIMB:
                if (_height >= 3600 || _speed >= 250)
                {
                    _vertical_state = VERTICAL_STATE.FREECLIMB;
                }
                break;

            default:
                /*
                 * if (_height >= 6000 || _speed >= _aircraft.VClean) {
                 *  Console.WriteLine("Trajectory reached max height or VClean");
                 *  _vertical_state = VERTICAL_STATE.END;
                 * }
                 */
                /*
                 * // force stop:
                 * if (duration >= 750) {
                 *  Console.WriteLine("Trajectory timeout");
                 *  fuel = int.MaxValue;
                 *  _vertical_state = VERTICAL_STATE.END;
                 * }
                 */
                break;
            }
        }