Fix SPICE simulator plot bug.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/1944
This commit is contained in:
Wayne Stambaugh 2021-07-09 16:20:23 -04:00
parent 387cd36f60
commit dffe2661e6
3 changed files with 45 additions and 23 deletions

View File

@ -2,6 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 CERN * Copyright (C) 2016 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -28,8 +30,12 @@
#include <sim/netlist_exporter_pspice_sim.h> #include <sim/netlist_exporter_pspice_sim.h>
DIALOG_SIGNAL_LIST::DIALOG_SIGNAL_LIST( SIM_PLOT_FRAME* aParent, NETLIST_EXPORTER_PSPICE_SIM* aExporter )
: DIALOG_SIGNAL_LIST_BASE( aParent ), m_plotFrame( aParent ), m_exporter( aExporter ) DIALOG_SIGNAL_LIST::DIALOG_SIGNAL_LIST( SIM_PLOT_FRAME* aParent,
NETLIST_EXPORTER_PSPICE_SIM* aExporter ) :
DIALOG_SIGNAL_LIST_BASE( aParent ),
m_plotFrame( aParent ),
m_exporter( aExporter )
{ {
} }
@ -70,7 +76,7 @@ bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
{ {
// Add all possible currents for the primitive // Add all possible currents for the primitive
for( const auto& current : for( const auto& current :
NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) ) NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
{ {
m_signals->Append( wxString::Format( "%s(%s)", current, item.m_refName ) ); m_signals->Append( wxString::Format( "%s(%s)", current, item.m_refName ) );
} }
@ -96,6 +102,7 @@ bool DIALOG_SIGNAL_LIST::addSignalToPlotFrame( const wxString& aPlotName )
if( !name.IsEmpty() ) if( !name.IsEmpty() )
{ {
wxUniChar firstChar = aPlotName[0]; wxUniChar firstChar = aPlotName[0];
if( firstChar == 'V' || firstChar == 'v' ) if( firstChar == 'V' || firstChar == 'v' )
{ {
m_plotFrame->AddVoltagePlot( name ); m_plotFrame->AddVoltagePlot( name );
@ -125,6 +132,7 @@ void DIALOG_SIGNAL_LIST::addSelectionToPlotFrame()
if( m_signals->IsSelected( i ) ) if( m_signals->IsSelected( i ) )
{ {
const wxString& plotName = m_signals->GetString( i ); const wxString& plotName = m_signals->GetString( i );
if( !addSignalToPlotFrame( plotName ) ) if( !addSignalToPlotFrame( plotName ) )
wxASSERT_MSG( false, "Unhandled plot type" ); wxASSERT_MSG( false, "Unhandled plot type" );
} }

View File

@ -52,6 +52,7 @@
#include <wx/filedlg.h> #include <wx/filedlg.h>
#include <dialog_shim.h> #include <dialog_shim.h>
SIM_PLOT_TYPE operator|( SIM_PLOT_TYPE aFirst, SIM_PLOT_TYPE aSecond ) SIM_PLOT_TYPE operator|( SIM_PLOT_TYPE aFirst, SIM_PLOT_TYPE aSecond )
{ {
int res = (int) aFirst | (int) aSecond; int res = (int) aFirst | (int) aSecond;
@ -801,7 +802,7 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, con
return true; return true;
} }
} }
m_workbook->AddTrace( aPlotPanel, aName, size, data_x.data(), data_y.data(), aType, aParam ); m_workbook->AddTrace( aPlotPanel, aName, size, data_x.data(), data_y.data(), aType, aParam );
updateFrame(); updateFrame();
@ -1577,7 +1578,7 @@ bool SIM_PLOT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
wxString msg = _( "Save changes to '%s' before closing?" ); wxString msg = _( "Save changes to '%s' before closing?" );
return HandleUnsavedChanges( this, wxString::Format( msg, filename.GetFullName() ), return HandleUnsavedChanges( this, wxString::Format( msg, filename.GetFullName() ),
[&]()->bool [&]()->bool
{ {
return saveWorkbook( Prj().AbsolutePath( filename.GetFullName() ) ); return saveWorkbook( Prj().AbsolutePath( filename.GetFullName() ) );
@ -1760,6 +1761,7 @@ void SIM_PLOT_FRAME::onSimUpdate( wxCommandEvent& aEvent )
{ {
// Incremental update // Incremental update
m_simConsole->Clear(); m_simConsole->Clear();
// Do not export netlist, it is already stored in the simulator // Do not export netlist, it is already stored in the simulator
applyTuners(); applyTuners();
m_simulator->Run(); m_simulator->Run();

View File

@ -2,6 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 CERN * Copyright (C) 2016 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -32,6 +34,7 @@
#include <wx/regex.h> #include <wx/regex.h>
static wxString formatFloat( double x, int nDigits ) static wxString formatFloat( double x, int nDigits )
{ {
wxString rv, fmt; wxString rv, fmt;
@ -131,9 +134,6 @@ static int countDecimalDigits( double x, int maxDigits )
template <typename parent> template <typename parent>
class LIN_SCALE : public parent class LIN_SCALE : public parent
{ {
private:
const wxString m_unit;
public: public:
LIN_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){}; LIN_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){};
@ -162,15 +162,15 @@ public:
l.visible = true; l.visible = true;
} }
} }
private:
const wxString m_unit;
}; };
template <typename parent> template <typename parent>
class LOG_SCALE : public parent class LOG_SCALE : public parent
{ {
private:
const wxString m_unit;
public: public:
LOG_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){}; LOG_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){};
@ -189,6 +189,9 @@ public:
l.visible = true; l.visible = true;
} }
} }
private:
const wxString m_unit;
}; };
@ -257,9 +260,11 @@ void CURSOR::Plot( wxDC& aDC, mpWindow& aWindow )
aWindow.y2p( m_trace->y2s( m_coords.y ) ) ); aWindow.y2p( m_trace->y2s( m_coords.y ) ) );
wxCoord leftPx = m_drawOutsideMargins ? 0 : aWindow.GetMarginLeft(); wxCoord leftPx = m_drawOutsideMargins ? 0 : aWindow.GetMarginLeft();
wxCoord rightPx = m_drawOutsideMargins ? aWindow.GetScrX() : aWindow.GetScrX() - aWindow.GetMarginRight(); wxCoord rightPx = m_drawOutsideMargins ? aWindow.GetScrX() :
aWindow.GetScrX() - aWindow.GetMarginRight();
wxCoord topPx = m_drawOutsideMargins ? 0 : aWindow.GetMarginTop(); wxCoord topPx = m_drawOutsideMargins ? 0 : aWindow.GetMarginTop();
wxCoord bottomPx = m_drawOutsideMargins ? aWindow.GetScrY() : aWindow.GetScrY() - aWindow.GetMarginBottom(); wxCoord bottomPx = m_drawOutsideMargins ? aWindow.GetScrY() :
aWindow.GetScrY() - aWindow.GetMarginBottom();
wxPen pen = GetPen(); wxPen pen = GetPen();
pen.SetStyle( m_continuous ? wxPENSTYLE_SOLID : wxPENSTYLE_LONG_DASH ); pen.SetStyle( m_continuous ? wxPENSTYLE_SOLID : wxPENSTYLE_LONG_DASH );
@ -278,8 +283,10 @@ bool CURSOR::Inside( wxPoint& aPoint )
if( !m_window ) if( !m_window )
return false; return false;
return ( std::abs( (double) aPoint.x - m_window->x2p( m_trace->x2s( m_coords.x ) ) ) <= DRAG_MARGIN ) return ( std::abs( (double) aPoint.x -
|| ( std::abs( (double) aPoint.y - m_window->y2p( m_trace->y2s( m_coords.y ) ) ) <= DRAG_MARGIN ); m_window->x2p( m_trace->x2s( m_coords.x ) ) ) <= DRAG_MARGIN )
|| ( std::abs( (double) aPoint.y -
m_window->y2p( m_trace->y2s( m_coords.y ) ) ) <= DRAG_MARGIN );
} }
@ -294,13 +301,14 @@ void CURSOR::UpdateReference()
SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxString aCommand, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame, SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxString aCommand, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) wxWindowID id, const wxPoint& pos, const wxSize& size,
: SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name ), long style, const wxString& name )
m_axis_x( nullptr ), : SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name ),
m_axis_y1( nullptr ), m_axis_x( nullptr ),
m_axis_y2( nullptr ), m_axis_y1( nullptr ),
m_dotted_cp( false ), m_axis_y2( nullptr ),
m_masterFrame( aMainFrame ) m_dotted_cp( false ),
m_masterFrame( aMainFrame )
{ {
m_sizer = new wxBoxSizer( wxVERTICAL ); m_sizer = new wxBoxSizer( wxVERTICAL );
m_plotWin = new mpWindow( this, wxID_ANY, pos, size, style ); m_plotWin = new mpWindow( this, wxID_ANY, pos, size, style );
@ -509,7 +517,11 @@ bool SIM_PLOT_PANEL::addTrace( const wxString& aName, int aPoints, const double*
else else
{ {
for( int i = 0; i < aPoints; i++ ) for( int i = 0; i < aPoints; i++ )
tmp[i] = 20 * log( tmp[i] ) / log( 10.0 ); // convert to dB {
// log( 0 ) is not valid.
if( tmp[i] != 0 )
tmp[i] = 20 * log( tmp[i] ) / log( 10.0 ); // convert to dB
}
} }
} }