mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-21 20:53:45 +00:00
Update simulation results as the sim runs.
Also adds a time axis which grows by 2X at a time rather than to the size of the current data. Fixes https://gitlab.com/kicad/code/kicad/-/issues/11255
This commit is contained in:
parent
9447c3d455
commit
9199d7a781
common/widgets
eeschema/sim
include/widgets
@ -2980,10 +2980,10 @@ void mpFXYVector::SetData( const std::vector<double>& xs, const std::vector<doub
|
||||
}
|
||||
else
|
||||
{
|
||||
m_minX = -1;
|
||||
m_maxX = 1;
|
||||
m_minY = -1;
|
||||
m_maxY = 1;
|
||||
m_minX = 0;
|
||||
m_maxX = 0;
|
||||
m_minY = 0;
|
||||
m_maxY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,6 +170,33 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class TIME_SCALE : public LIN_SCALE<mpScaleX>
|
||||
{
|
||||
public:
|
||||
TIME_SCALE( const wxString& name, const wxString& unit, int flags ) :
|
||||
LIN_SCALE( name, unit, flags )
|
||||
{};
|
||||
|
||||
void ExtendDataRange( double minV, double maxV ) override
|
||||
{
|
||||
if( !m_rangeSet )
|
||||
{
|
||||
m_minV = 0;
|
||||
m_maxV = 0;
|
||||
m_rangeSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( minV < m_minV )
|
||||
m_minV -= abs( maxV - minV );
|
||||
|
||||
if( maxV > m_maxV )
|
||||
m_maxV += abs( maxV - minV );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename parent>
|
||||
class LOG_SCALE : public parent
|
||||
{
|
||||
@ -511,7 +538,7 @@ void SIM_PLOT_PANEL::updateAxes( int aNewTraceType )
|
||||
case ST_TRANSIENT:
|
||||
if( !m_axis_x )
|
||||
{
|
||||
m_axis_x = new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "s" ), mpALIGN_BOTTOM );
|
||||
m_axis_x = new TIME_SCALE( wxEmptyString, wxT( "s" ), mpALIGN_BOTTOM );
|
||||
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
|
||||
m_plotWin->AddLayer( m_axis_x );
|
||||
|
||||
@ -793,7 +820,7 @@ void SIM_PLOT_PANEL::DeleteTrace( TRACE* aTrace )
|
||||
}
|
||||
|
||||
m_plotWin->DelLayer( aTrace, true, true );
|
||||
ResetScales();
|
||||
ResetScales( false );
|
||||
}
|
||||
|
||||
|
||||
@ -843,9 +870,9 @@ void SIM_PLOT_PANEL::EnableCursor( const wxString& aVectorName, int aType, int a
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_PANEL::ResetScales()
|
||||
void SIM_PLOT_PANEL::ResetScales( bool aIncludeX )
|
||||
{
|
||||
if( m_axis_x )
|
||||
if( m_axis_x && aIncludeX )
|
||||
m_axis_x->ResetDataRange();
|
||||
|
||||
if( m_axis_y1 )
|
||||
|
@ -300,7 +300,7 @@ public:
|
||||
const wxString& aSignalName );
|
||||
|
||||
///< Reset scale ranges to fit the current traces.
|
||||
void ResetScales();
|
||||
void ResetScales( bool aIncludeX );
|
||||
|
||||
///< Update trace line style
|
||||
void UpdateTraceStyle( TRACE* trace );
|
||||
|
@ -741,7 +741,7 @@ void SIMULATOR_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
||||
|
||||
m_simFinished = true;
|
||||
|
||||
m_panel->OnSimFinished();
|
||||
m_panel->OnSimRefresh( true );
|
||||
|
||||
m_schematicFrame->RefreshOperatingPointDisplay();
|
||||
m_schematicFrame->GetCanvas()->Refresh();
|
||||
@ -765,8 +765,8 @@ void SIMULATOR_FRAME::onSimUpdate( wxCommandEvent& aEvent )
|
||||
|
||||
if( m_panel->GetCurrentPlotWindow() != m_lastSimPlot )
|
||||
{
|
||||
// We need to rerun simulation, as the simulator currently stores
|
||||
// results for another plot
|
||||
// We need to rerun simulation, as the simulator currently stores results for another
|
||||
// plot
|
||||
StartSimulation();
|
||||
}
|
||||
else
|
||||
|
@ -402,6 +402,10 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#define ID_SIM_REFRESH 10207
|
||||
#define REFRESH_INTERVAL 50 // 20 frames/second.
|
||||
|
||||
|
||||
SIMULATOR_PANEL::SIMULATOR_PANEL( SIMULATOR_FRAME* aSimulatorFrame,
|
||||
SCH_EDIT_FRAME* aSchematicFrame ) :
|
||||
SIMULATOR_PANEL_BASE( aSimulatorFrame ),
|
||||
@ -409,7 +413,8 @@ SIMULATOR_PANEL::SIMULATOR_PANEL( SIMULATOR_FRAME* aSimulatorFrame,
|
||||
m_simulatorFrame( aSimulatorFrame ),
|
||||
m_schematicFrame( aSchematicFrame ),
|
||||
m_darkMode( true ),
|
||||
m_plotNumber( 0 )
|
||||
m_plotNumber( 0 ),
|
||||
m_refreshTimer( this, ID_SIM_REFRESH )
|
||||
{
|
||||
// Get the previous size and position of windows:
|
||||
LoadSettings( m_schematicFrame->eeconfig() );
|
||||
@ -456,6 +461,16 @@ SIMULATOR_PANEL::SIMULATOR_PANEL( SIMULATOR_FRAME* aSimulatorFrame,
|
||||
Bind( EVT_SIM_CURSOR_UPDATE, &SIMULATOR_PANEL::onPlotCursorUpdate, this );
|
||||
Bind( EVT_WORKBOOK_MODIFIED, &SIMULATOR_PANEL::onNotebookModified, this );
|
||||
|
||||
Bind( wxEVT_TIMER,
|
||||
[&]( wxTimerEvent& aEvent )
|
||||
{
|
||||
OnSimRefresh( false );
|
||||
|
||||
if( m_simulatorFrame->GetSimulator()->IsRunning() )
|
||||
m_refreshTimer.Start( REFRESH_INTERVAL, wxTIMER_ONE_SHOT );
|
||||
},
|
||||
m_refreshTimer.GetId() );
|
||||
|
||||
#ifndef wxHAS_NATIVE_TABART
|
||||
// Default non-native tab art has ugly gradients we don't want
|
||||
m_plotNotebook->SetArtProvider( new wxAuiSimpleTabArt() );
|
||||
@ -1373,7 +1388,7 @@ void SIMULATOR_PANEL::SetUserDefinedSignals( const std::map<int, wxString>& aNew
|
||||
|
||||
|
||||
void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType,
|
||||
SIM_PLOT_PANEL* aPlotPanel )
|
||||
SIM_PLOT_PANEL* aPlotPanel )
|
||||
{
|
||||
SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( aPlotPanel->GetSimCommand() );
|
||||
|
||||
@ -1402,31 +1417,28 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType,
|
||||
std::vector<double> data_x;
|
||||
std::vector<double> data_y;
|
||||
|
||||
if( m_simulatorFrame->SimFinished() )
|
||||
data_x = simulator()->GetMagPlot( (const char*) xAxisName.c_str() );
|
||||
|
||||
switch( simType )
|
||||
{
|
||||
data_x = simulator()->GetMagPlot( (const char*) xAxisName.c_str() );
|
||||
|
||||
switch( simType )
|
||||
{
|
||||
case ST_AC:
|
||||
if( aTraceType & SPT_AC_MAG )
|
||||
data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() );
|
||||
else if( aTraceType & SPT_AC_PHASE )
|
||||
data_y = simulator()->GetPhasePlot( (const char*) simVectorName.c_str() );
|
||||
else
|
||||
wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or AC_MAG bit" ) );
|
||||
|
||||
break;
|
||||
|
||||
case ST_NOISE:
|
||||
case ST_DC:
|
||||
case ST_TRANSIENT:
|
||||
case ST_AC:
|
||||
if( aTraceType & SPT_AC_MAG )
|
||||
data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() );
|
||||
break;
|
||||
else if( aTraceType & SPT_AC_PHASE )
|
||||
data_y = simulator()->GetPhasePlot( (const char*) simVectorName.c_str() );
|
||||
else
|
||||
wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or AC_MAG bit" ) );
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxT( "Unhandled plot type" ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_NOISE:
|
||||
case ST_DC:
|
||||
case ST_TRANSIENT:
|
||||
data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() );
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxT( "Unhandled plot type" ) );
|
||||
}
|
||||
|
||||
unsigned int size = data_x.size();
|
||||
@ -2316,11 +2328,15 @@ void SIMULATOR_PANEL::onPlotCursorUpdate( wxCommandEvent& aEvent )
|
||||
|
||||
void SIMULATOR_PANEL::OnSimUpdate()
|
||||
{
|
||||
// Incremental update
|
||||
if( SIM_PLOT_PANEL* plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( GetCurrentPlotWindow() ) )
|
||||
plotPanel->ResetScales( true );
|
||||
|
||||
m_simConsole->Clear();
|
||||
|
||||
// Do not export netlist, it is already stored in the simulator
|
||||
applyTuners();
|
||||
|
||||
m_refreshTimer.Start( REFRESH_INTERVAL, wxTIMER_ONE_SHOT );
|
||||
}
|
||||
|
||||
|
||||
@ -2331,7 +2347,7 @@ void SIMULATOR_PANEL::OnSimReport( const wxString& aMsg )
|
||||
}
|
||||
|
||||
|
||||
void SIMULATOR_PANEL::OnSimFinished()
|
||||
void SIMULATOR_PANEL::OnSimRefresh( bool aFinal )
|
||||
{
|
||||
SIM_TYPE simType = circuitModel()->GetSimType();
|
||||
SIM_PLOT_PANEL_BASE* plotPanelWindow = GetCurrentPlotWindow();
|
||||
@ -2397,7 +2413,10 @@ void SIMULATOR_PANEL::OnSimFinished()
|
||||
updateSignalsGrid();
|
||||
|
||||
plotPanel->GetPlotWin()->UpdateAll();
|
||||
plotPanel->ResetScales();
|
||||
|
||||
if( aFinal )
|
||||
plotPanel->ResetScales( true );
|
||||
|
||||
plotPanel->GetPlotWin()->Fit();
|
||||
}
|
||||
else if( simType == ST_OP )
|
||||
|
@ -228,7 +228,7 @@ public:
|
||||
|
||||
void OnSimUpdate();
|
||||
void OnSimReport( const wxString& aMsg );
|
||||
void OnSimFinished();
|
||||
void OnSimRefresh( bool aFinal );
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -331,6 +331,7 @@ private:
|
||||
int m_splitterTuneValuesSashPosition;
|
||||
bool m_darkMode;
|
||||
unsigned int m_plotNumber;
|
||||
wxTimer m_refreshTimer;
|
||||
};
|
||||
|
||||
#endif // SIMULATOR_PANEL_H
|
||||
|
@ -748,7 +748,7 @@ public:
|
||||
maxV = m_maxV;
|
||||
}
|
||||
|
||||
void ExtendDataRange( double minV, double maxV )
|
||||
virtual void ExtendDataRange( double minV, double maxV )
|
||||
{
|
||||
if( !m_rangeSet )
|
||||
{
|
||||
@ -771,7 +771,7 @@ public:
|
||||
|
||||
void ResetDataRange()
|
||||
{
|
||||
m_rangeSet = 0;
|
||||
m_rangeSet = false;
|
||||
}
|
||||
|
||||
double AbsMaxValue() const
|
||||
|
Loading…
Reference in New Issue
Block a user