KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_pns_tuning_path_through_pad.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
29
32#include <board.h>
33#include <footprint.h>
34#include <pad.h>
35#include <pcb_track.h>
37
38#include <router/pns_router.h>
40#include <router/pns_topology.h>
41#include <router/pns_item.h>
42#include <router/pns_itemset.h>
43#include <router/pns_line.h>
44#include <router/pns_solid.h>
45
46#include <set>
47
48
54
55
56static wxString refOfSolid( PNS::SOLID* aSolid )
57{
58 if( !aSolid || !aSolid->Parent() || aSolid->Parent()->Type() != PCB_PAD_T )
59 return wxEmptyString;
60
61 return static_cast<PAD*>( aSolid->Parent() )->GetParentFootprint()->GetReference();
62}
63
64
65BOOST_FIXTURE_TEST_CASE( TuningPathWalksThroughInlinePad, TUNING_PATH_FIXTURE )
66{
67 KI_TEST::LoadBoard( m_settingsManager, "tuning_path_through_pad", m_board );
68
69 NETINFO_ITEM* net = m_board->FindNet( "Net-(R1-Pad2)" );
70 BOOST_REQUIRE( net );
71
72 // The in-line resistor pad that the trace routes through.
73 PAD* inlinePad = m_board->FindFootprintByReference( "R1" )->FindPadByNumber( "2" );
74 BOOST_REQUIRE( inlinePad );
75
76 // Reference: the whole-net copper length, as the Net Inspector reports it, plus a start
77 // segment anchored on the resistor pad so the walk must cross TP2 to reach TP1.
78 int64_t fullNetLength = 0;
79 PCB_TRACK* startTrack = nullptr;
80
81 for( PCB_TRACK* t : m_board->Tracks() )
82 {
83 if( t->GetNetCode() != net->GetNetCode() )
84 continue;
85
86 fullNetLength += t->GetLength();
87
88 if( !startTrack && ( t->GetStart() == inlinePad->GetPosition() || t->GetEnd() == inlinePad->GetPosition() ) )
89 startTrack = t;
90 }
91
92 BOOST_REQUIRE( startTrack );
93 BOOST_REQUIRE_GT( fullNetLength, 0 );
94
95 // Build a PNS world from the board the same way the router does.
96 PNS::ROUTER router;
98 iface.SetBoard( m_board.get() );
99 router.SetInterface( &iface );
100 router.ClearWorld();
101 router.SyncWorld();
102
103 PNS::ITEM* startItem = router.GetWorld()->FindItemByParent( startTrack );
104 BOOST_REQUIRE( startItem );
105
106 PNS::TOPOLOGY topo( router.GetWorld() );
107 PNS::SOLID* startPad = nullptr;
108 PNS::SOLID* endPad = nullptr;
109
110 const PNS::ITEM_SET path = topo.AssembleTuningPath( &iface, startItem, &startPad, &endPad );
111
112 std::set<wxString> terminals = { refOfSolid( startPad ), refOfSolid( endPad ) };
113
114 BOOST_TEST_MESSAGE( "terminal pads: " + refOfSolid( startPad ) + " / " + refOfSolid( endPad ) );
115
116 // The path must terminate on the real net ends (TP1 and R1), never on the in-line pad TP2.
117 BOOST_CHECK( terminals.count( "TP1" ) );
118 BOOST_CHECK( terminals.count( "R1" ) );
119 BOOST_CHECK( !terminals.count( "TP2" ) );
120
121 // ... and it must cover (nearly) the whole net, not just one side of TP2.
122 int64_t pathLength = 0;
123
124 for( int i = 0; i < path.Size(); i++ )
125 {
126 if( path[i]->Kind() == PNS::ITEM::LINE_T )
127 pathLength += static_cast<const PNS::LINE*>( path[i] )->CLine().Length();
128 }
129
130 BOOST_TEST_MESSAGE( wxString::Format( "tuned path = %lld nm, full net = %lld nm", pathLength, fullNetLength ) );
131
132 BOOST_CHECK_GT( pathLength, fullNetLength * 9 / 10 );
133}
FOOTPRINT * GetParentFootprint() const
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
const wxString & GetReference() const
Definition footprint.h:841
Handle the data for a net.
Definition netinfo.h:46
int GetNetCode() const
Definition netinfo.h:94
Definition pad.h:61
VECTOR2I GetPosition() const override
Definition pad.cpp:245
Base class for PNS router board items.
Definition pns_item.h:98
BOARD_ITEM * Parent() const
Definition pns_item.h:199
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition pns_line.h:62
ITEM * FindItemByParent(const BOARD_ITEM *aParent)
void ClearWorld()
void SetInterface(ROUTER_IFACE *aIface)
void SyncWorld()
NODE * GetWorld() const
Definition pns_router.h:186
const ITEM_SET AssembleTuningPath(ROUTER_IFACE *aRouterIface, ITEM *aStart, SOLID **aStartPad=nullptr, SOLID **aEndPad=nullptr)
Like AssembleTrivialPath, but follows the track length algorithm, which discards segments that are fu...
void SetBoard(BOARD *aBoard)
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
std::string path
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
static wxString refOfSolid(PNS::SOLID *aSolid)
BOOST_FIXTURE_TEST_CASE(TuningPathWalksThroughInlinePad, TUNING_PATH_FIXTURE)
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:80