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.
*
* Copyright (C) 2016 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -28,8 +30,12 @@
#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
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 ) );
}
@ -96,6 +102,7 @@ bool DIALOG_SIGNAL_LIST::addSignalToPlotFrame( const wxString& aPlotName )
if( !name.IsEmpty() )
{
wxUniChar firstChar = aPlotName[0];
if( firstChar == 'V' || firstChar == 'v' )
{
m_plotFrame->AddVoltagePlot( name );
@ -125,6 +132,7 @@ void DIALOG_SIGNAL_LIST::addSelectionToPlotFrame()
if( m_signals->IsSelected( i ) )
{
const wxString& plotName = m_signals->GetString( i );
if( !addSignalToPlotFrame( plotName ) )
wxASSERT_MSG( false, "Unhandled plot type" );
}

View File

@ -52,6 +52,7 @@
#include <wx/filedlg.h>
#include <dialog_shim.h>
SIM_PLOT_TYPE operator|( SIM_PLOT_TYPE aFirst, SIM_PLOT_TYPE 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;
}
}
m_workbook->AddTrace( aPlotPanel, aName, size, data_x.data(), data_y.data(), aType, aParam );
updateFrame();
@ -1577,7 +1578,7 @@ bool SIM_PLOT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
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
{
return saveWorkbook( Prj().AbsolutePath( filename.GetFullName() ) );
@ -1760,6 +1761,7 @@ void SIM_PLOT_FRAME::onSimUpdate( wxCommandEvent& aEvent )
{
// Incremental update
m_simConsole->Clear();
// Do not export netlist, it is already stored in the simulator
applyTuners();
m_simulator->Run();

View File

@ -2,6 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -32,6 +34,7 @@
#include <wx/regex.h>
static wxString formatFloat( double x, int nDigits )
{
wxString rv, fmt;
@ -131,9 +134,6 @@ static int countDecimalDigits( double x, int maxDigits )
template <typename parent>
class LIN_SCALE : public parent
{
private:
const wxString m_unit;
public:
LIN_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){};
@ -162,15 +162,15 @@ public:
l.visible = true;
}
}
private:
const wxString m_unit;
};
template <typename parent>
class LOG_SCALE : public parent
{
private:
const wxString m_unit;
public:
LOG_SCALE( wxString name, wxString unit, int flags ) : parent( name, flags ), m_unit( unit ){};
@ -189,6 +189,9 @@ public:
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 ) ) );
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 bottomPx = m_drawOutsideMargins ? aWindow.GetScrY() : aWindow.GetScrY() - aWindow.GetMarginBottom();
wxCoord bottomPx = m_drawOutsideMargins ? aWindow.GetScrY() :
aWindow.GetScrY() - aWindow.GetMarginBottom();
wxPen pen = GetPen();
pen.SetStyle( m_continuous ? wxPENSTYLE_SOLID : wxPENSTYLE_LONG_DASH );
@ -278,8 +283,10 @@ bool CURSOR::Inside( wxPoint& aPoint )
if( !m_window )
return false;
return ( std::abs( (double) aPoint.x - 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 );
return ( std::abs( (double) aPoint.x -
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,
wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name )
: SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name ),
m_axis_x( nullptr ),
m_axis_y1( nullptr ),
m_axis_y2( nullptr ),
m_dotted_cp( false ),
m_masterFrame( aMainFrame )
wxWindowID id, const wxPoint& pos, const wxSize& size,
long style, const wxString& name )
: SIM_PANEL_BASE( aCommand, parent, id, pos, size, style, name ),
m_axis_x( nullptr ),
m_axis_y1( nullptr ),
m_axis_y2( nullptr ),
m_dotted_cp( false ),
m_masterFrame( aMainFrame )
{
m_sizer = new wxBoxSizer( wxVERTICAL );
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
{
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
}
}
}