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 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/common/console_log.h>
27 
29 
30 using namespace PNS;
31 
32 static const wxString readLine( FILE* f )
33 {
34  char str[16384];
35  fgets( str, sizeof( str ) - 1, f );
36  return wxString( str );
37 }
38 
40 {
41  m_routerSettings.reset( new PNS::ROUTING_SETTINGS( nullptr, "" ) );
42 }
43 
44 
45 bool PNS_LOG_FILE::Load( const std::string& logName, const std::string boardName )
46 {
47  FILE* f = fopen( logName.c_str(), "rb" );
48 
49  if (!f)
50  return false;
51 
52  while( !feof( f ) )
53  {
54  wxStringTokenizer tokens( readLine( f ) );
55  if( !tokens.CountTokens() )
56  continue;
57 
58  wxString cmd = tokens.GetNextToken();
59 
60  if (cmd == "event")
61  {
62  EVENT_ENTRY evt;
63  evt.p.x = wxAtoi( tokens.GetNextToken() );
64  evt.p.y = wxAtoi( tokens.GetNextToken() );
65  evt.type = (PNS::LOGGER::EVENT_TYPE) wxAtoi( tokens.GetNextToken() );
66  evt.uuid = KIID( tokens.GetNextToken() );
67  m_events.push_back(evt);
68  }
69  else if (cmd == "config")
70  {
71  m_routerSettings->SetMode( (PNS::PNS_MODE) wxAtoi( tokens.GetNextToken() ) );
72  m_routerSettings->SetRemoveLoops( wxAtoi( tokens.GetNextToken() ) );
73  m_routerSettings->SetFixAllSegments( wxAtoi( tokens.GetNextToken() ) );
74  }
75  }
76 
77  fclose( f );
78 
79  try {
80  PCB_IO io;
81  m_board.reset( io.Load( boardName.c_str(), nullptr, nullptr ) );
82 
83  std::shared_ptr<DRC_ENGINE> drcEngine( new DRC_ENGINE );
84 
85  CONSOLE_LOG consoleLog;
86  BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
87 
88  bds.m_DRCEngine = drcEngine;
89 
90  drcEngine->SetBoard( m_board.get() );
91  drcEngine->SetDesignSettings( &bds );
92  drcEngine->SetLogReporter( new CONSOLE_MSG_REPORTER ( &consoleLog ) );
93  drcEngine->InitEngine(wxFileName());
94 
95  } catch ( const PARSE_ERROR& parse_error ) {
96  printf("parse error : %s (%s)\n",
97  (const char *) parse_error.Problem().c_str(),
98  (const char *) parse_error.What().c_str() );
99 
100  return false;
101  }
102 
103  return true;
104 }
105 
107 {
108 
109 }
110 
112 {
113 
114 }
115 
117 {
118  m_mode = mode;
119 }
120 
121 
123 {
124  m_iface.reset ( new PNS_KICAD_IFACE_BASE);
125  m_router.reset( new ROUTER );
126  m_iface->SetBoard( m_board.get() );
127  m_router->SetInterface( m_iface.get() );
128  m_router->ClearWorld();
129  m_router->SetMode( m_mode );
130  m_router->SyncWorld();
131  m_router->LoadSettings( new PNS::ROUTING_SETTINGS (nullptr, ""));
132  m_router->Settings().SetMode( PNS::RM_Shove );
133  m_router->Settings().SetOptimizeDraggedTrack( true );
134 
135  m_debugDecorator.Clear();
136  m_iface->SetDebugDecorator( &m_debugDecorator );
137 }
138 
139 void PNS_TEST_ENVIRONMENT::ReplayLog ( PNS_LOG_FILE* aLog, int aStartEventIndex, int aFrom, int aTo )
140 {
141 
142  m_board = aLog->GetBoard();
143 
144  createRouter();
145 
146  m_router->LoadSettings( aLog->GetRoutingSettings() );
147 
148  printf("Router mode: %d\n", m_router->Settings().Mode() );
149 
150  for( auto evt : aLog->Events() )
151  {
152  auto item = aLog->ItemById(evt);
153  ITEM* ritem = item ? m_router->GetWorld()->FindItemByParent( item ) : nullptr;
154 
155  switch(evt.type)
156  {
158  {
159  m_debugDecorator.NewStage("route-start", 0);
160  printf(" rtr start-route (%d, %d) %p \n", evt.p.x, evt.p.y, ritem);
161  m_router->StartRouting( evt.p, ritem, ritem ? ritem->Layers().Start() : F_Cu );
162  break;
163  }
164 
166  {
167  m_debugDecorator.NewStage("drag-start", 0);
168  bool rv = m_router->StartDragging( evt.p, ritem, 0 );
169  printf(" rtr start-drag (%d, %d) %p ret %d\n", evt.p.x, evt.p.y, ritem, rv?1:0);
170  break;
171  }
172 
173  case LOGGER::EVT_FIX:
174  {
175  break;
176  }
177 
178  case LOGGER::EVT_MOVE:
179  {
180  m_debugDecorator.NewStage("move", 0);
181  printf(" move -> (%d, %d)\n", evt.p.x, evt.p.y );
182  m_router->Move( evt.p, ritem );
183  break;
184  }
185  default:
186  break;
187  }
188 
189 
190  PNS::NODE* node = nullptr;
191 
192 
193  if( m_router->GetState() == PNS::ROUTER::ROUTE_TRACK )
194  {
195  m_debugDecorator.BeginGroup( "head");
196 
197  auto traces = m_router->Placer()->Traces();
198  for ( const auto& t : traces.CItems() )
199  {
200  const LINE *l = static_cast<LINE*>(t.item);
201  const auto& sh = l->CLine();
202 
203  m_debugDecorator.AddLine( sh, 4, 10000 );
204  }
205 
206  m_debugDecorator.EndGroup();
207 
208  node = m_router->Placer()->CurrentNode(true);
209  }
210  else if( m_router->GetState() == PNS::ROUTER::DRAG_SEGMENT )
211  {
212  node = m_router->GetDragger()->CurrentNode();
213  }
214 
215  if(!node)
216  return;
217 
218  NODE::ITEM_VECTOR removed, added;
219 
220  node->GetUpdatedItems( removed, added );
221 
222  if( ! added.empty() )
223  {
224  bool first = true;
225  m_debugDecorator.BeginGroup( "node-added-items");
226 
227  for( auto t : added )
228  {
229  if( t->OfKind( PNS::ITEM::SEGMENT_T ) )
230  {
231  auto s = static_cast<PNS::SEGMENT*>(t);
232  m_debugDecorator.AddSegment( s->Seg(), 2 );
233  first = false;
234  }
235  }
236 
237  m_debugDecorator.EndGroup();
238  }
239  }
240 }
241 
242 
244 {
245  if (m_stages.empty() )
246  m_stages.push_back( new STAGE() );
247 
248  return m_stages.back();
249 }
250 
251 
253 {
254  STAGE* st = currentStage();
255  DEBUG_ENT *ent = new DEBUG_ENT();
256 
257  ent->m_name = name;
258  ent->m_iter = m_iter;
259 
260  if( m_activeEntry )
261  {
262  m_activeEntry->AddChild( ent );
263  }
264 
265  printf("LOG BeginGroup %s %p\n", name.c_str(), ent );
266 
267  m_activeEntry = ent;
268  m_grouping = true;
269 }
270 
271 
273 {
274  printf("LOG EndGroup\n" );
275 
276  if( !m_activeEntry )
277  return;
278 
279  m_activeEntry = m_activeEntry->m_parent;
280 
281  if( !m_activeEntry )
282  m_grouping = false;
283 }
284 
286 {
287  auto st = currentStage();
288  m_activeEntry->AddChild( ent );
289 }
290 
291 void PNS_TEST_DEBUG_DECORATOR::AddPoint( VECTOR2I aP, int aColor, int aSize, const std::string aName )
292 {
293  auto sh = new SHAPE_LINE_CHAIN;
294 
295  sh->Append( aP.x - aSize, aP.y - aSize);
296  sh->Append( aP.x + aSize, aP.y + aSize);
297  sh->Append( aP.x, aP.y );
298  sh->Append( aP.x - aSize, aP.y + aSize );
299  sh->Append( aP.x + aSize, aP.y - aSize );
300 
301  DEBUG_ENT* ent = new DEBUG_ENT();
302 
303  ent->m_shapes.push_back( sh );
304  ent->m_color = aColor;
305  ent->m_width = 30000;
306  ent->m_iter = m_iter;
307  ent->m_name = aName;
308 
309  addEntry( ent );
310 }
311 
312 
313 void PNS_TEST_DEBUG_DECORATOR::AddLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth,
314  const std::string aName )
315 {
316  auto sh = new SHAPE_LINE_CHAIN( aLine );
317  DEBUG_ENT* ent = new DEBUG_ENT();
318 
319  ent->m_shapes.push_back( sh );
320  ent->m_color = aType;
321  ent->m_width = aWidth;
322  ent->m_name = aName;
323  ent->m_iter = m_iter;
324 
325  addEntry( ent );
326 }
327 
328 void PNS_TEST_DEBUG_DECORATOR::AddSegment( SEG aS, int aColor, const std::string aName )
329 {
330  auto sh = new SHAPE_LINE_CHAIN ( { aS.A, aS.B } );
331  DEBUG_ENT* ent = new DEBUG_ENT();
332 
333  ent->m_shapes.push_back( sh );
334  ent->m_color = aColor;
335  ent->m_width = 10000;
336  ent->m_name = aName;
337  ent->m_iter = m_iter;
338  addEntry( ent );
339 
340 }
341 
342 void PNS_TEST_DEBUG_DECORATOR::AddBox( BOX2I aB, int aColor, const std::string aName )
343 {
344  auto sh = new SHAPE_RECT ( aB.GetPosition(), aB.GetWidth(), aB.GetHeight() );
345  DEBUG_ENT* ent = new DEBUG_ENT();
346 
347  ent->m_shapes.push_back( sh );
348  ent->m_color = aColor;
349  ent->m_width = 10000;
350  ent->m_name = aName;
351  ent->m_iter = m_iter;
352  addEntry( ent );
353 
354 }
355 
356 void PNS_TEST_DEBUG_DECORATOR::AddDirections( VECTOR2D aP, int aMask, int aColor, const std::string aName )
357 {
358 
359 }
360 
361 void PNS_TEST_DEBUG_DECORATOR::Message( const wxString msg )
362 {
363  DEBUG_ENT* ent = new DEBUG_ENT();
364  ent->m_msg = msg.c_str();
365  addEntry( ent );
366 }
367 
369 {
370  //dec_dbg("clear");
371 }
372 
373 void PNS_TEST_DEBUG_DECORATOR::NewStage(const std::string& name, int iter)
374 {
375  m_stages.push_back( new STAGE );
376  m_activeEntry = m_stages.back()->m_entries;
377 }
378 
379 
381 {
382  printf("LOG D:%d iter: %p\n", depth, this );
383  if( ! visitor( this ) )
384  return;
385 
386 
387  for( auto child : m_children )
388  {
389  child->IterateTree( visitor, depth+1 );
390  }
391 }
392 
394 {
395  STAGE* st = m_stages[stage];
396  BOX2I bb;
397  bool first = true;
398 
399  auto visitor = [ & ] ( DEBUG_ENT *ent ) -> bool
400  {
401  for( auto sh : ent->m_shapes )
402  {
403  if ( first )
404  bb = sh->BBox();
405  else
406  bb.Merge( sh->BBox() );
407 
408  first = false;
409  }
410 
411  return true;
412  };
413 
414  return bb;
415 }
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:45
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:80
virtual void BeginGroup(const std::string name) override
Definition: pns_log.cpp:252
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
Keep the router "world" - i.e.
Definition: pns_node.h:145
static const wxString readLine(FILE *f)
Definition: pns_log.cpp:32
BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PLUGIN implementation knows about into either ...
PNS_MODE
< Routing modes
virtual void AddBox(BOX2I aB, int aColor, const std::string aName="") override
Definition: pns_log.cpp:342
void addEntry(DEBUG_ENT *ent)
Definition: pns_log.cpp:285
std::vector< SHAPE * > m_shapes
Definition: pns_log.h:172
std::vector< EVENT_ENTRY > & Events()
Definition: pns_log.h:93
KIID uuid
Definition: pns_log.h:71
virtual void AddPoint(VECTOR2I aP, int aColor, int aSize=100000, const std::string aName="") override
Definition: pns_log.cpp:291
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:45
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
virtual void NewStage(const std::string &name, int iter) override
Definition: pns_log.cpp:373
int Start() const
Definition: pns_layerset.h:82
Definition: kiid.h:44
virtual void EndGroup() override
Definition: pns_log.cpp:272
Definition: pns_log.h:66
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
void SetMode(PNS::ROUTER_MODE mode)
Definition: pns_log.cpp:116
coord_type GetWidth() const
Definition: box2.h:197
virtual void AddDirections(VECTOR2D aP, int aMask, int aColor, const std::string aName="") override
Definition: pns_log.cpp:356
virtual void Clear() override
Definition: pns_log.cpp:368
PNS::LOGGER::EVENT_TYPE type
Definition: pns_log.h:69
virtual void Message(const wxString msg) override
Definition: pns_log.cpp:361
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
Definition: box2.h:386
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0, const std::string aName="") override
Definition: pns_log.cpp:313
BOX2I GetStageExtents(int stage) const
Definition: pns_log.cpp:393
const Vec & GetPosition() const
Definition: box2.h:194
Definition: seg.h:41
void IterateTree(std::function< bool(DEBUG_ENT *)> visitor, int depth=0)
Definition: pns_log.cpp:380
ROUTER_MODE
Definition: pns_router.h:62
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:118
const char * name
Definition: DXF_plotter.cpp:59
SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:49
VECTOR2I p
Definition: pns_log.h:68
coord_type GetHeight() const
Definition: box2.h:198
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:1244
virtual void AddSegment(SEG aS, int aColor, const std::string aName="") override
Definition: pns_log.cpp:328
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:139
std::shared_ptr< DRC_ENGINE > m_DRCEngine
const LAYER_RANGE & Layers() const
Definition: pns_item.h:150
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:149
Container for design settings for a BOARD object.
VECTOR2I B
Definition: seg.h:50