diff --git a/.gitignore b/.gitignore index 295355a..d680236 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ .idea/ .idea_/ .vs/ -.vscode/ __history/ __recovery/ __pycache__/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c6904c1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "iir1"] + path = iir1 + url = https://github.com/berndporr/iir1.git diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..b08ae57 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,19 @@ +{ + "configurations": [ + { + "name": "Linux-GCC", + "includePath": ["${workspaceFolder}/**", "/opt/opendaq/include/", "${workspaceFolder}/iir1/"], + "defines": ["MODULE_PATH=\"/opt/opendaq/lib/modules\""], + "compilerPath": "/usr/bin/g++", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "gcc-x64", + "browse": { + "path": ["${workspaceFolder}"], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 4 +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7c57bae --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/app", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/build", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c80a624 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,80 @@ +{ + "files.associations": { + "cmath": "cpp", + "ratio": "cpp", + "chrono": "cpp", + "array": "cpp", + "string_view": "cpp", + "span": "cpp", + "regex": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeinfo": "cpp", + "variant": "cpp", + "executor": "cpp", + "io_context": "cpp", + "netfwd": "cpp", + "timer": "cpp", + "filesystem": "cpp" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a008d39 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,29 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ +{ + "label": "run", + "type": "shell", + "command": "./fb_application_example", + "options": {"cwd": "${workspaceFolder}/build/bin"}, + "dependsOn":["build"], + "group": { + "kind": "test", + "isDefault": true + } + }, + { + "label": "build", + "type": "shell", + "command": "make", + "options": {"cwd": "${workspaceFolder}/build"}, + "args": ["-j12"], + "group": { + "kind": "build", + "isDefault": true + }, + } + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6137cc7..6787409 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,12 +31,13 @@ if(OPENDAQ_FB_EXAMPLE_ENABLE_APP) set(DAQMODULES_REF_DEVICE_MODULE ON CACHE BOOL "" FORCE) endif() -add_subdirectory(external) find_package(openDAQ) add_compile_definitions(MODULE_PATH="${OPENDAQ_MODULES_DIR}") add_subdirectory(example_module) +add_subdirectory(iir1) + if(OPENDAQ_FB_EXAMPLE_ENABLE_APP) message(STATUS "Enabled example function block application") add_subdirectory(example_application) diff --git a/OD_task.pdf b/OD_task.pdf new file mode 100644 index 0000000..1a38231 Binary files /dev/null and b/OD_task.pdf differ diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..dd91254 --- /dev/null +++ b/TODO.md @@ -0,0 +1,10 @@ +sudo apt remove opendaq + +cmake -DOPENDAQ_FB_EXAMPLE_ENABLE_APP=ON .. + + + + + + +https://rosettacode.org/wiki/Apply_a_digital_filter_(direct_form_II_transposed)#C++ \ No newline at end of file diff --git a/example_application/main.cpp b/example_application/main.cpp index e66c82b..5d0b386 100644 --- a/example_application/main.cpp +++ b/example_application/main.cpp @@ -5,22 +5,34 @@ #include #include +using namespace std::literals::chrono_literals; using namespace daq; int main(int /*argc*/, const char* /*argv*/[]) { - const auto instance = InstanceBuilder().addModulePath(MODULE_PATH).build(); - auto referenceDevice = instance.addDevice("daqref://device0"); - auto renderer = instance.addFunctionBlock("RefFBModuleRenderer"); - auto exampleModule = instance.addFunctionBlock("ExampleScalingModule"); - exampleModule.setPropertyValue("Scale", 3); - exampleModule.setPropertyValue("Offset", -2); + const InstancePtr instance = InstanceBuilder().addModulePath(MODULE_PATH).build(); - exampleModule.getInputPorts()[0].connect(referenceDevice.getSignalsRecursive()[0]); - renderer.getInputPorts()[0].connect(referenceDevice.getSignalsRecursive()[0]); - renderer.getInputPorts()[1].connect(exampleModule.getSignals()[0]); + DevicePtr device = instance.addDevice("daqref://device0"); - std::cout << "Press \"enter\" to exit the application..." << std::endl; - std::cin.get(); + ChannelPtr channel = device.getChannels()[0]; + + SignalPtr signal = channel.getSignals()[0]; + + FunctionBlockPtr renderer = instance.addFunctionBlock("RefFBModuleRenderer"); + FunctionBlockPtr module = instance.addFunctionBlock("ExampleIIRFilter"); + + module.setPropertyValue("CutoffFrequency", 10); + + module.getInputPorts()[0].connect(signal); + renderer.getInputPorts()[0].connect(signal); + renderer.getInputPorts()[1].connect(module.getSignals()[0]); + + + // Set the frequency to 5 Hz + channel.setPropertyValue("Frequency", 5); + // Set the noise amplitude to 0.75 + channel.setPropertyValue("NoiseAmplitude", 0.75); + + std::this_thread::sleep_for(5s); return 0; } diff --git a/example_module/include/example_module/example_fb.h b/example_module/include/example_module/example_fb.h index 290385b..29220d8 100644 --- a/example_module/include/example_module/example_fb.h +++ b/example_module/include/example_module/example_fb.h @@ -19,6 +19,7 @@ #include #include #include +#include BEGIN_NAMESPACE_EXAMPLE_MODULE @@ -50,8 +51,7 @@ private: std::vector inputDomainData; bool configValid = false; - Float scale; - Float offset; + Float cutoffFrequency; Float outputHighValue; Float outputLowValue; Bool useCustomOutputRange; @@ -62,7 +62,7 @@ private: void createSignals(); void calculate(); - void processData(SizeT readAmount, SizeT packetOffset) const; + void processData(SizeT readAmount, SizeT packetOffset); void processEventPacket(const EventPacketPtr& packet); void processSignalDescriptorChanged(const DataDescriptorPtr& dataDescriptor, @@ -72,6 +72,8 @@ private: void initProperties(); void propertyChanged(bool configure); void readProperties(); + + Iir::Butterworth::LowPass<4> filter; }; END_NAMESPACE_EXAMPLE_MODULE diff --git a/example_module/src/CMakeLists.txt b/example_module/src/CMakeLists.txt index dff37d8..40f0943 100644 --- a/example_module/src/CMakeLists.txt +++ b/example_module/src/CMakeLists.txt @@ -33,8 +33,8 @@ if (MSVC) target_compile_options(${LIB_NAME} PRIVATE /bigobj) endif() -target_link_libraries(${LIB_NAME} PUBLIC daq::opendaq -) +find_package(iir) +target_link_libraries(${LIB_NAME} PUBLIC daq::opendaq iir::iir_static) target_include_directories(${LIB_NAME} PUBLIC $ $ diff --git a/example_module/src/example_fb.cpp b/example_module/src/example_fb.cpp index f07197d..86fee3d 100644 --- a/example_module/src/example_fb.cpp +++ b/example_module/src/example_fb.cpp @@ -4,7 +4,7 @@ BEGIN_NAMESPACE_EXAMPLE_MODULE ExampleFBImpl::ExampleFBImpl(const ContextPtr& ctx, const ComponentPtr& parent, const StringPtr& localId) - : FunctionBlock(CreateType(), ctx, parent, localId) + : FunctionBlock(CreateType(), ctx, parent, localId) { initComponentStatus(); createInputPorts(); @@ -14,14 +14,9 @@ BEGIN_NAMESPACE_EXAMPLE_MODULE void ExampleFBImpl::initProperties() { - const auto scaleProp = FloatProperty("Scale", 1.0); + const auto scaleProp = FloatProperty("CutoffFrequency", 1.0); objPtr.addProperty(scaleProp); - objPtr.getOnPropertyValueWrite("Scale") += - [this](PropertyObjectPtr& obj, PropertyValueEventArgsPtr& args) { propertyChanged(true); }; - - const auto offsetProp = FloatProperty("Offset", 0.0); - objPtr.addProperty(offsetProp); - objPtr.getOnPropertyValueWrite("Offset") += + objPtr.getOnPropertyValueWrite("CutoffFrequency") += [this](PropertyObjectPtr& obj, PropertyValueEventArgsPtr& args) { propertyChanged(true); }; const auto useCustomOutputRangeProp = BoolProperty("UseCustomOutputRange", False); @@ -61,8 +56,7 @@ void ExampleFBImpl::propertyChanged(bool configure) void ExampleFBImpl::readProperties() { - scale = objPtr.getPropertyValue("Scale"); - offset = objPtr.getPropertyValue("Offset"); + cutoffFrequency = objPtr.getPropertyValue("CutoffFrequency"); useCustomOutputRange = objPtr.getPropertyValue("UseCustomOutputRange"); outputHighValue = objPtr.getPropertyValue("OutputHighValue"); outputLowValue = objPtr.getPropertyValue("OutputLowValue"); @@ -72,7 +66,7 @@ void ExampleFBImpl::readProperties() FunctionBlockTypePtr ExampleFBImpl::CreateType() { - return FunctionBlockType("ExampleScalingModule", "Scaling", "Signal scaling"); + return FunctionBlockType("ExampleIIRFilter", "Scaling", "Signal scaling"); } void ExampleFBImpl::processSignalDescriptorChanged(const DataDescriptorPtr& dataDescriptor, @@ -145,15 +139,15 @@ void ExampleFBImpl::configure() } else { - auto outputHigh = scale * static_cast(inputDataDescriptor.getValueRange().getLowValue()) + offset; - auto outputLow = scale * static_cast(inputDataDescriptor.getValueRange().getHighValue()) + offset; + auto outputHigh = static_cast(inputDataDescriptor.getValueRange().getLowValue()); + auto outputLow = static_cast(inputDataDescriptor.getValueRange().getHighValue()); if (outputLow > outputHigh) std::swap(outputLow, outputHigh); outputRange = Range(outputLow, outputHigh); } - auto name = outputName.empty() ? inputPort.getSignal().getName().toStdString() + "/Scaled" : outputName; + auto name = outputName.empty() ? inputPort.getSignal().getName().toStdString() + "/Filtered" : outputName; auto unit = outputUnit.empty() ? inputDataDescriptor.getUnit() : Unit(outputUnit); outputDataDescriptor = DataDescriptorBuilder() @@ -172,6 +166,9 @@ void ExampleFBImpl::configure() inputData.resize(sampleRate); inputDomainData.resize(sampleRate); + + filter.setup(sampleRate, cutoffFrequency); + setComponentStatus(ComponentStatus::Ok); } catch (const std::exception& e) @@ -208,17 +205,20 @@ void ExampleFBImpl::calculate() } } -void ExampleFBImpl::processData(SizeT readAmount, SizeT packetOffset) const +void ExampleFBImpl::processData(SizeT readAmount, SizeT packetOffset) { if (readAmount == 0) return; - const auto outputDomainPacket = DataPacket(outputDomainDataDescriptor, readAmount, packetOffset); - const auto outputPacket = DataPacketWithDomain(outputDomainPacket, outputDataDescriptor, readAmount); - auto outputData = static_cast(outputPacket.getRawData()); + const DataPacketPtr outputDomainPacket = DataPacket(outputDomainDataDescriptor, readAmount, packetOffset); + const DataPacketPtr outputPacket = DataPacketWithDomain(outputDomainPacket, outputDataDescriptor, readAmount); + Float* outputData = static_cast(outputPacket.getRawData()); for (size_t i = 0; i < readAmount; i++) - *outputData++ = scale * static_cast(inputData[i]) + offset; + { + // *outputData++ = static_cast(inputData[i]); + *outputData++ = filter.filter(inputData[i]); + } outputSignal.sendPacket(outputPacket); outputDomainSignal.sendPacket(outputDomainPacket); @@ -243,8 +243,8 @@ void ExampleFBImpl::createInputPorts() void ExampleFBImpl::createSignals() { - outputSignal = createAndAddSignal("Scaled"); - outputDomainSignal = createAndAddSignal("ScaledTime", nullptr, false); + outputSignal = createAndAddSignal("Filtered"); + outputDomainSignal = createAndAddSignal("FilteredTime", nullptr, false); outputSignal.setDomainSignal(outputDomainSignal); } diff --git a/example_module/tests/test_example_module.cpp b/example_module/tests/test_example_module.cpp index 45e6032..77809df 100644 --- a/example_module/tests/test_example_module.cpp +++ b/example_module/tests/test_example_module.cpp @@ -10,20 +10,20 @@ using ExampleModuleTest = testing::Test; TEST_F(ExampleModuleTest, TestAdd) { const auto instance = Instance(); - ASSERT_TRUE(instance.addFunctionBlock("ExampleScalingModule").assigned()); + ASSERT_TRUE(instance.addFunctionBlock("ExampleIIRFilter").assigned()); } TEST_F(ExampleModuleTest, TestPropCount) { const auto instance = Instance(); - auto fb = instance.addFunctionBlock("ExampleScalingModule"); - ASSERT_EQ(fb.getAllProperties().getCount(), 7); + auto fb = instance.addFunctionBlock("ExampleIIRFilter"); + ASSERT_EQ(fb.getAllProperties().getCount(), 6); } TEST_F(ExampleModuleTest, TestDataScaling) { const auto instance = Instance(); - auto fb = instance.addFunctionBlock("ExampleScalingModule"); + auto fb = instance.addFunctionBlock("ExampleIIRFilter"); fb.setPropertyValue("Scale", 2); auto dataDescriptor = DataDescriptorBuilder().setSampleType(SampleType::Float32).setValueRange(Range(-10, 10)).build(); diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt deleted file mode 100644 index c6ccc9d..0000000 --- a/external/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(CMAKE_FOLDER external) -list(APPEND CMAKE_MESSAGE_CONTEXT external) - -if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) - message(FATAL_ERROR "In-source build is not supported!") -endif() - -include(FetchContent) - -add_subdirectory(openDAQ) diff --git a/external/openDAQ/CMakeLists.txt b/external/openDAQ/CMakeLists.txt deleted file mode 100644 index 065369b..0000000 --- a/external/openDAQ/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(OPENDAQ_ENABLE_TESTS false) - -FetchContent_Declare( - openDAQ - GIT_REPOSITORY https://github.com/openDAQ/openDAQ.git - GIT_TAG v3.20.2 - GIT_PROGRESS ON - SYSTEM - FIND_PACKAGE_ARGS 3.20.2 GLOBAL -) - -FetchContent_MakeAvailable(openDAQ) diff --git a/iir1 b/iir1 new file mode 160000 index 0000000..bb21b64 --- /dev/null +++ b/iir1 @@ -0,0 +1 @@ +Subproject commit bb21b64ea2daa9eda92e57763e21c0e322411f34 diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..fe5e8d8 --- /dev/null +++ b/notes.md @@ -0,0 +1,32 @@ +Po instalaciji opendaq-3.30.apt + +in poskusu compile quick_start_full.cpp ne najde work_impl.h obstaja v dir + +dobim error +``` +In file included from /home/nik/Downloads/naloga/examples/applications/cpp/quick_start/quick_start_full.cpp:2: +/opt/opendaq/include/opendaq/work_factory.h:20:10: fatal error: opendaq/work_impl.h: No such file or directory + 20 | #include + | ^~~~~~~~~~~~~~~~~~~~~ +compilation terminated. +make[2]: *** [CMakeFiles/quick_start_full.dir/build.make:76: CMakeFiles/quick_start_full.dir/quick_start_full.cpp.o] Error 1 +make[1]: *** [CMakeFiles/Makefile2:115: CMakeFiles/quick_start_full.dir/all] Error 2 +make: *** [Makefile:91: all] Error 2 +``` + + +[tid: 8406][2026-02-23 11:39:09.966] [ModuleManager] [warning] Failed to check for network settings: open: Operation not permitted [system:1 at /__w/openDAQ/openDAQ/build/__external/src/Boost/libs/asio/include/boost/asio/detail/reactive_socket_service.hpp:133 in function 'open'] + + +sudo apt-get install libudev-dev +sudo apt-get install libfreetype6-dev + + + +Odstranil sem buildanje opendaq in uporabil installiranega + + + + + +