From 27422891d6f7cebae03aac67ced73f9ac04cc37f Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Mon, 21 Jul 2025 12:49:22 -0500 Subject: [PATCH 1/2] Enable complete type objects from opendds_idl. Increase stack size on Windows. --- tactical-microgrid-standard/CMakeLists.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tactical-microgrid-standard/CMakeLists.txt b/tactical-microgrid-standard/CMakeLists.txt index 50ee2f9..6c8dfba 100644 --- a/tactical-microgrid-standard/CMakeLists.txt +++ b/tactical-microgrid-standard/CMakeLists.txt @@ -19,7 +19,7 @@ opendds_target_sources(TMS_Common PUBLIC common/mil-std-3071_data_model.idl INCLUDE_BASE ${CMAKE_CURRENT_SOURCE_DIR} - OPENDDS_IDL_OPTIONS -Lc++11 + OPENDDS_IDL_OPTIONS -Lc++11 -Gxtypes-complete ) target_link_libraries(TMS_Common PUBLIC OpenDDS::Rtps_Udp) target_compile_features(TMS_Common PUBLIC cxx_std_17) @@ -29,7 +29,7 @@ add_library(Commands_Idl) opendds_target_sources(Commands_Idl PUBLIC cli_idl/CLICommands.idl - OPENDDS_IDL_OPTIONS -Lc++11 -I${CMAKE_CURRENT_SOURCE_DIR} + OPENDDS_IDL_OPTIONS -Lc++11 -Gxtypes-complete -I${CMAKE_CURRENT_SOURCE_DIR} INCLUDE_BASE ${CMAKE_CURRENT_SOURCE_DIR} ) target_link_libraries(Commands_Idl PUBLIC TMS_Common) @@ -43,7 +43,7 @@ opendds_export_header(PowerSim_Idl) opendds_target_sources(PowerSim_Idl PUBLIC power_devices/PowerSim.idl - OPENDDS_IDL_OPTIONS -Lc++11 -I${CMAKE_CURRENT_SOURCE_DIR} + OPENDDS_IDL_OPTIONS -Lc++11 -Gxtypes-complete -I${CMAKE_CURRENT_SOURCE_DIR} INCLUDE_BASE ${CMAKE_CURRENT_SOURCE_DIR} ) target_link_libraries(PowerSim_Idl PUBLIC TMS_Common) @@ -87,4 +87,16 @@ add_executable(Distribution target_include_directories(Distribution PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(Distribution PRIVATE PowerSim_Idl) +# Generated code with complete type objects enabled for the TMS IDL file +# causes stack overflow on Windows. +# Increase the stack size to 2MB (default is 1MB). +if (MSVC) + target_link_options(Controller PRIVATE "/STACK:2097152") + target_link_options(CLI PRIVATE "/STACK:2097152") + target_link_options(Source PRIVATE "/STACK:2097152") + target_link_options(Load PRIVATE "/STACK:2097152") + target_link_options(Distribution PRIVATE "/STACK:2097152") +endif() + + add_subdirectory(tests) From 03ec846ebeae962bf34a367ed9d2b5167f68a634 Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Wed, 23 Jul 2025 12:19:49 -0500 Subject: [PATCH 2/2] Release lock when connecting devices on CLI to avoid heartbeats not being processed --- tactical-microgrid-standard/cli/CLIClient.cpp | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tactical-microgrid-standard/cli/CLIClient.cpp b/tactical-microgrid-standard/cli/CLIClient.cpp index c4c85bd..c8a4d18 100644 --- a/tactical-microgrid-standard/cli/CLIClient.cpp +++ b/tactical-microgrid-standard/cli/CLIClient.cpp @@ -457,6 +457,7 @@ bool CLIClient::can_connect(const tms::Identity& id1, tms::DeviceRole role1, return false; } + std::lock_guard guard(data_m_); const bool dev1_is_not_connected = power_connections_.count(id1) == 0 || power_connections_.at(id1).empty(); const bool dev2_is_not_connected = power_connections_.count(id2) == 0 || power_connections_.at(id2).empty(); @@ -472,6 +473,7 @@ bool CLIClient::can_connect(const tms::Identity& id1, tms::DeviceRole role1, void CLIClient::connect(const tms::Identity& id1, tms::DeviceRole role1, const tms::Identity& id2, tms::DeviceRole role2) { + std::lock_guard guard(data_m_); power_connections_[id1].insert(powersim::ConnectedDevice{id2, role2}); power_connections_[id2].insert(powersim::ConnectedDevice{id1, role1}); } @@ -498,25 +500,36 @@ void CLIClient::consolidate_power_devices() // Each connection simulates a physical connection using a power cable. void CLIClient::connect_power_devices() { - std::lock_guard guard(data_m_); - if (power_devices_.empty()) { - consolidate_power_devices(); + // Reading input from user for connecting devices can take long. + // So we work on a copy of the power devices list and release the lock + // so that the CLI can continue processing heartbeats from MCs and + // does not incorrectly report available MCs as unavailable. + PowerDevices local_pds; + { + std::lock_guard guard(data_m_); + if (power_devices_.empty()) { + consolidate_power_devices(); + } + local_pds = power_devices_; } - for (auto it1 = power_devices_.begin(); it1 != power_devices_.end(); ++it1) { + for (auto it1 = local_pds.begin(); it1 != local_pds.end(); ++it1) { const tms::Identity& id1 = it1->first; const tms::DeviceRole role1 = it1->second.device_info().role(); auto it2 = it1; ++it2; - std::cout << "Select devices to connect to device Id: " << id1 << std::endl; - for (; it2 != power_devices_.end(); ++it2) { + if (it2 != local_pds.end()) { + std::cout << "=== Connections for device Id: " << id1 << std::endl; + } + + for (; it2 != local_pds.end(); ++it2) { const tms::Identity& id2 = it2->first; const tms::DeviceRole role2 = it2->second.device_info().role(); if (!can_connect(id1, role1, id2, role2)) { continue; } - std::cout << "Connect to device Id: " << id2 << " (Y/n)"; + std::cout << " Connect to device Id: " << id2 << " (Y/n)> "; while (true) { std::string line; std::getline(std::cin, line); @@ -535,6 +548,7 @@ void CLIClient::connect_power_devices() // Send the power topology to the current controller which then // distributes the power connections to its managed power devices. + std::lock_guard guard(data_m_); powersim::PowerTopology pt; pt.connections().reserve(power_connections_.size()); CORBA::ULong i = 0;