Skip to content
Snippets Groups Projects
Commit 63e580e1 authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

doc: modernise example(s)

parent ffa2299a
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 499 deletions
../This_project_uses_the_project-template.txt
\ No newline at end of file
../cmake/
\ No newline at end of file
<configuration>
<variable name="enableAutomation" type="int32" value="1"/>
</configuration>
# Conf file created at 17:08.38 13. Jun. 2016
# eq_fct_type's are defined in eq_fct_code.h
eq_conf:
oper_uid: -1
oper_gid: 422
xpert_uid: 0
xpert_gid: 0
ring_buffer: 10000
memory_buffer: 500
eq_fct_name: "NODENAME._SVR"
eq_fct_type: 1
{
SVR.NAME: "NODENAME._SVR"
STS: 0x1c
STS.ERROR: 0
STS.NEWERROR: 1
STS.ERRORMASK: 1
STS.ONLINE: 1
ERROR.STR: 0 0 0 1078761493 ""
SYS_MASK: 1
FCT_CODE: 1
FCT_PANEL: ""
X_POS: 0
Z_POS: 0
Z_POS.STRING: ""
DEVICE.INFO: 235672 0 0 0 "Device OK"
MESSAGE: ""
LAST_UPDATE: 1112798768 350 0 0
LAST_USR1: 0 0 0 0
SVR.ALIAS: 0
SVR.ARCFLUSH: 0
SVR.ARCFLUSH_B: 0
SVR.UPDATE: 1465830518
SVR.RATE: 1 0 0 0
SVR.RESIZE: 200
SVR.FILE: "demoApp.conf"
SVR.DESC: ""
SVR.PROGRAMMER: "mhier"
SVR.XMLFILE: ""
SVR.ERRORLOG: "/doocs/nodename/server/InstaCoSADevExample_server/InstaCoSADevExample_server.log"
SVR.STORE.RATE: 10
SVR.STORE.AUTO: 4
SVR.HOST_NAME: "mskpcx19821"
SVR.PROCESSNAME: "demoApp"
SVR.RPC_NUMBER: 610498009
SVR.STARTTIME: 1465830430
SVR.LIBINFO: "18.10.6"
SVR.LIBDATE: "Jun 2 13:38"
SVR.WDADDR: ""
SVR.CONTR: 0x0
SVR.MUST_RUN: 0
SVR.STOP_SVR: 0
SVR.START_CMD: ""
SVR.RPC_CALL_TIME.COMMENT: "Time per Call"
SVR.RPC_CALL_TIME.EGU: 1 1 100000 0 "rate"
SVR.RPC_CALL_TIME.XEGU: 0 0 100 0 "ms"
SVR.UPDATE_TIME.COMMENT: "Time per Update"
SVR.UPDATE_TIME.EGU: 1 1 100000 0 "rate"
SVR.UPDATE_TIME.XEGU: 0 0 100 0 "ms"
SVR.USR1_TIME.COMMENT: "run time of SIGUSR1"
SVR.USR1_TIME.EGU: 1 1 1e+06 1427728880 "counts"
SVR.USR1_TIME.XEGU: 0 0 100 1427728880 "ms"
SVR.USR1_PERIOD.COMMENT: "time between SIGUSR1"
SVR.USR1_PERIOD.EGU: 1 1 1e+06 1427728880 "counts"
SVR.USR1_PERIOD.XEGU: 0 0 500 1427728880 "ms"
SVR.ARCH_GET_TIME.COMMENT: "time per archiver get"
SVR.ARCH_GET_TIME.EGU: 1 1 1e+06 1459338630 "counts"
SVR.ARCH_GET_TIME.XEGU: 0 0 100 1459338630 "ms"
SVR.LAFL: 0
SVR.ERROR_COUNT: 0
DEVICE.ONLINE: 1
DEVICE.OFFLINE: 0
SVR.DEVMAX: 0
SVR.TINERUN: 0
SVR.TINEVERS: "4.05.0009"
SVR.TINEPREF: ""
SVR.TINESUFF: ""
SVR.TINE_DBG: 0
SVR.TINE_LOG: 0
SVR.TINE_FEC: 0 0 0 0 ""
SVR.TINE_PORT: 0
SVR.TINE_MTU: 1472
SVR.TINE_CTSZ: 32
SVR.TINE_MCTTL: 16
SVR.TINE_BLIM: 1000
SVR.TINE_CDLY: 20
SVR.TINE_GROUP: 0
SVR.FACILITY: "TEST.DOOCS"
SVR.DEVICE: "InstaCoSADevExample"
T_ZERO: 700
SVR.BPN: 0
SVR.SPR: 0
}
eq_fct_name: "Bakery"
eq_fct_type: 10
{
NAME: "Bakery"
STS: 0xc
STS.ERROR: 0
STS.NEWERROR: 1
STS.ERRORMASK: 0
STS.ONLINE: 1
ERROR.STR: 0 0 0 1112798768 "ok"
SYS_MASK: 222
FCT_CODE: 10
FCT_PANEL: ""
X_POS: 0
Z_POS: 0
Z_POS.STRING: ""
DEVICE.INFO: 0 0 0 0 "HALLO"
MESSAGE: ""
LAST_UPDATE: 1465830518 750 0 0
LAST_USR1: 0 0 0 0
readback: 20
setpoint: 10
}
oven (sharedMemoryDummy?map=oven.map)
# name nr of elements address size bar width fracbits signed R/W
heater.temperatureReadback 1 0 4 0 32 16 0 RO
heater.heatingCurrent 1 4 4 0 32 16 0 RW
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#include <ChimeraTK/ApplicationCore/ApplicationCore.h>
#include <ChimeraTK/ApplicationCore/ConfigReader.h>
#include <ChimeraTK/ApplicationCore/EnableXMLGenerator.h>
#include <ChimeraTK/ApplicationCore/PeriodicTrigger.h>
namespace ctk = ChimeraTK;
struct Controller : public ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
ctk::ScalarPollInput<float> sp{this, "temperatureSetpoint", "degC", "Description"};
ctk::ScalarPushInput<float> rb{this, "/heater/temperatureReadback", "degC", "..."};
ctk::ScalarOutput<float> cur{this, "/heater/heatingCurrent", "mA", "..."};
void mainLoop() final {
const float gain = 100.0F;
while(true) {
readAll(); // waits until rb updated, then reads sp
cur = gain * (sp - rb);
writeAll(); // writes any outputs
}
}
};
struct Automation : public ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
ctk::ScalarPollInput<float> opSp{this, "operatorSetpoint", "degC", "..."};
ctk::ScalarOutput<float> actSp{this, "/Controller/temperatureSetpoint", "degC", "..."};
ctk::ScalarPushInput<uint64_t> trigger{this, "/Timer/tick", "", "..."};
void mainLoop() final {
const float maxStep = 0.1F;
while(true) {
readAll(); // waits until trigger received, then read opSp
actSp += std::max(std::min(opSp - actSp, maxStep), -maxStep);
writeAll();
}
}
};
struct ExampleApp final : public ctk::Application {
ExampleApp() : Application("exampleApp2a") {
if(config.get<int>("enableAutomation")) {
automation = Automation(this, "Automation", "Slow setpoint ramping algorithm");
}
}
~ExampleApp() final { shutdown(); }
ctk::SetDMapFilePath dmapPath{"example2.dmap"};
ctk::ConfigReader config{this, "config", "demoApp2a.xml"};
Controller controller{this, "Controller", "The Controller"};
ctk::PeriodicTrigger timer{this, "Timer", "Periodic timer for the controller", 1000};
// ctk::DeviceModule oven{this, "oven"};
ctk::DeviceModule oven{this, "oven", "/Timer/tick"};
Automation automation;
};
static ExampleApp theExampleApp;
# Note: This CMakeLists.txt is a minimal complete example how to use the
# *installed* application core library. It is not included from the main CMakeLists.txt
# which is used to build ApplicationCore itself.
PROJECT(demo_example2c)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1)
# Use the project template to get the settings required for an application core project
set(${PROJECT_NAME}_MAJOR_VERSION 01)
set(${PROJECT_NAME}_MINOR_VERSION 00)
set(${PROJECT_NAME}_PATCH_VERSION 00)
include(cmake/set_version_numbers.cmake)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
include(cmake/add_dependency.cmake)
include(cmake/set_default_build_to_release.cmake)
include(cmake/set_default_flags.cmake)
# Add the dependencies. We need ApplicationCore and a control system adapter implementation.
add_dependency(ChimeraTK-ApplicationCore 03.00 REQUIRED)
#FIXME: Make the adapter configurable via command line parameter
add_dependency(ChimeraTK-ControlSystemAdapter-DoocsAdapter 00.10 REQUIRED)
AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR} demo_sources)
# The server proper. It depends on application core and the control system adapter implementation.
add_executable(${PROJECT_NAME} ${demo_sources})
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${ChimeraTK-ApplicationCore_LINK_FLAGS} ${ChimeraTK-ControlSystemAdapter-DoocsAdapter_LINK_FLAGS}")
target_link_libraries(${PROJECT_NAME} ${ChimeraTK-ApplicationCore_LIBRARIES} ${ChimeraTK-ControlSystemAdapter-DoocsAdapter_LIBRARIES} )
# We compile the same sources with the GENERATE_XML flag to get an xml generator.
# This one does not depent on a control system adapter implementation.
add_executable(${PROJECT_NAME}-xmlGenerator ${demo_sources})
set_target_properties( ${PROJECT_NAME}-xmlGenerator PROPERTIES COMPILE_FLAGS "-DGENERATE_XML")
set_target_properties(${PROJECT_NAME}-xmlGenerator PROPERTIES LINK_FLAGS "${ChimeraTK-ApplicationCore_LINK_FLAGS}")
target_link_libraries(${PROJECT_NAME}-xmlGenerator ${ChimeraTK-ApplicationCore_LIBRARIES})
# copy the (test) config files to the build directory for tests
FILE( COPY config/ DESTINATION ${PROJECT_BINARY_DIR})
FILE( COPY oven_sim/ DESTINATION ${PROJECT_BINARY_DIR})
# Tests:
# There are no dedicated tests for this demo. But we run the xml generator to
# check that the variable household can successfully be initialised.
# The test will fail if the xml generator crashes, just a smoke test.
ENABLE_TESTING()
add_test(${PROJECT_NAME}-xmlGenerator ${PROJECT_NAME}-xmlGenerator)
# Installation:
# FIXME: For doocs we need a special treatment when installing to /export/doocs/server (don't install to bin subdirectory, but a directory named like the server). This should go to the project template.
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/export/doocs/server")
install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-xmlGenerator RUNTIME DESTINATION ${PROJECT_NAME})
else()
install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-xmlGenerator RUNTIME DESTINATION bin)
endif()
# Do not install the config. It is only a test config.
# The real config will come from a config generator and usually depends on the instance.
../COPYING
\ No newline at end of file
../COPYING.LESSER
\ No newline at end of file
../This_project_uses_the_project-template.txt
\ No newline at end of file
../cmake/
\ No newline at end of file
<device_server>
<location name="Bakery">
<import>/</import>
</location>
</device_server>
eq_conf:
eq_fct_name: "LOCAHOST._SVR"
eq_fct_type: 1
{
SVR.RPC_NUMBER: 610498009
SVR.RATE: 6 0 0 0
}
# name n_elements address size bar width fracbits signed R/W
APP.0.TEMPERATURE_ADC 1 0 4 0 16 0 0 RO
APP.0.HEATING_CURRENT 1 4 4 0 32 16 0 RW
APP.0.SUPPLY_ADCS 4 8 16 0 16 0 0 RO
APP.0.POWER 1 24 4 0 1 0 0 RW
APP.0.SUPPLY_ADCS_GAIN 4 28 16 0 32 0 0 RW
APP.0.AREA_FW_UPGRADE 1024 256 4096 0 32 0 0 RW
<logicalNameMap>
<module name="heater">
<redirectedRegister name="heatingCurrent">
<targetDevice>oven_raw</targetDevice>
<targetRegister>APP/0/HEATING_CURRENT</targetRegister>
</redirectedRegister>
<redirectedRegister name="temperatureReadback">
<targetDevice>oven_raw</targetDevice>
<targetRegister>APP/0/TEMPERATURE_ADC</targetRegister>
<plugin name="math">
<!-- 16 bit ADC with 10 V, Sensor: 65 V/degC -->
<parameter name="formula">x / 2.^16 * 10. * 65.</parameter>
</plugin>
</redirectedRegister>
<redirectedRegister name="managementVoltage">
<targetDevice>oven_raw</targetDevice>
<targetRegister>APP/0/SUPPLY_ADCS</targetRegister>
<numberOfElements>1</numberOfElements>
<plugin name="math">
<!-- 16 bit ADC with 32 V -->
<parameter name="formula">x / 2.^16 * 32.</parameter>
</plugin>
</redirectedRegister>
<redirectedRegister name="threePhaseVoltages">
<targetDevice>oven_raw</targetDevice>
<targetRegister>APP/0/SUPPLY_ADCS</targetRegister>\
<targetStartIndex>1</targetStartIndex>
<numberOfElements>3</numberOfElements>
<plugin name="math">
<!-- 16 bit ADC with 650 V -->
<parameter name="formula">return[x / 2.^16 * 650.]</parameter>
</plugin>
</redirectedRegister>
<redirectedRegister name="power">
<targetDevice>oven_raw</targetDevice>
<targetRegister>APP/0/POWER</targetRegister>
</redirectedRegister>
</module>
<module name="settings">
<redirectedRegister name="supplyVoltageAdcGains">
<targetDevice>oven_raw</targetDevice>
<targetRegister>APP/0/SUPPLY_ADCS_GAIN</targetRegister>
</redirectedRegister>
</module>
</logicalNameMap>
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#include <ChimeraTK/ApplicationCore/ApplicationCore.h>
#include <ChimeraTK/ApplicationCore/DeviceManager.h>
#include <ChimeraTK/ApplicationCore/EnableXMLGenerator.h>
#include <ChimeraTK/ApplicationCore/PeriodicTrigger.h>
namespace ctk = ChimeraTK;
struct Controller : public ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
ctk::ScalarPollInput<double> sp{this, "temperatureSetpoint", "degC", "Description"};
ctk::ScalarPushInput<double> rb{this, "temperatureReadback", "degC", "..."};
ctk::ScalarOutput<double> cur{this, "heatingCurrent", "mA", "..."};
void mainLoop() {
const double gain = 100.0;
while(true) {
readAll(); // waits until rb updated, then reads sp
cur = gain * (sp - rb);
writeAll(); // writes any outputs
}
}
};
struct ExampleApp : public ctk::Application {
ExampleApp() : Application("demoApp2") {
// ChimeraTK::setDMapFilePath("example2.dmap");
// ovenManger.addInitialisationHandler(&initialiseOven);
}
~ExampleApp() { shutdown(); }
ctk::SetDMapFilePath dmapPath{"example2.dmap"};
// We can pick any name for the module. "Oven" is what we want to see in the CS
Controller controller{this, "Oven", "The controller of the oven"};
ctk::PeriodicTrigger timer{this, "Timer", "Periodic timer for the controller", 1000};
// ctk::DeviceManager ovenManger{this, "oven"};
// ctk::DeviceModule oven{this, "oven", &initialiseOven}; -> replaced with ConnectingDeviceModule
ctk::DeviceModule oven{this, "oven", "/Timer/tick", &initialiseOven};
// ctk::ControlSystemModule cs; -> not needed anymore as all is connected to cs automatically
// void defineConnections(); -> not needed anymore as all is connected to cs automatically
static void initialiseOven(ChimeraTK::DeviceManager* oven);
};
static ExampleApp theExampleApp;
void ExampleApp::initialiseOven(ChimeraTK::DeviceManager* ovenManager) {
// set the gain factors for the voltage monitoring ADCs
// ovenManager->device.write<uint32_t>("/settings/supplyVoltageAdcGains", {20, 1, 1, 1});
ovenManager->getDevice().write<uint32_t>("/settings/supplyVoltageAdcGains", {20, 1, 1, 1});
}
// void ExampleApp::defineConnections() {
// ChimeraTK::setDMapFilePath("example2.dmap");
// // Connect everything to the CS (except for the device, which is special)
// findTag(".*").connectTo(cs);
// // Connect device's "heater" to "Oven" in the CS, and use timer.tick as trigger
// oven["heater"].connectTo(cs["Oven"], timer.tick);
//}
#!/usr/bin/python3
import mtca4u
import time, math
mtca4u.set_dmap_location('example2.dmap')
d=mtca4u.Device('oven_raw')
#cooling rate c
c=0.001 #deg /(deg*s)
#heating rate h
h=0.0003 #deg/(A*s)
ovenTemp = 25.
environment = 25.
gains = d.read('APP.0','SUPPLY_ADCS_GAIN')
for i in range(4):
if gains[i] == 0:
gains[i] = 1
d.write('APP.0','SUPPLY_ADCS_GAIN',gains)
while True:
I = d.read('APP.0','HEATING_CURRENT')[0]
if d.read('APP.0','POWER') == 0:
I = 0
tempChange = 1 * (I*h + (environment-ovenTemp)*c)
# 1s current*heating rate deltaT * cooling rate
ovenTemp = ovenTemp + tempChange
tempRaw = ovenTemp / 65 * math.pow(2,16) / 10 # 65 V/degC, 10V on 16 bits
d.write('APP.0','TEMPERATURE_ADC.DUMMY_WRITEABLE',tempRaw)
print('change ' + str(tempChange) +', new temp ' +str(ovenTemp))
gains = d.read('APP.0','SUPPLY_ADCS_GAIN')
voltagesRaw = [24./650.*pow(2,16)*gains[0],
400./650.*pow(2,16)*gains[1],
400./650.*pow(2,16)*gains[2],
400./650.*pow(2,16)*gains[3] ]
d.write('APP.0','SUPPLY_ADCS.DUMMY_WRITEABLE', voltagesRaw)
time.sleep(1)
# Note: This CMakeLists.txt is a minimal complete example how to use the
# *installed* application core library. It is not included from the main CMakeLists.txt
# which is used to build ApplicationCore itself.
CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1)
#The regex matches everthing that is not a / until the end of the string (i.e. everyting after the last slash, if any)
string(REGEX MATCH "[^/]*$" PROJECT_BASE_NAME ${CMAKE_SOURCE_DIR})
message("REGEX MATCH is ${PROJECT_BASE_NAME}")
SET(PROJECT_NAME demo_${PROJECT_BASE_NAME})
# Use the project template to get the settings required for an application core project
set(${PROJECT_NAME}_MAJOR_VERSION 01)
set(${PROJECT_NAME}_MINOR_VERSION 00)
set(${PROJECT_NAME}_PATCH_VERSION 00)
include(cmake/set_version_numbers.cmake)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
include(cmake/add_dependency.cmake)
include(cmake/set_default_build_to_release.cmake)
include(cmake/set_default_flags.cmake)
# Add the dependencies. We need ApplicationCore and a control system adapter implementation.
add_dependency(ChimeraTK-ApplicationCore 03.00 REQUIRED)
#FIXME: Make the adapter configurable via command line parameter
add_dependency(ChimeraTK-ControlSystemAdapter-DoocsAdapter 00.10 REQUIRED)
AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR} demo_sources)
# The server proper. It depends on application core and the control system adapter implementation.
add_executable(${PROJECT_NAME} ${demo_sources})
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${ChimeraTK-ApplicationCore_LINK_FLAGS} ${ChimeraTK-ControlSystemAdapter-DoocsAdapter_LINK_FLAGS}")
target_link_libraries(${PROJECT_NAME} ${ChimeraTK-ApplicationCore_LIBRARIES} ${ChimeraTK-ControlSystemAdapter-DoocsAdapter_LIBRARIES} )
# We compile the same sources with the GENERATE_XML flag to get an xml generator.
# This one does not depent on a control system adapter implementation.
add_executable(${PROJECT_NAME}-xmlGenerator ${demo_sources})
set_target_properties( ${PROJECT_NAME}-xmlGenerator PROPERTIES COMPILE_FLAGS "-DGENERATE_XML")
set_target_properties(${PROJECT_NAME}-xmlGenerator PROPERTIES LINK_FLAGS "${ChimeraTK-ApplicationCore_LINK_FLAGS}")
target_link_libraries(${PROJECT_NAME}-xmlGenerator ${ChimeraTK-ApplicationCore_LIBRARIES})
# copy the (test) config files to the build directory for tests
FILE( COPY config/ DESTINATION ${PROJECT_BINARY_DIR})
# Tests:
# There are no dedicated tests for this demo. But we run the xml generator to
# check that the variable household can successfully be initialised.
# The test will fail if the xml generator crashes, just a smoke test.
ENABLE_TESTING()
add_test(${PROJECT_NAME}-xmlGenerator ${PROJECT_NAME}-xmlGenerator)
# Installation:
# FIXME: For doocs we need a special treatment when installing to /export/doocs/server (don't install to bin subdirectory, but a directory named like the server). This should go to the project template.
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/export/doocs/server")
install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-xmlGenerator RUNTIME DESTINATION ${PROJECT_NAME})
else()
install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-xmlGenerator RUNTIME DESTINATION bin)
endif()
# Do not install the config. It is only a test config.
# The real config will come from a config generator and usually depends on the instance.
../COPYING
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment