Documentation updated

This commit is contained in:
2025-09-15 09:19:13 -05:00
parent ac20b82496
commit 5a0b02ccdf
41 changed files with 673 additions and 377 deletions

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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.
*/

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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){

View File

@@ -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:

View File

@@ -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;

View File

@@ -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