/// <summary>
 /// Service State-based ctor
 /// </summary>
 /// <param name="state">Service State</param>
 public Replace(Parallax2011ReferencePlatformIoControllerState state) : base(state)
 {
 }
 /// <summary>
 /// State and Port ctor
 /// </summary>
 /// <param name="state">Service State</param>
 /// <param name="responsePort">Response Port</param>
 public Replace(Parallax2011ReferencePlatformIoControllerState state, PortSet <DefaultReplaceResponseType, Fault> responsePort)
     : base(state, responsePort)
 {
 }
        /// <summary>
        /// Allocation and assignments for first run
        /// </summary>
        /// <returns>True if initialization succeeded, otherwise False</returns>
        private bool Initialize()
        {
            if (this.initialized)
            {
                return(this.initialized);
            }

            try
            {
                // No persisted state file, create a new one
                if (this.state == null)
                {
                    this.state = new Parallax2011ReferencePlatformIoControllerState();
                }

                // Fill out the L/R drive state specifics
                if (this.state.DriveState.LeftWheel == null || this.state.DriveState.LeftWheel.Radius == 0)
                {
                    this.state.DriveState.LeftWheel = new motor.WheeledMotorState()
                    {
                        Radius = board.DefaultWheelRadius
                    };
                }

                this.state.DriveState.LeftWheel.MotorState      = new motor.MotorState();
                this.state.DriveState.LeftWheel.MotorState.Name = this.wheelNames[(int)Sides.Left];
                this.state.DriveState.LeftWheel.MotorState.HardwareIdentifier = (int)Sides.Left;
                this.state.DriveState.LeftWheel.MotorState.PowerScalingFactor = 1;

                if (this.state.DriveState.LeftWheel.EncoderState == null || this.state.DriveState.LeftWheel.EncoderState.TicksPerRevolution == 0)
                {
                    this.state.DriveState.LeftWheel.EncoderState = new Services.Encoder.EncoderState()
                    {
                        TicksPerRevolution = board.DefaultTicksPerRevolution
                    };
                }

                if (this.state.DriveState.RightWheel == null || this.state.DriveState.RightWheel.Radius == 0)
                {
                    this.state.DriveState.RightWheel = new motor.WheeledMotorState()
                    {
                        Radius = board.DefaultWheelRadius
                    };
                }

                this.state.DriveState.RightWheel.MotorState      = new motor.MotorState();
                this.state.DriveState.RightWheel.MotorState.Name = this.wheelNames[(int)Sides.Right];
                this.state.DriveState.RightWheel.MotorState.HardwareIdentifier = (int)Sides.Right;
                this.state.DriveState.RightWheel.MotorState.PowerScalingFactor = 1;

                if (this.state.DriveState.RightWheel.EncoderState == null || this.state.DriveState.RightWheel.EncoderState.TicksPerRevolution == 0)
                {
                    this.state.DriveState.RightWheel.EncoderState = new Services.Encoder.EncoderState()
                    {
                        TicksPerRevolution = board.DefaultTicksPerRevolution
                    };
                }

                // Reflect all the default GPIO pin states into the state

                if (this.state.GpioState == null)
                {
                    this.state.GpioState = new gpio.GpioPinArrayState();
                }

                this.state.GpioState.Pins = new List <gpio.GpioPinState>(board.GPIOPinCount);
                for (int pinIndex = 0; pinIndex < board.GPIOPinCount; pinIndex++)
                {
                    gpio.GpioPinState pinState = new gpio.GpioPinState();

                    // GPIO bank defaults to IN for PING sensors
                    pinState.PinDirection = gpio.GpioPinState.GpioPinDirection.In;

                    // Pins are labeled on the control board using 1-based indexing
                    pinState.Number = pinIndex + 1;

                    this.state.GpioState.Pins.Add(pinState);
                }

                // Populate the ADCPins
                // NOTE: Pins on the board are labelled using 1-based indexing

                if (this.state.AdcState == null)
                {
                    this.state.AdcState = new adc.ADCPinArrayState();
                }

                this.state.AdcState.Pins = new List <adc.ADCPinState>(board.ADCPinCount + board.DigitalPinCount);
                for (int pinIndex = 0; pinIndex < board.ADCPinCount + board.DigitalPinCount; pinIndex++)
                {
                    adc.ADCPinState a = new adc.ADCPinState();
                    a.Name      = string.Format("Pin_{0}", pinIndex);
                    a.TimeStamp = DateTime.Now;
                    a.Number    = pinIndex + 1;
                    this.state.AdcState.Pins.Add(a);
                }
            }
            catch (Exception e)
            {
                LogError(e);
                this.Shutdown();
                return(false);
            }

            this.state.DriveState.TimeStamp =
                this.state.LastStartTime    = DateTime.Now;

            SaveState(this.state);
            return(true);
        }