Commit a75674af authored by Jonathan Hanks's avatar Jonathan Hanks
Browse files

Merge branch 'librts' into 'master'

Librts integrated advligo and into rtcds build of models.

See merge request !428
parents c33652df 91937369
......@@ -99,6 +99,11 @@ ifdef RCG_BUILD_USP
@echo Done
endif
ifdef RCG_BUILD_LIBRTS
#ifneq ($(and $(RCG_BUILD_USP),$(RCG_BUILD_LIBRTS)),)
@env LIBRTS_OUT_OF_TREE_BUILD=1 env RCG_BUILDD=$(bld_dir) make --no-print-directory -f $(srcdir)/src/librts/Makefile $@
endif
@#Save build config and source files for traceability
@/bin/mkdir -p $(bld_info_dir)
@echo $(srcdir) > $(bld_info_dir)/rcg_location.txt
......
build/
*.doubles
*.swp
cmake_minimum_required(VERSION 3.0)
project (model_plant_sim)
if(NOT MODEL_NAME)
message(FATAL_ERROR "MODEL_NAME must be defined when generating the build files with CMake.")
endif()
set( RTS_LIB_NAME ${MODEL_NAME})
set( PYBIND_LIB_NAME ${MODEL_NAME}_pybind)
set(RCG_SRC $ENV{RCG_SRC})
set(RCG_BUILDD $ENV{RCG_BUILDD})
message (STATUS "Using ${RCG_BUILDD} as the build directory to look for model libraries.")
if(NOT EXISTS ${RCG_BUILDD}/models/${MODEL_NAME}/userspace/UserspaceVars.cmake )
message(FATAL_ERROR "${RCG_BUILDD}/models/${MODEL_NAME}/userspace/UserspaceVars.cmake Does not exist... Maybe the model has not been built?")
endif()
if(NOT EXISTS ${RCG_BUILDD}/models/${MODEL_NAME}/include/${MODEL_NAME}.h)
message(FATAL_ERROR "${RCG_BUILDD}/src/include/${MODEL_NAME}.h Does not exist... Maybe the model has not been built?")
endif()
#Make sure a static or shared lib exists for the model
if(NOT EXISTS ${RCG_BUILDD}/models/${MODEL_NAME}/userspace/build/lib${MODEL_NAME}.a
AND NOT EXISTS ${RCG_BUILDD}/models/${MODEL_NAME}/userspace/build/lib${MODEL_NAME}.so )
message(FATAL_ERROR "The model library has not been built, please build the model for userspace. Ex. make <model_name>")
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_subdirectory(src) #Build librts
# Examples
add_subdirectory(examples/load-run-model)
add_subdirectory(examples/filter-module-control)
add_subdirectory(examples/trend-model-var)
add_subdirectory(examples/load-coeffs)
# Pybind Build
add_subdirectory(python/pybind)
# Tests
enable_testing()
add_subdirectory(tests/general-test)
add_subdirectory(tests/filter-control-test)
add_subdirectory(tests/trend-model-var-test)
add_subdirectory(tests/set-get-var-test)
repo_dir:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
#When we are building from the rtcds command, set these from
#the environment that command sets
ifdef LIBRTS_OUT_OF_TREE_BUILD
bld_dir:=$(RCG_BUILDD)
srcdir:=$(RCG_SRC)
lib_bld_dir:=$(bld_dir)/models/librts/
else
bld_dir:=$(repo_dir)/build/rcg-build/
srcdir:=$(repo_dir)/../../
lib_bld_dir:=$(repo_dir)/build/cmake/
endif
code_gen_dir:=$(srcdir)/src/epics/util
models_dir:= $(bld_dir)/models
bld_utils_dir:= $(bld_dir)/utils
NUM_BUILD_THREDS?=2
include $(repo_dir)/env/RCG.mk
#include $(repo_dir)/env/USERAPPS_ENV_VARS.mk
ifndef RCG_SRC
export RCG_SRC:=$(srcdir)/
endif
ifndef RCG_BUILDD
export RCG_BUILDD:=$(bld_dir)
endif
ifndef CDS_IFO_SRC
export CDS_IFO_SRC=$(RCG_SRC)/src/include/
endif
ifndef RCG_LIB_PATH
export RCG_LIB_PATH:=:$(srcdir)/src/epics/simLink/:$(srcdir)/src/epics/simLink/lib/:$(srcdir)/test/:$(repo_dir)/models/:$(file < $(repo_dir)/env/RCG_LIB_PATH.env)
endif
ifndef
export RCG_TARGET:=$(bld_dir)/ipc/
endif
define DIE
(tail $(bld_log); cat $(err_log) && /bin/false)
endef
%:
@# Set path variables so we don't need the whole path everywhere
$(eval model_bld_dir := $(bld_dir)/models/$@/)
$(eval target_dir := $(model_bld_dir)/target/)
$(eval model_log_dir := $(bld_dir)/models/$@/logs)
$(eval err_log := $(model_log_dir)/$@_error.log)
$(eval bld_log := $(model_log_dir)/$@.log)
$(eval kern_bld_dir := $(model_bld_dir)/kernel_mod/)
$(eval us_bld_dir := $(model_bld_dir)/userspace/)
$(eval epics_dir := $(model_bld_dir)/epics/)
$(eval epics_src_dir := $(epics_dir)/src/)
$(eval epics_build_dir := $(target_dir)/$@epics/)
$(eval bld_info_dir := $(target_dir)/build_info/)
$(eval target_bin_dir := $(target_dir)/bin/)
#When we are doing an out of tree build (with rtcds) we don't need to parse the model again
ifndef LIBRTS_OUT_OF_TREE_BUILD
@rm -rf $(model_log_dir) #Clear out logs
@mkdir -p $(lib_bld_dir) $(bld_dir) $(bld_utils_dir)/epics/util $(models_dir) $(epics_dir)/fmseq $(models_dir)/$@/include $(model_log_dir)
@mkdir -p $(target_dir)/ $(target_bin_dir)/
@ln -fs $(srcdir)/src/epics/util/lib $(bld_utils_dir)/epics/util > /dev/null 2>&1 || /bin/true
@ln -fs $(srcdir)/src/epics/simLink $(bld_utils_dir)/epics > /dev/null 2>&1 || /bin/true
@ln -fs $(srcdir)/src/epics/util/Makefile.kernel $(bld_utils_dir)/epics/util > /dev/null 2>&1 || /bin/true
@ln -fs $(srcdir)/src/epics/util/Userspace_CMakeLists.cmake $(bld_utils_dir)/epics/util > /dev/null 2>&1
@echo Parsing the model $@...
@(cd $(bld_utils_dir)/epics/util && env SIMULATION_BUILD=1 env RCG_SRC_DIR=$(srcdir) PERL5LIB=$(code_gen_dir) $(code_gen_dir)/feCodeGen.pl $@.mdl $@ >> $(bld_log) 2>>$(err_log)) || $(DIE)
@echo Done
@/bin/rm -rf $(epics_dir)/$@epics-medm
@/bin/rm -rf $(epics_dir)/$@epics-config
@/bin/mv -f $(epics_src_dir)/medm $(epics_dir)/$@epics-medm
@/bin/mv -f $(epics_src_dir)/config $(epics_dir)/$@epics-config
@/bin/rm -rf $(epics_build_dir)/ $(epics_src_dir)/;
endif
@echo Building front-end user space object $@...
@if [ ! -L $(us_bld_dir)/src ]; then ln -s $(srcdir)/src/ $(us_bld_dir)/src; fi
@mkdir -p $(us_bld_dir)/build
@cmake -B$(us_bld_dir)/build/ -S$(us_bld_dir) -DDEFAULT_TO_SHMEM_BUFFERS=1 -DMODEL_NAME=$@ >> $(bld_log) 2>>$(err_log) || $(DIE)
@make -j $(NUM_BUILD_THREDS) -C $(us_bld_dir)/build >> $(bld_log) 2>>$(err_log) || $(DIE)
@$(RCG_SRC)/src/librts/scripts/buildMapFromHeader.py \
$(model_bld_dir)/include/$@.h \
$(model_bld_dir)/epics/fmseq/$@ \
$(model_bld_dir)/include/var_lookup_table.h >> $(bld_log) 2>>$(err_log) || $(DIE)
@echo Done
@echo Building rtsLib for the model $@...
@cmake -B $(lib_bld_dir) -S$(repo_dir) -DMODEL_NAME=$@ >> $(bld_log) 2>>$(err_log) || $(DIE)
@make -j $(NUM_BUILD_THREDS) -C $(lib_bld_dir) >> $(bld_log) 2>>$(err_log) || $(DIE)
@echo Done
ifndef LIBRTS_OUT_OF_TREE_BUILD
@echo RCG source code directory:
@echo $(srcdir)
@echo The following files were used for this build:
@sort $(epics_dir)/sources.$@ | uniq
endif
@echo
@echo Successfully compiled $@ librts interface
@#Print rcg warnings if we have any
@if [ -s $(model_log_dir)/$@_warnings.log ]; then \
printf '\nRGC Warnings found in $(model_log_dir)/$@_warnings.log:\n'; \
printf '***********************************************\n'; \
cat $(model_log_dir)/$@_warnings.log; \
printf '***********************************************\n'; fi
@#Print c compilation errors if we have any
@if [ -s $(err_log) ]; then \
printf '\nC Compilation Warnings found in $(err_log)\n'; \
printf '***********************************************\n'; \
cat $(err_log); \
printf '***********************************************\n'; fi
.DEFAULT: all
.PHONY: clean all test install-modules-from-source rmmod insmod check
all:
@echo "Please enter the name of the model you would like to build"
@false
clean:
rm -rf $(repo_dir)/build
check:
@if ( git submodule status | wc -w | grep "3" > /dev/null ) ; then echo "Check: advligorts submodule initialized!"; else echo "Error: advligorts submodule NOT initialized"; fi;
test:
cd $(lib_bld_dir) && ctest
# Lib RTS
The RTS library allows users to build advLIGO *models*, ie. `.mdl` files created with Simulink/cdsParts library, simulate inputs and capture outputs. It provides a c++ interface, as well as python bindings for use in either language.
## Dependencies
### Required
The required packages that should be installed from your distribution's repositories are:
```
build-essential cmake perl libswitch-perl libspdlog-dev catch python3-dev git python3-pybind11
```
### Others
Some python scrips have ***python dependencies*** that you will need to run them
```
numpy, matplotlib
```
## Directory Structure
| Directory | Uses |
| ---------------------- | ----------------------------------------- |
| `docker/` | Holds docker scripts showing how this repository might be cloned, built and run on a system |
| `env/` | Contains config scripts holding environmental variables sourced bu the build scripts |
| `examples` | C++ examples on how to use the `librts` interface |
| `include/` | `librts` header files |
| `models/` | Directory that is included in the search path for models (`.mdl` files) |
| `python/` | python pybind11 binding files and python example scripts on using the python interface |
| `scripts/` | Utility scripts for plotting c++ output and finding model search paths |
| `src/` | `librts` source files |
| `tests/` | C++ tests ran against `librts` |
## Building Custom Models
Simple custom models are very simple to build. The general steps are to make sure this repository's `Makefile` will be able to find your `.mdl` file. The simplest way is to just copy it into the `models/` directory, ex: `cp x1testmodel.mdl /home/$USER/git/rtsLib/models/` and then run make <model_name> from the repository directoy. ex: `cd /home/$USER/git/rtsLib/; make x1testmodel`.
## Building Production Models
(In progress)
Some production models have hard coded paths to `/opt/rtcds/userapps/release/` so you are going to need to setup a symlink from that path to your userapps or install userapps to that standard location.
## Running Python Examples
All you should need to do is build the model, set your `PYTHONPATH`, and run the script. Ex (from the repo root dir):
```
~/git/rtslib$ make x1unittest
~/git/rtslib$ source ./scripts/setDefaultPythonPath.sh
~/git/rtslib$ ./python/examples/load-module-example.py
```
## Parts Notes
### IPCs
IPCs dont work the same way with `librts`, because external sender/receiver models are not running. Some special considerations should be made.
| IPC Setup | Status | Notes |
| ----------- | ----------- | ------------ |
| Sender and receiver in same model | SUPPORTED | Works as it would with a real time model deployment |
| Receiver only | SUPPORTED | Because there is no "sender" model running, the output of these can be configured with a Generator |
| Sender only | SUPPORTED | Sender IPCs that would normally be sent to another model can be collected by recording and trending the IPC like any other recordable variable |
## Generator Objects
Many parts (excitations, ADCs, IPC receivers, etc.) can have their outputs simulated by a `Generator` object. The C++ library supports a number of generators, and more can be easily added. Checkout `include/RampGenerator.hh` for an example of a C++ Generator, and `python/examples/generators-example.py` for usage in python, as well as how you would define a custom Generator in python.
### Currently Implemented Generators
| Name | Function | Prototype |
| ------- | ------------------- | ----------- |
| `CannedSignalGenerator` | The output is simulated by reading samples from the provided list. If repeat is set to false, when you run out of canned samples the generator will return 0 on successive calls. If repeat is true, the buffer is replayed from the first sample each time the end is reached. | `CannedSignalGenerator(const std::vector<double>& canned_data, bool repeat = true)` |
| `ConstantGenerator` | Feeds the constant value configured as output | `ConstantGenerator(double value)` |
| `GaussianNoiseGenerator` | Simulates Gassian noise with the configured parameters | `GaussianNoiseGenerator(double mean, double stddev) ` |mak
| `RampGenerator` | Simulates a ramp output with the configured parameters | `RampGenerator(double start_val, double step)` |
| `UniformRealGenerator` | Generates real numbers in the range [a, b) | `UniformRealGenerator(double min, double max)` |
## TODO
- We might be able to expose more model variables, maybe even all edges, but right now some of those are static and others don't appear in the <model_name> header.
## Debugging
You can turn on more verbose logging by changing the spdlog level:
```
export SPDLOG_LEVEL=info
(run your app)
```
FROM registry.hub.docker.com/library/debian:bullseye-slim
# caqtdm is not absolutely required, but removes some warnings
RUN apt-get update -y \
&& apt-get install -y build-essential cmake perl libswitch-perl \
libspdlog-dev catch python3-dev git python3-pybind11
RUN useradd -rm -d /home/controls -s /bin/bash -g root -G sudo -u 1001 controls
USER controls
WORKDIR /home/controls
RUN git clone --recurse-submodules https://git.ligo.org/ezekiel.dohmen/rtslib.git
WORKDIR /home/controls/rtslib
RUN make x1unittest
RUN make test
/home/ej/trunk//aos/common/src:/home/ej/trunk//cal/common/src:/home/ej/trunk//cds/common/src:/home/ej/trunk//hpi/common/src:/home/ej/trunk//hpi/common/src/old_src:/home/ej/trunk//hpi/common/src:/home/ej/trunk//isc/common/src:/home/ej/trunk//isi/common/src:/home/ej/trunk//lsc/common/src:/home/ej/trunk//lsc/common/src/omc:/home/ej/trunk//pem/common/src:/home/ej/trunk//psl/common/src/dbb:/home/ej/trunk//psl/common/src/fss:/home/ej/trunk//psl/common/src/iss:/home/ej/trunk//psl/common/src/pmc:/home/ej/trunk//sus/common/src:/home/ej/trunk//sys/common/src:/home/ej/trunk//cal/x2/src:/home/ej/trunk//cds/x2/src:/home/ej/trunk//isc/x2/src:/home/ej/trunk//psl/x2/src
#Holds env for the make environment
export SITE=TST
export site=$(shell echo $(SITE) | tr A-Z a-z) #Lower Case
export IFO=X1
export ifo=$(shell echo $(IFO) | tr A-Z a-z) #Lower Case
:/home/ej/trunk//als/common/models:/home/ej/trunk//asc/common/models:/home/ej/trunk//cal/common/models:/home/ej/trunk//cds/common/models:/home/ej/trunk//hpi/common/models:/home/ej/trunk//isc/common/models:/home/ej/trunk//isi/common/models:/home/ej/trunk//lsc/common/models:/home/ej/trunk//omc/common/models:/home/ej/trunk//psl/common/models:/home/ej/trunk//sqz/common/models:/home/ej/trunk//sus/common/models:/home/ej/trunk//sys/common/models:/home/ej/trunk//tcs/common/models:/home/ej/trunk//als/h1/models:/home/ej/trunk//asc/h1/models:/home/ej/trunk//cal/h1/models:/home/ej/trunk//cds/h1/models:/home/ej/trunk//hpi/h1/models:/home/ej/trunk//isc/h1/models:/home/ej/trunk//isc/h1/scripts/a2l:/home/ej/trunk//isi/h1/models:/home/ej/trunk//lsc/h1/models:/home/ej/trunk//omc/h1/models:/home/ej/trunk//pem/h1/models:/home/ej/trunk//psl/h1/models:/home/ej/trunk//sqz/h1/models:/home/ej/trunk//sus/h1/models:/home/ej/trunk//sys/h1/models:/home/ej/trunk//tcs/h1/models
USERAPPS_BASE ?=/opt/rtcds/userapps/release
export ALS_SRC=$(USERAPPS_BASE)/als/common/src
export ALS_IFO_SRC=$(USERAPPS_BASE)/als/$(ifo)/src
export AOS_SRC=$(USERAPPS_BASE)/aos/common/src
export AOS_IFO_SRC=$(USERAPPS_BASE)/aos/$(ifo)/src
export ASC_SRC=$(USERAPPS_BASE)/asc/common/src
export ASC_IFO_SRC=$(USERAPPS_BASE)/asc/$(ifo)/src
export CAL_SRC=$(USERAPPS_BASE)/cal/common/src
export CAL_IFO_SRC=$(USERAPPS_BASE)/cal/$(ifo)/src
export CDS_SRC=$(USERAPPS_BASE)/cds/common/src
#export CDS_IFO_SRC=$(USERAPPS_BASE)/cds/$(ifo)/src
export HPI_SRC=$(USERAPPS_BASE)/hpi/common/src
export HPI_IFO_SRC=$(USERAPPS_BASE)/hpi/$(ifo)/src
export IMC_SRC=$(USERAPPS_BASE)/imc/common/src
export IMC_IFO_SRC=$(USERAPPS_BASE)/imc/$(ifo)/src
export IOO_SRC=$(USERAPPS_BASE)/ioo/common/src
export IOO_IFO_SRC=$(USERAPPS_BASE)/ioo/$(ifo)/src
export ISC_SRC=$(USERAPPS_BASE)/isc/common/src
export ISC_IFO_SRC=$(USERAPPS_BASE)/isc/$(ifo)/src
export ISI_SRC=$(USERAPPS_BASE)/isi/common/src
export ISI_IFO_SRC=$(USERAPPS_BASE)/isi/$(ifo)/src
export LSC_SRC=$(USERAPPS_BASE)/lsc/common/src
export LSC_IFO_SRC=$(USERAPPS_BASE)/lsc/$(ifo)/src
export OMC_SRC=$(USERAPPS_BASE)/omc/common/src
export OMC_IFO_SRC=$(USERAPPS_BASE)/odc/$(ifo)/src
export PEM_SRC=$(USERAPPS_BASE)/pem/common/src
export PEM_IFO_SRC=$(USERAPPS_BASE)/pem/$(ifo)/src
export PSL_SRC=$(USERAPPS_BASE)/psl/common/src
export PSL_IFO_SRC=$(USERAPPS_BASE)/psl/$(ifo)/src
export SQZ_SRC=$(USERAPPS_BASE)/sqz/common/src
export SQZ_IFO_SRC=$(USERAPPS_BASE)/sqz/$(ifo)/src
export SUS_SRC=$(USERAPPS_BASE)/sus/common/src
export SUS_IFO_SRC=$(USERAPPS_BASE)/sus/$(ifo)/src
export SYS_SRC=$(USERAPPS_BASE)/sys/common/src
export SYS_IFO_SRC=$(USERAPPS_BASE)/sys/$(ifo)/src
export TCS_SRC=$(USERAPPS_BASE)/tcs/common/src
export TCS_IFO_SRC=$(USERAPPS_BASE)/tcs/$(ifo)/src
export CDS_TEST_SRC=$(USERAPPS_BASE)/cds/test/src
project (filter-module-control)
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../include)
target_link_libraries(${PROJECT_NAME}
PRIVATE
${RTS_LIB_NAME}
)
#include "Model.hh"
#include <iostream>
#include <fstream>
int main(int argc, char** argv)
{
std::unique_ptr<rts::Model> model_ptr = rts::Model::create_instance();
if(model_ptr == nullptr)
{
std::cout << "Error coult not create Model. Exiting..." << std::endl;
return 2;
}
//Set inputs
//
//Configure modules
//
std::optional<rts::LIGO_FilterModule> filter1 = model_ptr->get_filter_module_by_name("FM0");
filter1.value().enable_input().enable_output().set_gain(1).set_ramp_time_s(0.0).enable_stages( {0} );
model_ptr->load_biquad_coefficients("FM0", {0}, { 0.56593403, -0.86813193, -0.86813193, -0.86813193, -0.86813193});
//Configure record points
//
model_ptr->record_dac_output(true);
//Run Model
//
model_ptr->run_model(model_ptr->get_model_rate_Hz()*1);
//Examine Outputs
const std::vector<double> & dac_chan = model_ptr->get_dac_output_by_id(0,0);
auto myfile = std::fstream("dac_0_0.doubles", std::ios::out | std::ios::binary);
myfile.write((char*)&dac_chan[0], dac_chan.size() * sizeof(double));
myfile.close();
return 0;
}
project (load-coeffs)
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../include)
target_link_libraries(${PROJECT_NAME}
PRIVATE
${RTS_LIB_NAME}
)
#include "Model.hh"
#include <iostream>
#include <fstream>
int main(int argc, char** argv)
{
std::unique_ptr<rts::Model> model_ptr = rts::Model::create_instance();
if(model_ptr == nullptr)
{
std::cout << "Error coult not create Model. Exiting..." << std::endl;
return 2;
}
//Set inputs
//
//Configure modules
//
std::optional<rts::LIGO_FilterModule> filter1 = model_ptr->get_filter_module_by_name("FM0");
filter1.value().enable_input().enable_output().set_gain(1).set_ramp_time_s(0.0).enable_stages( {0} );
//model_ptr->loadBiquadCoefficients("FM0", {0}, { 0.56593403, -0.86813193, -0.86813193, -0.86813193, -0.86813193});
//sos = np.signal.ellip(2, 0.009, 80, 0.5, output='sos')
model_ptr->load_scipy_sos_coef("FM0", {0}, {{0.66255005, 1.32507584, 0.66255005, 1.0, 1.20575514, 0.44716825}} );
//sos = sig.ellip(3, 0.009, 80, 0.5, output='sos')
model_ptr->load_scipy_sos_coef("FM0", {0}, {{0.34930217, 0.6967771, 0.34930217, 1.0, 0.23814351, 0.0}, {1.0, 1.0, 0.0, 1.0, 0.79352901, 0.46046083}});
//Configure record points
//
model_ptr->record_dac_output(true);
//Run Model
//
model_ptr->run_model(model_ptr->get_model_rate_Hz()*1);
//Examine Outputs
const std::vector<double> & dac_chan = model_ptr->get_dac_output_by_id(0,0);
auto myfile = std::fstream("dac_0_0.doubles", std::ios::out | std::ios::binary);
myfile.write((char*)&dac_chan[0], dac_chan.size() * sizeof(double));
myfile.close();
return 0;
}
project (load-and-run-example)
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../include)
target_link_libraries(${PROJECT_NAME}
PRIVATE
${RTS_LIB_NAME}
)
#include "Model.hh"
#include "RampGenerator.hh"
#include <iostream>
#include <fstream>
int main(int argc, char** argv)
{
std::unique_ptr<rts::Model> model_ptr = rts::Model::create_instance();
if(model_ptr == nullptr)
{
std::cout << "Error coult not create Model. Exiting..." << std::endl;
return 2;
}
/*
std::vector<std::string> names = model_ptr->getAllInputNames();
for (auto& adc : names)
{
std::cout << adc << std::endl;
}*/
std::vector<std::string> filter_names = model_ptr->get_all_filter_names();
for (auto& filter_name : filter_names)
{
std::cout << filter_name << std::endl;
}
//Set inputs
//
model_ptr->set_adc_channel_generator( 0, 31, std::make_unique<rts::RampGenerator>(0, 1) );
//Configure modules
//
model_ptr->set_var("EX_EPICS_BIN_IN", 5);
std::cout << model_ptr->get_var<int>("EX_EPICS_BIN_IN").value() << std::endl;
std::optional<rts::LIGO_FilterModule> filter1 = model_ptr->get_filter_module_by_name("FM0");
filter1.value().enable_input().enable_output().enable_offset(5);
//Configure record points
//
model_ptr->record_dac_output(true);
//Run Model
//
model_ptr->run_model(model_ptr->get_model_rate_Hz()*10);
//Maybe change config
//model_ptr->...()
//Run some more
//model_ptr->runModel(1024);
//Examine Outputs
const std::vector<double> & dac_chan = model_ptr->get_dac_output_by_id(0,0);
auto myfile = std::fstream("dac_0_0.doubles", std::ios::out | std::ios::binary);
myfile.write((char*)&dac_chan[0], dac_chan.size() * sizeof(double));
myfile.close();
std::cout << model_ptr->get_var<int>("EX_EPICS_BIN_IN").value() << std::endl;
return 0;
}
project (trend-model-var)
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../include)
target_link_libraries(${PROJECT_NAME}
PRIVATE
${RTS_LIB_NAME}
)
#include "Model.hh"
#include "RampGenerator.hh"
#include <iostream>
#include <fstream>
#include "spdlog/cfg/env.h"
int main(int argc, char** argv)
{
spdlog::cfg::load_env_levels();
std::unique_ptr<rts::Model> model_ptr = rts::Model::create_instance();
if(model_ptr == nullptr)
{
std::cout << "Error coult not create Model. Exiting..." << std::endl;