From db669afa3d3af05535f72b2950afef546602e262 Mon Sep 17 00:00:00 2001 From: Andrea Orlati Date: Wed, 16 Mar 2022 14:04:28 +0000 Subject: [PATCH] fix issue #655: Also included the check for power outage snd in case the sytem tries to recover from it. some test still required before merging. --- .../Servers/MedicinaMount/include/ACUData.h | 3 +++ .../MedicinaMount/include/ACUInterface.h | 7 ++++- .../include/MedicinaMountSocket.h | 22 +++++++++++++--- .../Servers/MedicinaMount/src/ACUData.cpp | 8 ++++++ .../MedicinaMount/src/ACUInterface.cpp | 6 +++++ .../MedicinaMount/src/MedicinaMountSocket.cpp | 26 +++++++++++++++++++ .../MedicinaMount/src/MedicinaMountThread.cpp | 1 + 7 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Medicina/Servers/MedicinaMount/include/ACUData.h b/Medicina/Servers/MedicinaMount/include/ACUData.h index 23d03ac68..5fbe0031e 100644 --- a/Medicina/Servers/MedicinaMount/include/ACUData.h +++ b/Medicina/Servers/MedicinaMount/include/ACUData.h @@ -83,6 +83,9 @@ public: /** Returns the section which the antenna is located in, at present */ CACUInterface::TAntennaSection getSection() const; + /** Return true if the driver power is on */ + bool getDrivePower() const; + /**Returns the number of free stack slots reserved for time tagged program track positions */ WORD getFreeStackPositions() const; diff --git a/Medicina/Servers/MedicinaMount/include/ACUInterface.h b/Medicina/Servers/MedicinaMount/include/ACUInterface.h index 6e3f8cd92..c765e6644 100644 --- a/Medicina/Servers/MedicinaMount/include/ACUInterface.h +++ b/Medicina/Servers/MedicinaMount/include/ACUInterface.h @@ -186,9 +186,14 @@ public: static TAxeModes getMode(BYTE mode); /** - * This function returns the antenna presnt section given the control word + * This function returns the antenna present section given the control word */ static TAntennaSection getSection(WORD controlWord); + + /** + * This function returns true i drive power is on, false otherwise + */ + static bool getDrivePower(WORD controlWord); }; diff --git a/Medicina/Servers/MedicinaMount/include/MedicinaMountSocket.h b/Medicina/Servers/MedicinaMount/include/MedicinaMountSocket.h index adaefefe5..2089303a5 100644 --- a/Medicina/Servers/MedicinaMount/include/MedicinaMountSocket.h +++ b/Medicina/Servers/MedicinaMount/include/MedicinaMountSocket.h @@ -453,16 +453,27 @@ public: /** * This method has been added to detect the event the ACU mode differs from previously commanded. In case it tries to - * recover from this event by commandind the correct mode. + * recover from this event by commanding the correct mode. * @throw AntennaErrors::ConnectionExImpl * @throw ComponentErrors::SocketErrorExImpl * @throw ComponentErrors::TimeoutExImpl * @throw AntennaErrors::NakExImpl - * @throwAntennaErrors::AntennaBusyExImpl + * @throw AntennaErrors::AntennaBusyExImpl */ void checkCommandedMode() throw (AntennaErrors::ConnectionExImpl,ComponentErrors::SocketErrorExImpl, ComponentErrors::TimeoutExImpl,AntennaErrors::NakExImpl,AntennaErrors::AntennaBusyExImpl); + /** + * This method has been added to detect a power failure in the servo system. In case it tries to + * recover from this event by reseting the servo. + * @throw AntennaErrors::ConnectionExImpl + * @throw ComponentErrors::SocketErrorExImpl + * @throw ComponentErrors::TimeoutExImpl + * @throw AntennaErrors::NakExImpl + */ + void checkPowerFailure() throw (ComponentErrors::TimeoutExImpl,AntennaErrors::NakExImpl, + AntennaErrors::ConnectionExImpl,ComponentErrors::SocketErrorExImpl); + /** * This member function is used by the control thread in order to check if a long job that was started as completed or not. * @param job job identifier @@ -622,7 +633,12 @@ private: /** * this flag indicates that a recovery from mode check in ongoing..... */ - bool m_modeCheckRecover; + bool m_modeCheckRecover; + + /** + * this flag indicates that a power failure has been detected + */ + bool m_powerFailDetected; /** * Stores the epoch of the last scan. Used in oscillation prevention diff --git a/Medicina/Servers/MedicinaMount/src/ACUData.cpp b/Medicina/Servers/MedicinaMount/src/ACUData.cpp index 07c67df79..147d5a4f2 100644 --- a/Medicina/Servers/MedicinaMount/src/ACUData.cpp +++ b/Medicina/Servers/MedicinaMount/src/ACUData.cpp @@ -114,6 +114,14 @@ CACUInterface::TAntennaSection CACUData::getSection() const memcpy(&Value,(m_MonitorData+36),2); return CACUInterface::getSection(Value); } + +bool CACUData::getDrivePower() const +{ + WORD val; + memcpy(&val,(m_MonitorData+36),2); + return CACUInterface::getDrivePower(val); +} + WORD CACUData::getFreeStackPositions() const { diff --git a/Medicina/Servers/MedicinaMount/src/ACUInterface.cpp b/Medicina/Servers/MedicinaMount/src/ACUInterface.cpp index 874ebfe18..a9d78da13 100644 --- a/Medicina/Servers/MedicinaMount/src/ACUInterface.cpp +++ b/Medicina/Servers/MedicinaMount/src/ACUInterface.cpp @@ -247,3 +247,9 @@ CACUInterface::TAntennaSection CACUInterface::getSection(WORD controlWord) else return CACUInterface::CCW; } +bool CACUInterface::getDrivePower(WORD controlWord) +{ + if (controlWord & (1 << 15)) return true; + else return false; +} + diff --git a/Medicina/Servers/MedicinaMount/src/MedicinaMountSocket.cpp b/Medicina/Servers/MedicinaMount/src/MedicinaMountSocket.cpp index 16ff05276..19004f193 100644 --- a/Medicina/Servers/MedicinaMount/src/MedicinaMountSocket.cpp +++ b/Medicina/Servers/MedicinaMount/src/MedicinaMountSocket.cpp @@ -131,6 +131,7 @@ void CMedicinaMountSocket::Init(CConfiguration *config,maci::ContainerServices * m_oscMode=CACUInterface::STANDBY; m_lastScanEpoch=0; m_modeCheckRecover=false; + m_powerFailDetected=false; } CACUInterface::TAxeModes CMedicinaMountSocket::getAzimuthMode() throw (ConnectionExImpl,SocketErrorExImpl,TimeoutExImpl) @@ -848,10 +849,35 @@ double CMedicinaMountSocket::getHWAzimuth(double destination,const CACUInterface return CIRATools::getHWAzimuth(pos,dest,m_configuration->azimuthLowerLimit(),m_configuration->azimuthUpperLimit(),section,m_configuration->cwLimit()); } +void CMedicinaMountSocket::checkPowerFailure() throw (ComponentErrors::TimeoutExImpl,AntennaErrors::NakExImpl, + AntennaErrors::ConnectionExImpl,ComponentErrors::SocketErrorExImpl) +{ + //_IRA_LOGDIKE_COMPLETION(m_logDike,__dummy,LM_DEBUG); + if (!m_configuration->checkForMode()) return; + if (m_Data.getDrivePower()) { //in case of a power outage of failure..... + if (!m_powerFailDetected) { //first detection + CUSTOM_LOG(LM_FULL_INFO,"CMedicinaMountSocket::checkPowerFailure()",(LM_CRITICAL, + "Servo system power failure detected")); + } + m_powerFailDetected=true; + } + else { // no power error + if (!m_powerFailDetected) { //first detection + CUSTOM_LOG(LM_FULL_INFO,"CMedicinaMountSocket::checkPowerFailure()",(LM_CRITICAL, + "Servo system power failure cleared")); + CUSTOM_LOG(LM_FULL_INFO,"CMedicinaMountSocket::checkPowerFailure()",(LM_NOTICE, + "Trying a servo system reset")); + failureReset();// throw (TimeoutExImpl,AntennaErrors::NakExImpl,ConnectionExImpl,SocketErrorExImpl) + m_powerFailDetected=false; + } + } +} + void CMedicinaMountSocket::checkCommandedMode() throw (ConnectionExImpl,SocketErrorExImpl,TimeoutExImpl,AntennaErrors::NakExImpl,AntennaBusyExImpl) { CACUInterface::TAxeModes commandedMode, mode; if (!m_configuration->checkForMode()) return; + if (m_powerFailDetected) return; // no need to try to recover from mode discrepancy if the cause is a power failure commandedMode=m_Data.getLastCommandedMode(); if ((commandedMode!=CACUInterface::STANDBY) && (commandedMode!=CACUInterface::UNSTOW) && (commandedMode!=CACUInterface::STOW) && (commandedMode!=CACUInterface::STOP)) { diff --git a/Medicina/Servers/MedicinaMount/src/MedicinaMountThread.cpp b/Medicina/Servers/MedicinaMount/src/MedicinaMountThread.cpp index 4236c18ae..4023b11c9 100644 --- a/Medicina/Servers/MedicinaMount/src/MedicinaMountThread.cpp +++ b/Medicina/Servers/MedicinaMount/src/MedicinaMountThread.cpp @@ -51,6 +51,7 @@ void CMedicinaMountControlThread::runLoop() CSecAreaResourceWrapper socket=m_pACUControl->Get(); socket->updateComponent(); // before commenting out or deleting consider that inside this method the flushing of pending event of the log dike object is called socket->detectOscillation(); + socket->checkPowerFailure(); socket->checkCommandedMode(); if (currentJobID!=0) { ACSErr::Completion_var comp; -- GitLab