Skip to content

Commit ee7eb10

Browse files
committed
FIxed bug in coil additioanl turn redisrtribution
1 parent 335eff7 commit ee7eb10

3 files changed

Lines changed: 114 additions & 22 deletions

File tree

‎src/constructive_models/Coil.cpp‎

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4791,12 +4791,45 @@ bool Coil::wind_toroidal_additional_turns() {
47914791
double currentBaseRadialHeightForLayers = currentBaseRadialHeight + turnsInSection[0].get_dimensions().value()[0] / 2;
47924792

47934793
auto layersThisSection = get_layers_by_section(section.get_name());
4794-
bool areLayersTaped = layersThisSection.size() > 1;
4795-
for (size_t layerIndex = 0; layerIndex < layersThisSection.size() - 1; ++layerIndex) {
4796-
if (layersThisSection[layerIndex].get_type() == ElectricalType::CONDUCTION && layersThisSection[layerIndex + 1].get_type() == ElectricalType::CONDUCTION) {
4797-
areLayersTaped = false;
4794+
// Check if there are at least 2 conduction layers with NO real insulation between them
4795+
// Real insulation = thickness > MIN_INSULATION_THICKNESS
4796+
const double MIN_INSULATION_THICKNESS = 1e-9;
4797+
bool areLayersTaped = true;
4798+
4799+
// Find all conduction layer indices
4800+
std::vector<size_t> conductionLayerIndices;
4801+
for (size_t i = 0; i < layersThisSection.size(); ++i) {
4802+
if (layersThisSection[i].get_type() == ElectricalType::CONDUCTION) {
4803+
conductionLayerIndices.push_back(i);
4804+
}
4805+
}
4806+
4807+
// If we have 2+ conduction layers, check if there's real insulation between any pair
4808+
if (conductionLayerIndices.size() >= 2) {
4809+
areLayersTaped = false; // Assume no tape until we find real insulation
4810+
4811+
for (size_t i = 0; i < conductionLayerIndices.size() - 1; ++i) {
4812+
size_t firstCondIdx = conductionLayerIndices[i];
4813+
size_t secondCondIdx = conductionLayerIndices[i + 1];
4814+
4815+
// Check all layers between these two conduction layers
4816+
bool hasRealInsulation = false;
4817+
for (size_t j = firstCondIdx + 1; j < secondCondIdx; ++j) {
4818+
if (layersThisSection[j].get_type() == ElectricalType::INSULATION) {
4819+
double insulationThickness = layersThisSection[j].get_dimensions()[0];
4820+
if (insulationThickness > MIN_INSULATION_THICKNESS) {
4821+
hasRealInsulation = true;
4822+
break;
4823+
}
4824+
}
4825+
}
4826+
4827+
if (hasRealInsulation) {
4828+
areLayersTaped = true;
4829+
}
47984830
}
47994831
}
4832+
48004833
for (auto layer : layersThisSection) {
48014834
if (layer.get_type() == ElectricalType::CONDUCTION) {
48024835
auto turnsThisLayer = get_turns_by_layer(layer.get_name());

‎src/support/BasicPainter.cpp‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -919,10 +919,6 @@ void BasicPainter::paint_toroidal_core(Core core) {
919919
std::string cssClassName = generate_random_string();
920920
_root.style("." + cssClassName).set_attr("stroke-width", strokeWidth * _scale).set_attr("fill", "none").set_attr("stroke", std::regex_replace(std::string(settings.get_painter_color_ferrite()), std::regex("0x"), "#"));
921921
paint_circle(0, 0, circleDiameter / 2, cssClassName, nullptr);
922-
923-
// _root.autoscale();
924-
_root.set_attr("width", _imageWidth * _scale).set_attr("height", _imageHeight * _scale); // TODO remove
925-
_root.set_attr("viewBox", std::to_string(-_imageWidth / 2 * _scale) + " " + std::to_string(-_imageHeight / 2 * _scale) + " " + std::to_string(_imageWidth * _scale) + " " + std::to_string(_imageHeight * _scale)); // TODO remove
926922
}
927923

928924
void BasicPainter::paint_two_piece_set_margin(Magnetic magnetic) {
@@ -2617,6 +2613,10 @@ void BasicPainter::paint_temperature_field(Magnetic magnetic, const std::map<std
26172613
}
26182614

26192615
std::string BasicPainter::export_svg() {
2616+
// Autoscale to fit all content before exporting
2617+
// This ensures proper centering when additional turns extend asymmetrically
2618+
_root.autoscale();
2619+
26202620
if (!_filepath.empty()) {
26212621
if (!std::filesystem::exists(_filepath)) {
26222622
std::filesystem::create_directory(_filepath);

‎tests/TestCoil.cpp‎

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9190,8 +9190,7 @@ TEST_CASE("Test_Additiona_Turns_Bug", "[constructive-model][coil][round-winding-
91909190
auto turns = coil.get_turns_description().value();
91919191
auto layers = coil.get_layers_description().value();
91929192

9193-
std::cout << "Number of layers: " << layers.size() << std::endl;
9194-
9193+
91959194
// Check that all turns have additional coordinates
91969195
for (auto& turn : turns) {
91979196
REQUIRE(turn.get_additional_coordinates());
@@ -9203,11 +9202,6 @@ TEST_CASE("Test_Additiona_Turns_Bug", "[constructive-model][coil][round-winding-
92039202
turnsByLayer[turns[i].get_layer().value()].push_back(i);
92049203
}
92059204

9206-
std::cout << "Turns per layer:" << std::endl;
9207-
for (auto& [layerName, indices] : turnsByLayer) {
9208-
std::cout << " " << layerName << ": " << indices.size() << " turns" << std::endl;
9209-
}
9210-
92119205
// Collect all additional radii
92129206
std::vector<double> additionalRadii;
92139207
for (size_t i = 0; i < turns.size(); ++i) {
@@ -9222,13 +9216,7 @@ TEST_CASE("Test_Additiona_Turns_Bug", "[constructive-model][coil][round-winding-
92229216
// Round to 0.1mm precision
92239217
uniqueRadii.insert(round(r * 10000) / 10000);
92249218
}
9225-
9226-
std::cout << "Unique additional radii: ";
9227-
for (auto r : uniqueRadii) {
9228-
std::cout << r * 1000 << "mm ";
9229-
}
9230-
std::cout << std::endl;
9231-
9219+
92329220
// The bug was that additional turns from layer 1 were placed at a different radius
92339221
// than turns from layer 0, even though there was space in the first additional layer.
92349222
// After the fix, all additional turns should be at the same radius (compacted).
@@ -10477,4 +10465,75 @@ TEST_CASE("Test_Toroidal_Delimit_And_Compact_Multilayer", "[toroidal][coil][comp
1047710465
settings.reset();
1047810466
}
1047910467

10468+
TEST_CASE("Test_Coil_Compacting_Tertiary_Winding", "[constructive-model][coil][bug][visualization]") {
10469+
auto testDataPath = get_test_data_path(std::source_location::current(), "bug_coil_compacting.json");
10470+
std::ifstream file(testDataPath);
10471+
REQUIRE(file.good());
10472+
10473+
json j;
10474+
file >> j;
10475+
10476+
auto magneticJson = j["magnetic"];
10477+
auto coilJson = magneticJson["coil"];
10478+
auto coreJson = magneticJson["core"];
10479+
10480+
OpenMagnetics::Coil coil(coilJson);
10481+
OpenMagnetics::Core core(coreJson);
10482+
10483+
// Enable compacting and additional coordinates
10484+
settings.set_coil_delimit_and_compact(true);
10485+
settings.set_coil_include_additional_coordinates(true);
10486+
10487+
// Wind the coil
10488+
coil.wind();
10489+
10490+
// Check if we have turns
10491+
REQUIRE(coil.get_turns_description().has_value());
10492+
auto turns = coil.get_turns_description().value();
10493+
10494+
// Create magnetic for visualization
10495+
OpenMagnetics::Magnetic magnetic;
10496+
magnetic.set_coil(coil);
10497+
magnetic.set_core(core);
10498+
10499+
// Paint the coil with core
10500+
auto outputFilePath = std::filesystem::path{std::source_location::current().file_name()}.parent_path().append("..").append("output");
10501+
auto outFile = outputFilePath;
10502+
outFile.append("Test_Coil_Compacting_Tertiary_Winding.svg");
10503+
std::filesystem::remove(outFile);
10504+
10505+
Painter painter(outFile);
10506+
painter.paint_core(magnetic);
10507+
painter.paint_bobbin(magnetic);
10508+
painter.paint_coil_sections(magnetic);
10509+
painter.paint_coil_turns(magnetic);
10510+
painter.export_svg();
10511+
10512+
// Analyze turns by winding
10513+
std::map<std::string, std::vector<Turn>> turnsByWinding;
10514+
for (const auto& turn : turns) {
10515+
turnsByWinding[turn.get_winding()].push_back(turn);
10516+
}
10517+
10518+
// Check each winding has additional coordinates
10519+
for (const auto& [windingName, windingTurns] : turnsByWinding) {
10520+
int withAdditional = 0;
10521+
int withoutAdditional = 0;
10522+
10523+
for (const auto& turn : windingTurns) {
10524+
if (turn.get_additional_coordinates().has_value()) {
10525+
withAdditional++;
10526+
} else {
10527+
withoutAdditional++;
10528+
}
10529+
}
10530+
10531+
// All turns should have additional coordinates
10532+
REQUIRE(withoutAdditional == 0);
10533+
}
10534+
10535+
settings.reset();
10536+
}
10537+
10538+
1048010539
} // namespace

0 commit comments

Comments
 (0)