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

Overview

In this tutorial, we will explore the complex initialization of a control, focusing on preparing a servo motor for operation.

The process includes:

  • Setting the initialization flags in the enterPreOp phase.
  • Performing checks in the enterOperational phase to confirm readiness for operation.

The initialization process ensures that the servo motor is safely and correctly configured before entering the operational phase.

The objectives of this tutorial are to:

  • Implement a control class for a servo motor with complex initialization requirements.
  • Use the enterPreOp phase to configure the initialization flags.
  • Perform readiness checks during the enterOperational phase to confirm the system's operational state.

Step 1: Define the ServoMotorControl Class

The ServoMotorControl class handles the initialization and control of a servo motor. It includes multiple flags for the initialization process, which are set and verified sequentially in the enterPreOp phase. It includes multiple flags for initialization and implements readiness checks during the enterOperational phase.

#pragma once
#include <xentara/cpp-control.h>
class ServoMotorControl final : public xentara::Control
{
public:
/// Initializes the control and sets up data points.
void initialize(xentara::InitContext &context) override;
/// Handles pre-operational initialization, setting up and verifying servo motor flags.
void enterPreOp(xentara::RunContext &context) override;
/// Checks readiness before entering the operational stage.
void enterOperational(xentara::RunContext &context) override;
/// Executes the main control logic.
void step(xentara::RunContext &context) override;
private:
/// Xentara-managed output data points for servo motor flags
xentara::BooleanOutput resetFault;
xentara::BooleanOutput releaseBrake;
xentara::BooleanOutput enableVoltage;
xentara::BooleanOutput enableCurrent;
xentara::BooleanOutput enableOperationState;
/// Xentara-managed output data points for servo motor flags status
xentara::BooleanOutput faultStatus;
xentara::BooleanOutput releaseBrakeStatus;
xentara::BooleanOutput enableVoltageStatus;
xentara::BooleanOutput enableCurrentStatus;
xentara::BooleanOutput enableOperationStateStatus;
};
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.
virtual auto enterOperational(RunContext &context) -> void
Called by the framework once at the conclusion of the pre-operational stage, just before entering int...
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 Flags

The JSON configuration file defines the data points for each flag required to initialize the servo motor.

{
"children": [
{
"@Skill.CPP.Control": {
"name": "Servo Motor Control",
"UUID": "8f9a0b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c",
"controlPath": "libservo-motor-control.so",
"parameters": {
"releaseBrake": "Servo Motor.Release Brake",
"releaseBrakeStatus": "Servo Motor.Release Brake Status",
"enableVoltage": "Servo Motor.Enable Voltage",
"enableVoltageStatus": "Servo Motor.Enable Voltage Status",
"enableCurrent": "Servo Motor.Enable Current",
"enableCurrentStatus": "Servo Motor.Enable Current Status",
"enableOperationState": "Servo Motor.Enable Operation State",
"enableOperationStateStatus": "Servo Motor.Enable Operation State Status",
"resetFault": "Servo Motor.Reset Fault",
"faultStatus": "Servo Motor.Fault Status"
}
}
},
{
"@Group": {
"name": "Servo Motor",
"UUID": "a22b1f0a-bb18-4a76-9acf-ba663f5e24a5",
"children": [
{
"@Skill.SignalFlow.Register": {
"name": "Release Brake",
"UUID": "324c6b50-da95-4d4b-b4c9-db0850340197",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Release Brake Status",
"UUID": "0d71d754-a3d9-4fd4-893c-cbb3a795a3e1",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Enable Voltage",
"UUID": "4c6c288a-3476-440b-941d-d567cf895d02",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Enable Voltage Status",
"UUID": "a385e3de-499f-4fb6-8453-eba3de05b9f4",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Enable Current",
"UUID": "e69aa889-1ff1-4ac6-bb83-1419ff17e357",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Enable Current Status",
"UUID": "d82a7643-9be6-40a8-88fd-753e89ffbea9",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Enable Operation State",
"UUID": "3f632bd8-ce96-4b05-b788-c45598d425ec",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Enable Operation State Status",
"UUID": "840c2157-b966-41a0-b0a7-765daa9d7434",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Reset Fault",
"UUID": "ad727673-98b0-47a2-9f40-3a014c0c0e5b",
"defaultValue": [ "bool", false ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Fault Status",
"UUID": "2c38b0a2-9a3a-48d4-86a8-402f829775db",
"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": "Servo Motor Control.step"
}
]
}
]
}
}
]
}
}
]
}

Note
The @Skill.SignalFlow.Register skill is used for simplicity in this example. For real-world systems, other skills like EtherCAT, Modbus, or OPC UA should be used depending on the communication protocol supported by the servo motor.

Step 3: Implement the Initialization Logic

The initialize method configures the data points for setting the flags and their corresponding status data points for verification. The enterPreOp phase sets and verifies the flags, while the enterOperational phase performs readiness checks using the status data points.

#include "ServoMotorControl.hpp"
/// Registers the ServoMotorControl with Xentara.
void ServoMotorControl::initialize(xentara::InitContext &context)
{
// Configure output data points for servo motor flags
resetFault = context.config().getDataPoint("resetFault");
releaseBrake = context.config().getDataPoint("releaseBrake");
enableVoltage = context.config().getDataPoint("enableVoltage");
enableCurrent = context.config().getDataPoint("enableCurrent");
enableOperationState = context.config().getDataPoint("enableOperationState");
// Configure status data points for readiness checks
releaseBrakeStatus = context.config().getDataPoint("releaseBrakeStatus");
enableVoltageStatus = context.config().getDataPoint("enableVoltageStatus");
enableCurrentStatus = context.config().getDataPoint("enableCurrentStatus");
enableOperationStateStatus = context.config().getDataPoint("enableOperationStateStatus");
faultStatus = context.config().getDataPoint("faultStatus");
}
void ServoMotorControl::enterPreOp(xentara::RunContext &context)
{
// Set flags to initialize the servo motor
resetFault.write(context, true);
releaseBrake.write(context, true);
enableVoltage.write(context, true);
enableCurrent.write(context, true);
enableOperationState.write(context, true);
}
void ServoMotorControl::enterOperational(xentara::RunContext &context)
{
// Perform readiness checks for the operational phase
if (!releaseBrakeStatus.read(context))
{
// handle error for Readiness check failed - 'Release Brake Status' flag is not set.
}
if (!enableVoltageStatus.read(context))
{
// handle error for Readiness check failed - 'Enable Voltage Status' flag is not set.
}
if (!enableCurrentStatus.read(context))
{
// handle error for Readiness check failed - 'Enable Current Status' flag is not set.
}
if (!enableOperationStateStatus.read(context))
{
// handle error for Readiness check failed - 'Enable Operation State Status' flag is not set.
}
if (faultStatus.read(context))
{
// handle error for Readiness check failed - 'Fault Status' flag is unexpectedly set.
}
}
void ServoMotorControl::step(xentara::RunContext &context)
{
// Placeholder for servo motor 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 a complex initialization process for a servo motor with separate status data points for readiness checks. The process included:

  • The enterPreOp phase sets each initialization flag.
  • The enterOperational phase confirms that all status flags are in their expected states before transitioning to the operational phase.

This implementation guarantees that the servo motor is correctly initialized and ready for operation.