520 likes | 733 Views
TANGO training. How to develop a TANGO device. Preamble. Ambition Approaching different steps of a device development Handling the tools Collective approach Operating concepts of session I A C++ example Individual approach Read the documentation ! Tutorial C++ & Java
E N D
TANGO training How to develop a TANGO device
Preamble • Ambition • Approaching different steps of a device development • Handling the tools • Collective approach • Operating concepts of session I • A C++ example • Individual approach • Read the documentation ! • Tutorial C++ & Java • Many implementation details
The example • Servers… • device BeamImage • Beam image (made in the plan of 1 screen) • Supposed to be linked to a camera (with on/off ctrl ) • Params : size (pixels) , scaling (mm/pixel) • device BeamDim • Profiles and size of beam • Logical device (SC service) • Analysis of the image produced by BeamImage • Params : image source (device) • The client(s)… • Matlab and/or Igor Pro and/or DeviceTree
E1 : Definition of interfaces • Preliminary essential step • Led by the clients’ need • Functionalities and/or datas to «export» ? • Contract with the clients • Attractive choice • Strong link with non generic clients • Elementary choices • Commands, Attributes, Ownerships • Command or Attribute ? • command ~ action • attribute ~ physical size «monitorable»
size pixels size pixels (size * scaling) mm (size * scaling) mm E1 : BeamImage : interface • 6 Commands • void SetImageSize(long) • long GetImageSize(void) • void SetImageScaling(double) • double GetImageScaling(void) • void SwitchOn (void) • void SwitchOff (void)
size pixels size pixels (size * scaling) mm (size * scaling) mm E1 : BeamImage : interface • 3 Attributes • size • WRITE, SCALAR, LONG • scaling • READ_WRITE, SCALAR, DOUBLE • bimage • READ, IMAGE, LONG
E1 : BeamImage : interface • 2 States • ON • Camera ON • All commands authorized except SwitchOn • Reading image authorized • OFF • Camera OFF • No authorized command except SwitchOn • Reading image forbidden • TANGO • State management -> command execution • No state management -> reading/writing attribute
E1 : BeamDim : interface • 2 Commands • string GetImageSource(void) • void SetImageSource(string)
E1 : BeamDim : interface • 4 Attributes • x_profil & y_profil • READ, SPECTRUM, LONG • x_dim & y_dim • READ, SCALAR, DOUBLE x_profil x_dim
E2 : Code generation • POGO • TheProgramObviouslyused toGenerate TangoObjects • Java Application • Win32, Linux, Sun-Solaris • Code generator • C++ or Java • Devices skeleton • Commands, Attributes, Ownerships, States • To launch POGO under Windows… • %SOLEIL_ROOT%\tango\win32\script\start-pogo.bat
Classe du device E2 : POGO : New Project
E2 : POGO : States • class BeamImage interface : états • ON : Camera on • OFF : Camera off
E2 : POGO : Commands • class BeamImage interface : commands • Tango::DEV_VOID SetImageSize(Tango::DEV_LONG) • - allowed for states: ON • Tango::DEV_LONG GetImageSize(Tango::DEV_VOID) • - allowed for states: ON • Tango::DEV_VOID SetImageScaling(Tango::DEV_DOUBLE) • - allowed for states: ON,OFF • Tango::DEV_DOUBLE GetImageScaling(Tango::DEV_VOID) • - allowed for states: ON,OFF • Tango::DEV_VOID SwitchOn(Tango::DEV_VOID) • allowed for states: OFF • Tango::DEV_VOID SwitchOff(Tango::DEV_VOID) • allowed for states: ON
E2 : POGO : Attributes • class BeamImage interface : attributes • size • WRITE, SCALAR, LONG • Val_Min = 100, Val_Max = 500, Unit = pixels • Write allowed for states : ON • scaling • READ_WRITE, SCALAR, DOUBLE • Val_Min = 0.001, Val_Max = 10, Unit = mm/pixel • Read/Write allowed for states : ON, OFF • image • READ, IMAGE, LONG • Read allowed for states : ON
E3 : Compilation • Creating the working environment • Positioning the variables of environnement • %SOLEIL_ROOT%\env\win32\envSOLEIL.bat • executing this script in a console • Copying and modifying the Makefile • %SOLEIL_ROOT%\env\win32\Makefile.VC • copying to the directory of the device • editing : device_server = BeamImage • Compiler • nmake –f MakeFile.VC all • nmake –f MakeFile.VC clean
E3 : Compilation • Where is the result of the compilation ? • Intermediate files • C:\TEMP\{USER NAME}\{DEVICE NAME} • Executable • C:\DeviceServers\ds_{DEVICE NAME}.exe
E4 : Execution • Syntax • {EXEC NAME} {INSTANCE NAME} [-v{VERBOSE LEVEL}] • {EXEC NAME} = name of the binary • {INSTANCE NAME} = name of the device instance • C:\DeviceServers\ds_BeamImage 1 –v4
E4 : Execution • Syntax • {EXEC NAME} {INSTANCE NAME} [-v {VERBOSE LEVEL}] • {EXEC NAME} = name of the binary • {INSTANCE NAME} = instance name of the device • C:\ds_BeamImage 1 –v4 • Oups! • The device server ds_BeamImage/1 is not defined in database. Exiting! • Save the server in the TANGO database • Jive : %SOLEIL_ROOT%\win32\script\start-jive.bat • Option –nodb (cf. TANGO programmer’s manual)
E4 : Execution • Second attempt • {EXEC NAME} {INSTANCE NAME} [-v {VERBOSE LEVEL}] • {EXEC NAME} = name of the binary • {INSTANCE NAME} = instance name of the device • C:\ds_BeamImage 1 –v4
E4 : Execution • Second attempt • {EXEC NAME} {INSTANCE NAME} [-v {VERBOSE LEVEL}] • {EXEC NAME} = name of the binary • {INSTANCE NAME} = instance name of the device • C:\ds_BeamImage 1 –v4 • This time … • Ready to accept request • Device waiting for external requests • Integrated into the control system • Appreciate what is done for you !
E4 : Execution • Test • Generic client : DeviceTree, Igor Pro, Matlab • At this stage … • The device runs but does nothing • The interface remains to be implemented • Do what you declare doing !
E5 : Implementation • What is POGO ? • Basic code of the device : 6 files • main.cpp • initialisation of the process and activation of the device • ClassFactory.cpp • Internal cooking of TANGO (extra load via linker) • {BeamImage}Class.h • {BeamImage}Class.cpp • header and impl. of the class (in the TANGO sense) of BeamImage devices. • Implement a « BeamImage factory » • Instanciation of devices , commands, attributes • States management (for the execution of commands only!) • Reading/writing of «class properties» in the TANGO database • {BeamImage}.h • {BeamImage}.cpp • «Implementation class» of BeamImage devices • Implementation of the interface : role of the developer ! Free ! Not expensive !
E4 : Implementation • What is POGO generating (continuation) ? • The « glue» allowing to integrate the device to SC • An «empty» implementation of the device ! • Developer role • Implementing the specific code (acquisition, calculation, simulation, …) • Linking this code to the TANGO interface (generated by POGO)
C S C SOLEIL Control system S S (applications network) client application. C C Server application. S S POGO TANGO Developer Application logic Material Supplier (driver, lib, …) E5 : Implementation
E5 : Implementation • To do … • Implementing the commands • Implementing reading/writing of attributes • Managing the states • Taking into account the ownerships (stored in the database) • Where to intervene? • {DeviceClassName}.h et {DeviceClassName}.cpp • Here : BeamImage.h et BeamImage.cpp
command_inout command_handler CORBA::Any always_executed_hook CORBA::Any is_allowed execute set_image_size CORBA::Any Tango::DevLong Tango::DevLong CORBA::Any CORBA::Any CORBA::Any E5 : Implementation : command • Execution command : • Tango::DEV_LONGSetImageSize(Tango::DEV_LONG) BeamImage (Device Impl.) BeamImage (CORBA Obj.) BeamImageClass (Device Class) SetImageSize (Command)
E5 : Implementation : command BeamImage.h /** * Turns the camera on * @exception DevFailed */ void switch_on(); BeamImage.cpp //------------------------------------------------------------- // method: BeamImage::switch_on // description: method to execute "SwitchOn" // Turns the camera on //------------------------------------------------------------- void BeamImage::switch_on() { cout2 << "BeamImage::switch_on(): entering... !" << endl; // Add your own code to control device here }
E5 : Implementation : command BeamImage.h /** * Turns the camera on * @exception DevFailed */ void switch_on(); BeamImage.cpp //------------------------------------------------------------- // method: BeamImage::switch_on // description: method to execute "SwitchOn" // Turns the camera on //------------------------------------------------------------- void BeamImage::switch_on() { cout2 << "BeamImage::switch_on(): entering... !" << endl; // Add your own code to control device here set_state(Tango::ON); set_status(‘Device up and ready (camera is on)’); } The TANGO command «SwitchOn» is implemented !
E5 : Implementation : command • Main difficulties • Client/server exchange • Device client of a device (cf. BeamDim) • Rules of management of the memory in C++ • Allocation/De-allocation (Ownership) • CORBA (for certain types) • Strings, Sequences, Any (insertion/extraction) • Section 7.2 of the Tango programmer’s guide • Read this or die ! • An example (a model) • Device TangoTest • An ex. of command for each TANGO type
E5 : Implementation : command • Management of errors • C++ Exceptions • spread towards the client (CORBA) • Generic exception • Tango: DevFailed • Reason, Description, Origin, Severity • Other exceptions (more semantic) • ConnectionFailed, CommunicationFailed, … • Section 7.2.4 of the programmer’s guide
E5 : Implementation : command • Management of errors (example) // Allocate image buffer image_buffer = new Tango::DevLong[new_size]; // Check allocation if (image_buffer == 0) { TangoSys_OMemStream o; o << "Failed to allocate beam image buffer" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception( (const char *)"Out of memory error", o.str(), (const char *)"BeamImage::set_image_size"); }
E5 : Implementation : command • Management of errors (example) Tango::DeviceProxy *isource = … try { Tango::DeviceData dd; dd = isource->command_inout(“GetImageScaling”); } cacth (Tango::DevFailed& ex) { TangoSys_OMemStream o; o << "Failed to execute GetImageScaling" << ends; LOG_ERROR((o.str())); Tango::Except::re_throw_exception( ex, (const char *)"Tango command failed", o.str(), (const char *)"BeamDim::read_attr_hardware"); }
E5 : Implementation : attributes • Tricks to know… • The developer «handles» data associated to the attribute, not the attribute itself ! • Variables member of the implementation class with the type of the attribute (and not instances of the Tango class :Attribute) • For a READ attribute, the associated variable member represents the current value of the attribute (i.e. last value read on the hardware) • For a WRITE attribute, it represents the value of the instruction (i.e. value to «write» on the hardware) • Current implementation of TANGO • item being discussed • re-implementation considered
E5 : Implementation : attributes • READ attribute • 1 variable member of the implementation class • name : attr_{ATTR NAME}_read • type : pointer on the attribute type • Ex : image attribute of a BeamImage device • BeamImage.h (header of the BeamImage class ) • POGO code : Tango::DevLong *attr_image_read; • BeamImage.cpp (impl. de la classe BeamImage) • POGO code : Nothing ! • Data associated to the attribute must be instanced • attr_image_read = new Tango::DevLong[size*size]; • Beware of memory leaks (init_device vs delete_device) !
E5 : Implementation : attributes • Reading mecanism BeamImage (Device Impl.) BeamImage (CORBA Obj.) read_attributes(Attr1, Attr2) always_executed_hook read_attr_hardware (Attr1, Attr2) read_attr (Attr1) read_attr (Attr2)
E5 : Implementation : attributes • Reading mecanism • About read_attribut_hardware… • 1 call for the n attributes to read • object : reading the hardware only once • update of variable members of the type <…_read> • About read_attr… • 1 call per attribute to read • object : affected a value to the attribute • associating the attribute and the variable member which represents it • attr.set_value(attr_image_read, size, size)
E5 : Implementation : attributes • WRITE attribute • 1 variable member of the implementation class • name : attr_{ATTR NAME}_write • POGO 1.33 imperfection : also generates attr_{ATTR NAME}_read (do not take into account) • type : attribute type • Ex : attribute size of a BeamImage device • BeamImage.h (header of the BeamImage class ) • POGO code : Tango::DevLong attr_size_write; • BeamImage.cpp (impl. of the BeamImage class ) • POGO code : Nothing ! • attr_size_write = initialSize;
E5 : Implementation : attributes • Writing mecanism BeamImage (Device Impl.) BeamImage (CORBA Obj.) write_attributes(Attr1, Attr2) always_executed_hook write_attr_hardware (Attr1, Attr2)
E5 : Implementation : attributes • Writing mecanism • About write_attribut_hardware… • 1 call for n attributes to write • object : «writing» on the hardware (instruction) • update of variable members of type <…_write> • attr.get_write_value(attr_size_write) • exception removed beforehand (by TANGO) if … • val_min > valeur_utilisateur • or • Valeur_utilisateur > val_max • In that case … • no call to write_attribut_hardware ! • for no attribute !
E5 : Implementation : attributes • READ_WRITE attribute • READ_WRITE = READ + WRITE • 2 variables member of the implementation class • instruction vs real value • <read part> • name : attr_{ATTR NAME}_read • type : pointer on the attribute type • <write part> • name : attr_{ATTR NAME}_write • type : attribute type • Ex : attribute scaling of a BeamImage device • BeamImage.h (header of the BeamImage class) • Tango::DevDouble *attr_scaling_read; • Tango::DevDouble attr_scaling_write; • BeamImage.cpp (impl. of the BeamImage class ) • POGO code : Nothing ! • attr_scaling_read = new Tango::DevDouble; • attr_scaling_write = initialScaling;
E5 : Implementation : miscellaneous • About the init_device… • Method linked to the initialisation of a device • Contents • Everything in line with the device init • Instanciations and memory allocations • Reading of the properties from the TANGO database • A constraint … • The exec of the TANGO Init commands (on the DServer and/or the device) causes the one of <init_device> • Memory leaks ! • A reflex … • Overload delete_device • De-allott everyting (re)allotted by init_device