public virtual IEnumerator<ITask> SetMotorRotationHandler(SetMotorRotation setMotorRotation)
        {
            if (!ValidateConnection(_state, setMotorRotation.ResponsePort))
                yield break;

            _internalMotorRotationPort.Post(setMotorRotation);
            yield break;
        }
        public virtual IEnumerator<ITask> RotateForDurationHandler(RotateForDuration rotateForDuration)
        {
            if (!ValidateConnection(_state, rotateForDuration.ResponsePort))
                yield break;

            // Send a notification that the power has been set.
            SendNotification<RotateForDuration>(_subMgrPort, rotateForDuration);

            SetMotorRotation setMotorRotation = new SetMotorRotation(new SetMotorRotationRequest(rotateForDuration.Body.TargetPower));
            _internalMotorRotationPort.Post(setMotorRotation);

            yield return Timeout(rotateForDuration.Body.StopAfterMs);
                Arbiter.Receive(false, TimeoutPort(new TimeSpan((long)(10000.0 * rotateForDuration.Body.StopAfterMs))), EmptyHandler<DateTime>);

            setMotorRotation = new SetMotorRotation(new SetMotorRotationRequest(0.0), rotateForDuration.ResponsePort);
            setMotorRotation.Body.StopState = rotateForDuration.Body.StopState;
            _internalMotorRotationPort.Post(setMotorRotation);
            yield break;
        }
        public virtual IEnumerator<ITask> GenericSetMotorPowerHandler(pxmotor.SetMotorPower genericMotorPower)
        {
            if (!ValidateConnection(_state, genericMotorPower.ResponsePort))
                yield break;

            SetMotorRotation setMotorRotation = new SetMotorRotation(new SetMotorRotationRequest(genericMotorPower.Body.TargetPower));
            _internalMotorRotationPort.Post(setMotorRotation);

            yield return Arbiter.Choice(setMotorRotation.ResponsePort,
                delegate(DefaultUpdateResponseType response)
                {
                    SendNotification<pxmotor.SetMotorPower>(_subMgrPort, genericMotorPower);
                    genericMotorPower.ResponsePort.Post(response);
                },
                delegate(Fault fault)
                {
                    genericMotorPower.ResponsePort.Post(fault);
                });

            yield break;
        }
        /// <summary>
        /// Internal Motor Rotation Handler
        /// Exclusive handler which controls all motor commands
        /// Responds to a flood of incoming motor commands by 
        /// only processing the newest command.
        /// </summary>
        /// <param name="setMotorPower"></param>
        /// <returns></returns>
        public virtual IEnumerator<ITask> InternalMotorRotationHandler(SetMotorRotation setMotorPower)
        {
            try
            {
                #region Check for a backlog of motor commands
                // Take a snapshot of the number of pending commands at the time
                // we entered this routine.
                // This will prevent a livelock which can occur if we try to
                // process the queue until it is empty, but the inbound queue
                // is growing faster than we are pulling off the queue.
                int pendingCommands = _internalMotorRotationPort.ItemCount;

                // If newer commands have been issued,
                // respond fault to the older command and
                // move to the newer one.
                SetMotorRotation newerRotationRequest;
                Fault faultNewerCommand = Fault.FromException(new InvalidOperationException("A newer motor command was received before this command was processed."));
                while (pendingCommands > 0)
                {
                    if (_internalMotorRotationPort.Test(out newerRotationRequest))
                    {
                        setMotorPower.ResponsePort.Post(faultNewerCommand);
                        setMotorPower = newerRotationRequest;
                    }
                    pendingCommands--;
                }
                #endregion

                // Get a snapshot of our state.
                MotorState currentState = _state.Clone();
                Fault faultResponse = null;

                int motorPower;
                long targetEncoderDegrees = 0;
                long targetRotationDegrees;
                CalculatePowerAndTargetDegrees(setMotorPower.Body, currentState.ReversePolarity,
                    out motorPower,
                    out targetRotationDegrees);

                #region Cancel any prior encoder target

                // If a prior encoder target was active,
                // signal that it is cancelled by a new Motor command.
                if (_targetEncoderPending)
                {
                    lock (_targetEncoderReachedPort)
                    {
                        if (_targetEncoderPending)
                        {
                            LogVerbose(LogGroups.Console, string.Format("Cancel prior target! New TgtDegrees: {0}", targetRotationDegrees));
                            _targetEncoderReachedPort.Post(false);
                            _targetEncoderPending = false;
                            _state.TargetEncoderDegrees = 0;
                            _state.CurrentEncoderTimeStamp = DateTime.Now;
                        }
                    }
                }
                #endregion

                _state.TargetPower = setMotorPower.Body.TargetPower;

                if (_state.TargetPower == 0)
                    SendNotification<AllStop>(_subMgrPort, new AllStop(setMotorPower.Body.StopState));

                // If rotating for a specific number of rotations,
                // set up the extended transaction and get the most recent encoder reading.
                if (targetRotationDegrees != 0)
                {

                    #region If encoder reading is old, update the encoder now.
                    if (DateTime.Now.Subtract(currentState.CurrentEncoderTimeStamp).TotalMilliseconds > 45)
                    {
                        LegoGetOutputState getEncoder = new LegoGetOutputState(currentState.MotorPort);
                        getEncoder.TryCount = 2;
                        yield return Arbiter.Choice(_legoBrickPort.SendNxtCommand(getEncoder),
                            delegate(LegoResponse legoResponse)
                            {
                                LegoResponseGetOutputState encoderResponse = legoResponse as LegoResponseGetOutputState;
                                if (encoderResponse == null) encoderResponse = new LegoResponseGetOutputState(legoResponse.CommandData);
                                if (encoderResponse.Success)
                                {
                                    int reversePolaritySign = (currentState.ReversePolarity) ? -1 : 1;
                                    _state.CurrentPower = ((double)(encoderResponse.PowerSetPoint * reversePolaritySign)) / 100.0;
                                    _state.CurrentEncoderTimeStamp = encoderResponse.TimeStamp;
                                    _state.CurrentEncoderDegrees = encoderResponse.EncoderCount * reversePolaritySign;
                                    _state.ResetableEncoderDegrees = encoderResponse.ResettableCount * reversePolaritySign;
                                    currentState = _state.Clone();
                                }
                                else
                                {
                                    LogError(LogGroups.Console, "Failed to set motor: " + legoResponse.ErrorCode.ToString());
                                    faultResponse = Fault.FromException(new InvalidOperationException(legoResponse.ErrorCode.ToString()));
                                }
                            },
                            delegate(Fault fault)
                            {
                                LogError(LogGroups.Console, fault.ToString());
                                faultResponse = fault;
                            });

                        if (faultResponse != null)
                        {
                            setMotorPower.ResponsePort.Post(faultResponse);
                            yield break;
                        }
                    }
                    #endregion

                    // Calcuate a new target encoder which is based on the current encoder position.
                    targetEncoderDegrees = targetRotationDegrees + currentState.CurrentEncoderDegrees;

                    // A target of zero diables the PD control.  Make sure our result isn't 0.
                    if (targetEncoderDegrees == 0) targetEncoderDegrees++;

                    LogVerbose(LogGroups.Console, string.Format("*** Target Degrees {0} Encoder {1}", targetRotationDegrees, targetEncoderDegrees));
                    _state.TargetEncoderDegrees = targetEncoderDegrees;
                    _state.TargetStopState = setMotorPower.Body.StopState;
                    lock (_targetEncoderReachedPort)
                    {
                        _targetEncoderPending = true;
                    }
                }
                else
                {
                    _state.TargetEncoderDegrees = 0;
                }

                LogVerbose(LogGroups.Console, string.Format("{0} SetMotorPower: {1}  Encoder: {2}  AdjPwr: {3}  TgtRot: {4}  TgtEnc {5}",
                    DateTime.Now.ToString("HH:mm:ss.fffffff"),
                    motorPower,
                    currentState.CurrentEncoderDegrees,
                    motorPower,
                    targetRotationDegrees,
                    targetEncoderDegrees));

                #region Set up the LEGO Motor Command

                // If we aren't polling, let the motor regulate it's own distance.
                int motorRotationLimit = 0;
                if (targetRotationDegrees != 0 && (currentState.PollingFrequencyMs <= 0 || currentState.PollingFrequencyMs > 100))
                    motorRotationLimit = (int)targetRotationDegrees;

                LegoRegulationMode regulationMode = LegoRegulationMode.Individual;
                LegoOutputMode outputMode = LegoOutputMode.MotorOn | LegoOutputMode.Regulated;
                RunState powerAdjustment = (setMotorPower.Body.RampUp && targetRotationDegrees != 0) ? RunState.RampUp : RunState.Constant;

                // Are we stopping?
                if (setMotorPower.Body.TargetPower == 0.0)
                {
                    motorRotationLimit = 0;
                    switch (setMotorPower.Body.StopState)
                    {
                        case MotorStopState.Brake:
                            outputMode = LegoOutputMode.MotorOn | LegoOutputMode.Regulated | LegoOutputMode.Brake;
                            powerAdjustment = RunState.Constant;
                            break;
                        case MotorStopState.Coast:
                            powerAdjustment = RunState.Idle;
                            regulationMode = LegoRegulationMode.Idle;
                            break;
                    }
                }

                // Set up the LEGO motor command
                LegoSetOutputState motorCmd = new LegoSetOutputState(
                    currentState.MotorPort,
                    motorPower,
                    outputMode,
                    regulationMode,
                    0,  /* Turn ratio */
                    powerAdjustment,
                    motorRotationLimit);

                #endregion

                #region Send the LEGO Motor Command

                bool abort = false;
                LogVerbose(LogGroups.Console, motorCmd.ToString());
                yield return Arbiter.Choice(_legoBrickPort.SendNxtCommand(motorCmd),
                    delegate(LegoResponse response)
                    {
                        if (!response.Success)
                        {
                            LogError(LogGroups.Console, "Invalid SetMotorOutput " + response.ErrorCode.ToString());
                            abort = true;
                            setMotorPower.ResponsePort.Post(
                                Fault.FromException(
                                    new InvalidOperationException(response.ErrorCode.ToString())));
                        }
                    },
                    delegate(Fault fault)
                    {
                        abort = true;
                        LogError(LogGroups.Console, "Fault in SetMotorOutput " + fault.ToString());
                        setMotorPower.ResponsePort.Post(fault);
                    });

                #endregion

                if (abort)
                    yield break;

                // Send a notification that the power has been set.
                SendNotification<SetMotorRotation>(_subMgrPort, setMotorPower);

                // Wait for the target encoder to either be cancelled or reach its target.
                if (_targetEncoderPending)
                {
                    LogVerbose(LogGroups.Console, "Waiting for motor to reach target...");

                    // Wait for the target encoder to either be cancelled or reached.
                    Activate(Arbiter.Receive<bool>(false, _targetEncoderReachedPort,
                        delegate(bool finished)
                        {
                            RespondToMotorPowerRequest(setMotorPower.ResponsePort, finished);
                        }));
                }
                else
                {
                    RespondToMotorPowerRequest(setMotorPower.ResponsePort, true);
                }
                yield break;
            }
            finally
            {
                Activate(Arbiter.ReceiveWithIterator<SetMotorRotation>(false, _internalMotorRotationPort, InternalMotorRotationHandler));
            }
        }
        public virtual IEnumerator<ITask> AllStopHandler(AllStop stop)
        {
            if (!ValidateConnection(_state, stop.ResponsePort))
                yield break;

            SetMotorRotation setMotorRotation = new SetMotorRotation(new SetMotorRotationRequest(0.0));
            setMotorRotation.Body.StopState = stop.Body.StopState;
            _internalMotorRotationPort.Post(setMotorRotation);

            yield return Arbiter.Choice(setMotorRotation.ResponsePort,
                delegate(DefaultUpdateResponseType response)
                {
                    stop.ResponsePort.Post(response);
                },
                delegate(Fault fault)
                {
                    stop.ResponsePort.Post(fault);
                });

            yield break;
        }