Tango Controls Logo
latest
  • Welcome to Tango Controls documentation!
    • How this documentation is organized
    • Indices and tables
  • Authors
    • Acknowledgements
  • Overview
    • Introduction
    • Overview of Tango Controls
      • What is Tango Controls
      • Tango Technologies
      • Tango Community
    • Simplified Tango Device Server Model
      • Primary Presentation
      • Elements
      • Attributes
      • Relations
    • Ecosystem
    • History
  • Installation
    • Overview
      • What is Tango Controls
        • Tango Host Role
        • Tango development Role
        • Tango applications Role
        • Tango device servers Role
        • Every roles
      • Single computer
      • Multiple computers
      • Multiple control systems
      • No database
    • Source Code
    • Linux
      • Debian + Ubuntu
        • Non-interactive installation
        • Other packages
      • CentOS
        • Installation
      • Video
      • Testing
    • Windows
      • Tango package installation
      • Tango Host role
      • Running Device Servers
      • What’s next
      • Typical issues
    • Raspberry Pi
      • Installation with database
      • Installation without database
    • Amazon Cloud
      • TangoBox 9.3 AMI
        • SSH access
        • Remote Desktop
      • Previous version
    • Virtual Machine
      • TangoBox 9.3
        • Minimum Requirements
        • TangoBox 9.3 on the Amazon cloud
      • Previous versions
        • TangoBox 9.2
        • Elder versions
    • PyTango and Taurus on Windows
    • Binary packages
    • Patches
      • omniORB patches
      • Version 9.3.4 source patches
      • Version 9.2.2 source patches
      • Version 9.1.0 source patches
      • Version 8.1.2 source patches
      • Version 8.0.5 source patches
  • Getting Started
    • First steps with Tango Controls
    • End-user applications guide
      • Jive
      • ATKPanel
      • LogViewer
    • How to develop for Tango Controls
      • Getting started with JTango (Java implementation of Tango-Controls)
        • Developing your first Java TANGO client
        • Developing your first Java TANGO device class
      • Getting started with cppTango (C++ implementation of Tango-Controls)
        • Writing your first C++ TANGO client
        • TANGO C++ Quick start
        • Your first C++ TANGO device class
      • Getting started with PyTango (Python implementation of Tango-Controls)
        • Developing Python TANGO device class
    • Administration applications guide
      • Astor
      • Jive
      • LogViewer
      • Tango Database
      • Installation
  • Developer’s Guide
    • Overview
      • C++ and Python
      • Java
    • General guidelines
      • Tango object naming (device, attribute and property)
        • Device name
        • Full object name
        • Device and attribute name alias
        • Reserved words and characters, limitations
    • 10 things you should know about CORBA
    • Tango Client
      • Writing a TANGO client using TANGO C++ APIs
        • Introduction
        • Getting Started
        • Basic Philosophy
        • Data types
        • Request model
        • Events
        • Group
        • Reading/Writing device pipe
        • Device locking
        • Reconnection and exception
        • Thread safety
        • Compiling and linking a Tango client
      • TangoATK Programmer’s Guide
        • Introduction
        • The key concepts of TangoATK
        • The real getting started
        • The key objects of TangoATK
      • PyTango - a Python binding to Tango
    • Device Servers
      • Introduction to device server
      • TANGO Device Server Guidelines
        • Guidelines
        • Tango Concepts
        • Tango Device Design
        • Tango device implementation
        • Appendices
      • The TANGO device server model
        • Introduction to CORBA
        • The model
        • The device
        • The server
        • The Tango Logging Service
        • The database
        • The controlled access
        • The Application Programmers Interfaces
      • Writing a TANGO device server
        • The device server framework
        • Exchanging data between client and server
        • The Tango Logging Service
        • Writing a device server process
        • Device server under Windows
        • Compiling, linking and executing a TANGO device server process
        • Advanced programming techniques
      • Attribute alarms
        • The level alarms
        • The Read Different than Set (RDS) alarm
      • Enumerated attribute
        • Usage in a Tango class
        • Usage in a Tango client
      • Memorized attribute
      • Forwarded attribute
        • Definition
        • Coding
      • Device polling
        • Introduction
        • Configuring the polling system
        • Reading data from the polling buffer
        • Retrieving command/attribute result history
        • Externally triggered polling
        • Filling polling buffer
        • Setting and tuning the polling in a Tango class
      • Generating events in a device server
      • Tango Device in Java
      • PyTango - a Python binding to Tango
    • Debugging and Testing
      • Using Tango docker containers
        • Tango docker containers
        • Extending existing containers
    • Advanced
      • Threading
        • Device server process
        • Client process
      • Transferring images
      • Device server with user defined event loop
      • Tango Device Server Model
        • Primary Presentation
        • Elements
        • Attributes
        • Relations
        • Rationale
      • Tango REST API
        • Tango REST API specification
        • Tango REST API implementations
        • Deployment
        • Further steps
        • References
      • The TANGO IDL file : Module Tango
        • Aliases
        • Enums
        • Structs
        • Unions
        • Exceptions
        • Interface Tango::Device
        • Interface Tango::Device_2
        • Interface Tango::Device_3
        • Interface Tango::Device_4
        • Interface Tango::Device_5
      • Reference part
        • Device parameter
        • Device attribute
        • Device pipe
        • Device class parameter
        • The device black box
        • Automatically added commands
        • DServer class device commands
        • DServer class device properties
        • Tango log consumer
        • Control system specific
        • C++ specific
        • Device server process option and environment variables
      • Known issues
        • Tango 9
        • Tango 8
    • Tango Core C++ Classes Reference Documentation
    • Contributing
      • How to work with Tango Controls documentation
        • About this documentation
        • Updating the documentation
        • Sources structure
        • Configuration
      • How to contribute to Tango Controls C++ library (cppTango)
        • Workflow
        • reStructuredText and Sphinx
        • Releasing a new version
  • Tools and Extensions
    • Built-in tools
      • Astor (TANGO Manager)
        • Introduction to Astor
        • Astor Main Window
        • Host Status Window
        • Add a new controlled host
        • Start a new server with Astor
        • New Server Wizard
        • Multi Servers Start/Stop
        • Tree Branch Management
        • Astor Configuration
        • Event Manager
        • Polling Management
        • Server Statistics
        • Reset statistics:
        • Server TANGO versions
        • Tango Access Control (TAC) Configuration
        • Features overview
        • ICALEPCS 2011 paper
      • Jive
        • Contents
      • ATKPanel
        • ATKPanel
        • Overview
        • Device testing
        • Trends
        • Error History
        • Diagnostics
        • Preferences
      • Pogo (Class Generator)
        • Introduction
        • Starting with Pogo
        • Generated files
        • Inheritance Management
        • Preferences
        • Dynamic Attributes
        • Multiple C++ Classes Manager
        • Tango Server Packaging
        • Pogo-6 Compatibility
      • Synoptic and JDraw
        • Test the synoptic : “Tango Synoptic view”
        • Jdraw editor
        • Include the Synoptic in an ATK application
        • Predefined run time behavior
      • Tango Application Toolkit “ATK”
        • Tango ATK Tutorial
        • ATK Java documentation
      • LogViewer
        • LogViewer
        • Overview
        • Adding devices
        • Actions menu
        • Loading logs from files
    • GUI building
      • Taurus (Python GUI library)
      • QTango
    • Web tools
      • Canone
        • Introduction
        • Requirements
        • Download
        • Panels
        • Panel Configuration
        • Widgets
        • Widget Configuration
        • Users
        • User Login
        • Permissions
        • Administration
        • Communications
        • A side-effect: SOAP
        • The TODO list
        • FAQ
      • Waltz
    • Archiving
      • Overview
      • HDB
        • Mambo User Manual
      • HDB++
        • Target
        • Primary Presentation
        • Elements
        • Source code
        • Documentation for building and installing
        • Rationale
        • Presentations and papers
      • SNAP
        • SNAPshot (Archiving) installation and configuration
        • Bensikin User Manual
    • Bindings
      • Overview
      • C Language
      • Matlab & Octave
      • LabVIEW
      • Igor Pro
      • Panorama
      • Tango REST API
        • Tango REST API specification
        • Tango REST API implementations
        • Deployment
        • Further steps
        • References
    • Other tools
      • PANIC Alarm System
  • Administration
    • Overview
    • Deployment
      • Starting a Tango control system
        • Without database
        • With database
        • With database and event
        • With file used as database
        • With file used as database and event
        • With the controlled access
      • The Starter device
        • Introduction
        • Installation
        • Configuration
        • Usage
        • Autostarting Starter
        • References
      • Running a device server without SQL database
        • Device server using file as database
        • Device server without database
      • Multiple database servers within a Tango control system
      • The property file syntax
        • Property file usage
        • Property file syntax
      • High Availability
        • Tactics to improve the availability
      • Tango Controls versions in use
    • Services
      • Event system
        • Using multicast protocol to transfer events
        • Events in Tango releases lower than 8
      • The Tango controlled access system
        • User rights definition
        • Running a Tango control system with the controlled access
      • HDB++ - an archiving/historian service
        • HDB++ Design and implementation
    • Maintenance
      • Tango Admin utility
        • Using tango_admin
  • Tutorials and How-Tos
    • Tutorials
      • Documentation, how to contribute
        • Prerequisites
        • Sphinx installation
        • Get documentation sources
        • Updating documentation
        • Committing changes
        • Pushing (to the GitHub repository)
        • Pull request (asking for merge)
        • Continuing the contribution
      • Waltz (ex. TangoWebapp) installation tutorial (Windows)
      • Scada introduction with TANGO examples
      • Snapshots from TANGO labs at the ESRF
      • TANGO as CS course in Uni
      • Write a TANGO device class for an Arduino temperature sensor
      • General TANGO training for C++
      • General TANGO training for Python
    • HOW-TOs
      • How to cross compile omniORB
      • How to create inheritance link between Tango classes (C++)
        • The example case
        • The HighLevelClass.h file
        • The HighLevelClass.cpp file
        • The HighLevel.h file
        • The HighLevel.cpp file
        • Defining the class in the Tango control system
        • Running your class
        • Conclusion
      • How to deal with string Tango attribute (C++)
        • Scalar attribute - static allocation
        • Scalar attribute - dynamic allocation
        • Spectrum / Image attribute - static allocation
        • Spectrum / Image attribute - dynamic allocation
        • Conclusion
      • How to reconnect Database at device server startup time
      • How to distinguish clients on the server side
        • Problem overview
        • Detailed cases
        • Solution overview
        • Java:
        • CPP:
        • Python:
      • How to add dynamic attributes to a device class
        • Creating new attributes at Startup
        • Generating your class with Pogo
        • Implementing the Dynamic Attributes
        • Running the server
        • Conclusion
      • How to extract read and set values from a scalar attribute
      • How to Fandango
        • fun4tango, functional programming for Tango
        • Downloading
        • Features
        • Main Classes
        • Where it us used
        • Requirements
        • Recipes
      • How to write your first Device Class
        • Start Pogo Generator
        • Fill in your Class
        • Generate
        • Compile And Run
      • How to import multiple device classes to the Catalogue
        • Requirements
        • How-to import multiple classes
        • How the script works
      • Integrate Java Tango servers with Astor
        • Problem overview
        • Detailed cases
        • Solution overview
      • Tango with systemd integration
      • How to PyTango
        • Before anything else
        • Installation notes
        • Using the DeviceProxy object
        • Device Server Internal Objects
        • Using Database Object
        • Useful constants and enums
        • Using Tango Groups
        • About Exceptions
        • Passing Arguments to Device command_inout
        • Using asynchronous commands
        • Setting Attribute Config
        • Porting device servers to PyTango
      • PyTangoArchiving Recipes
        • Installing PyTangoArchiving:
        • Accessing MySQL:
        • Download
        • Submodules
        • General usage
        • Using the Python API
        • Using CSV files
      • How to run a device server with an active Windows firewall
      • How to run device servers on Windows XP with IPv6
      • How to start a device server
        • How to start a device server
        • Starting device servers with Jive
        • Starting device servers with Astor
        • Other options
      • How to try Tango Controls
        • Installation notes on Linux base distribution OS
        • Running the Tango System
        • Installation on CentOS
        • Play with Tango Controls
      • Using Tango servers without DB for unit testing
        • Problem overview
        • Detailed cases
        • Solution overview
        • Java:
        • CPP:
        • Python:
      • How to tune polling by code in a TANGO class
        • In C++
        • In Python
        • In Java
      • How to use vectors to set attributes
  • Reference
    • Map Key
      • Acknowledgements
      • Making Modifications
    • Glossary
    • Bibliography
Tango Controls
  • Docs »
  • Tutorials and How-Tos »
  • HOW-TOs »
  • How to create inheritance link between Tango classes (C++)
  • Edit on GitHub

How to create inheritance link between Tango classes (C++)¶

Intended audience: developers, Programming language: c++

This HowTo explains how it is possible to create a new Tango class which inherits from an already existing Tango class.

In Tango’s vocabulary, a Tango class is not a computer language class. A Tango class has at least 2 computer language classes and very often even more than 2. This HowTo explains how you can create a new Tango class which “inherits” from an already existing class. In this case, inheritance means:

  1. The high level class supports all the commands defined in the low level class on top of its own commands (if any),
  2. The high  level class supports all the attributes defined by the low leval class on top of its own attributes (if any),
  3. The device(s) available for the external world is(are) an instance(s) of the high level class.

Warning

Once modified, Pogo will not be able to understand the high level Tango class and therefore can’t be used for further changes in this class

The example case¶

Let’s say that we already have a Tango class called LowLevel with one command called LowLevelCmd and one attribute called LowLevelAttr. We want to create a new Tango class called HighLevel with its own command called HighLevelCmd and its own attribute called HighLevelAttr. Both classes has been generated using Pogo. The following is a description of what has to be modified in the code generated by Pogo for the HighLevel Tango class in order to create this “inheritance” link.

All modified code in the following code snippets is in bold font.

The HighLevelClass.h file¶

In this file, we will modify the HighLevelClass declaration in order to inherit from the LowLevelClass class instead of inheriting from the Tango::DeviceClass class but we first need to add an extra include file at the file beginning:

1
2
3
4
5
6
7
#ifndef _HIGHLEVELCLASS_H
#define _HIGHLEVELCLASS_H

#include <tango.h>
#include <HighLevel.h>

#include <LowLevelClass.h>

Then, we change the HighLevelClass inheritance declaration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//
// The HighLevelClass singleton definition
//

class
#ifdef WIN32
    __declspec(dllexport)
#endif
HighLevelClass : public LowLevel_ns::LowLevelClass
{
public:
//  properties member data

//  add your own data members here
//------------------------------------

The HighLevelClass.cpp file¶

In this file, we have to modify:

  1. The HighLevelClass definition (due to the change in its inheritance),
  2. The HighLevelClass command_factory() method,
  3. The HighLevelClass attribute_factory() method.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
//+----------------------------------------------------------------------------
//
// method :         HighLevelClass::HighLevelClass(string &s)
//
// description :    constructor for the HighLevelClass
//
// in : - s : The class name
//
//-----------------------------------------------------------------------------
HighLevelClass::HighLevelClass(string &s):LowLevel_ns::LowLevelClass(s)
{

    cout2 << "Entering HighLevelClass constructor" << endl;
    set_default_property();
    get_class_property();
    write_class_property();

    cout2 << "Leaving HighLevelClass constructor" << endl;

}

Then, the changes in the command_factory() method which needs to call the LowLevelClass command_factory() method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//+----------------------------------------------------------------------------
//
// method :         HighLevelClass::command_factory
//
// description :    Create the command object(s) and store them in the
//          command list
//
//-----------------------------------------------------------------------------
void HighLevelClass::command_factory()
{
    LowLevel_ns::LowLevelClass::command_factory();

    command_list.push_back(new HighLevelCmdClass("HighLevelCmd",
        Tango::DEV_VOID, Tango::DEV_VOID,
        "",
        "",
        Tango::OPERATOR));

    //  add polling if any
    for (unsigned int i=0 ; i<command_list.size(); i++)
    {
    }
}

Finally, the changes in the attribute_factory() method which needs to call the LowLevelClass attribute_factory() method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//+----------------------------------------------------------------------------
//  Method: HighLevelClass::attribute_factory(vector<Tango::Attr *> &att_list)
//-----------------------------------------------------------------------------
void HighLevelClass::attribute_factory(vector<Tango::Attr *> &att_list)
{
    LowLevel_ns::LowLevelClass::attribute_factory(att_list);

    //  Attribute : HighLevelAttr
    HighLevelAttrAttrib *high_level_attr = new HighLevelAttrAttrib();
    att_list.push_back(high_level_attr);

    //  End of Automatic code generation
    //-------------------------------------------------------------
}

The HighLevel.h file¶

This file has to be modified in order to:

  1. Change the HighLevel class inheritance from Tango::Device_3Impl to
    LowLevel_ns::LowLevel
  2. Add a new data member in the HighLevel class in order to correctly
    implement the device Init command (a boolean is enough)
  3. Modify the class destructor for a correct management of the device
    Init command

First, we have to add a new include file:

1
2
3
4
5
#ifndef _HIGHLEVEL_H
#define _HIGHLEVEL_H

#include <tango.h>
#include <LowLevel.h>

Then, the change in the HighLevel class inheritance:

1
2
3
4
5
class HighLevel: public LowLevel_ns::LowLevel
{
public :
    //  Add your own data members here
    //-----------------------------------------

The addition of the new data member at the end of the HighLevel class declaration:

1
2
3
4
5
protected :
    //  Add your own data members here
    //-----------------------------------------
    bool device_constructed;
}

And finally, the change in the HighLevel class destructor:

1
2
3
4
/**
 * The object desctructor.
 */
    ~HighLevel() {device_constructed=false;delete_device();}

The HighLevel.cpp file¶

In this file, we have to modify

  1. The HighLevel class constructors to reflect the change in its inheritance and to initialize the new data member (device_constructed)
  2. The HighLevel class delete_device() and init_device() to correctly handle the device Init command
  3. The HighLevel class always_executed_hook() and read_attr_hardware() methods in order that they call the corresponding LowLevel class method

Let’s start with the changes in the HighLevel class constructors:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//+----------------------------------------------------------------------------
//
// method :         HighLevel::HighLevel(string &s)
//
// description :    constructor for simulated HighLevel
//
// in : - cl : Pointer to the DeviceClass object
//      - s : Device name
//
//-----------------------------------------------------------------------------
HighLevel::HighLevel(Tango::DeviceClass *cl,string &s)
:LowLevel_ns::LowLevel(cl,s.c_str()),device_constructed(false)
{
    init_device();
    device_constructed = true;
}

HighLevel::HighLevel(Tango::DeviceClass *cl,const char *s)
:LowLevel_ns::LowLevel(cl,s),device_constructed(false)
{
    init_device();
    device_constructed = true;
}

HighLevel::HighLevel(Tango::DeviceClass *cl,const char *s,const char *d)
:LowLevel_ns::LowLevel(cl,s,d),device_constructed(false)
{
    init_device();
    device_constructed = true;
}

Now, the modified HighLevel class init_device() and delete_device() methods:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//+----------------------------------------------------------------------------
//
// method :         HighLevel::delete_device()
//
// description :    will be called at device destruction or at init command.
//
//-----------------------------------------------------------------------------
void HighLevel::delete_device()
{
    INFO_STREAM << "In HighLevel::delete_device()" << endl;

    //  Delete device's allocated object

//    Your specific code (if any)
if (device_constructed == true)
        LowLevel_ns::LowLevel::delete_device();
}

//+----------------------------------------------------------------------------
//
// method :         HighLevel::init_device()
//
// description :    will be called at device initialization.
//
//-----------------------------------------------------------------------------
void HighLevel::init_device()
{
    if (device_constructed == true)
        LowLevel_ns::LowLevel::init_device();

    INFO_STREAM << "HighLevel::HighLevel() create device " << device_name << endl;

    // Initialise variables to default values
    //--------------------------------------------

And finally, the HighLevel class always_executed_hook() and read_attr_hardware() methods:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//+----------------------------------------------------------------------------
//
// method :         HighLevel::always_executed_hook()
//
// description :    method always executed before any command is executed
//
//-----------------------------------------------------------------------------
void HighLevel::always_executed_hook()
{
    LowLevel_ns::LowLevel::always_executed_hook();
    INFO_STREAM << "In HighLevel::always_executed_hook()" << endl;
//     Your code here (if any)
}

//+----------------------------------------------------------------------------
//
// method :         HighLevel::read_attr_hardware
//
// description :    Hardware acquisition for attributes.
//
//-----------------------------------------------------------------------------
void HighLevel::read_attr_hardware(vector<long> &attr_list)
{
    LowLevel_ns::LowLevel::read_attr_hardware(attr_list);
        DEBUG_STREAM << "HighLevel::read_attr_hardware(vector<long> &attr_list) entering... "<< endl;
    //  Add your own code here
}

Don’t forget to also modify the Makefile in order to link the three LowLevel Tango class object files (Lowlevel.o, LowLevelClass.o and LowLevelStateMachine.o) to your executable.

Defining the class in the Tango control system¶

Once the executable is linked, the device server process instance has to be created in the Tango database (using Jive for instance).

../../_images/jive1.png

Running your class¶

Nothing special here. Simply start your device server as usual. Connecting to the device using a “Test Panel” shows that the device now has:

  • two commands (one from the LowLevel class and the other from the HighLevel class),
  • two attributes (from LowLevel class and from HighLevel class).
../../_images/testdevice_cmd.png
../../_images/testdevice_attr.png

Conclusion¶

With these relatively simple changes in the HighLevel class, we now have a device instance of a Tango class which “inherits” from another Tango class. The drawback of this method is that once the file has been modified, Pogo will not be able to understand the HighLevel class any more and should not be used for further changes in this class!

With a couple of “virtual” methods, it is also possible in the HighLevel class to overwrite a command or an attribute defined in the Lowlevel class.

Next Previous

© Copyright 2017-2020, Tango Community, Creative Commons Attribution 4.0 International (CC BY 4.0) Revision 8bce80de.

Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest
Versions
latest
stable
9.3.4
9.3.3
9.2.5
rtd-build-test
dev
Downloads
pdf
epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.