KiCad PCB EDA Suite
pns_log.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 (C) 2020-2021 KiCad Developers.
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, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include "pns_log.h"
25 
26 #include <qa/drc_proto/drc_proto.h>
27 
28 #include <board_design_settings.h>
29 #include <pcbnew/drc/drc_engine.h>
31 
32 using namespace PNS;
33 
34 static const wxString readLine( FILE* f )
35 {
36  char str[16384];
37  fgets( str, sizeof( str ) - 1, f );
38  return wxString( str );
39 }
40 
41 
43 {
44  m_routerSettings.reset( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
45 }
46 
47 
48 bool PNS_LOG_FILE::Load( const std::string& logName, const std::string boardName )
49 {
50  FILE* f = fopen( logName.c_str(), "rb" );
51 
52  if( !f )
53  return false;
54 
55  while( !feof( f ) )
56  {
57  wxStringTokenizer tokens( readLine( f ) );
58 
59  if( !tokens.CountTokens() )
60  continue;
61 
62  wxString cmd = tokens.GetNextToken();
63 
64  if( cmd == "event" )
65  {
66  EVENT_ENTRY evt;
67  evt.p.x = wxAtoi( tokens.GetNextToken() );
68  evt.p.y = wxAtoi( tokens.GetNextToken() );
69  evt.type = (PNS::LOGGER::EVENT_TYPE) wxAtoi( tokens.GetNextToken() );
70  evt.uuid = KIID( tokens.GetNextToken() );
71  m_events.push_back( evt );
72  }
73  else if( cmd == "config" )
74  {
75  m_routerSettings->SetMode( (PNS::PNS_MODE) wxAtoi( tokens.GetNextToken() ) );
76  m_routerSettings->SetRemoveLoops( wxAtoi( tokens.GetNextToken() ) );
77  m_routerSettings->SetFixAllSegments( wxAtoi( tokens.GetNextToken() ) );
78  }
79  }
80 
81  fclose( f );
82 
83  try
84  {
85  PCB_IO io;
86  m_board.reset( io.Load( boardName.c_str(), nullptr, nullptr ) );
87 
88  std::shared_ptr<DRC_ENGINE> drcEngine( new DRC_ENGINE );
89 
90  CONSOLE_LOG consoleLog;
91  BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
92 
93  bds.m_DRCEngine = drcEngine;
94 
95  drcEngine->SetBoard( m_board.get() );
96  drcEngine->SetDesignSettings( &bds );
97  drcEngine->SetLogReporter( new CONSOLE_MSG_REPORTER( &consoleLog ) );
98  drcEngine->InitEngine( wxFileName() );
99  }
100  catch( const PARSE_ERROR& parse_error )
101  {
102  printf( "parse error : %s (%s)\n", (const char*) parse_error.Problem().c_str(),
103  (const char*) parse_error.What().c_str() );
104 
105  return false;
106  }
107 
108  return true;
109 }
110 
111 
113 {
114 }
115 
116 
118 {
119 }
120 
121 
123 {
124  m_mode = mode;
125 }
126 
127 
129 {
130  m_iface.reset( new PNS_KICAD_IFACE_BASE );
131  m_router.reset( new ROUTER );
132  m_iface->SetBoard( m_board.get() );
133  m_router->SetInterface( m_iface.get() );
134  m_router->ClearWorld();
135  m_router->SetMode( m_mode );
136  m_router->SyncWorld();
137  m_router->LoadSettings( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
138  m_router->Settings().SetMode( PNS::RM_Walkaround );
139  m_router->Sizes().SetTrackWidth( 250000 );
140 
141  //m_router->Settings().SetOptimizeDraggedTrack( true );
142 
143  m_debugDecorator.Clear();
144  m_iface->SetDebugDecorator( &m_debugDecorator );
145 }
146 
147 void PNS_TEST_ENVIRONMENT::ReplayLog ( PNS_LOG_FILE* aLog, int aStartEventIndex, int aFrom,
148  int aTo )
149 {
150 
151  m_board = aLog->GetBoard();
152 
153  createRouter();
154 
155  m_router->LoadSettings( aLog->GetRoutingSettings() );
156 
157  printf("Router mode: %d\n", m_router->Settings().Mode() );
158 
159  for( auto evt : aLog->Events() )
160  {
161  auto item = aLog->ItemById(evt);
162  ITEM* ritem = item ? m_router->GetWorld()->FindItemByParent( item ) : nullptr;
163 
164  switch(evt.type)
165  {
167  {
168  m_debugDecorator.NewStage( "route-start", 0 );
169  printf( " rtr start-route (%d, %d) %p \n", evt.p.x, evt.p.y, ritem );
170  m_router->StartRouting( evt.p, ritem, ritem ? ritem->Layers().Start() : F_Cu );
171  break;
172  }
173 
175  {
176  m_debugDecorator.NewStage( "drag-start", 0 );
177  bool rv = m_router->StartDragging( evt.p, ritem, 0 );
178  printf( " rtr start-drag (%d, %d) %p ret %d\n", evt.p.x, evt.p.y, ritem, rv ? 1 : 0 );
179  break;
180  }
181 
182  case LOGGER::EVT_FIX:
183  {
184  break;
185  }
186 
187  case LOGGER::EVT_MOVE:
188  {
189  m_debugDecorator.NewStage( "move", 0 );
190  printf( " move -> (%d, %d)\n", evt.p.x, evt.p.y );
191  m_router->Move( evt.p, ritem );
192  break;
193  }
194 
195  default:
196  break;
197  }
198 
199  PNS::NODE* node = nullptr;
200 
201  if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
202  {
203 #if 0
204  m_debugDecorator.BeginGroup( "head");
205 
206  auto traces = m_router->Placer()->Traces();
207 
208  for( const auto& t : traces.CItems() )
209  {
210  const LINE *l = static_cast<LINE*>(t.item);
211  const auto& sh = l->CLine();
212 
213  m_debugDecorator.AddLine( sh, 4, 10000 );
214  }
215 
216  m_debugDecorator.EndGroup();
217 #endif
218 
219  node = m_router->Placer()->CurrentNode( true );
220  }
221  else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
222  {
223  node = m_router->GetDragger()->CurrentNode();
224  }
225 
226  if( !node )
227  return;
228 
229  NODE::ITEM_VECTOR removed, added;
230 
231  node->GetUpdatedItems( removed, added );
232 
233 #if 0
234  if( ! added.empty() )
235  {
236  bool first = true;
237  m_debugDecorator.BeginGroup( "node-added-items");
238 
239  for( auto t : added )
240  {
241  if( t->OfKind( PNS::ITEM::SEGMENT_T ) )
242  {
243  auto s = static_cast<PNS::SEGMENT*>( t );
244  m_debugDecorator.AddSegment( s->Seg(), 2 );
245  first = false;
246  }
247  }
248 
249  m_debugDecorator.EndGroup();
250  }
251 #endif
252  }
253 }
254 
255 
257 {
258  if( m_stages.empty() )
259  m_stages.push_back( new STAGE() );
260 
261  return m_stages.back();
262 }
263 
264 
266  const SRC_LOCATION_INFO& aSrcLoc )
267 {
268  STAGE* st = currentStage();
269  DEBUG_ENT *ent = new DEBUG_ENT();
270 
271  ent->m_name = name;
272  ent->m_iter = m_iter;
273 
274  if( m_activeEntry )
275  {
276  m_activeEntry->AddChild( ent );
277  }
278 
279  printf( "LOG BeginGroup %s %p\n", name.c_str(), ent );
280 
281  m_activeEntry = ent;
282  m_grouping = true;
283 }
284 
285 
287 {
288  printf( "LOG EndGroup\n" );
289 
290  if( !m_activeEntry )
291  return;
292 
293  m_activeEntry = m_activeEntry->m_parent;
294 
295  if( !m_activeEntry )
296  m_grouping = false;
297 }
298 
300 {
301  auto st = currentStage();
302  m_activeEntry->AddChild( ent );
303 }
304 
305 
306 /* virtual void AddLine( const SHAPE_LINE_CHAIN& aLine, const KIGFX::COLOR4D& aColor,
307  int aWidth, const std::string aName,
308  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override;
309  virtual void AddSegment( SEG aS, const KIGFX::COLOR4D& aColor,
310  const std::string aName,
311  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override;
312  virtual void AddBox( BOX2I aB, const KIGFX::COLOR4D& aColor,
313  const std::string aName,
314  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override;
315 */
316 
317 
319  int aSize, const std::string& aName,
320  const SRC_LOCATION_INFO& aSrcLoc )
321 {
322  auto sh = new SHAPE_LINE_CHAIN;
323 
324  sh->Append( aP.x - aSize, aP.y - aSize );
325  sh->Append( aP.x + aSize, aP.y + aSize );
326  sh->Append( aP.x, aP.y );
327  sh->Append( aP.x - aSize, aP.y + aSize );
328  sh->Append( aP.x + aSize, aP.y - aSize );
329 
330  DEBUG_ENT* ent = new DEBUG_ENT();
331 
332  ent->m_shapes.push_back( sh );
333  ent->m_color = aColor;
334  ent->m_width = 30000;
335  ent->m_iter = m_iter;
336  ent->m_name = aName;
337  ent->m_hasLabels = false;
338  ent->m_srcLoc = aSrcLoc;
339 
340  addEntry( ent );
341 }
342 
343 
345  int aWidth, const std::string& aName,
346  const SRC_LOCATION_INFO& aSrcLoc )
347 {
348  auto sh = new SHAPE_LINE_CHAIN( aLine );
349  DEBUG_ENT* ent = new DEBUG_ENT();
350 
351  ent->m_shapes.push_back( sh );
352  ent->m_color = aColor;
353  ent->m_width = aWidth;
354  ent->m_name = aName;
355  ent->m_iter = m_iter;
356  ent->m_srcLoc = aSrcLoc;
357 
358  addEntry( ent );
359 }
360 
361 
363  const std::string& aName,
364  const SRC_LOCATION_INFO& aSrcLoc )
365 {
366  auto sh = new SHAPE_LINE_CHAIN( { aS.A, aS.B } );
367  DEBUG_ENT* ent = new DEBUG_ENT();
368 
369  ent->m_shapes.push_back( sh );
370  ent->m_color = aColor;
371  ent->m_width = 10000;
372  ent->m_name = aName;
373  ent->m_iter = m_iter;
374  ent->m_srcLoc = aSrcLoc;
375 
376  addEntry( ent );
377 }
378 
379 
381  const std::string& aName, const SRC_LOCATION_INFO& aSrcLoc )
382 {
383  auto sh = new SHAPE_RECT( aB.GetPosition(), aB.GetWidth(), aB.GetHeight() );
384  DEBUG_ENT* ent = new DEBUG_ENT();
385 
386  ent->m_shapes.push_back( sh );
387  ent->m_color = aColor;
388  ent->m_width = 10000;
389  ent->m_name = aName;
390  ent->m_iter = m_iter;
391  ent->m_srcLoc = aSrcLoc;
392  addEntry( ent );
393 }
394 
395 
396 void PNS_TEST_DEBUG_DECORATOR::Message( const wxString& msg, const SRC_LOCATION_INFO& aSrcLoc )
397 {
398  DEBUG_ENT* ent = new DEBUG_ENT();
399  ent->m_msg = msg.c_str();
400  ent->m_srcLoc = aSrcLoc;
401  addEntry( ent );
402 }
403 
404 
405 void PNS_TEST_DEBUG_DECORATOR::NewStage( const std::string& name, int iter,
406  const SRC_LOCATION_INFO& aSrcLoc )
407 {
408  m_stages.push_back( new STAGE );
409  m_activeEntry = m_stages.back()->m_entries;
410 }
411 
412 
414  std::function<bool( PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT* )> visitor, int depth )
415 {
416  if( !visitor( this ) )
417  return;
418 
419 
420  for( auto child : m_children )
421  {
422  child->IterateTree( visitor, depth + 1 );
423  }
424 }
425 
426 
428 {
429  STAGE* st = m_stages[stage];
430  BOX2I bb;
431  bool first = true;
432 
433  auto visitor = [&]( DEBUG_ENT* ent ) -> bool {
434  for( auto sh : ent->m_shapes )
435  {
436  if( first )
437  bb = sh->BBox();
438  else
439  bb.Merge( sh->BBox() );
440 
441  first = false;
442  }
443 
444  return true;
445  };
446 
447  return bb;
448 }
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:137
bool Load(const std::string &logName, const std::string boardName)
Definition: pns_log.cpp:48
Base class for PNS router board items.
Definition: pns_item.h:55
Contain all persistent settings of the router, such as the mode, optimization effort,...
Design Rule Checker object that performs all the DRC tests.
Definition: drc_engine.h:81
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
Keep the router "world" - i.e.
Definition: pns_node.h:144
static const wxString readLine(FILE *f)
Definition: pns_log.cpp:34
PNS_MODE
< Routing modes
void addEntry(DEBUG_ENT *ent)
Definition: pns_log.cpp:299
std::vector< SHAPE * > m_shapes
Definition: pns_log.h:173
std::vector< EVENT_ENTRY > & Events()
Definition: pns_log.h:93
KIID uuid
Definition: pns_log.h:71
std::shared_ptr< BOARD > GetBoard() const
Definition: pns_log.h:95
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:60
BOARD_CONNECTED_ITEM * ItemById(const EVENT_ENTRY &evt)
Definition: pns_log.h:77
PNS::ROUTING_SETTINGS * GetRoutingSettings() const
Definition: pns_log.h:99
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
virtual void NewStage(const std::string &name, int iter, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:405
int Start() const
Definition: pns_layerset.h:82
Definition: kiid.h:44
Definition: pns_log.h:66
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
void SetMode(PNS::ROUTER_MODE mode)
Definition: pns_log.cpp:122
coord_type GetWidth() const
Definition: box2.h:180
PNS::LOGGER::EVENT_TYPE type
Definition: pns_log.h:69
virtual void AddBox(const BOX2I &aB, const KIGFX::COLOR4D &aColor, const std::string &aName, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:380
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
BOX2I GetStageExtents(int stage) const
Definition: pns_log.cpp:427
const Vec & GetPosition() const
Definition: box2.h:177
virtual void AddSegment(const SEG &aS, const KIGFX::COLOR4D &aColor, const std::string &aName, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:362
Definition: seg.h:40
void IterateTree(std::function< bool(DEBUG_ENT *)> visitor, int depth=0)
Definition: pns_log.cpp:413
ROUTER_MODE
Definition: pns_router.h:62
PNS::DEBUG_DECORATOR::SRC_LOCATION_INFO m_srcLoc
Definition: pns_log.h:181
virtual void Message(const wxString &msg, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:396
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:118
virtual void AddPoint(const VECTOR2I &aP, const KIGFX::COLOR4D &aColor, int aSize, const std::string &aName, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:318
const char * name
Definition: DXF_plotter.cpp:56
virtual void BeginGroup(const std::string &name, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:265
Represent a polyline (an zero-thickness chain of connected line segments).
virtual void EndGroup(const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:286
Definition: layer_ids.h:70
VECTOR2I A
Definition: seg.h:48
VECTOR2I p
Definition: pns_log.h:68
coord_type GetHeight() const
Definition: box2.h:181
Only walk around.
void GetUpdatedItems(ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
Return the list of items removed and added in this branch with respect to the root branch.
Definition: pns_node.cpp:1321
BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr) override
Load information from some input file format that this PLUGIN implementation knows about into either ...
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, const KIGFX::COLOR4D &aColor, int aWidth, const std::string &aName, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:344
Push and Shove diff pair dimensions (gap) settings dialog.
void ReplayLog(PNS_LOG_FILE *aLog, int aStartEventIndex=0, int aFrom=0, int aTo=-1)
Definition: pns_log.cpp:147
std::shared_ptr< DRC_ENGINE > m_DRCEngine
const LAYER_RANGE & Layers() const
Definition: pns_item.h:152
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:148
Container for design settings for a BOARD object.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103
VECTOR2I B
Definition: seg.h:49