xentara-cpp-control v1.0.1
The Xentara C++ Control Framework
Loading...
Searching...
No Matches
Initialization

Overview

In this tutorial, we will explore the initialization phase of a control. Initialization is essential for setting up the control before it enters operation. This process includes:

  • Configuring data points and retrieving initial configuration parameters.
  • Preparing the control with necessary pre-run setups, such as resetting specific variables during the enterPreOp stage.

The objectives of this tutorial are to:

  • Understand the role of the initialization and enterPreOp phases.
  • Implement a PIDControl class with an initialize and enterPreOp method.
  • Configure data points, parameters, and reset pre-operational values.

What is PID Control?

PID (Proportional-Integral-Derivative) control is a widely used feedback control algorithm in industrial and control systems. It adjusts a control output based on the difference between a desired setpoint and the actual process variable. The algorithm uses three terms:

  1. Proportional Term (P): Reacts to the current error.
  2. Integral Term (I): Accounts for past errors.
  3. Derivative Term (D): Predicts future errors based on the rate of change.

PID control helps maintain a system at its setpoint by calculating the optimal control signal to minimize error over time.

Step 1: Define the PIDControl Class

The PIDControl class implements the initialization phase for a PID controller. During initialization, it sets up input and output data points and reads PID coefficients (Proportional, Integral, Derivative) from the configuration. Additionally, an accumulatedIntegral variable is introduced for managing the integral term of the PID controller, and it is reset during the enterPreOp stage.

#pragma once
#include <xentara/cpp-control.h>
class PIDControl final : public xentara::Control
{
public:
/// Initializes the control, setting up input and output data points and PID parameters.
void initialize(xentara::InitContext &context) override;
/// Executes the main control logic.
void step(xentara::RunContext &context) override;
/// Resets the accumulated integral during pre-operational stage.
void enterPreOp(xentara::RunContext &context) override;
private:
/// Xentara-managed input data points
xentara::Float64Input processVariable;
xentara::Float64Input setPoint;
/// Xentara-managed output data point for the control signal
xentara::Float64Output controlSignal;
/// PID parameters
double proportionalGain {0.0};
double integralGain {0.0};
double derivativeGain {0.0};
/// Accumulated integral value for the PID controller
double accumulatedIntegral {0.0};
};
An interface class which provides declaration of all the callbacks for this control.
Definition Control.hpp:19
virtual auto enterPreOp(RunContext &context) -> void
Called by the framework at the beginning of the pre-operational stage.
virtual auto initialize(InitContext &context) -> void=0
Callback that is called by the framework to initialize the control object.
virtual auto step(RunContext &context) -> void=0
Main callback responsible for executing the core control logic.
An initialization context with configuration information and access to Xentara Elements.
Definition InitContext.hpp:35
An run context with execution information and is required for the read and write for Input and Output...
Definition RunContext.hpp:46

Step 2: JSON Configuration for Initialization

The JSON configuration file defines the control's data points and parameters for the initialization phase.

{
"children": [
{
"@Skill.CPP.Control": {
"name": "PID Control",
"UUID": "5f6a7b8c-9d10-4e3f-8b5c-d2a7f3e6c5d4",
"controlPath": "lib-pid-control.so",
"parameters": {
"processVariable": "Process Variable",
"setPoint": "Set Point",
"controlSignal": "Control Signal",
"proportionalGain": 1.0,
"integralGain": 0.1,
"derivativeGain": 0.01
}
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Process Variable",
"UUID": "8bc4ffc2-eac5-4c36-86f8-c4d2899233f4",
"defaultValue": [ "float64", 0.0 ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Set Point",
"UUID": "46cf7f96-ab8f-4ab5-8c41-0d6407303fe6",
"defaultValue": [ "float64", 100.0 ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Control Signal",
"UUID": "42b9e84b-547e-4b2f-85f6-f3f6896d6d6c",
"defaultValue": [ "float64", 0.0 ]
}
},
{
"@Track": {
"name": "Control Track",
"UUID": "fb0a26f8-7d84-4af9-9345-4145263d09c7",
"children": [
{
"@Timer": {
"name": "Timer",
"UUID": "e6580c24-dbf9-43a0-aa81-c5ed8da6f734",
"period": "50ms"
}
},
{
"@Pipeline": {
"name": "Pipeline",
"UUID": "040f156e-2744-4008-8195-cd7f17078668",
"triggers": [
"Control Track.Timer.expired"
],
"checkpoints": [
{},
{}
],
"segments": [
{
"start": 0,
"end": 1,
"tasks": [
{
"function": "PID Control.step"
}
]
}
]
}
}
]
}
}
]
}

Note
In this example, @Skill.SignalFlow.Register is used for simplicity. However, for real-world control systems, other skills like EtherCAT, Modbus, or OPC UA should be used to interface with actual devices and sensors. Choose the appropriate skill based on the hardware and communication protocols in your system.

Step 3: Implement the Initialization Logic

The initialize method sets up the control's data points and retrieves PID coefficients from the configuration. The enterPreOp method resets the accumulatedIntegral value to ensure a clean state before entering the operational phase.

#include "PIDControl.hpp"
/// Registers the PIDControl with Xentara.
void PIDControl::initialize(xentara::InitContext &context)
{
// Initialize input and output data points using the context configuration
processVariable = context.config().getDataPoint("processVariable");
setPoint = context.config().getDataPoint("setPoint");
controlSignal = context.config().getDataPoint("controlSignal");
// Retrieve PID parameters from configuration
proportionalGain = context.config().getDouble("proportionalGain");
integralGain = context.config().getDouble("integralGain");
derivativeGain = context.config().getDouble("derivativeGain");
}
void PIDControl::enterPreOp(xentara::RunContext &context)
{
// Reset the accumulated integral to ensure a clean state
accumulatedIntegral = 0.0;
}
void PIDControl::step(xentara::RunContext &context)
{
// Placeholder for PID control logic (to be implemented later)
}
A class used to export your control class with Xentara.
Definition ControlExporter.hpp:38
auto config() const -> const Config &
Gets the configuration.

Conclusion

In this tutorial, we implemented the initialization phase for a PIDControl. This included setting up input and output data points, retrieving configuration parameters, and resetting the accumulatedIntegral variable during the enterPreOp stage to ensure a clean state. Initialization ensures the control is correctly configured and ready for operation, preventing errors during runtime.