simulator: working on magnitude/phase plots

This commit is contained in:
Tomasz Wlostowski 2016-08-11 14:41:49 +02:00 committed by Maciej Suminski
parent e5bf70996b
commit e8d6a42e1a
7 changed files with 78 additions and 25 deletions

View File

@ -1110,12 +1110,16 @@ void mpScaleXLog::recalculateTicks ( wxDC & dc, mpWindow & w )
double visibleDecades = log( maxVvis / minVvis ) / log(10);
//printf("visibleD %.1f %.1f %.1f\n", visibleDecades, maxVvis, minVvis);
printf("visibleD %f %f\n", minDecade, maxDecade);
double d;
m_tickValues.clear();
m_labeledTicks.clear();
if ( minDecade == 0.0 )
return;
for ( d= minDecade; d<=maxDecade; d *= 10.0)
{
//printf("d %.1f\n",d );
@ -2944,13 +2948,14 @@ double log10( double x)
return log(x)/log(10.0);
}
#if 0
mpFSemiLogXVector::mpFSemiLogXVector(wxString name, int flags ) :
mpFXYVector ( name, flags )
{}
IMPLEMENT_DYNAMIC_CLASS(mpFSemiLogXVector, mpFXYVector)
#endif
void mpFXYVector::Rewind()
{

View File

@ -305,7 +305,7 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aNa
return false;
aPanel->AddTrace( aSpiceName, aName + " (mag)", size, data_x.data(), data_mag.data(), 0 );
aPanel->AddTrace( aSpiceName, aName + " (phase)", size, data_x.data(), data_phase.data(), 0 );
aPanel->AddTrace( aSpiceName, aName + " (phase)", size, data_x.data(), data_phase.data(), SPF_AC_PHASE );
}
break;
@ -668,11 +668,15 @@ void SIM_PLOT_FRAME::onSimUpdate( wxCommandEvent& aEvent )
if( !m_simulator )
return;
aEvent.Discard();
if( IsSimulationRunning() )
StopSimulation();
m_simConsole->Clear();
printf("SimUpdate\n");
// Apply tuned values
if( SIM_PLOT_PANEL* plotPanel = CurrentPlot() )
{

View File

@ -76,7 +76,7 @@ static wxString formatSI ( double x, const wxString& unit, int decimalDigits, do
if (maxValue != 0.0)
rangeHit = fabs(maxValue) >= r_cur && fabs(maxValue) < r_cur * 1000.0 ;
else
rangeHit = fabs(x) >= maxValue && fabs(x) < maxValue * 1000.0 ;
rangeHit = fabs(x) >= r_cur && fabs(x) < r_cur * 1000.0 ;
if( (!lockSuffix && rangeHit) || (lockSuffix && suffix == powers[i].suffix ) )
{
@ -105,6 +105,7 @@ public:
const wxString getLabel( int n )
{
printf("%.10f\n", m_labeledTicks[n] );
return formatSI ( m_labeledTicks[n], wxT("Hz"), 2 );
}
};
@ -270,7 +271,7 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
m_axis_y1 = new mpScaleY( wxT( "noise [(V or A)^2/Hz]" ), mpALIGN_BORDER_LEFT );
break;
#endif
#endif
case ST_TRANSIENT:
m_axis_x = new TIME_SCALE( wxT( "Time" ), mpALIGN_BOTTOM );
@ -340,6 +341,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aName
{
TRACE* t = NULL;
// Find previous entry, if there is one
auto prev = m_traces.find( aName );
bool addedNewEntry = ( prev == m_traces.end() );
@ -353,17 +355,36 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aName
t = new TRACE_TRANSIENT( aName, aSpiceName );
break;
case ST_AC:
//printf("makeFreqResp!\n");
t = new TRACE_FREQ_RESPONSE( aName, aSpiceName );
break;
default:
assert(false);
}
assert(m_axis_x);
assert(m_axis_y1);
printf("points : %d\n", aPoints );
std::vector<double> tmp(aY, aY + aPoints);
if( m_type == ST_AC )
{
if( aFlags & SPF_AC_PHASE)
{
for(int i = 0; i < aPoints; i++ )
tmp[i] = tmp[i] * 180.0 / M_PI;
} else {
for(int i = 0; i < aPoints; i++ )
tmp[i] = 20 * log( tmp[i] ) / log(10.0);
}
}
t->SetData( std::vector<double>( aT, aT + aPoints ), tmp );
if( aFlags & SPF_AC_PHASE )
t->SetScale ( m_axis_x, m_axis_y2 );
else
t->SetScale ( m_axis_x, m_axis_y1 );
t->SetData( std::vector<double>( aT, aT + aPoints ), std::vector<double>( aY, aY + aPoints ) );
t->SetScale ( m_axis_x, m_axis_y1 );
t->SetPen( wxPen( generateColor(), 2, wxSOLID ) );
m_traces[aName] = t;

View File

@ -90,8 +90,14 @@ private:
class TRACE : public mpFXYVector
{
public:
TRACE( const wxString& aSpiceName ) :
m_spiceName( aSpiceName ), m_cursor( nullptr ) {};
TRACE( const wxString& aName, const wxString& aSpiceName ) :
mpFXYVector ( aName ), m_spiceName( aSpiceName ), m_cursor( nullptr )
{
SetContinuity( true );
SetDrawOutsideMargins( false );
ShowName( false );
}
const wxString& GetSpiceName() const
{
@ -128,15 +134,13 @@ protected:
CURSOR* m_cursor;
};
class TRACE_FREQ_RESPONSE : public TRACE, public mpFSemiLogXVector
class TRACE_FREQ_RESPONSE : public TRACE
{
public:
TRACE_FREQ_RESPONSE( const wxString& aName, const wxString& aSpiceName )
: mpFSemiLogXVector( aName ), TRACE( aSpiceName )
TRACE_FREQ_RESPONSE( const wxString& aName, const wxString& aSpiceName ) :
TRACE( aName, aSpiceName )
{
mpFSemiLogXVector::SetContinuity( true );
mpFSemiLogXVector::SetDrawOutsideMargins( false );
mpFSemiLogXVector::ShowName( false );
printf("makeFreqResponse!\n");
}
};
@ -144,18 +148,16 @@ public:
class TRACE_TRANSIENT : public TRACE
{
public:
TRACE_TRANSIENT( const wxString& aName, const wxString& aSpiceName ) :
TRACE( aSpiceName )
TRACE_TRANSIENT( const wxString& aName, const wxString& aSpiceName ) :
TRACE( aName, aSpiceName )
{
mpFXYVector::SetName ( aName ); // hack
SetContinuity( true );
SetDrawOutsideMargins( false );
ShowName( false );
}
};
enum SIM_PLOT_FLAGS {
SPF_AC_PHASE = 0x1
};
class SIM_PLOT_PANEL : public mpWindow
{

View File

@ -36,6 +36,7 @@ TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aParent, SCH_COMPONENT* aComponent )
const wxString compName = aComponent->GetField( REFERENCE )->GetText();
m_name->SetLabel( compName );
m_value = SPICE_VALUE( aComponent->GetField( VALUE )->GetText() );
m_changed = false;
// Generate Spice component name
char prim = NETLIST_EXPORTER_PSPICE::GetSpiceField( SPICE_PRIMITIVE, aComponent, 0 )[0];
@ -142,6 +143,7 @@ void TUNER_SLIDER::onSliderChanged( wxScrollEvent& event )
m_value = m_min + ( m_max - m_min ) * SPICE_VALUE( m_slider->GetValue() / 100.0 );
updateValueText();
updateComponentValue();
m_changed = true;
}
@ -166,6 +168,7 @@ void TUNER_SLIDER::onValueTextEnter( wxCommandEvent& event )
{
SPICE_VALUE newCur( m_valueText->GetValue() );
SetValue( newCur );
m_changed = true;
}
catch( std::exception& e )
{
@ -192,5 +195,10 @@ void TUNER_SLIDER::onMinTextEnter( wxCommandEvent& event )
void TUNER_SLIDER::onSimTimer( wxTimerEvent& event )
{
wxQueueEvent( GetParent(), new wxCommandEvent( EVT_SIM_UPDATE ) );
if(m_changed)
{
printf("Slider Ch\n");
wxQueueEvent( GetParent(), new wxCommandEvent( EVT_SIM_UPDATE ) );
m_changed = false;
}
}

View File

@ -94,6 +94,7 @@ private:
SCH_COMPONENT* m_component;
SPICE_VALUE m_min, m_max, m_value;
bool m_changed;
};
#endif /* TUNER_SLIDER_H */

View File

@ -728,7 +728,16 @@ public:
m_minV = std::min(minV, m_minV);
m_maxV = std::max(maxV, m_maxV);
}
printf("Extend min %.10f max %.10f\n", m_minV, m_maxV);
if (m_minV == m_maxV)
{
m_minV = -1.0;
m_maxV = 1.0;
}
}
double AbsMaxValue() const
{
@ -1503,6 +1512,8 @@ protected:
};
#if 0
class WXDLLIMPEXP_MATHPLOT mpFSemiLogXVector : public mpFXYVector
{
public:
@ -1520,6 +1531,7 @@ class WXDLLIMPEXP_MATHPLOT mpFSemiLogXVector : public mpFXYVector
DECLARE_DYNAMIC_CLASS(mpFSemiLogXVector)
};
#endif
//-----------------------------------------------------------------------------
// mpText - provided by Val Greene