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

Overview

In this tutorial, we will explore error handling during the initialization and operational phases of a HysteresisControl.
Error handling ensures the control system can detect, respond to, and recover from errors gracefully.

The process includes:

  • Detecting configuration errors in the initialize phase.
  • Handling runtime errors, such as BadQuality inputs, during the step phase.

The objectives of this tutorial are to:

  • Implement error handling during initialization to validate configurations.
  • Handle runtime errors during the operational phase using RunContext.

Step 1: Define the HysteresisControl Class

The HysteresisControl class implements a hysteresis-based temperature control system. It includes error handling during initialization for configuration validation and in the operational phase.

#pragma once
#include <xentara/cpp-control.h>
class HysteresisControl final : public xentara::Control
{
public:
/// Initializes the control and validates configuration parameters.
void initialize(xentara::InitContext &context) override;
/// Executes the main control logic and handles runtime errors.
void step(xentara::RunContext &context) override;
private:
/// Xentara-managed input data point for the temperature value
xentara::Float64Input temperature;
/// Xentara-managed output data point for the heater state
xentara::BooleanOutput heaterState;
/// Hysteresis thresholds
double lowerThreshold {0.0};
double upperThreshold {0.0};
};
An interface class which provides declaration of all the callbacks for this control.
Definition Control.hpp:19
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 Hysteresis Control

The JSON configuration file defines the data points for the control, along with the hysteresis thresholds.

{
"children": [
{
"@Skill.CPP.Control": {
"name": "Simple Hysteresis Temperature Control",
"UUID": "d95a4f25-4ccd-4496-a37f-aa9730a30633",
"controlPath": "libsimple-hysteresis-temperature-control.so",
"parameters": {
"lowerThreshold": 18.0,
"upperThreshold": 22.0,
"temperatureInput": "Temperature Input",
"heaterState": "Heater State"
}
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Temperature Input",
"UUID": "59a39dfb-b465-4849-a24d-dc3403030f1e",
"defaultValue": [ "float64", 20.0 ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Heater State",
"UUID": "af680196-9d8c-4c87-8a8f-4e92c9a351df",
"defaultValue": [ "bool", false ]
}
},
{
"@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": "Simple Hysteresis Temperature Control.step"
}
]
}
]
}
}
]
}
}
]
}

Step 3: Implement Error Handling Logic

The initialize method validates configuration parameters, and the step method handles runtime errors by checking the error in the RunContext.

#include "HysteresisControl.hpp"
#include <stdexcept> // For runtime_error
/// Registers the HysteresisControl with Xentara.
void HysteresisControl::initialize(xentara::InitContext &context)
{
// Initialize input and output data points
temperature = context.config().getDataPoint("temperature");
heaterState = context.config().getDataPoint("heaterState");
// Retrieve hysteresis thresholds
lowerThreshold = context.config().getDouble("lowerThreshold");
upperThreshold = context.config().getDouble("upperThreshold");
// Validate thresholds
if (lowerThreshold >= upperThreshold)
{
throw std::runtime_error("Invalid configuration: lowerThreshold must be less than upperThreshold.");
}
}
void HysteresisControl::step(xentara::RunContext &context)
{
// Read the current temperature value
auto currentTemperature = temperature.read(context);
// Check for errors while reading the input
if (context.error())
{
// Log the error or take an appropriate action (e.g., disable the heater)
heaterState.write(context, false); // Turn off the heater for safety
return; // Exit the step function
}
// Apply hysteresis control logic
if (currentTemperature < lowerThreshold)
{
heaterState.write(context, true); // Turn the heater ON
}
else if (currentTemperature > upperThreshold)
{
heaterState.write(context, false); // Turn the heater OFF
}
else
{
// Otherwise, maintain the current state
}
}
A class used to export your control class with Xentara.
Definition ControlExporter.hpp:38
auto config() const -> const Config &
Gets the configuration.
auto error() const -> std::error_code
Gets the error that occurred during read or write operations.

Conclusion

In this tutorial, we implemented error handling for the HysteresisControl:

  • The control validates configuration parameters during initialization to detect logical errors early.
  • It uses RunContext to detect and handle errors during the operational phase, ensuring safety and stability.

This approach ensures a robust and resilient control system capable of handling errors gracefully in industrial environments.