// ********************************************************************************************************** // LSPSMotion.cs // 1/8/2024 // NGI - Next Generation Interceptor // // Contract No. HQ0856-21-C-0003/1022000209 // // THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S. // INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS. // // RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON // COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. // DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON // COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED // TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF // RAYTHEON COMPANY. // // UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. // // DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M, // NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006, // INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3, // DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3, // SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4, // INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION. // // CONTROLLED BY: MISSILE DEFENSE AGENCY // CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE // CUI CATEGORY: CTI // DISTRIBUTION/DISSEMINATION CONTROL: F // POC: Alex Kravchenko (1118268) // ********************************************************************************************************** using NLog; using Raytheon.Common; using Raytheon.Instruments.Lib; using Raytheon.Instruments.LSPS; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text.RegularExpressions; namespace Raytheon.Instruments { /// /// Low-Background Scanning Point Source instrument /// public class LspsChamber : ILspsChamber { public enum UutType { SENSOR_SELF_TEST_BOX = 0, SENSOR = 1, SENSOR_W_IMU = 2, IMU = 3, SEEKER_SELF_TEST_BOX = 4, SEEKER = 5, NOTCONNECTED }; public enum FilterWheelPos { NEEDS_HOME = 0, HOMING = 1, MOVING = 2, HOME_SWITCH_ERROR = 3, POSITION_SWITCH_ERROR = 4, FIND_POSITION_ERROR = 5, IN_POSITION = 6 }; public enum Events { QUIT, SCRIPT_ABORT, NUM_EVENTS }; public enum StartEvents { START, QUIT_THREAD, NUM_EVENTS }; public enum TargetSize { BIG_TARGET = 7, SMALL_TARGET = 6 }; /// /// NLog logger /// private static ILogger _logger; /// /// Raytheon configuration /// private readonly IConfigurationManager _configurationManager; private readonly IConfiguration _configuration; private List _profiles = new List(); private int _profileSteps = 0; private int _currentProfileStep = 0; public string DetailedStatus => throw new NotImplementedException(); public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); } public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); } public InstrumentMetadata Info => throw new NotImplementedException(); public string Name { get; set; } public SelfTestResult SelfTestResult => throw new NotImplementedException(); public State Status => throw new NotImplementedException(); private LSPS.TcpClientSock _tcpClientSock; private readonly int SendCommandResponseTimeoutMs; // ms private readonly int SleepDelayBeforeMonitoringMs; // ms private string lspsAddress_; private int lspsPort_; private static Dictionary commandToStopwatchDict = new Dictionary(); public bool ClearErrors() => false; public SelfTestResult PerformSelfTest() => throw new NotImplementedException(); /// /// Initialize the device /// public void Initialize() { _logger?.Trace($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method..."); _tcpClientSock = new LSPS.TcpClientSock(lspsAddress_, lspsPort_); _tcpClientSock.Connect(); _tcpClientSock.ClearReceiveBuffer(); } /// /// Shuts down the device /// public void Shutdown() { _logger?.Trace($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method..."); _tcpClientSock.Disconnect(); } public void Reset() { _logger?.Trace($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method..."); Shutdown(); Initialize(); } /// /// LSPS factory constructor /// /// /// public LspsChamber(string deviceName, IConfigurationManager configurationManager, ILogger logger) { Name = deviceName; _logger = logger; _configurationManager = configurationManager; _configuration = _configurationManager.GetConfiguration(Name); SendCommandResponseTimeoutMs = _configuration.GetConfigurationValue("LSPSMotion", "SendCommandResponseTimeoutMs", 5000); SleepDelayBeforeMonitoringMs = _configuration.GetConfigurationValue("LSPSMotion", "SleepDelayBeforeMonitoringMs", 2000); lspsAddress_ = _configuration.GetConfigurationValue("LSPS_Controller", "address", "127.0.0.1"); lspsPort_ = _configuration.GetConfigurationValue("LSPS_Controller", "port", 2300); } #region Autofill Functions /// /// Autofill Cool Down command /// public void AutoFillCoolDown() { string command = LSPS.Autofill.GetFullCommand(LSPS.Autofill.Command.COOLDOWN); SendCommandAndGetResponse(command); } /// /// Autofill Warm Up command /// public void AutoFillWarmUp() { string command = LSPS.Autofill.GetFullCommand(LSPS.Autofill.Command.WARMUP); SendCommandAndGetResponse(command); } /// /// Autofill Fill Force command /// public void AutoFillForce() { string command = LSPS.Autofill.GetFullCommand(LSPS.Autofill.Command.FORCE); SendCommandAndGetResponse(command); } /// /// Autofill Turn off command /// public void AutoFillTurnOff() { string command = LSPS.Autofill.GetFullCommand(LSPS.Autofill.Command.TURN_OFF); SendCommandAndGetResponse(command); } public LSPS.AutoFillState GetAutoFillState() { int state = 0; string command = LSPS.Autofill.GetFullCommand(LSPS.Autofill.Command.GET_STATE); string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(' '); Int32.TryParse(stringArray[0], out state); return (LSPS.AutoFillState)state; } public double GetTimeToFill() { double ttf = 0.0; string command = LSPS.Autofill.GetFullCommand(LSPS.Autofill.Command.GET_TIME_TO_FILL); Double.TryParse(SendCommandAndGetResponse(command), out ttf); return ttf; } #endregion Autofill Functions #region NIF Functions /// /// closes gate valve /// public void CloseLspsGateValve() { string command = LSPS.NIF.GetFullCommand(LSPS.NIF.Command.CLOSE_UUT_GV); SendCommandAndGetResponse(command); } /// /// opens gate valve /// public void OpenLspsGateValve() { string command = LSPS.NIF.GetFullCommand(LSPS.NIF.Command.OPEN_UUT_GV); SendCommandAndGetResponse(command); } /// /// Get UUT Gate Valve Position /// public GateValvePosition GetLspsGateValvePosition() { GateValvePosition pos = GateValvePosition.OPEN; int val = 0; string command = $"{LSPS.NIF.GetFullCommand(LSPS.NIF.Command.GET_INPUT_INDEX)} INDEX={(int)LSPS.NIF.InputIndex.UUT_GV_CLOSE}"; string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(','); Int32.TryParse(stringArray[0], out val); if (val == 1) pos = GateValvePosition.CLOSE; return pos; } /// /// Get Input Index /// public int GetInputIndex(int inputIndex) { int val = 0; string command = $"{LSPS.NIF.GetFullCommand(LSPS.NIF.Command.GET_INPUT_INDEX)} INDEX={inputIndex}"; string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(','); Int32.TryParse(stringArray[0], out val); return val; } public double GetTemperature(LSPS.TemperatureIndex tempIndex) { double val = 0; string command = $"{LSPS.NIF.GetFullCommand(LSPS.NIF.Command.GET_TEMP_INDEX)} INDEX={(int)tempIndex}"; string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(','); Double.TryParse(stringArray[0], out val); return val; } #endregion #region RIO Functions /// /// closes gate valve /// public void CloseVhfGateValve() { string command = LSPS.RIO.GetFullCommand(LSPS.RIO.Command.GV_CLOSE); SendCommandAndGetResponse(command); } /// /// opens gate valve /// public void OpenVhfGateValve() { string command = LSPS.RIO.GetFullCommand(LSPS.RIO.Command.GV_OPEN); SendCommandAndGetResponse(command); } /// /// Get Gate Valve Chamber Pressure /// public double GetVhfGateValveChamberPressure() { string command = LSPS.RIO.GetFullCommand(LSPS.RIO.Command.GET_GV_CHAMBER_PRESSURE); string response = SendCommandAndGetResponse(command); double val = 0.0; Double.TryParse(response, out val); return val; } /// /// Get Gate Valve UUT Pressure /// public double GetVhfGateValveUutPressure() { string command = LSPS.RIO.GetFullCommand(LSPS.RIO.Command.GET_GV_CANISTER_PRESSURE); string response = SendCommandAndGetResponse(command); double val = 0.0; Double.TryParse(response, out val); return val; } /// /// Get VHF Gate Valve Closed Input /// public int GetVhfGateValveClosedInput() { string command = LSPS.RIO.GetFullCommand(LSPS.RIO.Command.GET_GV_CLOSED_INPUT); string response = SendCommandAndGetResponse(command); int val = 0; Int32.TryParse(response, out val); return val; } /// /// Get VHF Gate Valve Open Input /// public int GetVhfGateValveOpenInput() { string command = LSPS.RIO.GetFullCommand(LSPS.RIO.Command.GET_GV_OPEN_INPUT); string response = SendCommandAndGetResponse(command); int val = 0; Int32.TryParse(response, out val); return val; } #endregion #region Chamber Vacuum Functions /// /// Get Chamber Pressure (CVAC) /// public double GetLspsChamberPressure() { string command = LSPS.ChamberVacuum.GetFullCommand(LSPS.ChamberVacuum.Command.GET_CVAC); string response = SendCommandAndGetResponse(command); double val = 0.0; Double.TryParse(response, out val); return val; } /// /// Get Sensor Pressure (SVAC) /// public double GetLspsUutPressure() { string command = LSPS.ChamberVacuum.GetFullCommand(LSPS.ChamberVacuum.Command.GET_SVAC); string response = SendCommandAndGetResponse(command); double val = 0.0; Double.TryParse(response, out val); return val; } #endregion #region GALIL Functions /// /// home filter wheel /// public void FilterWheelHome() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.FW_HOME); SendCommandAndGetResponse(command); } /// /// sets filter wheel position /// /// public void SetFilterWheelPosition(int position) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.FW_SET_POS)} POS={position}"; SendCommandAndGetResponse(command); } /// /// Get filter wheel position /// public int GetFilterWheelPosition() { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.FW_GET_POS)}"; string response = SendCommandAndGetResponse(command); int val = 0; Int32.TryParse(response, out val); return val; } /// /// get filter wheel status /// public LSPS.TargetAndFilterWheelStatus GetFilterWheelStatus() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.FW_GET_STATUS); string response = SendCommandAndGetResponse(command); int val = 0; Int32.TryParse(response, out val); return (LSPS.TargetAndFilterWheelStatus)val; } /// /// home filter wheel /// public void TargetWheelHome() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.TW_HOME); SendCommandAndGetResponse(command); } /// /// Sets target wheel position /// /// public void SetTargetWheelPosition(int position) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.TW_SET_POS)} POS={(int)position}"; SendCommandAndGetResponse(command); } /// /// Get target wheel position /// public int GetTargetWheelPosition() { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.TW_GET_POS)}"; string response = SendCommandAndGetResponse(command); int val = 0; Int32.TryParse(response, out val); return val; } /// /// get target wheel status /// public LSPS.TargetAndFilterWheelStatus GetTargetWheelStatus() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.TW_GET_STATUS); string response = SendCommandAndGetResponse(command); int val = 0; Int32.TryParse(response, out val); return (LSPS.TargetAndFilterWheelStatus)val; } /// /// steering mirror home /// public void SteeringMirrorHome() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_HOME); SendCommandAndGetResponse(command); } /// /// steering mirror stop /// public void SteeringMirrorStop() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_STOP); SendCommandAndGetResponse(command); } /// /// steering mirror move /// public void SteeringMirrorMove(double az, double el, double speed) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_SET_BEAM_ANGLES)} AZ={az} EL={el} SPEED={speed}"; SendCommandAndGetResponse(command); } /// /// steering mirror get beam angles /// public Tuple SteeringMirrorGetBeamAngles() { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_GET_BEAM_ANGLES)}"; string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(','); double az = 0.0; double el = 0.0; Double.TryParse(stringArray[0], out az); Double.TryParse(stringArray[1], out el); return new Tuple(az, el); } /// /// steering mirror set beam speed /// public void SteeringMirrorSetBeamSpeed(double speed) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_SET_BEAM_SPEED)} SPEED={speed}"; SendCommandAndGetResponse(command); } /// /// steering mirror set right left arrow angle /// public void SteeringMirrorSetRightLeftArrowAngle(double angle) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_SET_RIGHT_LEFT_ARROW_ANGLE)} ANGLE={angle}"; SendCommandAndGetResponse(command); } /// /// steering mirror set up down arrow angle /// public void SteeringMirrorSetUpDownArrowAngle(double angle) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_SET_UP_DOWN_ARROW_ANGLE)} ANGLE={angle}"; SendCommandAndGetResponse(command); } /// /// steering mirror status /// public Tuple GetSteeringMirrorStatus() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_GET_AZ_STATUS); string response = SendCommandAndGetResponse(command); int az = 0; int el = 0; Int32.TryParse(response, out az); command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_GET_EL_STATUS); response = SendCommandAndGetResponse(command); Int32.TryParse(response, out el); return new Tuple((LSPS.SteeringMirrorStatus)az, (LSPS.SteeringMirrorStatus)el); } /// /// steering mirror load profile from file /// public void SteeringMirrorLoadProfileFromFile(string profileFilePath) { try { using (var fileStream = new FileStream(profileFilePath, FileMode.Open, FileAccess.Read)) using (var streamReader = new StreamReader(fileStream)) { string line; while ((line = streamReader.ReadLine()) != null) { Match regexMatch; regexMatch = Regex.Match(line, @"^[\s]*([\d-\.]+)[\s]*,[\s]*([\d-\.]+)[\s]*,[\s]*([\d-\.]+).*", RegexOptions.IgnoreCase); if (regexMatch.Success) { double az = 0.0; double el = 0.0; double speed = 0.0; Double.TryParse(regexMatch.Groups[1].Value, out speed); Double.TryParse(regexMatch.Groups[2].Value, out az); Double.TryParse(regexMatch.Groups[3].Value, out el); SteeringMirrorLoadProfileStep(az, el, speed); _profileSteps++; } } } } catch (IOException) { throw; } if (_profileSteps == 0) { throw new ChamberException("Invalid profile provided. Please load a valid Steering Mirror's profile!"); } _currentProfileStep = 0; } /// /// steering mirror load profile step /// public void SteeringMirrorLoadProfileStep(double az, double el, double speed) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_LOAD_PROFILE)} AZ={az} EL={el} SPEED={speed}"; SendCommandAndGetResponse(command); } /// /// steering mirror reset profile /// public void SteeringMirrorResetProfile() { string command = LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_RESET_PROFILE); SendCommandAndGetResponse(command); } /// /// steering mirror run profile /// public void SteeringMirrorRunProfile(LSPS.SteeringMirrorProfileMode profileMode, LSPS.SteeringMirrorMovementMode movementMode) { string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_MOVE_PROFILE)} MODE={(int)profileMode} TYPE={(int)movementMode}"; SendCommandAndGetResponse(command); } /// /// steering mirror move to beginning of profile /// public void SteeringMirrorMoveToBeginningOfProfile() { _currentProfileStep = 0; SteeringMirrorRunNextStepInProfile(); } /// /// steering mirror run next step in profile /// public void SteeringMirrorRunNextStepInProfile() { if (_profileSteps == 0) { string msg = "Please load a valid Steering Mirror's profile!"; throw new ChamberException(msg); } if (_currentProfileStep == _profileSteps) { _currentProfileStep = 0; } string command = $"{LSPS.GALIL.GetFullCommand(LSPS.GALIL.Command.SM_GET_PROFILE)} INDEX={_currentProfileStep}"; _currentProfileStep++; string response = SendCommandAndGetResponse(command); double az = 0.0; double el = 0.0; double speed = 0.0; string[] stringArray = response.Split(','); Double.TryParse(stringArray[0], out az); Double.TryParse(stringArray[1], out el); Double.TryParse(stringArray[2], out speed); SteeringMirrorMove(az, el, speed); } #endregion #region BlackBody Functions /// /// sets BlackBody setpoint temperature /// /// /// /// /// public void SetBlackBodySetpointTemperature(double temperature) { string command = $"{LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.CONTROL_SETPOINT)} SETPOINT={temperature}"; SendCommandAndGetResponse(command); } /// /// Get BlackBody Temperature /// public Tuple GetBlackbodyTemperature() { string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_TEMP); string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(','); double tempA = 0.0; double tempB = 0.0; Double.TryParse(stringArray[0], out tempA); Double.TryParse(stringArray[1], out tempB); return new Tuple(tempA, tempB); } /// /// Get BlackBody Rate of Change /// public double GetBlackbodyRateOfChange() { double val = 0.0; string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_RATE_OF_CHANGE); Double.TryParse(SendCommandAndGetResponse(command), out val); return val; } /// /// Get BlackBody Control State /// public LSPS.BlackBodyControlState GetBlackbodyControlState() { int val = 0; string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_CONTROL_STATE); Int32.TryParse(SendCommandAndGetResponse(command), out val); return (LSPS.BlackBodyControlState)val; } /// /// Get BlackBody Stability /// public Tuple GetBlackbodyStability(int? logRateInMs = null) { string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_STABILITY); string response = SendCommandAndGetResponse(command, logRateInMs); string[] stringArray = response.Split(','); int stabilityA = 0; int stabilityB = 0; Int32.TryParse(stringArray[0], out stabilityA); Int32.TryParse(stringArray[1], out stabilityB); return new Tuple((LSPS.Stability)stabilityA, (LSPS.Stability)stabilityB); } /// /// Get BlackBody Setpoint /// public double GetBlackbodySetpoint() { double val = 0.0; string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_CONTROL_SETPOINT); Double.TryParse(SendCommandAndGetResponse(command), out val); return val; } /// /// Get BlackBody Heater Percent /// public double GetBlackbodyHeaterPercent() { double val = 0.0; string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_HTR); Double.TryParse(SendCommandAndGetResponse(command), out val); return val; } /// /// Get BlackBody BIT /// public int GetBlackbodyBIT() { int val = 0; string command = LSPS.BlackBody.GetFullCommand(LSPS.BlackBody.Command.GET_BIT); Int32.TryParse(SendCommandAndGetResponse(command), out val); return val; } #endregion #region Chopper Functions /// /// Sets chopper frequency /// /// public void SetChopperFrequency(double frequency) { string command = $"{LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_SET_SETPOINT)} SETPOINT={frequency}"; SendCommandAndGetResponse(command); } public double GetChopperFrequency() { double frequency = 0.0; string command = LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_GET_CHOP_FREQ); Double.TryParse(SendCommandAndGetResponse(command), out frequency); return frequency; } public LSPS.Stability GetChopperStability() { string command = LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_GET_STABILITY); int stability = 0; Int32.TryParse(SendCommandAndGetResponse(command), out stability); return (LSPS.Stability)stability; } /// /// Turn off chopper wheel /// public void TurnOffChopperWheel() { string command = LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_TURN_OFF); SendCommandAndGetResponse(command); } /// /// Stopping chopper wheel at open position /// /// public void SetStopOpen() { string command = LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_STOP_OPEN); SendCommandAndGetResponse(command); } /// /// Stopping chopper wheel at closed position /// /// public void SetStopClosed() { string command = LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_STOP_CLOSED); SendCommandAndGetResponse(command); } /// /// Sets chopper state /// /// public LSPS.ChopperState GetChopperState() { string command = LSPS.Chopper.GetFullCommand(LSPS.Chopper.Command.CW_GET_STATE); int state = 0; string response = SendCommandAndGetResponse(command); string[] stringArray = response.Split(' '); Int32.TryParse(stringArray[0], out state); return (LSPS.ChopperState)state; } #endregion Chopper Functions #region Misc Functions /// /// Send A Command. Only for SET commands. /// DO NOT use for GET Commands as they require processing of returned data /// /// public void SendACommand(string command) { SendCommandAndGetResponse(command); } #endregion #region Undefined and Not Implemented /// /// not implemented /// /// public void StartJogging() { throw new NotImplementedException(); } /// /// not implemented /// /// public void StopJogging() { throw new NotImplementedException(); } /// /// /// /// /// public void SetBackgroundScene(int scene) { throw new NotImplementedException(); } /// /// /// /// /// public void SetTargetSource(int source) { throw new NotImplementedException(); } /// /// ??? /// /// /// public void SendMessageGetResponse(uint message) { throw new NotImplementedException(); } #endregion #region Private Functions /// /// standard message sending function /// /// private string SendCommandAndGetResponse(string command, int? logRateInMs = null) { if (logRateInMs == null || ToLog(command, logRateInMs)) _logger?.Trace("Executing LSPS Command: " + command); LSPS.LspsResponse response = new LSPS.LspsResponse(_tcpClientSock.SendCommandAndGetResponse(command + "\r\n")); if (response.commandType_ == LSPS.LspsResponse.CommandType.SET && !response.successful_) { throw new ChamberException("LSPS Command Failed with error: " + response.text_); } return response.text_; } /// /// If we have a thread sending command at a high rate, we want to slow down the logging of the command /// otherwise the log will be inundated with this high-rate message /// /// private bool ToLog(string command, int? logRateInMs) { bool toLog = true; if (logRateInMs != null) { if (commandToStopwatchDict.ContainsKey(command)) { if (commandToStopwatchDict[command].ElapsedMilliseconds >= logRateInMs) { toLog = true; commandToStopwatchDict[command].Reset(); commandToStopwatchDict[command].Start(); } else { toLog = false; } } else { toLog = true; commandToStopwatchDict[command] = new Stopwatch(); commandToStopwatchDict[command].Start(); } } return toLog; } #endregion } }