Documentation updated
This commit is contained in:
@@ -31,6 +31,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Virtual destructor.
|
||||
* Ensures that derived strategy objects are properly destroyed.
|
||||
*/
|
||||
virtual ~Strategy_Behavior() = default;
|
||||
|
||||
@@ -44,6 +45,9 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Checks if the strategy's update interval has elapsed.
|
||||
* This method manages the execution frequency of the strategy. It should be
|
||||
* called in each update loop to determine if it's time to execute the
|
||||
* strategy's logic again.
|
||||
* @param currentMillis The current time from `millis()`.
|
||||
* @return True if the strategy should be executed, false otherwise.
|
||||
*/
|
||||
@@ -55,6 +59,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Identifies if the strategy is a PID controller.
|
||||
* This virtual method provides a way to check for a specific strategy type
|
||||
* without using `dynamic_cast`. It is overridden by `PIDStrategy` to return true.
|
||||
* @return `false` for all non-PID strategies, `true` for PID strategies.
|
||||
*/
|
||||
virtual bool isPID() const { return false; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -7,8 +7,15 @@
|
||||
#include "Strategy_PID.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
// CORRECTED CONSTRUCTOR
|
||||
// You should pass in your gains here, but for now we'll add setters and initialize to 0.
|
||||
/**
|
||||
* @brief Constructs a new PIDStrategy object.
|
||||
* Initializes the PID controller with default gains and stores the names of the
|
||||
* Modbus points used for the setpoint and the process variable input.
|
||||
* @param setpointName The description key for the Modbus point that holds the setpoint value.
|
||||
* @param interval The update interval in milliseconds, passed to the base class.
|
||||
* @param inputSensorName The description key for the Modbus point that provides the
|
||||
* process variable (the input to the PID controller).
|
||||
*/
|
||||
PIDStrategy::PIDStrategy(const std::string& setpointName, unsigned long interval, const std::string& inputSensorName)
|
||||
: Strategy_Behavior(interval), _setpointName(setpointName), _inputSensorName(inputSensorName) {
|
||||
|
||||
@@ -21,23 +28,47 @@ PIDStrategy::PIDStrategy(const std::string& setpointName, unsigned long interval
|
||||
_lastTime = millis();
|
||||
}
|
||||
|
||||
// It's good practice to have methods to set your gains
|
||||
/**
|
||||
* @brief Sets the gains for the PID controller.
|
||||
* @param kp The proportional gain (P). Determines the reaction to the current error.
|
||||
* @param ki The integral gain (I). Determines the reaction based on the sum of recent errors.
|
||||
* @param kd The derivative gain (D). Determines the reaction based on the rate at which the error has been changing.
|
||||
*/
|
||||
void PIDStrategy::setGains(float kp, float ki, float kd) {
|
||||
_kp = kp;
|
||||
_ki = ki;
|
||||
_kd = kd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the target setpoint for the PID controller.
|
||||
* This value is typically read from a Modbus register in the `_applyStrategies` loop.
|
||||
* @param setpoint The new target value for the process variable.
|
||||
*/
|
||||
void PIDStrategy::setSetpoint(float setpoint) {
|
||||
_setpoint = setpoint;
|
||||
}
|
||||
|
||||
// This function is less necessary if execute() takes the current value, but can be used for setting an initial state.
|
||||
/**
|
||||
* @brief Manually sets the process variable (input) value.
|
||||
* @note This is typically not needed as the `execute` method receives the current
|
||||
* input value on each call from the `_applyStrategies` loop.
|
||||
* @param input The new process variable value.
|
||||
*/
|
||||
void PIDStrategy::setInput(float input) {
|
||||
_input = input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Executes one cycle of the PID control algorithm.
|
||||
*
|
||||
* This method calculates the error between the setpoint and the current input,
|
||||
* computes the proportional, integral (with anti-windup), and derivative terms,
|
||||
* and returns a new control output value. The final output is clamped between 0.0 and 100.0.
|
||||
*
|
||||
* @param currentValue The current process variable (e.g., temperature) read from the input sensor.
|
||||
* @return The calculated control output (e.g., fan speed), clamped between 0.0 and 100.0.
|
||||
*/
|
||||
float PIDStrategy::execute(float currentValue) {
|
||||
unsigned long now = millis();
|
||||
float timeChange = (float)(now - _lastTime);
|
||||
@@ -60,14 +91,6 @@ float PIDStrategy::execute(float currentValue) {
|
||||
|
||||
if (output > 100.0) output = 100.0;
|
||||
if (output < 0.0) output = 0.0;
|
||||
Serial.printf("PID timeChange: %f.\n", timeChange);
|
||||
Serial.printf("PID _input: %f.\n", _input);
|
||||
Serial.printf("PID error: %f.\n", error);
|
||||
Serial.printf("PID _integral: %f.\n", _integral);
|
||||
Serial.printf("PID derivative: %f.\n", derivative);
|
||||
Serial.printf("PID _kp: %f.\n", _kp);
|
||||
Serial.printf("PID _ki: %f.\n", _ki);
|
||||
Serial.printf("PID _kd: %f.\n", _kd);
|
||||
Serial.printf("PID output: %f.\n", output);
|
||||
return output;
|
||||
}
|
||||
@@ -1,4 +1,13 @@
|
||||
// In BaseEmulator/Strategies/Strategy_PID.h
|
||||
/**
|
||||
* @file Strategy_PID.h
|
||||
* @brief Defines the PIDStrategy class for PID control logic.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-06
|
||||
*
|
||||
* This file contains the definition for a behavior strategy that implements a
|
||||
* Proportional-Integral-Derivative (PID) controller. It's used to control a
|
||||
* process variable by adjusting an output based on a setpoint.
|
||||
*/
|
||||
|
||||
#ifndef PID_Strategy_h
|
||||
#define PID_Strategy_h
|
||||
@@ -6,38 +15,69 @@
|
||||
#include "Strategy_Behavior.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @class PIDStrategy
|
||||
* @brief A strategy that implements a PID (Proportional-Integral-Derivative) controller.
|
||||
*
|
||||
* This class inherits from Strategy_Behavior and provides the logic for a PID
|
||||
* controller. It calculates an output value designed to drive a process variable
|
||||
* (read from an input sensor) towards a desired setpoint. The setpoint itself
|
||||
* is also read from a Modbus point.
|
||||
*/
|
||||
class PIDStrategy : public Strategy_Behavior {
|
||||
public:
|
||||
// MODIFIED CONSTRUCTOR: Takes the setpoint, interval, and the name of the input sensor.
|
||||
/**
|
||||
* @brief Constructs a new PIDStrategy object.
|
||||
* @param setpointName The description key for the Modbus point that holds the setpoint value.
|
||||
* @param interval The update interval in milliseconds for the PID calculation.
|
||||
* @param inputSensorName The description key for the Modbus point that provides the
|
||||
* process variable (the input to the PID controller).
|
||||
*/
|
||||
PIDStrategy(const std::string& setpointName, unsigned long interval, const std::string& inputSensorName);
|
||||
|
||||
/**
|
||||
* @brief Executes one cycle of the PID control algorithm.
|
||||
* @param currentValue The current process variable (e.g., temperature) read from the input sensor.
|
||||
* @return The calculated control output (e.g., fan speed), clamped between 0.0 and 100.0.
|
||||
*/
|
||||
float execute(float currentValue) override;
|
||||
|
||||
// Add a getter for the sensor name
|
||||
/**
|
||||
* @brief Gets the name of the Modbus point used as the process variable input.
|
||||
* @return The description key of the input sensor point.
|
||||
*/
|
||||
std::string getInputSensorName() const { return _inputSensorName; }
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the Modbus point used as the setpoint.
|
||||
* @return The description key of the setpoint point.
|
||||
*/
|
||||
std::string getSetpointName() const { return _setpointName; }
|
||||
|
||||
// Add this virtual function to easily identify this strategy as a PID
|
||||
/**
|
||||
* @brief Identifies this strategy as a PID controller.
|
||||
* @return Always returns `true`.
|
||||
*/
|
||||
bool isPID() const override { return true; }
|
||||
|
||||
// ... (other methods like setSetpoint, setGains)
|
||||
/** @brief Updates the target setpoint for the PID controller. */
|
||||
void setSetpoint(float setpoint);
|
||||
/** @brief Sets the gains for the PID controller (Proportional, Integral, Derivative). */
|
||||
void setGains(float kp, float ki, float kd);
|
||||
/** @brief Manually sets the process variable (input) value. */
|
||||
void setInput(float input);
|
||||
|
||||
|
||||
private:
|
||||
// ... (PID variables like _kp, _ki, _kd, etc.)
|
||||
float _kp;
|
||||
float _ki;
|
||||
float _kd;
|
||||
unsigned long _lastTime;
|
||||
float _setpoint;
|
||||
float _input;
|
||||
float _lastError;
|
||||
float _integral;
|
||||
std::string _inputSensorName; // <-- Add this to store the name of our input
|
||||
std::string _setpointName; // <-- Add this to store the name of our input
|
||||
float _kp; /**< @brief Proportional gain. */
|
||||
float _ki; /**< @brief Integral gain. */
|
||||
float _kd; /**< @brief Derivative gain. */
|
||||
unsigned long _lastTime; /**< @brief Timestamp of the last calculation. */
|
||||
float _setpoint; /**< @brief The target value for the process variable. */
|
||||
float _input; /**< @brief The current value of the process variable. */
|
||||
float _lastError; /**< @brief The error from the previous calculation. */
|
||||
float _integral; /**< @brief The accumulated integral term. */
|
||||
std::string _inputSensorName; /**< @brief The description key for the input sensor point. */
|
||||
std::string _setpointName; /**< @brief The description key for the setpoint point. */
|
||||
};
|
||||
#endif
|
||||
@@ -46,6 +46,11 @@ float RampStrategy::execute(float currentValue) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a new target value for the ramp.
|
||||
* This allows the ramp's destination to be changed dynamically at runtime.
|
||||
* @param targetValue The new target value for the ramp.
|
||||
*/
|
||||
void RampStrategy::setTarget(float targetValue) {
|
||||
_targetValue = targetValue;
|
||||
}
|
||||
@@ -30,12 +30,18 @@ public:
|
||||
*/
|
||||
RampStrategy(float targetValue, float step, unsigned long interval);
|
||||
/**
|
||||
* @brief Executes the strategy to set the target setpoint in the ramp strategy.
|
||||
* @param targetValue The target value that is going to be set.
|
||||
* @brief Sets a new target value for the ramp.
|
||||
* This allows the ramp's destination to be changed dynamically at runtime.
|
||||
* @param targetValue The new target value for the ramp.
|
||||
*/
|
||||
void setTarget(float targetValue);
|
||||
/**
|
||||
* @brief Executes the strategy to get the next value in the ramp sequence.
|
||||
* @brief Calculates the next value in the ramp sequence towards a target.
|
||||
*
|
||||
* This method compares the current value to the target value and returns
|
||||
* the current value incremented or decremented by the step amount. To prevent
|
||||
* overshooting, if the next step would pass the target, it returns the target
|
||||
* value directly.
|
||||
* @param currentValue The current value, used to determine the next step.
|
||||
* @return The next value in the ramp sequence.
|
||||
*/
|
||||
|
||||
@@ -20,10 +20,18 @@
|
||||
SawStrategy::SawStrategy(float minValue, float maxValue, float step, unsigned long interval)
|
||||
: Strategy_Behavior(interval), _minValue(minValue), _maxValue(maxValue), _step(step) {}
|
||||
|
||||
/**
|
||||
* @brief Sets a new minimum value for the sawtooth wave.
|
||||
* @param minValue The new lower bound for the wave.
|
||||
*/
|
||||
void SawStrategy::setMinValue(float minValue) {
|
||||
_minValue = minValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a new maximum value for the sawtooth wave.
|
||||
* @param maxValue The new upper bound for the wave.
|
||||
*/
|
||||
void SawStrategy::setMaxValue(float maxValue) {
|
||||
_maxValue = maxValue;
|
||||
}
|
||||
|
||||
@@ -39,8 +39,16 @@ public:
|
||||
*/
|
||||
float execute(float currentValue) override;
|
||||
|
||||
/**
|
||||
* @brief Sets a new minimum value for the sawtooth wave.
|
||||
* @param minValue The new lower bound for the wave.
|
||||
*/
|
||||
void setMinValue(float minValue);
|
||||
|
||||
/**
|
||||
* @brief Sets a new maximum value for the sawtooth wave.
|
||||
* @param maxValue The new upper bound for the wave.
|
||||
*/
|
||||
void setMaxValue(float maxValue);
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
SingleValueStrategy::SingleValueStrategy(float setpoint, float noiseMagnitude, unsigned long interval)
|
||||
: Strategy_Behavior(interval), _setpoint(setpoint), _noiseMagnitude(noiseMagnitude) {}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets a setpoint value for the single value strategy.
|
||||
* @param setpoint The new setpoint target for the single value strategy.
|
||||
*/
|
||||
void SingleValueStrategy::setSetpoint(float setpoint) {
|
||||
_setpoint = setpoint;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* @file Strategy_SingleValue.h
|
||||
* @brief Defines the SingleValueStrategy class for setup a value with noise.
|
||||
* @brief Defines the SingleValueStrategy class for generating a value with random noise.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-05
|
||||
*
|
||||
* This file contains the definition for a behavior strategy that sets the
|
||||
* value to a setpoint and the generates simulates noise with a random number.
|
||||
* This file contains the definition for a behavior strategy that maintains a
|
||||
* value around a given setpoint by adding random noise.
|
||||
*/
|
||||
#ifndef SingleValue_strategy_h
|
||||
#define SingleValue_strategy_h
|
||||
@@ -13,32 +13,38 @@
|
||||
|
||||
/**
|
||||
* @class SingleValueStrategy
|
||||
* @brief A strategy that sets a value to a setpoint and generates noise around it.
|
||||
* @brief A strategy that generates a value that fluctuates around a setpoint.
|
||||
*
|
||||
* This class implements the Strategy_Behavior interface to produce a noise
|
||||
* pattern. Each time `execute` is called, it add a random number (+/-10) to
|
||||
* emulate noise around the value
|
||||
* This class implements the Strategy_Behavior interface to produce a value that
|
||||
* fluctuates around a central setpoint. Each time `execute` is called, it adds
|
||||
* a small, random amount of noise to the setpoint value.
|
||||
*/
|
||||
class SingleValueStrategy : public Strategy_Behavior {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new SquareStrategy object.
|
||||
* @param setpoiny Target value.
|
||||
* @param interval The time in milliseconds between each value toggle.
|
||||
* @brief Constructs a new SingleValueStrategy object.
|
||||
* @param setpoint The base value around which noise will be generated.
|
||||
* @param noiseMagnitude The maximum amount of noise to add or subtract.
|
||||
* @param interval The time in milliseconds between each value generation.
|
||||
*/
|
||||
SingleValueStrategy(float setpoint, float noiseMagnitude, unsigned long interval);
|
||||
|
||||
/**
|
||||
* @brief Executes the strategy to get the next random value around setpoint.
|
||||
* @brief Generates a new value by adding random noise to the setpoint.
|
||||
* @param currentValue The current value of the Modbus point (ignored in this strategy).
|
||||
* @return The next value in the sequence, either the lower or upper bound.
|
||||
* @return The setpoint with added random noise.
|
||||
*/
|
||||
float execute(float currentValue) override;
|
||||
|
||||
/**
|
||||
* @brief Sets a setpoint value for the single value strategy.
|
||||
* @param setpoint The new setpoint target for the single value strategy.
|
||||
*/
|
||||
void setSetpoint(float setpoint);
|
||||
|
||||
|
||||
private:
|
||||
float _setpoint;
|
||||
float _noiseMagnitude;
|
||||
float _setpoint; /**< @brief The setpoint for the single value strategy. */
|
||||
float _noiseMagnitude; /**< @brief The noise magnitude for the target value. */
|
||||
};
|
||||
#endif
|
||||
@@ -19,19 +19,28 @@
|
||||
SquareStrategy::SquareStrategy(float lowerValue, float upperValue, unsigned long interval)
|
||||
: Strategy_Behavior(interval), _lowerValue(lowerValue), _upperValue(upperValue) {}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Toggles between the upper and lower values on each execution.
|
||||
* @param currentValue The current value of the Modbus point (ignored).
|
||||
* @return The next value in the square wave sequence.
|
||||
* @brief Sets a new lower value for the square wave.
|
||||
* @param lowerValue The new lower bound for the wave.
|
||||
*/
|
||||
void SquareStrategy::setLowerValue(float lowerValue) {
|
||||
_lowerValue = lowerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a new upper value for the square wave.
|
||||
* @param upperValue The new upper bound for the wave.
|
||||
*/
|
||||
void SquareStrategy::setUpperValue(float upperValue) {
|
||||
_upperValue = upperValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles between the upper and lower values on each execution.
|
||||
* @param currentValue The current value of the Modbus point (ignored).
|
||||
* @return The next value in the square wave sequence.
|
||||
*/
|
||||
float SquareStrategy::execute(float currentValue) {
|
||||
_upState = !_upState;
|
||||
if(_upState){
|
||||
|
||||
@@ -34,7 +34,15 @@ public:
|
||||
* @return The next value in the sequence, either the lower or upper bound.
|
||||
*/
|
||||
float execute(float currentValue) override;
|
||||
/**
|
||||
* @brief Sets a new lower value for the square wave.
|
||||
* @param lowerValue The new lower bound for the wave.
|
||||
*/
|
||||
void setLowerValue(float lowerValue);
|
||||
/**
|
||||
* @brief Sets a new upper value for the square wave.
|
||||
* @param upperValue The new upper bound for the wave.
|
||||
*/
|
||||
void setUpperValue(float upperValue);
|
||||
|
||||
private:
|
||||
|
||||
@@ -10,12 +10,11 @@
|
||||
/**
|
||||
* @brief Constructs a new TotalizerStrategy object.
|
||||
*
|
||||
* Initializes the square wave strategy by passing the update interval to the
|
||||
* base Strategy_Behavior class and storing the lower and upper bounds.
|
||||
* Initializes the totalizer by passing the update interval to the base
|
||||
* Strategy_Behavior class and setting the initial value to a random number
|
||||
* between 0 and 1000.
|
||||
*
|
||||
* @param lowerValue The lower value of the square wave.
|
||||
* @param upperValue The upper value of the square wave.
|
||||
* @param interval The time in milliseconds between each value toggle.
|
||||
* @param interval The time in milliseconds between each increment.
|
||||
*/
|
||||
TotalizerStrategy::TotalizerStrategy(unsigned long interval)
|
||||
: Strategy_Behavior(interval) {
|
||||
@@ -24,9 +23,9 @@ TotalizerStrategy::TotalizerStrategy(unsigned long interval)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles between the upper and lower values on each execution.
|
||||
* @param currentValue The current value of the Modbus point (ignored).
|
||||
* @return The next value in the square wave sequence.
|
||||
* @brief Increments the totalizer's value on each execution.
|
||||
* @param currentValue The current value of the Modbus point (ignored in this strategy).
|
||||
* @return The new, incremented value. The value resets to 0 if it exceeds 60000.
|
||||
*/
|
||||
float TotalizerStrategy::execute(float currentValue) {
|
||||
_currentValue += 1;
|
||||
|
||||
@@ -1,42 +1,39 @@
|
||||
/**
|
||||
* @file Strategy_Square.h
|
||||
* @brief Defines the SquareStrategy class for generating a square wave pattern.
|
||||
* @file Strategy_Totalizer.h
|
||||
* @brief Defines the TotalizerStrategy class for simulating an accumulating value.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-05
|
||||
*
|
||||
* This file contains the definition for a behavior strategy that alternates
|
||||
* between a lower and an upper value, creating a square wave effect.
|
||||
* This file contains the definition for a behavior strategy that increments
|
||||
* a value at a regular interval, simulating a run-time counter or totalizer.
|
||||
*/
|
||||
#ifndef totalizer_strategy_h
|
||||
#define totalizer_strategy_h
|
||||
#include "Strategy_Behavior.h"
|
||||
|
||||
/**
|
||||
* @class SquareStrategy
|
||||
* @brief A strategy that alternates between a lower and an upper value on each execution.
|
||||
* @class TotalizerStrategy
|
||||
* @brief A strategy that increments a value on each execution.
|
||||
*
|
||||
* This class implements the Strategy_Behavior interface to produce a square wave
|
||||
* pattern. Each time `execute` is called, it toggles between returning the
|
||||
* `_lowerValue` and the `_upperValue`.
|
||||
* This class implements the Strategy_Behavior interface to produce a continuously
|
||||
* increasing value. Each time `execute` is called, it increments its internal
|
||||
* counter and returns the new value.
|
||||
*/
|
||||
class TotalizerStrategy : public Strategy_Behavior {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new SquareStrategy object.
|
||||
* @param lowerValue The lower value of the square wave.
|
||||
* @param upperValue The upper value of the square wave.
|
||||
* @param interval The time in milliseconds between each value toggle.
|
||||
* @brief Constructs a new TotalizerStrategy object.
|
||||
* @param interval The time in milliseconds between each increment.
|
||||
*/
|
||||
TotalizerStrategy(unsigned long interval);
|
||||
/**
|
||||
* @brief Executes the strategy to get the next value in the square wave.
|
||||
* @brief Executes the strategy to get the next incremented value.
|
||||
* @param currentValue The current value of the Modbus point (ignored in this strategy).
|
||||
* @return The next value in the sequence, either the lower or upper bound.
|
||||
* @return The new, incremented value.
|
||||
*/
|
||||
float execute(float currentValue) override;
|
||||
|
||||
private:
|
||||
float _currentValue; /**< @brief The lower bound of the square wave. */
|
||||
|
||||
float _currentValue; /**< @brief The current accumulated value of the totalizer. */
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user