Ejemplo n.º 1
0
        private async void LightSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            // Invert
            var reading = 1 - args.Reading.Ratio;

            // Update UI
            await Dispatcher.RunIdleAsync((s) =>
            {
                // Value
                LightProgress.Value = reading;

                // Color
                if (reading < .25)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Red);
                }
                else if (reading < .75 )
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Yellow);
                }
                else
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Green);
                }
            });

        }
Ejemplo n.º 2
0
    public IAnalogSensor viewIAnalogSensor()
    {
        global::System.IntPtr cPtr = yarpPINVOKE.PolyDriver_viewIAnalogSensor(swigCPtr);
        IAnalogSensor         ret  = (cPtr == global::System.IntPtr.Zero) ? null : new IAnalogSensor(cPtr, false);

        return(ret);
    }
Ejemplo n.º 3
0
        private async void LightSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            // Invert
            var reading = 1 - args.Reading.Ratio;

            // Update UI
            await Dispatcher.RunIdleAsync((s) =>
            {
                // Value
                LightProgress.Value = reading;

                // Color
                if (reading < .25)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Red);
                }
                else if (reading < .75)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Yellow);
                }
                else
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Green);
                }
            });
        }
Ejemplo n.º 4
0
        void Ahrs_ValueChanged(IHardwareComponent sender)
        {
            IAnalogSensor a   = (IAnalogSensor)sender;
            int           val = a.AnalogValue; // 0v = 0, 5V = 470 approx

            /*
             * Yaw    PWM     val
             * --------------------
             *
             */

            double heading;

            if (val > 507)
            {
                heading = GeneralMath.map(val, 508, 1024, 0, 180);
            }
            else
            {
                heading = GeneralMath.map(val, 0, 507, 180, 360);
            }

            //Debug.WriteLine("Ahrs: Value=" + val + "  heading: " + heading);

            lock (currentSensorsDataLock)
            {
                ISensorsData sensorsData = new SensorsDataShorty(this.currentSensorsData);
                sensorsData.CompassHeadingDegrees = heading;
                //Debug.WriteLine(sensorsData.ToString());

                this.currentSensorsData = sensorsData;
            }
        }
Ejemplo n.º 5
0
        private void AnalogSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            // Get reading
            var r = args.Reading;

            currentReading = args.Reading.Ratio - ambientThreshold;
            maxReading     = Math.Max(maxReading, currentReading);

            var t = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
            {
                if (currentState == States.Cooldown)
                {
                    CurrentValueProg.Value = currentReading;
                }
                else
                {
                    CurrentValueProg.Value = maxReading;
                }
                PercentBlock.Text = string.Format("{0:N0}%", maxReading * 100);
                await TestAndUpdateStateAsync();
            });

            // Print
            Debug.WriteLine(string.Format("Value: {0}  Ratio: {1}", r.Value, r.Ratio));
        }
Ejemplo n.º 6
0
        private async void TempSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            var reading = args.Reading.Value;

            tempVals.Add(((9 / 5) * (reading / 10)) + 32);
            tempVals.RemoveAt(0);
            double temp = tempVals.Average();

            #region comment this out if running headless.
            await Dispatcher.RunIdleAsync((s) =>
            {
                // Value
                TemperatureProgress.Text = "Temperature: " + temp.ToString() + "deg F";

                // Color
                if (temp < 40)
                {
                    TemperatureProgress.Foreground = new SolidColorBrush(Colors.LightBlue);
                }
                else if (temp < 80)
                {
                    TemperatureProgress.Foreground = new SolidColorBrush(Colors.Yellow);
                }
                else
                {
                    TemperatureProgress.Foreground = new SolidColorBrush(Colors.Red);
                }
            });

            #endregion comment this out if running headless.
        }
Ejemplo n.º 7
0
        private void AnalogSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            // Get reading
            var r = args.Reading;

            // Store for reporting
            lastAnalog = r.Ratio;

            // Print
            Debug.WriteLine(string.Format("Value: {0}  Ratio: {1}", r.Value, r.Ratio));
        }
Ejemplo n.º 8
0
        private IAnalogSensor CreateBatteryVoltageMeter(IAbstractRobotHardware brick, int frequency, double thresholdVolts)
        {
            // analog pin 5 in Element board is internally tied to 1/3 of the supply voltage level. The 5.0d is 5V, microcontroller's ADC reference and 1024 is range.
            int threshold = (int)Math.Round((thresholdVolts * 1024.0d) / (3.0d * 5.0d));

            Debug.WriteLine("CreateBatteryVoltageMeter()   threshold=" + threshold);

            // analog pin 5 is internally tied to 1/3 of the supply voltage level
            IAnalogSensor bv = brick.produceAnalogSensor(AnalogPinId.A5, frequency, threshold);

            bv.AnalogValueChanged += new HardwareComponentEventHandler(batteryVoltage_ValueChanged);

            return(bv);
        }
Ejemplo n.º 9
0
        private IAnalogSensor CreateBatteryVoltageMeter(IAbstractRobotHardware brick, int frequency, double thresholdVolts)
        {
            // analog pin 5 in Element board is internally tied to 1/3 of the supply voltage level.
            // The 5.0d is 5V, microcontroller's ADC reference and 1024 is range.
            // on Plucky the battery voltage goes through 1/3 divider and comes to Arduino Pin 3, which is reported as Pin 5 to here.
            // see PluckyWheels.ino sketch
            int threshold = (int)Math.Round((thresholdVolts * 1024.0d) / (3.0d * 5.0d));

            Debug.WriteLine("CreateBatteryVoltageMeter()   threshold=" + threshold);

            // analog pin 5 is internally tied to 1/3 of the supply voltage level
            IAnalogSensor bv = brick.produceAnalogSensor(AnalogPinId.A5, frequency, threshold);

            bv.AnalogValueChanged += new HardwareComponentEventHandler(batteryVoltage_ValueChanged);

            return(bv);
        }
Ejemplo n.º 10
0
        void batteryVoltage_ValueChanged(IHardwareComponent sender)
        {
            lock (currentSensorsDataLock)
            {
                SensorsDataShorty sensorsData = new SensorsDataShorty(this.currentSensorsData);

                IAnalogSensor bv = sender as IAnalogSensor;

                Debug.Assert(bv != null, "SensorsControllerElement: batteryVoltage_ValueChanged(): AnalogSensor must be non-null");

                // analog pin 5 in Element board is internally tied to 1/3 of the supply voltage level. The 5.0d is 5V, microcontroller's ADC reference and 1024 is range.

                double voltage = 3.0d * (bv.AnalogValue * 5.0d) / 1024.0d;

                sensorsData.BatteryVoltage = voltage;   // also sets sensorsData.BatteryVoltageTimestamp

                this.currentSensorsData = sensorsData;
            }

            Debug.WriteLine(this.currentSensorsData.ToString());
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Event Handler for Light Sensor Reading Changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async void LightSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            //Read the ratio, which is readvalue/maxvalue
            var reading = args.Reading.Ratio;

            //Add reading to end of list
            lightVals.Add(reading * 100);
            //remove first reading.  Constant size of list is 10.
            lightVals.RemoveAt(0);
            //Smooth the reading out by averaging all 10
            //this is average light value across 5 seconds
            //Note: You occasionally get bad values, hence the smoothing.
            var avg = lightVals.Average();

            // Update UI
            #region comment this out if running headless.
            await Dispatcher.RunIdleAsync((s) =>
            {
                // Value
                LightProgress.Text = "Light: " + avg.ToString() + "%";

                // Color
                if (avg < 25)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.OrangeRed);
                }
                else if (avg < 75)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Yellow);
                }
                else
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Green);
                }
            });

            #endregion comment this out if running headless.
        }
Ejemplo n.º 12
0
        private void batteryVoltage_ValueChanged(IHardwareComponent sender)
        {
            lock (currentSensorsDataLock)
            {
                SensorsDataPlucky sensorsData = new SensorsDataPlucky(this.currentSensorsData);

                IAnalogSensor bv = sender as IAnalogSensor;

                Debug.Assert(bv != null, "SensorsControllerPlucky: batteryVoltage_ValueChanged(): AnalogSensor must be non-null");

                // analog pin 5 in Element board is internally tied to 1/3 of the supply voltage level.
                // The 5.0d is 5V, microcontroller's ADC reference and 1024 is range.
                // on Plucky the battery voltage goes through 1/3 divider and comes to Arduino Pin 3, which is reported as Pin 5 to here.
                // see PluckyWheels.ino sketch

                double voltage = 3.0d * (bv.AnalogValue * 5.0d) / 1024.0d;

                sensorsData.BatteryVoltage = voltage;   // also sets sensorsData.BatteryVoltageTimestamp

                this.currentSensorsData = sensorsData;
            }

            Debug.WriteLine(this.currentSensorsData.ToString());
        }
Ejemplo n.º 13
0
        /// <summary>
        /// we can create sensors here, but cannot send commands before bridge_CommunicationStarted is called in PluckyTheRobot
        /// for example, encoder.Clear() will hang.
        /// </summary>
        public async Task InitSensors(CancellationTokenSource cts)
        {
            // see C:\Projects\Serializer_3_0\ExampleApps\AnalogSensorExample\AnalogSensorExample\Form1.cs

            // Note: the Element board communicates at 19200 Baud, which is roughly 1.5 kbytes/sec
            //       Comm link is busy with motor commands and has to be responsive to encoders, for odometry to work.
            //       Sensors must carefully adjust their demands by setting UpdateFrequency and Enabled properties.

            // *********************** infrared rangers:
            SensorPose spIrLeft = new SensorPose() { XMeters = 0.0d, YMeters = 0.1d, ThetaRadians = Math.PI / 2.0d };
            RangerIrLeft = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrLeft", spIrLeft,
                                                                                        hardwareBrick, AnalogPinId.A1, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrLeft.distanceChangedEvent += new EventHandler<RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrLeft.Name, RangerIrLeft);

            SensorPose spIrRight = new SensorPose() { XMeters = 0.0d, YMeters = -0.1d, ThetaRadians = -Math.PI / 2.0d };
            RangerIrRight = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrRight", spIrRight,
                                                                                        hardwareBrick, AnalogPinId.A0, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrRight.distanceChangedEvent += new EventHandler<RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrRight.Name, RangerIrRight);

            SensorPose spIrFront = new SensorPose() { XMeters = 0.1d, YMeters = 0.0d, ThetaRadians = 0.0d };
            RangerIrFront = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrFront", spIrFront,
                                                                                        hardwareBrick, AnalogPinId.A3, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrFront.distanceChangedEvent += new EventHandler<RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrFront.Name, RangerIrFront);

            SensorPose spIrRear = new SensorPose() { XMeters = -0.1d, YMeters = 0.0d, ThetaRadians = Math.PI };
            RangerIrRear = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrRear", spIrRear,
                                                                                        hardwareBrick, AnalogPinId.A2, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrRear.distanceChangedEvent += new EventHandler<RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrRear.Name, RangerIrRear);


            // *********************** ultrasonic rangers:
            SensorPose spSonarLeft = new SensorPose() { XMeters = 0.1d, YMeters = 0.05d, ThetaRadians = Math.PI / 6.0d };
            RangerSonarLeft = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorSonar, "SonarLeft", spSonarLeft,
                                                                                        hardwareBrick, GpioPinId.Pin4, GpioPinId.Pin5, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerSonarLeft.distanceChangedEvent += new EventHandler<RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerSonarLeft.Name, RangerSonarLeft);

            SensorPose spSonarRight = new SensorPose() { XMeters = 0.1d, YMeters = -0.05d, ThetaRadians = -Math.PI / 6.0d };
            RangerSonarRight = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorSonar, "SonarRight", spSonarRight,
                                                                                        hardwareBrick, GpioPinId.Pin2, GpioPinId.Pin3, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerSonarRight.distanceChangedEvent += new EventHandler<RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerSonarRight.Name, RangerSonarRight);


            // *********************** wheel encoders - roughly 500 ticks per wheel revolution, 1200 ticks per meter.
            encoderLeft = CreateWheelEncoder(hardwareBrick, WheelEncoderId.Encoder2, (int)mainLoopCycleMs, encodersSensitivityThresholdTicks);
            encoderRight = CreateWheelEncoder(hardwareBrick, WheelEncoderId.Encoder1, (int)mainLoopCycleMs, encodersSensitivityThresholdTicks);

            Compass = hardwareBrick.produceCompassCMPS03(0x60, CompassSamplingIntervalMs, CompassSensitivityThreshold);
            Compass.HeadingChanged += new HardwareComponentEventHandler(Compass_HeadingChanged);

            // arduino based AHRS - PWM DAC to pin 4:
            Ahrs = hardwareBrick.produceAnalogSensor(AnalogPinId.A4, CompassSamplingIntervalMs, CompassSensitivityThreshold);
            Ahrs.AnalogValueChanged += new HardwareComponentEventHandler(Ahrs_ValueChanged);

            // arduino based AHRS - I2C does not connect:
            //Ahrs = new I2CDevice(hardwareBrick);
            //Ahrs.I2CAddress = 173;  // The Wire library uses 7 bit addresses throughout. 
            //                        // If you have a datasheet or sample code that uses 8 bit address, you'll want to drop the low bit (i.e. shift the value one bit to the right),
            //                        // yielding an address between 0 and 127. However the addresses from 0 to 7 are not used because are reserved so the first address that can be used is 8.
            //Ahrs.WriteCommand = "234";
            //Ahrs.ReadCommand = "6";

            await PixyCameraSensor.Open(cts);
            PixyCameraSensor.TargetingCameraTargetsChanged += PixyCameraSensor_PixyCameraBlocksChanged;

            batteryVoltage = CreateBatteryVoltageMeter(hardwareBrick, batterySamplingIntervalMs, batterySensitivityThresholdVolts);

            batteryVoltage.Enabled = true;  // slow update rate, leave it turned on

            IrRangersEnabled = true;    // if false, do not sample or update
            SonarsEnabled = false;      // will enable sonars with an interval 50ms to avoid interference
            EncodersEnabled = true;
            //CompassEnabled = true;    // compass no good inside concrete buildings, use gyro instead
            CompassEnabled = false;
            Ahrs.Enabled = true;
            PixyCameraSensor.Enabled = true;

            currentSensorsData = new SensorsData() { RangerSensors = this.RangerSensors };
        }
Ejemplo n.º 14
0
        private async void TempSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            var reading = args.Reading.Value;
            tempVals.Add(reading * 5000.0 / 1024.0 / 10.0);
            tempVals.RemoveAt(0);
            double temp = tempVals.Average();
            #region comment this out if running headless.
            await Dispatcher.RunIdleAsync((s) =>
            {
                // Value
                TemperatureProgress.Text = "Temperature: " + temp.ToString() + "deg F";

                // Color
                if (temp < 40)
                {
                    TemperatureProgress.Foreground = new SolidColorBrush(Colors.LightBlue);
                }
                else if (temp < 80)
                {
                    TemperatureProgress.Foreground = new SolidColorBrush(Colors.Yellow);
                }
                else
                {
                    TemperatureProgress.Foreground = new SolidColorBrush(Colors.Red);
                }
            });
            #endregion comment this out if running headless.
        }
Ejemplo n.º 15
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(IAnalogSensor obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Ejemplo n.º 16
0
        private void AnalogSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            // Get reading
            var r = args.Reading;

            // Store for reporting
            lastAnalog = r.Ratio;

            // Print
            Debug.WriteLine(string.Format("Value: {0}  Ratio: {1}", r.Value, r.Ratio));
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Event Handler for Light Sensor Reading Changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async void LightSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            //Read the ratio, which is readvalue/maxvalue
            var reading = args.Reading.Ratio;
            //Add reading to end of list
            lightVals.Add(reading * 100);
            //remove first reading.  Constant size of list is 10.
            lightVals.RemoveAt(0);
            //Smooth the reading out by averaging all 10
            //this is average light value across 5 seconds
            //Note: You occasionally get bad values, hence the smoothing. 
            var avg = lightVals.Average();
            // Update UI
            #region comment this out if running headless.
            await Dispatcher.RunIdleAsync((s) =>
            {
                // Value
                LightProgress.Text = "Light: " + avg.ToString() + "%";

                // Color
                if (avg < 25)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.OrangeRed);
                }
                else if (avg < 75)
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Yellow);
                }
                else
                {
                    LightProgress.Foreground = new SolidColorBrush(Colors.Green);
                }
            });
            #endregion comment this out if running headless.
        }
Ejemplo n.º 18
0
 private void Sensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
 {
     // Perform update, existing reading
     Update(args.Reading);
 }
Ejemplo n.º 19
0
        private void AnalogSensor_ReadingChanged(IAnalogSensor sender, AnalogSensorReadingChangedEventArgs args)
        {
            // Get reading
            var r = args.Reading;

            currentReading = args.Reading.Ratio - ambientThreshold;
            maxReading = Math.Max(maxReading, currentReading);

            var t = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
            {
                if (currentState == States.Cooldown)
                {
                    CurrentValueProg.Value = currentReading;
                }
                else
                {
                    CurrentValueProg.Value = maxReading;
                }
                PercentBlock.Text = string.Format("{0:N0}%", maxReading * 100);
                await TestAndUpdateStateAsync();
            });

            // Print
            Debug.WriteLine(string.Format("Value: {0}  Ratio: {1}", r.Value, r.Ratio));
        }
Ejemplo n.º 20
0
        /// <summary>
        /// we can create sensors here, but cannot send commands before bridge_CommunicationStarted is called in PluckyTheRobot
        /// for example, encoder.Clear() will hang.
        /// </summary>
        public async Task InitSensors(CancellationTokenSource cts)
        {
            // see C:\Projects\Serializer_3_0\ExampleApps\AnalogSensorExample\AnalogSensorExample\Form1.cs

            // Note: the Element board communicates at 19200 Baud, which is roughly 1.5 kbytes/sec
            //       Comm link is busy with motor commands and has to be responsive to encoders, for odometry to work.
            //       Sensors must carefully adjust their demands by setting UpdateFrequency and Enabled properties.

            // *********************** infrared rangers:
            SensorPose spIrLeft = new SensorPose()
            {
                XMeters = 0.0d, YMeters = 0.1d, ThetaRadians = Math.PI / 2.0d
            };

            RangerIrLeft = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrLeft", spIrLeft,
                                                                   hardwareBrick, AnalogPinId.A1, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrLeft.distanceChangedEvent += new EventHandler <RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrLeft.Name, RangerIrLeft);

            SensorPose spIrRight = new SensorPose()
            {
                XMeters = 0.0d, YMeters = -0.1d, ThetaRadians = -Math.PI / 2.0d
            };

            RangerIrRight = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrRight", spIrRight,
                                                                    hardwareBrick, AnalogPinId.A0, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrRight.distanceChangedEvent += new EventHandler <RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrRight.Name, RangerIrRight);

            SensorPose spIrFront = new SensorPose()
            {
                XMeters = 0.1d, YMeters = 0.0d, ThetaRadians = 0.0d
            };

            RangerIrFront = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrFront", spIrFront,
                                                                    hardwareBrick, AnalogPinId.A3, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrFront.distanceChangedEvent += new EventHandler <RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrFront.Name, RangerIrFront);

            SensorPose spIrRear = new SensorPose()
            {
                XMeters = -0.1d, YMeters = 0.0d, ThetaRadians = Math.PI
            };

            RangerIrRear = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorIR10_80, "IrRear", spIrRear,
                                                                   hardwareBrick, AnalogPinId.A2, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerIrRear.distanceChangedEvent += new EventHandler <RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerIrRear.Name, RangerIrRear);


            // *********************** ultrasonic rangers:
            SensorPose spSonarLeft = new SensorPose()
            {
                XMeters = 0.1d, YMeters = 0.05d, ThetaRadians = Math.PI / 6.0d
            };

            RangerSonarLeft = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorSonar, "SonarLeft", spSonarLeft,
                                                                      hardwareBrick, GpioPinId.Pin4, GpioPinId.Pin5, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerSonarLeft.distanceChangedEvent += new EventHandler <RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerSonarLeft.Name, RangerSonarLeft);

            SensorPose spSonarRight = new SensorPose()
            {
                XMeters = 0.1d, YMeters = -0.05d, ThetaRadians = -Math.PI / 6.0d
            };

            RangerSonarRight = RangerSensorFactory.produceRangerSensor(RangerSensorFactoryProducts.RangerSensorSonar, "SonarRight", spSonarRight,
                                                                       hardwareBrick, GpioPinId.Pin2, GpioPinId.Pin3, rangersSamplingIntervalMs, rangersSensitivityThresholdCm);
            RangerSonarRight.distanceChangedEvent += new EventHandler <RangerSensorEventArgs>(RangerDistanceChangedEvent);
            RangerSensors.Add(RangerSonarRight.Name, RangerSonarRight);


            // *********************** wheel encoders - roughly 500 ticks per wheel revolution, 1200 ticks per meter.
            encoderLeft  = CreateWheelEncoder(hardwareBrick, WheelEncoderId.Encoder2, (int)mainLoopCycleMs, encodersSensitivityThresholdTicks);
            encoderRight = CreateWheelEncoder(hardwareBrick, WheelEncoderId.Encoder1, (int)mainLoopCycleMs, encodersSensitivityThresholdTicks);

            Compass = hardwareBrick.produceCompassCMPS03(0x60, CompassSamplingIntervalMs, CompassSensitivityThreshold);
            Compass.HeadingChanged += new HardwareComponentEventHandler(Compass_HeadingChanged);

            // arduino based AHRS - PWM DAC to pin 4:
            Ahrs = hardwareBrick.produceAnalogSensor(AnalogPinId.A4, CompassSamplingIntervalMs, CompassSensitivityThreshold);
            Ahrs.AnalogValueChanged += new HardwareComponentEventHandler(Ahrs_ValueChanged);

            // arduino based AHRS - I2C does not connect:
            //Ahrs = new I2CDevice(hardwareBrick);
            //Ahrs.I2CAddress = 173;  // The Wire library uses 7 bit addresses throughout.
            //                        // If you have a datasheet or sample code that uses 8 bit address, you'll want to drop the low bit (i.e. shift the value one bit to the right),
            //                        // yielding an address between 0 and 127. However the addresses from 0 to 7 are not used because are reserved so the first address that can be used is 8.
            //Ahrs.WriteCommand = "234";
            //Ahrs.ReadCommand = "6";

            if (PixyCameraSensor != null)
            {
                try
                {
                    await PixyCameraSensor.Open(cts);

                    PixyCameraSensor.TargetingCameraTargetsChanged += PixyCameraSensor_PixyCameraBlocksChanged;
                }
                catch (Exception exc)
                {
                    speaker.Speak("Could not open Pixy Camera at " + PixyCameraSensor.ComPortName);
                    PixyCameraSensor = null;
                }
            }

            batteryVoltage = CreateBatteryVoltageMeter(hardwareBrick, batterySamplingIntervalMs, batterySensitivityThresholdVolts);

            batteryVoltage.Enabled = true; // slow update rate, leave it turned on

            IrRangersEnabled = true;       // if false, do not sample or update
            SonarsEnabled    = false;      // will enable sonars with an interval 50ms to avoid interference
            EncodersEnabled  = true;
            //CompassEnabled = true;    // compass no good inside concrete buildings, use gyro instead
            CompassEnabled = false;
            Ahrs.Enabled   = true;
            if (PixyCameraSensor != null)
            {
                PixyCameraSensor.Enabled = true;
            }
            currentSensorsData = new SensorsDataShorty()
            {
                RangerSensors = this.RangerSensors
            };
        }