From d62601142cd053a9980745f2654d1539ff05fd9f Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 11:50:55 +0200 Subject: [PATCH 1/8] Allow RealTimeSimulation to be initialized with CommandLineArgs Signed-off-by: Niklas Eiling --- dpsim/include/dpsim/RealTimeSimulation.h | 1 + dpsim/src/RealTimeSimulation.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/dpsim/include/dpsim/RealTimeSimulation.h b/dpsim/include/dpsim/RealTimeSimulation.h index ff3246d3e5..5829f0497d 100644 --- a/dpsim/include/dpsim/RealTimeSimulation.h +++ b/dpsim/include/dpsim/RealTimeSimulation.h @@ -24,6 +24,7 @@ class RealTimeSimulation : public Simulation { Timer mTimer; public: + RealTimeSimulation(String name, CommandLineArgs &args); /// Standard constructor RealTimeSimulation(String name, CPS::Logger::Level logLevel = CPS::Logger::Level::info); diff --git a/dpsim/src/RealTimeSimulation.cpp b/dpsim/src/RealTimeSimulation.cpp index 03fbe8209d..ba94868ecd 100644 --- a/dpsim/src/RealTimeSimulation.cpp +++ b/dpsim/src/RealTimeSimulation.cpp @@ -14,6 +14,9 @@ using namespace CPS; using namespace DPsim; +RealTimeSimulation::RealTimeSimulation(String name, CommandLineArgs &args) + : Simulation(name, args), mTimer(){}; + RealTimeSimulation::RealTimeSimulation(String name, Logger::Level logLevel) : Simulation(name, logLevel), mTimer() { From ee20880d599f5b80f669770339c385d06838fa1f Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 11:54:30 +0200 Subject: [PATCH 2/8] villas-interface: add FpgaExample to CMakeLists Signed-off-by: Niklas Eiling --- dpsim-villas/examples/cxx/CMakeLists.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dpsim-villas/examples/cxx/CMakeLists.txt b/dpsim-villas/examples/cxx/CMakeLists.txt index 4ea80b857f..a767829a38 100644 --- a/dpsim-villas/examples/cxx/CMakeLists.txt +++ b/dpsim-villas/examples/cxx/CMakeLists.txt @@ -10,11 +10,14 @@ list(APPEND LIBRARIES ${VILLASNODE_LIBRARIES}) list(APPEND LIBRARIES "jansson") list(APPEND LIBRARIES "uuid") list(APPEND LIBRARIES "villas-common") +list(APPEND LIBRARIES "villas-fpga") +list(APPEND LIBRARIES "xil") list(APPEND INCLUDE_DIRS ${VILLASNODE_INCLUDE_DIRS}) set(SHMEM_SOURCES FileExample.cpp MqttExample.cpp + FpgaExample.cpp SharedMemExample.cpp #ShmemExample.cpp #ShmemDistributedReference.cpp @@ -27,11 +30,7 @@ set(SHMEM_SOURCES ) if(WITH_CIM) - set(CIM_SHMEM_SOURCES - #Shmem_WSCC-9bus.cpp - #Shmem_WSCC-9bus_Ctrl.cpp - #Shmem_WSCC-9bus_CtrlDist.cpp - ) + list(APPEND INCLUDE_DIRS ${CIMPP_INCLUDE_DIRS}) endif() foreach(SOURCE ${SHMEM_SOURCES} ${CIM_SHMEM_SOURCES}) From df2aaea892504cb73c26955920b68fd76990701a Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 11:55:46 +0200 Subject: [PATCH 3/8] villas-interface: Update FpgaExample with close-loop example Signed-off-by: Niklas Eiling --- dpsim-villas/examples/cxx/FpgaExample.cpp | 154 ++++++++++++++-------- 1 file changed, 100 insertions(+), 54 deletions(-) diff --git a/dpsim-villas/examples/cxx/FpgaExample.cpp b/dpsim-villas/examples/cxx/FpgaExample.cpp index 08cb887e39..dbe2d30bc3 100644 --- a/dpsim-villas/examples/cxx/FpgaExample.cpp +++ b/dpsim-villas/examples/cxx/FpgaExample.cpp @@ -1,91 +1,137 @@ -// SPDX-License-Identifier: Apache-2.0 +/* Simple test circuit for testing connection to a FPGA via VILLASnode + * + * Author: Niklas Eiling + * SPDX-FileCopyrightText: 2024 Niklas Eiling + * SPDX-License-Identifier: Apache-2.0 + */ +#include #include #include +#include +#include #include +#include using namespace DPsim; using namespace CPS::DP; using namespace CPS::DP::Ph1; int main(int argc, char *argv[]) { - // Very simple test circuit. Just a few resistors and an inductance. - // Voltage is read from VILLASnode and current through everything is written back. - String simName = "Fpga_example"; - CPS::Logger::setLogDir("logs/" + simName); - Real timeStep = 0.01; + CommandLineArgs args(argc, argv, "FpgaExample", 0.01, 10 * 60, 5.); + std::filesystem::path fpgaIpPath = + "/usr/local/etc/villas/node/etc/fpga/vc707-xbar-pcie-dino/" + "vc707-xbar-pcie-dino.json"; + + if (args.options.find("ips") != args.options.end()) { + fpgaIpPath = std::filesystem::path(args.getOptionString("ips")); + } + CPS::Logger::setLogDir("logs/" + args.name); // Nodes auto n1 = SimNode::make("n1"); auto n2 = SimNode::make("n2"); - auto n3 = SimNode::make("n3"); - auto n4 = SimNode::make("n4"); // Components - auto evs = VoltageSource::make("v_s"); - evs->setParameters(Complex(5, 0)); + auto vs = VoltageSource::make("v_s"); + vs->setParameters(Complex(10, 0), args.sysFreq); auto rs = Resistor::make("r_s"); rs->setParameters(1); - auto rl = Resistor::make("r_line"); - rl->setParameters(1); - auto ll = Inductor::make("l_line"); - ll->setParameters(1); - auto rL = Resistor::make("r_load"); - rL->setParameters(1000); + + auto cs = CurrentSource::make("i_l"); + cs->setParameters(Complex(0, 0)); // Topology - evs->connect({SimNode::GND, n1}); + vs->connect({SimNode::GND, n1}); rs->connect({n1, n2}); - rl->connect({n2, n3}); - ll->connect({n3, n4}); - rL->connect({n4, SimNode::GND}); + cs->connect({n2, SimNode::GND}); - auto sys = SystemTopology(50, SystemNodeList{SimNode::GND, n1, n2, n3, n4}, - SystemComponentList{evs, rs, rl, ll, rL}); + auto sys = SystemTopology(args.sysFreq, SystemNodeList{SimNode::GND, n1, n2}, + SystemComponentList{vs, rs, cs}); - RealTimeSimulation sim(simName); + RealTimeSimulation sim(args.name, args); sim.setSystem(sys); - sim.setTimeStep(timeStep); - sim.setFinalTime(10.0); - - std::string fpgaConfig = R"STRING({ - type = "fpga", - card = { - interface = "pcie", - id = "10ee:7021", - slot = "0000:88:00.0", - do_reset = true, - ips = "../../fpga/vc707-xbar-pcie-dino/vc707-xbar-pcie-dino-v2.json", - polling = true, - }, - connect = ["0->3", "dino<-dma", "dino->dma"], - signals = ({ name = "dino", unit = "Volts", type = "float"}), - builtin = false, - lowLatencyMode = true, - })STRING"; - - auto intf = std::make_shared(fpgaConfig); + + std::string cardConfig = fmt::format( + R"STRING("card": {{ + "interface": "pcie", + "id": "10ee:7021", + "slot": "0000:88:00.0", + "do_reset": true, + "ips": "{}", + "polling": true + }}, + "connect": [ + "0->3", + "dino<-dma", + "dino->dma" + ], + "low_latency_mode": true, + "timestep": {})STRING", + fpgaIpPath.string(), args.timeStep); + std::string signalOutConfig = fmt::format( + R"STRING("out": {{ + "signals": [{{ + "name": "from_dpsim", + "type": "complex", + "unit": "V" + }}], + "hooks": [{{ + "type": "dp", + "signal": "from_dpsim", + "f0": {}, + "dt": {}, + "harmonics": [0], + "inverse": true + }}] + }})STRING", + args.sysFreq, args.timeStep); + std::string signalInConfig = fmt::format( + R"STRING("in": {{ + "signals": [{{ + "name": "to_dpsim", + "type": "float", + "unit": "V", + "builtin": false + }}], + "hooks": ["print", {{ + "type": "dp", + "signal": "to_dpsim", + "f0": {}, + "dt": {}, + "harmonics": [0], + "inverse": false + }}] + }})STRING", + args.sysFreq, args.timeStep); + std::string config = fmt::format( + R"STRING({{ + "type": "fpga", + {}, + {}, + {} + }})STRING", + cardConfig, signalOutConfig, signalInConfig); + DPsim::Logger::get("FpgaExample")->debug("Config for Node:\n{}", config); + + auto intf = std::make_shared(config); // Interface + intf->importAttribute(cs->mCurrentRef, 0, false, false, "from_dino", "A"); + intf->exportAttribute(n2->mVoltage->deriveCoeff(0, 0), 0, true, + "to_dino", "V"); sim.addInterface(intf); - intf->importAttribute(evs->mVoltageRef, 0, true, true); - intf->exportAttribute(evs->mIntfVoltage->deriveCoeff(0, 0), 0, true, - "v_src"); + intf->printVillasSignals(); // Logger - auto logger = DataLogger::make(simName); + auto logger = DataLogger::make(args.name); logger->logAttribute("v1", n1->mVoltage); logger->logAttribute("v2", n2->mVoltage); - logger->logAttribute("v3", n3->mVoltage); - logger->logAttribute("v4", n4->mVoltage); - logger->logAttribute("v_src", evs->mVoltageRef); - logger->logAttribute("i_r", rl->mIntfCurrent, 1, 1); - logger->logAttribute("i_evs", evs->mIntfCurrent, 1, 1); - logger->logAttribute("v_evs", evs->mIntfVoltage, 1, 1); + logger->logAttribute("cs_i", cs->mIntfCurrent); sim.addLogger(logger); - sim.run(1); + sim.run(); //std::ofstream of("task_dependencies.svg"); //sim.dependencyGraph().render(of); From 63a54360074a3de762beb9bafcadef6dac4a77fc Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 11:56:51 +0200 Subject: [PATCH 4/8] villas-interface: make signals more verbose Signed-off-by: Niklas Eiling --- .../include/dpsim-villas/InterfaceVillas.h | 5 ++- .../dpsim-villas/InterfaceWorkerVillas.h | 5 ++- dpsim-villas/src/InterfaceVillas.cpp | 12 ++++-- dpsim-villas/src/InterfaceWorkerVillas.cpp | 40 +++++++++++++++---- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/dpsim-villas/include/dpsim-villas/InterfaceVillas.h b/dpsim-villas/include/dpsim-villas/InterfaceVillas.h index dfd409faa8..388450140d 100644 --- a/dpsim-villas/include/dpsim-villas/InterfaceVillas.h +++ b/dpsim-villas/include/dpsim-villas/InterfaceVillas.h @@ -39,7 +39,8 @@ class InterfaceVillas : public Interface, /// @param syncOnSimulationStart Whether the simulation should block before the first timestep until this attribute has been updated void importAttribute(CPS::AttributeBase::Ptr attr, UInt idx, Bool blockOnRead = false, - Bool syncOnSimulationStart = true); + Bool syncOnSimulationStart = true, + const String &name = "", const String &unit = ""); /// @brief configure an attribute export /// @param attr the attribute which's value should be exported @@ -50,5 +51,7 @@ class InterfaceVillas : public Interface, void exportAttribute(CPS::AttributeBase::Ptr attr, UInt idx, Bool waitForOnWrite, const String &name = "", const String &unit = ""); + + void printVillasSignals() const; }; } // namespace DPsim diff --git a/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h b/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h index 713b2c590e..1d7695c624 100644 --- a/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h +++ b/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h @@ -65,12 +65,15 @@ class InterfaceWorkerVillas : public InterfaceWorker, std::vector &updatedAttrs) override; virtual void configureImport(UInt attributeId, const std::type_info &type, - UInt idx); + UInt idx, const String &name = "", + const String &unit = ""); virtual void configureExport(UInt attributeId, const std::type_info &type, UInt idx, Bool waitForOnWrite, const String &name = "", const String &unit = ""); + void printSignals() const; + private: void prepareNode(); void setupNodeSignals(); diff --git a/dpsim-villas/src/InterfaceVillas.cpp b/dpsim-villas/src/InterfaceVillas.cpp index c28c410288..5feb144bd8 100644 --- a/dpsim-villas/src/InterfaceVillas.cpp +++ b/dpsim-villas/src/InterfaceVillas.cpp @@ -16,11 +16,12 @@ InterfaceVillas::InterfaceVillas(const String &nodeConfig, UInt queueLength, void InterfaceVillas::importAttribute(CPS::AttributeBase::Ptr attr, UInt idx, Bool blockOnRead, - Bool syncOnSimulationStart) { + Bool syncOnSimulationStart, + const String &name, const String &unit) { Interface::addImport(attr, blockOnRead, syncOnSimulationStart); std::dynamic_pointer_cast(mInterfaceWorker) ->configureImport((UInt)mImportAttrsDpsim.size() - 1, attr->getType(), - idx); + idx, name, unit); } void InterfaceVillas::exportAttribute(CPS::AttributeBase::Ptr attr, UInt idx, @@ -32,4 +33,9 @@ void InterfaceVillas::exportAttribute(CPS::AttributeBase::Ptr attr, UInt idx, idx, waitForOnWrite, name, unit); } -} // namespace DPsim \ No newline at end of file +void InterfaceVillas::printVillasSignals() const { + std::dynamic_pointer_cast(mInterfaceWorker) + ->printSignals(); +} + +} // namespace DPsim diff --git a/dpsim-villas/src/InterfaceWorkerVillas.cpp b/dpsim-villas/src/InterfaceWorkerVillas.cpp index 7326e76331..b3efbf3d78 100644 --- a/dpsim-villas/src/InterfaceWorkerVillas.cpp +++ b/dpsim-villas/src/InterfaceWorkerVillas.cpp @@ -109,6 +109,7 @@ void InterfaceWorkerVillas::prepareNode() { ret); std::exit(1); } + SPDLOG_LOGGER_INFO(mLog, "Node: {}", mNode->getNameFull()); mNode->getFactory()->start( nullptr); //We have no SuperNode, so just hope type_start doesnt use it... @@ -141,8 +142,12 @@ void InterfaceWorkerVillas::setupNodeSignals() { idx++; } - node::SignalList::Ptr nodeInputSignals = mNode->getInputSignals(false); - nodeInputSignals->clear(); + node::SignalList::Ptr nodeInputSignals = mNode->getInputSignals(true); + if (nodeInputSignals == nullptr) { + nodeInputSignals = std::make_shared(); + } else { + nodeInputSignals->clear(); + } idx = 0; for (const auto &[id, signal] : mImportSignals) { while (id > idx) { @@ -488,7 +493,8 @@ void InterfaceWorkerVillas::configureExport(UInt attributeId, void InterfaceWorkerVillas::configureImport(UInt attributeId, const std::type_info &type, - UInt idx) { + UInt idx, const String &name, + const String &unit) { if (mOpened) { if (mLog != nullptr) { SPDLOG_LOGGER_WARN(mLog, "InterfaceVillas has already been opened! " @@ -518,7 +524,7 @@ void InterfaceWorkerVillas::configureImport(UInt attributeId, }, 0); mImportSignals[idx] = - std::make_shared("", "", node::SignalType::INTEGER); + std::make_shared(name, unit, node::SignalType::INTEGER); } else if (type == typeid(Real)) { mImports.emplace_back( [idx, log](Sample *smp) -> AttributeBase::Ptr { @@ -531,7 +537,7 @@ void InterfaceWorkerVillas::configureImport(UInt attributeId, }, 0); mImportSignals[idx] = - std::make_shared("", "", node::SignalType::FLOAT); + std::make_shared(name, unit, node::SignalType::FLOAT); } else if (type == typeid(Complex)) { mImports.emplace_back( [idx, log](Sample *smp) -> AttributeBase::Ptr { @@ -544,7 +550,7 @@ void InterfaceWorkerVillas::configureImport(UInt attributeId, }, 0); mImportSignals[idx] = - std::make_shared("", "", node::SignalType::COMPLEX); + std::make_shared(name, unit, node::SignalType::COMPLEX); } else if (type == typeid(Bool)) { mImports.emplace_back( [idx, log](Sample *smp) -> AttributeBase::Ptr { @@ -557,7 +563,7 @@ void InterfaceWorkerVillas::configureImport(UInt attributeId, }, 0); mImportSignals[idx] = - std::make_shared("", "", node::SignalType::BOOLEAN); + std::make_shared(name, unit, node::SignalType::BOOLEAN); } else { if (mLog != nullptr) { SPDLOG_LOGGER_WARN(mLog, "Unsupported attribute type! Interface " @@ -565,3 +571,23 @@ void InterfaceWorkerVillas::configureImport(UInt attributeId, } } } + +void InterfaceWorkerVillas::printSignals() const { + SPDLOG_LOGGER_INFO( + mLog, + "InterfaceWorkerVillas Settings: Queue Length: {}, Sample Length: {}", + mQueueLength, mSampleLength); + SPDLOG_LOGGER_INFO(mLog, "Export signals:"); + for (const auto &[id, signal] : mExportSignals) { + SPDLOG_LOGGER_INFO(mLog, "ID: {}, Name: {}, Unit: {}, Type: {}", id, + signal->name, signal->unit, + node::signalTypeToString(signal->type)); + } + + SPDLOG_LOGGER_INFO(mLog, "Import signals:"); + for (const auto &[id, signal] : mImportSignals) { + SPDLOG_LOGGER_INFO(mLog, "ID: {}, Name: {}, Unit: {}, Type: {}", id, + signal->name, signal->unit, + node::signalTypeToString(signal->type)); + } +} From a505ef7356a6867350a6e0b38bc0cfdaa54b6f0b Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 14:11:54 +0200 Subject: [PATCH 5/8] pybind: update parameters of InterfaceVillas::importAttribute Signed-off-by: Niklas Eiling --- dpsim-villas/src/pybind-dpsim-villas.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dpsim-villas/src/pybind-dpsim-villas.cpp b/dpsim-villas/src/pybind-dpsim-villas.cpp index dc33e2534d..067ce5c614 100644 --- a/dpsim-villas/src/pybind-dpsim-villas.cpp +++ b/dpsim-villas/src/pybind-dpsim-villas.cpp @@ -43,7 +43,8 @@ PYBIND11_MODULE(dpsimpyvillas, m) { "name"_a = "", "downsampling"_a = 1) .def("import_attribute", &PyInterfaceVillas::importAttribute, "attr"_a, // cppcheck-suppress assignBoolToPointer - "idx"_a, "block_on_read"_a = false, "sync_on_start"_a = true) + "idx"_a, "block_on_read"_a = false, "sync_on_start"_a = true, + "name"_a = "", "unit"_a = "") .def("export_attribute", &PyInterfaceVillas::exportAttribute, "attr"_a, // cppcheck-suppress assignBoolToPointer "idx"_a, "wait_for_on_write"_a = true, "name"_a = "", "unit"_a = ""); From 86da1f1d6bc7353540ff0f45e8a2cce10010322a Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 15:40:10 +0200 Subject: [PATCH 6/8] Dockerfile: Update VILLAS_VERSION Signed-off-by: Niklas Eiling --- packaging/Docker/Dockerfile.dev | 2 +- packaging/Docker/Dockerfile.dev-debian | 2 +- packaging/Docker/Dockerfile.manylinux | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/Docker/Dockerfile.dev b/packaging/Docker/Dockerfile.dev index 4eb81ea9ed..fbb314e6c1 100644 --- a/packaging/Docker/Dockerfile.dev +++ b/packaging/Docker/Dockerfile.dev @@ -1,7 +1,7 @@ FROM fedora:36 AS base ARG CIM_VERSION=CGMES_2.4.15_16FEB2016 -ARG VILLAS_VERSION=66569cf9c43d2d7a4626b9a84321c4e340d3fe18 +ARG VILLAS_VERSION=bda163e99bda145b03847af33bd3c0a1a9bfb94d ARG CMAKE_OPTS ARG MAKE_OPTS=-j4 diff --git a/packaging/Docker/Dockerfile.dev-debian b/packaging/Docker/Dockerfile.dev-debian index 46dff10309..49a6d86bd5 100644 --- a/packaging/Docker/Dockerfile.dev-debian +++ b/packaging/Docker/Dockerfile.dev-debian @@ -1,7 +1,7 @@ FROM debian:11 ARG CIM_VERSION=CGMES_2.4.15_16FEB2016 -ARG VILLAS_VERSION=66569cf9c43d2d7a4626b9a84321c4e340d3fe18 +ARG VILLAS_VERSION=bda163e99bda145b03847af33bd3c0a1a9bfb94d ARG CMAKE_OPTS ARG MAKE_OPTS=-j4 diff --git a/packaging/Docker/Dockerfile.manylinux b/packaging/Docker/Dockerfile.manylinux index 756b7d8cd9..dc28e588ed 100644 --- a/packaging/Docker/Dockerfile.manylinux +++ b/packaging/Docker/Dockerfile.manylinux @@ -6,7 +6,7 @@ FROM quay.io/pypa/manylinux_2_28_x86_64 ARG CIM_VERSION=CGMES_2.4.15_16FEB2016 -ARG VILLAS_VERSION=66569cf9c43d2d7a4626b9a84321c4e340d3fe18 +ARG VILLAS_VERSION=bda163e99bda145b03847af33bd3c0a1a9bfb94d ARG CMAKE_OPTS ARG MAKE_OPTS=-j4 From 95fb64c28afb0e63342e77e4d13175bf0fffa505 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Thu, 6 Jun 2024 15:41:12 +0200 Subject: [PATCH 7/8] FpgaExample: allow different topologies to be tested Signed-off-by: Niklas Eiling --- dpsim-villas/examples/cxx/FpgaExample.cpp | 118 ++++++++++++++++------ 1 file changed, 85 insertions(+), 33 deletions(-) diff --git a/dpsim-villas/examples/cxx/FpgaExample.cpp b/dpsim-villas/examples/cxx/FpgaExample.cpp index dbe2d30bc3..8953ccf12e 100644 --- a/dpsim-villas/examples/cxx/FpgaExample.cpp +++ b/dpsim-villas/examples/cxx/FpgaExample.cpp @@ -18,8 +18,7 @@ using namespace DPsim; using namespace CPS::DP; using namespace CPS::DP::Ph1; -int main(int argc, char *argv[]) { - CommandLineArgs args(argc, argv, "FpgaExample", 0.01, 10 * 60, 5.); +const std::string buildFpgaConfig(CommandLineArgs &args) { std::filesystem::path fpgaIpPath = "/usr/local/etc/villas/node/etc/fpga/vc707-xbar-pcie-dino/" "vc707-xbar-pcie-dino.json"; @@ -27,32 +26,6 @@ int main(int argc, char *argv[]) { if (args.options.find("ips") != args.options.end()) { fpgaIpPath = std::filesystem::path(args.getOptionString("ips")); } - CPS::Logger::setLogDir("logs/" + args.name); - - // Nodes - auto n1 = SimNode::make("n1"); - auto n2 = SimNode::make("n2"); - - // Components - auto vs = VoltageSource::make("v_s"); - vs->setParameters(Complex(10, 0), args.sysFreq); - auto rs = Resistor::make("r_s"); - rs->setParameters(1); - - auto cs = CurrentSource::make("i_l"); - cs->setParameters(Complex(0, 0)); - - // Topology - vs->connect({SimNode::GND, n1}); - rs->connect({n1, n2}); - cs->connect({n2, SimNode::GND}); - - auto sys = SystemTopology(args.sysFreq, SystemNodeList{SimNode::GND, n1, n2}, - SystemComponentList{vs, rs, cs}); - - RealTimeSimulation sim(args.name, args); - sim.setSystem(sys); - std::string cardConfig = fmt::format( R"STRING("card": {{ "interface": "pcie", @@ -105,7 +78,7 @@ int main(int argc, char *argv[]) { }}] }})STRING", args.sysFreq, args.timeStep); - std::string config = fmt::format( + const std::string config = fmt::format( R"STRING({{ "type": "fpga", {}, @@ -114,23 +87,102 @@ int main(int argc, char *argv[]) { }})STRING", cardConfig, signalOutConfig, signalInConfig); DPsim::Logger::get("FpgaExample")->debug("Config for Node:\n{}", config); + return config; +} + +SystemTopology loopbackTopology(CommandLineArgs &args, + std::shared_ptr intf, + std::shared_ptr logger) { + // Nodes + auto n1 = SimNode::make("n1"); + + // Components + auto vs = VoltageSource::make("v_s"); + vs->setParameters(Complex(10, 0), args.sysFreq); + auto rl = Resistor::make("r_l"); + rl->setParameters(1); + + // Topology + vs->connect({SimNode::GND, n1}); + rl->connect({n1, SimNode::GND}); + + // Interface + intf->importAttribute(vs->mVoltageRef, 0, false, false, "from_dino", "A"); + intf->exportAttribute(n1->mVoltage->deriveCoeff(0, 0), 0, true, + "to_dino", "V"); + intf->printVillasSignals(); - auto intf = std::make_shared(config); + // Logger + logger->logAttribute("v1", n1->mVoltage); + logger->logAttribute("rl_i", rl->mIntfCurrent); + + return SystemTopology(args.sysFreq, SystemNodeList{SimNode::GND, n1}, + SystemComponentList{vs, rl}); +} + +SystemTopology hilTopology(CommandLineArgs &args, + std::shared_ptr intf, + std::shared_ptr logger) { + // Nodes + auto n1 = SimNode::make("n1"); + auto n2 = SimNode::make("n2"); + + // Components + auto vs = VoltageSource::make("v_s"); + vs->setParameters(Complex(10, 0), args.sysFreq); + auto rs = Resistor::make("r_s"); + rs->setParameters(1); + + auto cs = CurrentSource::make("i_l"); + cs->setParameters(Complex(0, 0)); + + // Topology + vs->connect({SimNode::GND, n1}); + rs->connect({n1, n2}); + cs->connect({n2, SimNode::GND}); // Interface intf->importAttribute(cs->mCurrentRef, 0, false, false, "from_dino", "A"); intf->exportAttribute(n2->mVoltage->deriveCoeff(0, 0), 0, true, "to_dino", "V"); - sim.addInterface(intf); intf->printVillasSignals(); // Logger - auto logger = DataLogger::make(args.name); logger->logAttribute("v1", n1->mVoltage); logger->logAttribute("v2", n2->mVoltage); logger->logAttribute("cs_i", cs->mIntfCurrent); - sim.addLogger(logger); + return SystemTopology(args.sysFreq, SystemNodeList{SimNode::GND, n1, n2}, + SystemComponentList{vs, rs, cs}); +} + +SystemTopology getTopology(CommandLineArgs &args, + std::shared_ptr intf, + std::shared_ptr logger) { + if (args.options.find("topology") != args.options.end()) { + std::string topology = args.getOptionString("topology"); + if (topology == "hil") { + return hilTopology(args, intf, logger); + } else if (topology == "loopback") { + return loopbackTopology(args, intf, logger); + } + } + return hilTopology(args, intf, logger); +} + +int main(int argc, char *argv[]) { + CommandLineArgs args(argc, argv, "FpgaExample", 0.01, 10 * 60, 5.); + CPS::Logger::setLogDir("logs/" + args.name); + + auto intf = std::make_shared(buildFpgaConfig(args)); + auto logger = DataLogger::make(args.name); + + auto sys = getTopology(args, intf, logger); + + RealTimeSimulation sim(args.name, args); + sim.setSystem(sys); + sim.addInterface(intf); + sim.addLogger(logger); sim.run(); //std::ofstream of("task_dependencies.svg"); From 0f913be7eef4b3f9de17d9b1c00153f699fedc4c Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Fri, 7 Jun 2024 16:15:52 +0200 Subject: [PATCH 8/8] villas inteface: fix interface between villas and dpsim Signed-off-by: Niklas Eiling --- dpsim-villas/include/dpsim-villas/InterfaceVillas.h | 4 ++-- dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h | 4 ++-- dpsim/include/dpsim/InterfaceWorker.h | 2 +- packaging/Docker/Dockerfile.dev | 2 +- packaging/Docker/Dockerfile.dev-debian | 2 +- packaging/Docker/Dockerfile.manylinux | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dpsim-villas/include/dpsim-villas/InterfaceVillas.h b/dpsim-villas/include/dpsim-villas/InterfaceVillas.h index 388450140d..66ee20dde4 100644 --- a/dpsim-villas/include/dpsim-villas/InterfaceVillas.h +++ b/dpsim-villas/include/dpsim-villas/InterfaceVillas.h @@ -5,10 +5,10 @@ #include #include -#include #include -#include #include +#include +#include #include #include #include diff --git a/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h b/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h index 1d7695c624..24a04a176d 100644 --- a/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h +++ b/dpsim-villas/include/dpsim-villas/InterfaceWorkerVillas.h @@ -5,10 +5,10 @@ #include #include -#include #include -#include #include +#include +#include #include #include #include diff --git a/dpsim/include/dpsim/InterfaceWorker.h b/dpsim/include/dpsim/InterfaceWorker.h index fa5ce10df7..e169d6b546 100644 --- a/dpsim/include/dpsim/InterfaceWorker.h +++ b/dpsim/include/dpsim/InterfaceWorker.h @@ -57,4 +57,4 @@ class InterfaceWorker { */ virtual void close() = 0; }; -} // namespace DPsim \ No newline at end of file +} // namespace DPsim diff --git a/packaging/Docker/Dockerfile.dev b/packaging/Docker/Dockerfile.dev index fbb314e6c1..f52fb3e436 100644 --- a/packaging/Docker/Dockerfile.dev +++ b/packaging/Docker/Dockerfile.dev @@ -1,7 +1,7 @@ FROM fedora:36 AS base ARG CIM_VERSION=CGMES_2.4.15_16FEB2016 -ARG VILLAS_VERSION=bda163e99bda145b03847af33bd3c0a1a9bfb94d +ARG VILLAS_VERSION=411b0ad49e2629ad41c6918d2a6c51e9a72220b4 ARG CMAKE_OPTS ARG MAKE_OPTS=-j4 diff --git a/packaging/Docker/Dockerfile.dev-debian b/packaging/Docker/Dockerfile.dev-debian index 49a6d86bd5..800dbef43a 100644 --- a/packaging/Docker/Dockerfile.dev-debian +++ b/packaging/Docker/Dockerfile.dev-debian @@ -1,7 +1,7 @@ FROM debian:11 ARG CIM_VERSION=CGMES_2.4.15_16FEB2016 -ARG VILLAS_VERSION=bda163e99bda145b03847af33bd3c0a1a9bfb94d +ARG VILLAS_VERSION=411b0ad49e2629ad41c6918d2a6c51e9a72220b4 ARG CMAKE_OPTS ARG MAKE_OPTS=-j4 diff --git a/packaging/Docker/Dockerfile.manylinux b/packaging/Docker/Dockerfile.manylinux index dc28e588ed..5f425c31c0 100644 --- a/packaging/Docker/Dockerfile.manylinux +++ b/packaging/Docker/Dockerfile.manylinux @@ -6,7 +6,7 @@ FROM quay.io/pypa/manylinux_2_28_x86_64 ARG CIM_VERSION=CGMES_2.4.15_16FEB2016 -ARG VILLAS_VERSION=bda163e99bda145b03847af33bd3c0a1a9bfb94d +ARG VILLAS_VERSION=411b0ad49e2629ad41c6918d2a6c51e9a72220b4 ARG CMAKE_OPTS ARG MAKE_OPTS=-j4