Add tuner support for potentiometer code model
This commit is contained in:
parent
e618ef98e9
commit
f004665df8
|
@ -61,6 +61,36 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceDevice( const wxString& aSymbol ) cons
|
|||
}
|
||||
|
||||
|
||||
// most part is identical to above GetSpiceDevice()
|
||||
std::pair<wxString, bool>
|
||||
NETLIST_EXPORTER_PSPICE::GetSpiceTuningCommand( const wxString& aSymbol ) const
|
||||
{
|
||||
const std::list<SPICE_ITEM>& spiceItems = GetSpiceItems();
|
||||
|
||||
auto it = std::find_if( spiceItems.begin(), spiceItems.end(),
|
||||
[&]( const SPICE_ITEM& item )
|
||||
{
|
||||
return item.m_refName == aSymbol;
|
||||
} );
|
||||
|
||||
if( it == spiceItems.end() )
|
||||
return { wxEmptyString, false };
|
||||
|
||||
/// @todo assuming ngspice potentiometer code model
|
||||
/// @todo no ngspice hard coding
|
||||
if( it->m_primitive == SP_CODEMODEL )
|
||||
return { "altermod @" + it->m_model.Lower() + "[position]=", true };
|
||||
|
||||
// Prefix the device type if plain reference would result in a different device type
|
||||
wxString name = it->m_primitive != it->m_refName[0]
|
||||
? wxString( it->m_primitive + it->m_refName )
|
||||
: it->m_refName;
|
||||
|
||||
/// @todo no ngspice hard coding
|
||||
return { "alter @" + name.Lower() + "=", false };
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
FILE_OUTPUTFORMATTER outputFile( aOutFileName, wxT( "wt" ), '\'' );
|
||||
|
|
|
@ -119,6 +119,16 @@ public:
|
|||
*/
|
||||
wxString GetSpiceDevice( const wxString& aSymbol ) const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the command to alter a Spice parameter of a schematic symbol.
|
||||
*
|
||||
* @param aSymbol is the symbol reference.
|
||||
* @return Spice command or empty string if there is no such component in the netlist,
|
||||
* and true if it is a code model parameter, false if it is an instance parameter.
|
||||
*/
|
||||
std::pair<wxString, bool> GetSpiceTuningCommand( const wxString& aSymbol ) const;
|
||||
|
||||
/**
|
||||
* Write to specified output file
|
||||
*/
|
||||
|
|
|
@ -539,11 +539,11 @@ void SIM_PLOT_FRAME::AddTuner( SCH_SYMBOL* aSymbol )
|
|||
if( !plotPanel )
|
||||
return;
|
||||
|
||||
// For now limit the tuner tool to RLC components
|
||||
// For now limit the tuner tool to RLC and code model components
|
||||
char primitiveType = NETLIST_EXPORTER_PSPICE::GetSpiceField( SF_PRIMITIVE, aSymbol, 0 )[0];
|
||||
|
||||
if( primitiveType != SP_RESISTOR && primitiveType != SP_CAPACITOR
|
||||
&& primitiveType != SP_INDUCTOR )
|
||||
&& primitiveType != SP_INDUCTOR && primitiveType != SP_CODEMODEL )
|
||||
return;
|
||||
|
||||
const wxString componentName = aSymbol->GetField( REFERENCE_FIELD )->GetText();
|
||||
|
@ -917,11 +917,15 @@ void SIM_PLOT_FRAME::applyTuners()
|
|||
{
|
||||
for( auto& tuner : m_tuners )
|
||||
{
|
||||
/// @todo no ngspice hard coding
|
||||
std::string command( "alter @" + tuner->GetSpiceName()
|
||||
+ "=" + tuner->GetValue().ToSpiceString() );
|
||||
std::pair<wxString, bool> command = tuner->GetSpiceTuningCommand();
|
||||
const SPICE_VALUE& value = tuner->GetValue();
|
||||
|
||||
m_simulator->Command( command );
|
||||
// 0 < value < 1 for model parameter to avoid division by zero, etc.
|
||||
command.first += command.second
|
||||
? wxString::FromCDouble( Clamp( 1e-9, value.ToDouble() / 100.0, 1-1e-9 ), 9 )
|
||||
: value.ToSpiceString();
|
||||
|
||||
m_simulator->Command( command.first.ToStdString() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,26 +34,40 @@
|
|||
TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_SYMBOL* aSymbol ) :
|
||||
TUNER_SLIDER_BASE( aParent ),
|
||||
m_symbol( aSymbol ),
|
||||
m_fieldId( MANDATORY_FIELD_T::VALUE_FIELD ),
|
||||
m_min( 0.0 ),
|
||||
m_max( 0.0 ),
|
||||
m_changed( false ),
|
||||
m_value( 0.0 ),
|
||||
m_frame ( aFrame )
|
||||
{
|
||||
const wxString compName = aSymbol->GetField( REFERENCE_FIELD )->GetText();
|
||||
m_name->SetLabel( compName );
|
||||
m_spiceTuningCommand = aFrame->GetExporter()->GetSpiceTuningCommand( compName );
|
||||
|
||||
if( aSymbol->FindField( NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( SF_MODEL ) ) )
|
||||
m_fieldId = aSymbol->FindField( NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( SF_MODEL ) )->GetId();
|
||||
if( m_spiceTuningCommand.second )
|
||||
{
|
||||
// model parameter, with fixed %-range and unknown initial value
|
||||
m_min = 0;
|
||||
m_max = 100;
|
||||
m_value = ( m_max - m_min ) / 2.0; // midpoint
|
||||
m_minText->Disable();
|
||||
m_maxText->Disable();
|
||||
m_saveBtn->Disable(); // not an instance parameter that could be updated (invalid m_fieldId)
|
||||
}
|
||||
else
|
||||
m_fieldId = aSymbol->GetField( VALUE_FIELD )->GetId();
|
||||
{
|
||||
// instance parameter
|
||||
if( aSymbol->FindField( NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( SF_MODEL ) ) )
|
||||
m_fieldId = aSymbol->FindField( NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( SF_MODEL ) )->GetId();
|
||||
else
|
||||
m_fieldId = aSymbol->GetField( VALUE_FIELD )->GetId();
|
||||
|
||||
m_value = SPICE_VALUE( aSymbol->GetFieldById( m_fieldId )->GetText() );
|
||||
m_spiceName = aFrame->GetExporter()->GetSpiceDevice( compName ).Lower();
|
||||
m_value = SPICE_VALUE( aSymbol->GetFieldById( m_fieldId )->GetText() );
|
||||
m_min = SPICE_VALUE( 0.5 ) * m_value;
|
||||
m_max = SPICE_VALUE( 2.0 ) * m_value;
|
||||
}
|
||||
|
||||
// Call Set*() methods to update fields and slider
|
||||
m_max = SPICE_VALUE( 2.0 ) * m_value;
|
||||
m_min = SPICE_VALUE( 0.5 ) * m_value;
|
||||
|
||||
m_minText->SetValue( m_min.ToOrigString() );
|
||||
m_maxText->SetValue( m_max.ToOrigString() );
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@ public:
|
|||
return m_name->GetLabel();
|
||||
}
|
||||
|
||||
const wxString& GetSpiceName() const
|
||||
const std::pair<wxString, bool>& GetSpiceTuningCommand() const
|
||||
{
|
||||
return m_spiceName;
|
||||
return m_spiceTuningCommand;
|
||||
}
|
||||
|
||||
const SPICE_VALUE& GetValue() const
|
||||
|
@ -96,7 +96,7 @@ private:
|
|||
|
||||
void onSimTimer( wxTimerEvent& event );
|
||||
|
||||
wxString m_spiceName;
|
||||
std::pair<wxString, bool> m_spiceTuningCommand;
|
||||
|
||||
///< Timer that restarts the simulation after the slider value has changed
|
||||
wxTimer m_simTimer;
|
||||
|
|
Loading…
Reference in New Issue