Intro 3: Tutorial of Making Reusable Objects in C++
Intro 3: Tutorial of Making Reusable Objects in C++
This tutorial gives you an introduction to how to create your own components (objects) to create specific functional blocks that you can use in your projects. These components are made in libraries.
This tutorial shows
- What are libraries and how to create them
- How to write your own components (function blocks)
- How components are executed (run) in parallel and in real-time
- How to use your components in a project
This is the step-by-step guide to creating the example Intro 3: Make Reusable Objects in C++. The project files are found in the Examples section in Welcome mode
By completing the tutorial, you will have been through the steps to create a library and create your own components.
Recommended: See first Intro 2: Setting Up IO for REST.
Project Overview
In this tutorial we will develop our own component ConvertNegativeValue that converts a negative number to a positive number. We use the pre-made Sine component, a sine generator, to generate the value to be converted. The output from our component is used in a system to convert the sine curve to only have positive values. The sine curve and the converted sine curve are plotted using the Signal Graph widget.
Project Description
The real-time component ConvertNegativeValue is created in a library (MyFirstLibraryTutorial) and has 2 CDPSignals: InputValue and ConvertedValue. The fs (frequency) property is automatically created for all components. The component acts like a rectifier, converts negative InputValue to a positive ConvertedValue (multiply with -1). When the library is built, the component will become available in the Resource tree in Configure mode.
Note: For simple function blocks like the one in this example, we recommend to do the implementation as a CDPOperator and not as a CDPComponent. General recommendation is to use CDPOperator for simple functions that only have input/output signals. CDPComponents are used when there is more complex behaviour, require state machines or it makes sense for the component to have its own processing frequency.
The Signal Graph widget plots the changing ConvertedValue over time, showing a rectified sine curve.
The ConvertNegativeValue component is by default set to run with the frequency (fs) of 5 times a second, i.e. every 200 ms. The sine is in parallel running with fs=100, i.e. the sine Output is updated every 10 ms, but the ConvertNegativeValue is only converting the value every 200 ms. This is visible in the plotted sine curve as a stepped line (staircase). Note that the GUI is by default running on fs=30 so increasing the fs any higher for ConvertNegativeValue will not have a visible effect in the GUI.
Creating the Library and Component
Reusable components (objects) are created in libraries and when the library is built, the components appear as a resource in the Resource tree.
First step in making a reusable component is to create a library.
- From the 'File' menu, select 'Create New...' or click on the "New Project" button on the Welcome mode
- In the Wizard that pops up, select 'CDP' under "Projects", then 'CDP Library' and click on 'Choose...'
- Name the library 'MyFirstLibraryTutorial', then click on 'Next >'
- Select the most recent version, then click on 'Finish'
- Open the Deploy Configuration tab and ensure that the Toolkits checkbox is ticked for your PCs operating system (Windows x86 or Linux)
The library is now created and we can create our reusable components.
- From the 'File' menu, select 'Create New...' or hover the mouse over 'MyFirstLibraryTutorial' and right click and select 'Add New'
- In the Wizard that pops up, select 'CDP' under Files and Classes, then 'CDP Component Model' and click on 'Choose...'
- Just select 'Next >' to use the default library path
- Name the component 'ConvertNegativeValue', then click on 'Next >'
- Just select 'Finish' to use the default values for project management and to create the component
CDP Studio will take you to Code mode, you may also navigate to the C++ file by selecting Code mode, double click on 'MyFirstLibraryTutorial', double click on "Sources" and double click on 'ConvertedNegativeValue.cpp'.
Important Concepts to Understand: Components
CDP comes with the complete Framework for running systems. This means that you focus on creating function blocks (CDPComponents) (see Basics: Architecture) and not the overall system when you develop new functionality and logic. You develop the components in Libraries using Code mode.
When adding CDP Component, CDP Studio automatically generates code for the functions, include files, initializations (simplifying the process of writing the code). Components are written using C++ and since the functions shell is auto-generated, only the logic has to be added. CDP objects like Signals/Parameters/Alarms are added from menus/wizards, and all required C++ code is again auto-generated.
A Component is always created with a ProcessNull function, and if you do not wish to use a state machine, this is where you write your code (the ProcessNull function will be called regularly at specified fs). Remember not to do blocking operations/length tasks in the Process-function(s), see paragraph Overview - Control Design Platform.
All components in a CDP System are executed (run) in parallel at a specified frequency and priority. The frequency specifies how many times the component is run per second and the frequency is set for each instance of the component. See also CDPComponent Description and Best Practice of System Design.
Creating the actual system, i.e. the interaction between components and a GUI is done in Configure mode without any coding.
You may have many components in a library and many libraries.
The Components
A component contains the code you write, and you may add CDP objects such as signals, messages, parameters, alarms, properties and state machine, see CDP Component.
There are 2 types of components:
- For Real-time tasks: CDP Component
- For Asynchronous (lengthy) tasks: Threaded Component
A component is a self-contained, independent function block that is truly reusable in projects. They become part of your company toolbox. When the library is built successfully, all the components in the library become available as Resources for all projects in Configure mode for the toolchains the library is built for.
Writing the Component Logic
CDP Studio automatically creates the complete C++ framework, functions and necessary model files. There is help text that explains what the different pre-made functions do.
Now we can create the logic or function that our component shall execute. In this tutorial, the component shall convert a negative input to a positive output value.
We will use the Wizard to create the input and output signal.
- In the 'ConvertNegativeValue.cpp' source file, right click anywhere in the source file window.
- Select 'CDP' -> 'Add' -> 'Signal'
- In the pop-up window, name the signal 'InputValue', check the 'Input' and 'Create Another' box and click on 'OK'. This creates an input signal.
- In the refreshed box, name the signal 'ConvertedValue', uncheck the 'Input' and 'Create Another' box and click on 'OK'. This creates an output signal. The required C++ code is automatically generated for the 2 signals.
- Locate the 'void ConvertNegativeValue::ProcessNull()' function (normally at the end of the file).
- Below the '/* Write your code here */' help text add the C++ code:
if (InputValue < 0) ConvertedValue = -1*InputValue; else ConvertedValue = InputValue;
Building the Component
The library and component is now created and is ready to be built. Building the library compiles the C++ code and adds the library and component to the Resource tree. In this way, 'ConvertNegativeValue' becomes a reusable component that can be used in any project.
To build the library: in Configure mode, right click on your library project 'MyFirstLibraryTutorial' and select Build. For more information on building libraries see Running an Example
Creating the System and Application
Now we are ready to create our project, the first step is to create the system and then the application.
Create a system named MyFirstComponentTutorial using the pre-selected recent toolkit version, and make sure to add a GUI application called MyFirstComponentTutorialApp. For details on creating a system, see Intro 1: Connect Variables to HMI GUI or How to Create a System.
Add the Components to the Application and Connect the Components
This example combines the component we created with a pre-made system component 'Sine'. These components are added by:
- In Configure mode select MyFirstComponentTutorialApp from the Project tree
- In the Resource tree, expand CDPCore
- Locate Sine in the Resource tree and double-click it to add the sine component
- In the Resource tree, expand MyFirstLibraryTutorial
- Locate ConvertNegativeValue in the Resource tree and double-click on it to add it to MyFirstComponentTutorialApp
We now need to connect the sine Output signal to the 'ConvertNegativeValue' InputValue signal.
- In Configure mode, open the Block Diagram tab and hover the mouse over the coloured circle to the right of the Output signal in the Sine component
- Click and hold the left mouse button and drag the mouse over to the coloured cirle to the left of InputValue in the ConvertNegativeValue component
- Release the left mouse button to complete the routing.
Creating the Graphical User Interface (GUI)
GUIs are made in the CDP Studio Design mode and CDP Studio comes with a large set of pre-made widgets. This tutorial use the Signal Graph widget to show the sine output and ConvertedValue, the label and line edit widgets to display a text and to change the frequency the ConvertNegativeValue is executed. All widgets can be extensively styled and customised, but in this example we only use some basic styling.
Place and resize the widgets as shown here:
Follow the steps below to create the GUI:
- Go to Configure mode and select MyFirstComponentTutorialApp in the Project tree
- Click on Design mode to go into the GUI editor
- In the resource-list to the left, find the widget named Label and drag it into the form
- Select the Label in the form by clicking on it
- In the Properties window, set the following properties: text=Set Frequency of component
- In the resource-list to the left, find the widget named Line Edit and drag it into the form
- In the Properties window, set the following properties: cdpRouting=MyFirstComponentTutorialApp.ConvertNegativeValue.fs , precision=0 and uncheck cdpPromptForChanges
- Find the widget named Signal Graph and drag it into the form, remember to resize it vertically to see the y-axis
- In the Properties window, locate the property cdpSignals and click on the "Value" field , then click on the button "Change String List" and a dialog window will open
- Click "New" and set value to MyFirstComponentTutorialApp.ConvertNegativeValue.ConvertedValue
- Click again to "New" and set value to MyFirstComponentTutorialApp.Sine.Output and click on "OK"
- Now set other properties: plottingMode=Scrolling, yAxisMinValue=-1
How to Run the Tutorial
To run the tutorial from CDP Studio, select Configure mode, right-click on the system project and select Run & Connect. See the Running and Connecting to the System tutorial for more information.
Inspect Real-time Info and Plot Values
A very useful feature is the possibility to see, in real time, all values in the table format and to plot values changes in a graph. This is very useful when testing, analyzing, tuning and searching for possible issues in a system.
After selecting Run & Connect, you will be connected to the running system. Select a component in Configure mode and you will see that the values change in real-time.
Visualizing the values in a graphical plot is done in Analyze mode as is described in the Analyze Mode Manual.
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.