From aea29fc7307eca4e1b0af78f1ebb7af9a7412768 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 11 Aug 2016 14:41:18 +0200 Subject: [PATCH] Update already plotted signals upon simulation run --- eeschema/sim/sim_plot_frame.cpp | 67 ++++++++++++++++++--------------- eeschema/sim/sim_plot_frame.h | 17 +++++++++ eeschema/sim/sim_plot_panel.cpp | 9 +++-- eeschema/sim/sim_plot_panel.h | 13 +++++-- 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index da37117a82..ca52f0931d 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -133,8 +133,6 @@ void SIM_PLOT_FRAME::StartSimulation() STRING_FORMATTER formatter; m_exporter->Format( &formatter, GNL_ALL ); - //m_plotPanel->DeleteTraces(); - m_simulator->LoadNetlist( formatter.GetString() ); // Execute the simulation in a separate thread @@ -201,24 +199,13 @@ void SIM_PLOT_FRAME::NewPlotPanel() void SIM_PLOT_FRAME::AddVoltagePlot( const wxString& aNetName ) { - if( !m_exporter ) - return; + int nodeNumber = getNodeNumber( aNetName ); - const auto& netMapping = m_exporter->GetNetIndexMap(); - - if( netMapping.count( aNetName ) == 0 ) - return; - - wxString spiceName( wxString::Format( "V(%d)", netMapping.at( aNetName ) ) ); - auto data_y = m_simulator->GetPlot( (const char*) spiceName.c_str() ); - - if( data_y.empty() ) - return; - - auto data_t = m_simulator->GetPlot( "time" ); - - SIM_PLOT_PANEL* plotPanel = static_cast( m_plotNotebook->GetCurrentPage() ); - plotPanel->AddTrace( aNetName, data_t.size(), data_t.data(), data_y.data(), 0 ); + if( nodeNumber >= -1 ) + { + updatePlot( wxString::Format( "V(%d)", nodeNumber ), aNetName, + static_cast( m_plotNotebook->GetCurrentPage() ) ); + } } @@ -227,7 +214,33 @@ bool SIM_PLOT_FRAME::isSimulationRunning() wxCriticalSectionLocker lock( m_simThreadCS ); return ( m_simThread != NULL ); +} + +void SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aTitle, SIM_PLOT_PANEL* aPanel ) +{ + auto data_y = m_simulator->GetPlot( (const char*) aSpiceName.c_str() ); + auto data_t = m_simulator->GetPlot( "time" ); + + if( data_y.empty() || data_t.empty() ) + return; + + aPanel->AddTrace( aSpiceName, aTitle, data_t.size(), data_t.data(), data_y.data(), 0 ); +} + + +int SIM_PLOT_FRAME::getNodeNumber( const wxString& aNetName ) +{ + if( !m_exporter ) + return -1; + + const auto& netMapping = m_exporter->GetNetIndexMap(); + auto it = netMapping.find( aNetName ); + + if( it == netMapping.end() ) + return -1; + + return it->second; } @@ -322,18 +335,12 @@ void SIM_PLOT_FRAME::onSimFinished( wxThreadEvent& aEvent ) m_signals->Append( net.first ); } -// TODO remove? -#if 0 - for( auto& name : m_exporter->GetProbeList() ) + // If there are any signals plotted, update them + for( unsigned int i = 0; i < m_plotNotebook->GetPageCount(); ++i ) { - char spiceName[1024]; + SIM_PLOT_PANEL* plotPanel = static_cast( m_plotNotebook->GetPage( i ) ); - snprintf( spiceName, sizeof( spiceName ), "V(%d)", netMapping.at( name ) ); - //wxLogDebug( "probe %s->%s\n", (const char *) name.c_str(), spiceName ); - // auto data_y = m_simulator->GetPlot( spiceName ); - - //wxLogDebug( "%d - %d data points\n", data_t.size(), data_y.size() ); - // m_plotPanel->AddTrace(wxT("V(") + name + wxT(")"), data_t.size(), data_t.data(), data_y.data(), 0); + for( const auto& trace : plotPanel->GetTraces() ) + updatePlot( trace.spiceName, trace.title, plotPanel ); } -#endif } diff --git a/eeschema/sim/sim_plot_frame.h b/eeschema/sim/sim_plot_frame.h index 90e9a1e997..66e1871e07 100644 --- a/eeschema/sim/sim_plot_frame.h +++ b/eeschema/sim/sim_plot_frame.h @@ -65,6 +65,23 @@ class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE private: bool isSimulationRunning(); + /** + * @brief Updates plot in a particular SIM_PLOT_PANEL. If the panel does not contain + * the plot, it will be added. + * @param aSpiceName is the plot name in the format accepted by the current simulator instance + * (for NGSPICE it is e.g. "V(1)"). + * @param aTitle is the name used in the legend. + * @param aPanel is the panel that should receive the update. + */ + void updatePlot( const wxString& aSpiceName, const wxString& aTitle, SIM_PLOT_PANEL* aPanel ); + + /** + * @brief Returns node number for a given net. + * @param aNetName is the net number. + * @return Corresponding net number or -1 if there is no such net. + */ + int getNodeNumber( const wxString& aNetName ); + void onNewPlot( wxCommandEvent& aEvent ) override { NewPlotPanel(); diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp index 707d0c679f..093803df27 100644 --- a/eeschema/sim/sim_plot_panel.cpp +++ b/eeschema/sim/sim_plot_panel.cpp @@ -63,18 +63,19 @@ static std::pair find_minmax( const T* aArray, unsigned int aSize ) } -void SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints, +void SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints, double* aT, double* aY, int aFlags ) { // Find previous entry, if there is one auto it = std::find_if( m_traces.begin(), m_traces.end(), - [&](const TRACE& t) { return t.name == aName; }); + [&](const TRACE& t) { return t.title == aTitle; }); if( it == m_traces.end() ) { // New entry TRACE trace; - trace.name = aName; + trace.spiceName = aSpiceName; + trace.title = aTitle; trace.style = wxString( '-' ) + m_painter.GenerateColor( SIM_PLOT_PAINTER::DARK ); trace.x.Set( aT, aPoints ); trace.y.Set( aY, aPoints ); @@ -159,7 +160,7 @@ int SIM_PLOT_PAINTER::Draw( mglGraph* aGraph ) // Draw traces for( auto t : traces ) { - aGraph->AddLegend( (const char*) t.name.c_str(), t.style ); + aGraph->AddLegend( (const char*) t.title.c_str(), t.style ); aGraph->Plot( t.y, t.style ); } diff --git a/eeschema/sim/sim_plot_panel.h b/eeschema/sim/sim_plot_panel.h index 74c5f92f20..45ceb5c7a3 100644 --- a/eeschema/sim/sim_plot_panel.h +++ b/eeschema/sim/sim_plot_panel.h @@ -64,14 +64,21 @@ public: ~SIM_PLOT_PANEL(); - struct TRACE { - wxString name, style; + struct TRACE + { + wxString spiceName, title, style; mglData x, y; }; - void AddTrace( const wxString& name, int n_points, double *t, double *x, int flags = 0 ); + void AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints, + double* aT, double* aY, int aFlags ); void DeleteTraces(); + const std::vector& GetTraces() const + { + return m_traces; + } + private: SIM_PLOT_PAINTER m_painter;