コード例 #1
0
        /// <summary>
        ///     Wait for the given <see cref="SaciaBoard"/> motor
        ///     to reach its stopped position.
        /// </summary>
        /// <param name="board">The <see cref="SaciaBoard"/></param>
        /// <param name="distance">The distance to run the motor</param>
        /// <param name="timeout">The time to wait. If time reach <see cref="TimeoutException"/> will be thrown</param>
        /// <returns></returns>
        /// <exception cref="System.TimeoutException">The operation has timed out waiting for an output to be set.</exception>
        public static async Task RunUntilStopped(this SaciaBoard board, int distance, TimeSpan timeout)
        {
            var expectedPos = board.Position + distance;

            var waitForStopped = board.WaitForStopped(CancellationToken.None, timeout);

            if (board.UseSoftwarePosition)
            {
                board.Run(distance);

                var task = await Task.WhenAny(waitForStopped)
                           .ConfigureAwait(false);

                // re-await so any cancellations or exceptions can be rethrown
                await task;
            }
            else
            {
                var waitForPos = board.WaitForPositionReached(expectedPos, timeout);

                board.Run(distance);

                var task = await Task.WhenAny(waitForStopped, waitForPos).ConfigureAwait(false);

                // re-await so any cancellations or exceptions can be rethrown
                await task;
            }
        }
コード例 #2
0
        /// <summary>
        ///     Sets the zero-based output of the given <see cref="SaciaBoard"/>
        ///     to the specified value. Exits when confirmation recieved from
        ///     the specifed board that the output has been set.
        /// </summary>
        /// <param name="board">The <see cref="SaciaBoard"/></param>
        /// <param name="output">The zero-based output to set.</param>
        /// <param name="value">The value to set the output to.</param>
        /// <returns></returns>
        public static async Task SetOutputSafe(this SaciaBoard board, int output, bool value)
        {
            if (board.Outputs[output] != value)
            {
                var wait = board.WaitForOutput(output, value, CancellationToken.None, TimeSpan.FromSeconds(3));

                board.SetOutput(output, value);

                await wait.ConfigureAwait(false);
            }
        }
コード例 #3
0
        private static async Task WaitForPositionReached(this SaciaBoard board, double motorPosition, TimeSpan timeout)
        {
            DateTime start = DateTime.UtcNow;

            while (board.Position > motorPosition + 1 || board.Position < motorPosition - 1) // account for potential half step rounding
            {
                if (start + timeout < DateTime.UtcNow)
                {
                    throw new TimeoutException("The operation has timed out waiting for the motor to complete.");
                }
                await Task.Delay(20);
            }
        }
コード例 #4
0
        /// <summary>
        ///     Wait for the given <see cref="SaciaBoard"/> motor
        ///     to reach its stopped position.
        /// </summary>
        /// <param name="board">The <see cref="SaciaBoard"/></param>
        /// <param name="timeout">The time to wait for the zero value to be set. If time reach <see cref="TimeoutException"/> will be thrown</param>
        /// <exception cref="System.TimeoutException">The operation has timed out waiting for a zero value to be set.</exception>
        public static async Task ZeroSafe(this SaciaBoard board, TimeSpan timeout)
        {
            board.Zero();

            var start = DateTime.UtcNow;

            while (board.Position != 0)
            {
                if (start + timeout < DateTime.UtcNow)
                {
                    throw new InvalidOperationException("The operation has timed out waiting for a zero value to be set.");
                }
                await Task.Delay(200);
            }
        }
コード例 #5
0
        /// <summary>
        ///     Wait for the given <see cref="SaciaBoard"/> motor
        ///     to reach its stopped position.
        /// </summary>
        /// <param name="board">The <see cref="SaciaBoard"/></param>
        /// <param name="maxDistance">The maximum distance to run the motor.</param>
        /// <param name="input">The input to wait for.</param>
        /// <param name="value">The expected value of the input.</param>
        /// <param name="timeout">The time to wait. If time reach <see cref="TimeoutException"/> will be thrown</param>
        /// <param name="errorIfMaxDistanceReached">
        ///     If true, throw <see cref="InvalidOperationException"/>
        ///     if max distance reached before input detected
        /// </param>
        /// <returns></returns>
        /// <exception cref="System.TimeoutException">The operation has timed out waiting for an output to be set.</exception>
        public static async Task RunUntilStopped(this SaciaBoard board, int maxDistance, int input, bool value, TimeSpan timeout, bool errorIfMaxDistanceReached = true)
        {
            var maxPos = board.Position + maxDistance;

            var waitForInput = board.WaitForInput(input, value, CancellationToken.None, timeout);
            var motorStopped = board.WaitForStopped(CancellationToken.None, timeout);

            if (board.UseSoftwarePosition)
            {
                board.Run(maxDistance, input, value);

                var task = await Task.WhenAny(waitForInput, motorStopped).ConfigureAwait(false);

                //if (board.Inputs[input] != value)
                //{
                //    if (board.Position == maxPos && errorIfMaxDistanceReached)
                //    {
                //        throw new InvalidOperationException("Max distance reached before input detected.");
                //    }
                //}

                await task;
            }
            else
            {
                var waitForPos = board.WaitForPositionReached(maxPos, timeout);

                board.Run(maxDistance, input, value);

                var task = await Task.WhenAny(waitForInput, motorStopped, waitForPos);

                if (board.Inputs[input] != value)
                {
                    if (board.Position == maxPos && errorIfMaxDistanceReached)
                    {
                        throw new InvalidOperationException("Max distance reached before input detected.");
                    }
                }

                await task;
            }
        }
コード例 #6
0
        /// <summary>
        ///     Wait for the given <see cref="SaciaBoard"/> to stop.
        /// </summary>
        /// <param name="board">The <see cref="SaciaBoard"/></param>
        /// <param name="token">The cancellation token.</param>
        /// <param name="timeout">The time to wait. If time reach <see cref="TimeoutException"/> will be thrown</param>
        /// <returns></returns>
        /// <exception cref="System.TimeoutException">The operation has timed out waiting for the motor to complete.</exception>
        public static async Task WaitForStopped(this SaciaBoard board, CancellationToken token, TimeSpan timeout)
        {
            var task = TaskExtensions.FromEvent <EventHandler <MotorStoppedEventArgs>, MotorStoppedEventArgs>(
                (complete, cancel, reject) => // get handler
                (sender, args) => complete(args),
                handler =>                    // subscribe
                board.MotorStopped += handler,
                handler =>                    // unsubscribe
                board.MotorStopped -= handler,
                (complete, cancel, reject) => // start the operation
                { },
                token);

            if (await Task.WhenAny(task, Task.Delay(timeout)).ConfigureAwait(false) == task)
            {
                // re-await so any cancellations or exceptions can be rethrown
                await task;
            }
            else
            {
                throw new TimeoutException("The operation has timed out waiting for the motor to complete.");
            }
        }
コード例 #7
0
        /// <summary>
        ///     Wait for the given <see cref="SaciaBoard"/> input
        ///     to change to the expected value.
        /// </summary>
        /// <param name="board">The <see cref="SaciaBoard"/></param>
        /// <param name="input">The input to wait for</param>
        /// <param name="value">The expected value.</param>
        /// <param name="token">The cancellation token.</param>
        /// <param name="timeout">The time to wait. If time reach <see cref="TimeoutException"/> will be thrown</param>
        /// <returns></returns>
        /// <exception cref="System.TimeoutException">The operation has timed out waiting for an input to be set.</exception>
        public static async Task WaitForInput(this SaciaBoard board, int input, bool value, CancellationToken token, TimeSpan timeout)
        {
            if (board.Inputs[input] != value)
            {
                bool complete = false;
                board.InputChanged += (o, e) =>
                {
                    if (e.Input == input && e.NewValue == value)
                    {
                        complete = true;
                    }
                };

                DateTime start = DateTime.UtcNow;
                while (!complete)
                {
                    if (DateTime.UtcNow > start + timeout)
                    {
                        throw new TimeoutException("The operation has timed out waiting for an input to be set.");
                    }
                    await Task.Delay(100).ConfigureAwait(false);
                }
            }
        }