/// <summary> /// Constructor used to set the values needed to initialize the components of the class. It will not start waiting for data until /// StartSensorMonitoringRoutine() is called. /// /// The reason the client IP address is a string and not an IPAddress is because none of the TCPClient class's /// constructors take an IPAddress. :( /// </summary> /// <param name="serverIPAddress">This is the IP address the SensorNetworkServer is "listening" to.</param> /// <param name="serverPort">This is the port the SensorNetworkServer is "listening" to.</param> /// <param name="clientIPAddress">This is the IP address of the SensorNetwork that we will be sending the sensor initialization to.</param> /// <param name="clientPort">This is the port of the SensorNetwork that we will be sending the sensor initialization to.</param> /// <param name="telescopeId">The Radio Telescope that the SensorNetworkConfig will apply to.</param> /// <param name="isSimulation">Tells the SensorNetworkServer if it should initialize the SimulationSensorNetwork, /// or if it is connecting to the production hardware (or maybe an outside simulation).</param> public SensorNetworkServer(IPAddress serverIPAddress, int serverPort, string clientIPAddress, int clientPort, int telescopeId, bool isSimulation) { // Initialize main parts of the Sensor Network Server = new TcpListener(serverIPAddress, serverPort); InitializationClient = new SensorNetworkClient(clientIPAddress, clientPort, telescopeId); // Sensor data initialization CurrentElevationMotorTemp = new Temperature[1]; CurrentElevationMotorTemp[0] = new Temperature(); CurrentAzimuthMotorTemp = new Temperature[1]; CurrentAzimuthMotorTemp[0] = new Temperature(); CurrentAbsoluteOrientation = new Orientation(); CurrentElevationMotorAccl = new Acceleration[1]; CurrentElevationMotorAccl[0] = new Acceleration(); CurrentAzimuthMotorAccl = new Acceleration[1]; CurrentAzimuthMotorAccl[0] = new Acceleration(); CurrentCounterbalanceAccl = new Acceleration[1]; CurrentCounterbalanceAccl[0] = new Acceleration(); AbsoluteOrientationOffset = new Orientation(); // Sensor error initialization SensorStatuses = new SensorStatuses(); SensorStatuses.AzimuthAbsoluteEncoderStatus = SensorNetworkSensorStatus.Okay; SensorStatuses.ElevationAbsoluteEncoderStatus = SensorNetworkSensorStatus.Okay; SensorStatuses.AzimuthTemperature1Status = SensorNetworkSensorStatus.Okay; SensorStatuses.AzimuthTemperature2Status = SensorNetworkSensorStatus.Okay; SensorStatuses.ElevationTemperature1Status = SensorNetworkSensorStatus.Okay; SensorStatuses.ElevationTemperature2Status = SensorNetworkSensorStatus.Okay; SensorStatuses.AzimuthAccelerometerStatus = SensorNetworkSensorStatus.Okay; SensorStatuses.ElevationAccelerometerStatus = SensorNetworkSensorStatus.Okay; SensorStatuses.CounterbalanceAccelerometerStatus = SensorNetworkSensorStatus.Okay; // Initialize threads and additional processes, if applicable SensorMonitoringThread = new Thread(() => { SensorMonitoringRoutine(); }); SensorMonitoringThread.Name = "SensorMonitorThread"; // We only want to run the internal simulation if the user selected to run the Simulated Sensor Network if (isSimulation) { SimulationSensorNetwork = new SimulationSensorNetwork(serverIPAddress.ToString(), serverPort, IPAddress.Parse(clientIPAddress), clientPort); } else { SimulationSensorNetwork = null; } // Initialize the timeout timer but don't start it yet Timeout = new System.Timers.Timer(); Timeout.Elapsed += TimedOut; // TimedOut is the function at the bottom that executes when this elapses Timeout.AutoReset = false; AccBlob = new AccelerationBlob(); }
/// <summary> /// This is used to parse the sensor statuses into the SensorStatuses object. /// </summary> /// <param name="statuses">Regular statuses.</param> /// <param name="errors">Various error codes if there are errors.</param> /// <returns></returns> private SensorStatuses ParseSensorStatuses(BitArray statuses, UInt32 errors) { SensorStatuses s = new SensorStatuses { // Regular statuses AzimuthAbsoluteEncoderStatus = statuses[0] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, AzimuthTemperature1Status = statuses[2] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, AzimuthTemperature2Status = statuses[1] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, ElevationTemperature1Status = statuses[4] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, ElevationTemperature2Status = statuses[3] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, AzimuthAccelerometerStatus = statuses[6] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, ElevationAccelerometerStatus = statuses[7] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, CounterbalanceAccelerometerStatus = statuses[5] ? SensorNetworkSensorStatus.Okay : SensorNetworkSensorStatus.Error, // TODO: Parse errors here. You will need to add the errors to the SensorStatuses object (issue #353) }; return(s); }
/// <summary> /// This is important for the simulation. This will convert the data arrays we get from CSV files /// to bytes that we can send to the SensorNetworkServer. /// </summary> /// <param name="elAccl">Array of RAW elevation accelerometer samples.</param> /// <param name="azAccl">Array of RAW azimuth accelerometer samples.</param> /// <param name="cbAccl">Array of RAW counterbalance accelerometer samples.</param> /// <param name="elTemps">Array of elevation temperature samples.</param> /// <param name="azTemps">Array of azimuth temperature samples.</param> /// <param name="elEnc">Array of elevation encoder samples.</param> /// <param name="azEnc">Array of azimuth encoder samples.</param> /// <param name="statuses">All the sensor statuses and errors that come from the sensor network.</param> /// <returns></returns> public static byte[] ConvertDataArraysToBytes(RawAccelerometerData[] elAccl, RawAccelerometerData[] azAccl, RawAccelerometerData[] cbAccl, double[] elTemps, double[] azTemps, double[] elEnc, double[] azEnc, SensorStatuses statuses) { uint dataSize = CalcDataSize(elAccl.Length, azAccl.Length, cbAccl.Length, elTemps.Length, azTemps.Length, elEnc.Length, azEnc.Length); // If you want to input raw data instead, just comment out the next few loops. // They exist so that we can input data into our CSV files that make sense to us, since // raw data values are not very readable // Convert elevation temperature to raw data short[] rawElTemps = new short[elTemps.Length]; for (int i = 0; i < elTemps.Length; i++) { rawElTemps[i] = ConvertTempCToRawData(elTemps[i]); } // Convert azimuth temperature to raw data short[] rawAzTemps = new short[azTemps.Length]; for (int i = 0; i < azTemps.Length; i++) { rawAzTemps[i] = ConvertTempCToRawData(azTemps[i]); } // Convert elevation position to raw data short[] rawElEnc = new short[elEnc.Length]; for (int i = 0; i < elEnc.Length; i++) { rawElEnc[i] = ConvertDegreesToRawElData(elEnc[i]); } // Convert azimuth position to raw data short[] rawAzEnc = new short[azEnc.Length]; for (int i = 0; i < azEnc.Length; i++) { rawAzEnc[i] = ConvertDegreesToRawAzData(azEnc[i]); } bool[] sensorStatusBoolArray = new bool[] { statuses.ElevationAccelerometerStatus == SensorNetworkSensorStatus.Okay, statuses.AzimuthAccelerometerStatus == SensorNetworkSensorStatus.Okay, statuses.CounterbalanceAccelerometerStatus == SensorNetworkSensorStatus.Okay, statuses.ElevationTemperature1Status == SensorNetworkSensorStatus.Okay, statuses.ElevationTemperature2Status == SensorNetworkSensorStatus.Okay, statuses.AzimuthTemperature1Status == SensorNetworkSensorStatus.Okay, statuses.AzimuthTemperature2Status == SensorNetworkSensorStatus.Okay, statuses.AzimuthAbsoluteEncoderStatus == SensorNetworkSensorStatus.Okay }; int errors = 0; // TODO: implement conversion (issue #376) return(EncodeRawData(dataSize, elAccl, azAccl, cbAccl, rawElTemps, rawAzTemps, rawElEnc, rawAzEnc, sensorStatusBoolArray, errors)); }