Bugfix for movTimeoutWatchdog

Update of README.md
This commit is contained in:
2025-02-14 16:17:11 +01:00
parent c06cf8e76c
commit e92a867189
9 changed files with 948 additions and 480 deletions

View File

@@ -1,5 +1,6 @@
/*
This class extends asynMotorController by some features used in SINQ.
This class extends asynMotorController by some features used in SINQ. See the
README.md for details.
Stefan Mathis, November 2024
*/
@@ -7,6 +8,8 @@ Stefan Mathis, November 2024
#ifndef __sinqController
#define __sinqController
#include "asynMotorController.h"
#include <deque>
#include <initHooks.h>
#define motorMessageIsFromDriverString "MOTOR_MESSAGE_DRIVER"
#define motorMessageTextString "MOTOR_MESSAGE_TEXT"
@@ -90,7 +93,8 @@ class epicsShareClass sinqController : public asynMotorController {
* @return asynStatus Returns input status.
*/
asynStatus paramLibAccessFailed(asynStatus status, const char *parameter,
const char *functionName, int lineNumber);
int axisNo, const char *functionName,
int lineNumber);
/**
* @brief Error handling in case parsing a command response failed.
@@ -122,20 +126,122 @@ class epicsShareClass sinqController : public asynMotorController {
*/
const char *stringifyAsynStatus(asynStatus status);
/**
* @brief This function should be called when a communication timeout
occured. It calculates the frequency of communication timeout events and
creates an error message, if an threshold has been exceeded.
*
Occasionally, communication timeouts between the IOC and the motor
controller may happen, usually because the controller takes too long to
respond. If this happens infrequently, this is not a problem. However, if it
happens very often, this may indicate a network problem and must therefore
be forwarded to the user. This is checked by calculating the moving average
of events and comparing it to a threshhold. Both the threshold and the time
window for the moving average can be configured in the IOC via the function
setThresholdCom.
This function exists in two variants: Either the error message can be
written into a buffer provided by the caller or it written directly into the
parameter library of the provided axis.
* @param axis Axis to which the error message is sent
*
* @return asynStatus asynError, if the threshold has been
exceeded, asynSuccess otherwise
*/
virtual asynStatus checkComTimeoutWatchdog(class sinqAxis *axis);
/**
* @brief See documentation of checkComTimeoutWatchdog(sinqAxis * axis)
*
* @param userMessage Buffer for the user message
* @param userMessageSize Buffer size in chars
* @return asynStatus
*/
virtual asynStatus checkComTimeoutWatchdog(int axisNo, char *motorMessage,
size_t motorMessageSize);
/**
* @brief Set the threshold for the communication timeout mechanism
*
* @param comTimeoutWindow Size of the time window used to calculate
* the moving average of timeout events. Set this value to 0 to deactivate
* the watchdog.
* @param maxNumberTimeouts Maximum number of timeouts which may occur
* within the time window before the watchdog is triggered.
* @return asynStatus
*/
virtual asynStatus setThresholdComTimeout(time_t comTimeoutWindow,
size_t maxNumberTimeouts) {
comTimeoutWindow_ = comTimeoutWindow;
maxNumberTimeouts_ = maxNumberTimeouts;
return asynSuccess;
}
/**
* @brief Inform the user, if the number of timeouts exceeds the threshold
* specified with setMaxSubsequentTimeouts
*
* @param timeoutNo Number of subsequent timeouts which already
* happened.
* @param axis
* @return asynStatus
*/
virtual asynStatus checkMaxSubsequentTimeouts(int timeoutNo,
class sinqAxis *axis);
/**
* @brief See documentation of checkMaxSubsequentTimeouts(sinqAxis * axis)
*
* @param userMessage Buffer for the user message
* @param userMessageSize Buffer size in chars
* @return asynStatus
*/
virtual asynStatus checkMaxSubsequentTimeouts(int timeoutNo, int axisNo,
char *motorMessage,
size_t motorMessageSize);
/**
* @brief Set the maximum number of subsequent timeouts before the user is
* informed.
*
* @param maxSubsequentTimeouts
* @return asynStatus
*/
asynStatus setMaxSubsequentTimeouts(int maxSubsequentTimeouts) {
maxSubsequentTimeouts_ = maxSubsequentTimeouts;
return asynSuccess;
}
friend class sinqAxis;
protected:
asynUser *lowLevelPortUser_;
double movingPollPeriod_;
double idlePollPeriod_;
// Internal variables used in the communication timeout frequency watchdog
time_t comTimeoutWindow_; // Size of the time window
size_t maxNumberTimeouts_; // Maximum acceptable number of events within the
// time window
std::deque<time_t>
timeoutEvents_; // Deque holding the timestamps of the individual events
// Communicate a timeout to the user after it has happened this many times
// in a row
int maxSubsequentTimeouts_;
bool maxSubsequentTimeoutsExceeded_;
#define FIRST_SINQMOTOR_PARAM motorMessageText_
int motorMessageText_;
int motorTargetPosition_;
int motorEnable_;
int motorEnableRBV_;
int motorCanDisable_;
int motorEnableMovWatchdog_;
int motorCanSetSpeed_;
int motorLimitsOffset_;
int motorForceStop_;
/*
These parameters are here to write values from the hardware to the EPICS
motor record. Using motorHighLimit_ / motorLowLimit_ does not work:
@@ -151,6 +257,9 @@ class epicsShareClass sinqController : public asynMotorController {
int motorLowLimitFromDriver_;
int encoderType_;
#define LAST_SINQMOTOR_PARAM encoderType_
private:
static void epicsInithookFunction(initHookState iState);
};
#define NUM_SINQMOTOR_DRIVER_PARAMS \
(&LAST_SINQMOTOR_PARAM - &FIRST_SINQMOTOR_PARAM + 1)