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 #include <pns_arc.h>
32 
33 
34 #define PNSLOGINFO PNS::DEBUG_DECORATOR::SRC_LOCATION_INFO( __FILE__, __FUNCTION__, __LINE__ )
35 
36 using namespace PNS;
37 
38 static const wxString readLine( FILE* f )
39 {
40  char str[16384];
41  fgets( str, sizeof( str ) - 1, f );
42  return wxString( str );
43 }
44 
45 
47 {
48  m_routerSettings.reset( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
49 }
50 
51 
52 bool PNS_LOG_FILE::Load( const std::string& logName, const std::string boardName )
53 {
54  FILE* f = fopen( logName.c_str(), "rb" );
55 
56  if( !f )
57  return false;
58 
59  while( !feof( f ) )
60  {
61  wxStringTokenizer tokens( readLine( f ) );
62 
63  if( !tokens.CountTokens() )
64  continue;
65 
66  wxString cmd = tokens.GetNextToken();
67 
68  if( cmd == "event" )
69  {
70  EVENT_ENTRY evt;
71  evt.p.x = wxAtoi( tokens.GetNextToken() );
72  evt.p.y = wxAtoi( tokens.GetNextToken() );
73  evt.type = (PNS::LOGGER::EVENT_TYPE) wxAtoi( tokens.GetNextToken() );
74  evt.uuid = KIID( tokens.GetNextToken() );
75  m_events.push_back( evt );
76  }
77  else if( cmd == "config" )
78  {
79  m_routerSettings->SetMode( (PNS::PNS_MODE) wxAtoi( tokens.GetNextToken() ) );
80  m_routerSettings->SetRemoveLoops( wxAtoi( tokens.GetNextToken() ) );
81  m_routerSettings->SetFixAllSegments( wxAtoi( tokens.GetNextToken() ) );
82  m_routerSettings->SetCornerMode(
83  (DIRECTION_45::CORNER_MODE) wxAtoi( tokens.GetNextToken() ) );
84  }
85  }
86 
87  fclose( f );
88 
89  try
90  {
91  PCB_PLUGIN io;
92  m_board.reset( io.Load( boardName.c_str(), nullptr, nullptr ) );
93 
94  std::shared_ptr<DRC_ENGINE> drcEngine( new DRC_ENGINE );
95 
96  CONSOLE_LOG consoleLog;
97  BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
98 
99  bds.m_DRCEngine = drcEngine;
100 
101  drcEngine->SetBoard( m_board.get() );
102  drcEngine->SetDesignSettings( &bds );
103  drcEngine->SetLogReporter( new CONSOLE_MSG_REPORTER( &consoleLog ) );
104  drcEngine->InitEngine( wxFileName() );
105  }
106  catch( const PARSE_ERROR& parse_error )
107  {
108  printf( "parse error : %s (%s)\n", (const char*) parse_error.Problem().c_str(),
109  (const char*) parse_error.What().c_str() );
110 
111  return false;
112  }
113 
114  return true;
115 }
116 
117 
119 {
120 }
121 
122 
124 {
125 }
126 
127 
129 {
130  m_mode = mode;
131 }
132 
133 
135 {
136  m_iface.reset( new PNS_KICAD_IFACE_BASE );
137  m_router.reset( new ROUTER );
138  m_iface->SetBoard( m_board.get() );
139  m_router->SetInterface( m_iface.get() );
140  m_router->ClearWorld();
141  m_router->SetMode( m_mode );
142  m_router->SyncWorld();
143  m_router->LoadSettings( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
144  m_router->Settings().SetMode( PNS::RM_Walkaround );
145  m_router->Sizes().SetTrackWidth( 250000 );
146 
147  //m_router->Settings().SetOptimizeDraggedTrack( true );
148 
149  m_debugDecorator.Clear();
150  m_iface->SetDebugDecorator( &m_debugDecorator );
151 }
152 
153 void PNS_TEST_ENVIRONMENT::ReplayLog ( PNS_LOG_FILE* aLog, int aStartEventIndex, int aFrom,
154  int aTo )
155 {
156 
157  m_board = aLog->GetBoard();
158 
159  createRouter();
160 
161  m_router->LoadSettings( aLog->GetRoutingSettings() );
162 
163  printf("Router mode: %d\n", m_router->Settings().Mode() );
164 
165  for( auto evt : aLog->Events() )
166  {
167  auto item = aLog->ItemById(evt);
168  ITEM* ritem = item ? m_router->GetWorld()->FindItemByParent( item ) : nullptr;
169 
170  switch(evt.type)
171  {
173  {
174  m_debugDecorator.NewStage( "route-start", 0, PNSLOGINFO );
175  m_debugDecorator.Message( wxString::Format( "route-start (%d, %d)", evt.p.x, evt.p.y ) );
176  printf( " rtr start-route (%d, %d) %p \n", evt.p.x, evt.p.y, ritem );
177  m_router->StartRouting( evt.p, ritem, ritem ? ritem->Layers().Start() : F_Cu );
178  break;
179  }
180 
182  {
183  m_debugDecorator.NewStage( "drag-start", 0, PNSLOGINFO );
184  m_debugDecorator.Message( wxString::Format( "drag-start (%d, %d)", evt.p.x, evt.p.y ) );
185  bool rv = m_router->StartDragging( evt.p, ritem, 0 );
186  printf( " rtr start-drag (%d, %d) %p ret %d\n", evt.p.x, evt.p.y, ritem, rv ? 1 : 0 );
187  break;
188  }
189 
190  case LOGGER::EVT_FIX:
191  {
192  m_debugDecorator.NewStage( "fix", 0, PNSLOGINFO );
193  m_debugDecorator.Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
194  bool rv = m_router->FixRoute( evt.p, ritem );
195  printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
196  break;
197  }
198 
199  case LOGGER::EVT_MOVE:
200  {
201  m_debugDecorator.NewStage( "move", 0, PNSLOGINFO );
202  m_debugDecorator.Message( wxString::Format( "move (%d, %d)", evt.p.x, evt.p.y ) );
203  printf( " move -> (%d, %d)\n", evt.p.x, evt.p.y );
204  m_router->Move( evt.p, ritem );
205  break;
206  }
207 
208  default:
209  break;
210  }
211 
212  PNS::NODE* node = nullptr;
213 
214  if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
215  {
216 #if 1
217  m_debugDecorator.BeginGroup( "current route", PNSLOGINFO );
218 
219  auto traces = m_router->Placer()->Traces();
220 
221  for( const auto& t : traces.CItems() )
222  {
223  const LINE *l = static_cast<LINE*>(t.item);
224  const auto& sh = l->CLine();
225 
226  m_debugDecorator.AddLine( sh, YELLOW, l->Width(), "line seg",
227  PNSLOGINFO );
228  }
229 
230  m_debugDecorator.EndGroup( PNSLOGINFO );
231 #endif
232 
233  node = m_router->Placer()->CurrentNode( true );
234  }
235  else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
236  {
237  node = m_router->GetDragger()->CurrentNode();
238  }
239 
240  if( !node )
241  return;
242 
243  NODE::ITEM_VECTOR removed, added;
244 
245  node->GetUpdatedItems( removed, added );
246 
247 #if 1
248  if( ! added.empty() )
249  {
250  bool first = true;
251  m_debugDecorator.BeginGroup( "node-added-items", PNSLOGINFO );
252 
253  for( auto t : added )
254  {
255  if( t->OfKind( PNS::ITEM::SEGMENT_T ) )
256  {
257  auto s = static_cast<PNS::SEGMENT*>( t );
258  m_debugDecorator.AddLine( SHAPE_LINE_CHAIN( { s->Seg().A, s->Seg().B } ),
259  MAGENTA, s->Width(), "seg",
260  PNSLOGINFO );
261  first = false;
262  }
263  else if( t->OfKind( PNS::ITEM::ARC_T ) )
264  {
265  PNS::ARC* arc = static_cast<PNS::ARC*>( t );
266  m_debugDecorator.AddLine( SHAPE_LINE_CHAIN( arc->Arc() ), MAGENTA,
267  arc->Width(), "arc", PNSLOGINFO );
268  first = false;
269  }
270  }
271 
272  m_debugDecorator.EndGroup( PNSLOGINFO );
273  }
274 #endif
275  }
276 }
277 
278 
280 {
281  if( m_stages.empty() )
282  m_stages.push_back( new STAGE() );
283 
284  return m_stages.back();
285 }
286 
287 
289  const SRC_LOCATION_INFO& aSrcLoc )
290 {
291  STAGE* st = currentStage();
292  DEBUG_ENT *ent = new DEBUG_ENT();
293 
294  ent->m_name = name;
295  ent->m_iter = m_iter;
296 
297  if( m_activeEntry )
298  {
299  m_activeEntry->AddChild( ent );
300  }
301 
302  printf( "LOG BeginGroup %s %p\n", name.c_str(), ent );
303 
304  m_activeEntry = ent;
305  m_grouping = true;
306 }
307 
308 
310 {
311  printf( "LOG EndGroup\n" );
312 
313  if( !m_activeEntry )
314  return;
315 
316  m_activeEntry = m_activeEntry->m_parent;
317 
318  if( !m_activeEntry )
319  m_grouping = false;
320 }
321 
323 {
324  auto st = currentStage();
325  m_activeEntry->AddChild( ent );
326 }
327 
328 
329 /* virtual void AddLine( const SHAPE_LINE_CHAIN& aLine, const KIGFX::COLOR4D& aColor,
330  int aWidth, const std::string aName,
331  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override;
332  virtual void AddSegment( SEG aS, const KIGFX::COLOR4D& aColor,
333  const std::string aName,
334  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override;
335  virtual void AddBox( BOX2I aB, const KIGFX::COLOR4D& aColor,
336  const std::string aName,
337  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override;
338 */
339 
340 
342  int aSize, const std::string& aName,
343  const SRC_LOCATION_INFO& aSrcLoc )
344 {
345  auto sh = new SHAPE_LINE_CHAIN;
346 
347  sh->Append( aP.x - aSize, aP.y - aSize );
348  sh->Append( aP.x + aSize, aP.y + aSize );
349  sh->Append( aP.x, aP.y );
350  sh->Append( aP.x - aSize, aP.y + aSize );
351  sh->Append( aP.x + aSize, aP.y - aSize );
352 
353  DEBUG_ENT* ent = new DEBUG_ENT();
354 
355  ent->m_shapes.push_back( sh );
356  ent->m_color = aColor;
357  ent->m_width = 30000;
358  ent->m_iter = m_iter;
359  ent->m_name = aName;
360  ent->m_hasLabels = false;
361  ent->m_srcLoc = aSrcLoc;
362 
363  addEntry( ent );
364 }
365 
366 
368  int aWidth, const std::string& aName,
369  const SRC_LOCATION_INFO& aSrcLoc )
370 {
371  auto sh = new SHAPE_LINE_CHAIN( aLine );
372  DEBUG_ENT* ent = new DEBUG_ENT();
373 
374  ent->m_shapes.push_back( sh );
375  ent->m_color = aColor;
376  ent->m_width = aWidth;
377  ent->m_name = aName;
378  ent->m_iter = m_iter;
379  ent->m_srcLoc = aSrcLoc;
380 
381  addEntry( ent );
382 }
383 
384 
386  const std::string& aName,
387  const SRC_LOCATION_INFO& aSrcLoc )
388 {
389  auto sh = new SHAPE_LINE_CHAIN( { aS.A, aS.B } );
390  DEBUG_ENT* ent = new DEBUG_ENT();
391 
392  ent->m_shapes.push_back( sh );
393  ent->m_color = aColor;
394  ent->m_width = 10000;
395  ent->m_name = aName;
396  ent->m_iter = m_iter;
397  ent->m_srcLoc = aSrcLoc;
398 
399  addEntry( ent );
400 }
401 
402 
404  const std::string& aName, const SRC_LOCATION_INFO& aSrcLoc )
405 {
406  auto sh = new SHAPE_RECT( aB.GetPosition(), aB.GetWidth(), aB.GetHeight() );
407  DEBUG_ENT* ent = new DEBUG_ENT();
408 
409  ent->m_shapes.push_back( sh );
410  ent->m_color = aColor;
411  ent->m_width = 10000;
412  ent->m_name = aName;
413  ent->m_iter = m_iter;
414  ent->m_srcLoc = aSrcLoc;
415  addEntry( ent );
416 }
417 
418 
419 void PNS_TEST_DEBUG_DECORATOR::Message( const wxString& msg, const SRC_LOCATION_INFO& aSrcLoc )
420 {
421  DEBUG_ENT* ent = new DEBUG_ENT();
422  ent->m_msg = msg.c_str();
423  ent->m_srcLoc = aSrcLoc;
424  addEntry( ent );
425 }
426 
427 
428 void PNS_TEST_DEBUG_DECORATOR::NewStage( const std::string& name, int iter,
429  const SRC_LOCATION_INFO& aSrcLoc )
430 {
431  STAGE* stage = new STAGE();
432  stage->m_name = name;
433  stage->m_iter = iter;
434 
435  m_stages.push_back( new STAGE);
436  m_activeEntry = m_stages.back()->m_entries;
437 }
438 
439 
441  std::function<bool( PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT* )> visitor, int depth )
442 {
443  if( !visitor( this ) )
444  return;
445 
446 
447  for( auto child : m_children )
448  {
449  child->IterateTree( visitor, depth + 1 );
450  }
451 }
452 
453 
455 {
456  STAGE* st = m_stages[stage];
457  BOX2I bb;
458  bool first = true;
459 
460  auto visitor = [&]( DEBUG_ENT* ent ) -> bool {
461  for( auto sh : ent->m_shapes )
462  {
463  if( first )
464  bb = sh->BBox();
465  else
466  bb.Merge( sh->BBox() );
467 
468  first = false;
469  }
470 
471  return true;
472  };
473 
474  return bb;
475 }
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:52
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
Keep the router "world" - i.e.
Definition: pns_node.h:146
static const wxString readLine(FILE *f)
Definition: pns_log.cpp:38
PNS_MODE
< Routing modes
void addEntry(DEBUG_ENT *ent)
Definition: pns_log.cpp:322
int Width() const override
Definition: pns_arc.h:87
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
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
Definition: pcb_plugin.h:141
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
SHAPE_ARC & Arc()
Definition: pns_arc.h:114
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:428
int Start() const
Definition: pns_layerset.h:82
#define PNSLOGINFO
Definition: pns_log.cpp:34
Definition: color4d.h:67
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:128
coord_type GetWidth() const
Definition: box2.h:180
CORNER_MODE
Corner modes.
Definition: direction45.h:66
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:403
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:454
const Vec & GetPosition() const
Definition: box2.h:177
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 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:385
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Definition: seg.h:40
void IterateTree(std::function< bool(DEBUG_ENT *)> visitor, int depth=0)
Definition: pns_log.cpp:440
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:419
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:341
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:288
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual void EndGroup(const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
Definition: pns_log.cpp:309
Definition: layer_ids.h:71
VECTOR2I A
Definition: seg.h:48
VECTOR2I p
Definition: pns_log.h:68
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:156
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:1339
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:367
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:153
std::shared_ptr< DRC_ENGINE > m_DRCEngine
const LAYER_RANGE & Layers() const
Definition: pns_item.h:154
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:150
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