mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Refactor PCB calcs to common library, and add coupled stripline
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16863
This commit is contained in:
parent
2fd2fe6e2d
commit
aac9731852
@ -557,6 +557,14 @@ set( COMMON_IO_SRCS
|
||||
io/easyedapro/easyedapro_import_utils.cpp
|
||||
)
|
||||
|
||||
set ( COMMON_TRANSLINE_CALCULATION_SRCS
|
||||
transline_calculations/transline_calculation_base.cpp
|
||||
transline_calculations/microstrip.cpp
|
||||
transline_calculations/coupled_microstrip.cpp
|
||||
transline_calculations/stripline.cpp
|
||||
transline_calculations/coupled_stripline.cpp
|
||||
)
|
||||
|
||||
set( COMMON_IMPORT_GFX_SRCS
|
||||
import_gfx/graphics_import_mgr.cpp
|
||||
import_gfx/graphics_importer.cpp
|
||||
@ -591,6 +599,7 @@ set( COMMON_SRCS
|
||||
${FONT_SRCS}
|
||||
${COMMON_IMPORT_GFX_SRCS}
|
||||
${COMMON_GIT_SRCS}
|
||||
${COMMON_TRANSLINE_CALCULATION_SRCS}
|
||||
base_screen.cpp
|
||||
bin_mod.cpp
|
||||
bitmap_base.cpp
|
||||
|
@ -4893,6 +4893,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
|
||||
aBitmapInfoCache[BITMAPS::color_code_tolerance].emplace_back( BITMAPS::color_code_tolerance, wxT( "color_code_tolerance.png" ), -1, wxT( "light" ) );
|
||||
aBitmapInfoCache[BITMAPS::color_code_value].emplace_back( BITMAPS::color_code_value, wxT( "color_code_value.png" ), -1, wxT( "light" ) );
|
||||
aBitmapInfoCache[BITMAPS::color_code_value_and_name].emplace_back( BITMAPS::color_code_value_and_name, wxT( "color_code_value_and_name.png" ), -1, wxT( "light" ) );
|
||||
aBitmapInfoCache[BITMAPS::coupled_stripline].emplace_back( BITMAPS::coupled_stripline, wxT( "coupled_stripline.png" ), -1, wxT( "light" ) );
|
||||
aBitmapInfoCache[BITMAPS::creepage_clearance].emplace_back( BITMAPS::creepage_clearance, wxT( "creepage_clearance.png" ), -1, wxT( "light" ) );
|
||||
aBitmapInfoCache[BITMAPS::cpw].emplace_back( BITMAPS::cpw, wxT( "cpw.png" ), -1, wxT( "light" ) );
|
||||
aBitmapInfoCache[BITMAPS::cpw_back].emplace_back( BITMAPS::cpw_back, wxT( "cpw_back.png" ), -1, wxT( "light" ) );
|
||||
@ -4928,6 +4929,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
|
||||
aBitmapInfoCache[BITMAPS::color_code_tolerance].emplace_back( BITMAPS::color_code_tolerance, wxT( "color_code_tolerance_dark.png" ), -1, wxT( "dark" ) );
|
||||
aBitmapInfoCache[BITMAPS::color_code_value].emplace_back( BITMAPS::color_code_value, wxT( "color_code_value_dark.png" ), -1, wxT( "dark" ) );
|
||||
aBitmapInfoCache[BITMAPS::color_code_value_and_name].emplace_back( BITMAPS::color_code_value_and_name, wxT( "color_code_value_and_name_dark.png" ), -1, wxT( "dark" ) );
|
||||
aBitmapInfoCache[BITMAPS::coupled_stripline].emplace_back( BITMAPS::coupled_stripline, wxT( "coupled_stripline_dark.png" ), -1, wxT( "dark" ) );
|
||||
aBitmapInfoCache[BITMAPS::creepage_clearance].emplace_back( BITMAPS::creepage_clearance, wxT( "creepage_clearance_dark.png" ), -1, wxT( "dark" ) );
|
||||
aBitmapInfoCache[BITMAPS::cpw].emplace_back( BITMAPS::cpw, wxT( "cpw_dark.png" ), -1, wxT( "dark" ) );
|
||||
aBitmapInfoCache[BITMAPS::cpw_back].emplace_back( BITMAPS::cpw_back, wxT( "cpw_back_dark.png" ), -1, wxT( "dark" ) );
|
||||
|
823
common/transline_calculations/coupled_microstrip.cpp
Normal file
823
common/transline_calculations/coupled_microstrip.cpp
Normal file
@ -0,0 +1,823 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <transline_calculations/coupled_microstrip.h>
|
||||
#include <transline_calculations/units.h>
|
||||
|
||||
|
||||
namespace TC = TRANSLINE_CALCULATIONS;
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::Analyse()
|
||||
{
|
||||
// Compute thickness corrections
|
||||
delta_u_thickness();
|
||||
|
||||
// Get effective dielectric constants
|
||||
er_eff_static();
|
||||
|
||||
// Impedances for even- and odd-mode
|
||||
Z0_even_odd();
|
||||
|
||||
// Calculate freq dependence of er_eff_e, er_eff_o
|
||||
er_eff_freq();
|
||||
|
||||
// Calculate frequency dependence of Z0e, Z0o */
|
||||
Z0_dispersion();
|
||||
|
||||
// Calculate losses
|
||||
attenuation();
|
||||
|
||||
// Calculate electrical lengths
|
||||
line_angle();
|
||||
|
||||
// Calculate diff impedance
|
||||
diff_impedance();
|
||||
}
|
||||
|
||||
|
||||
bool COUPLED_MICROSTRIP::Synthesize( const SYNTHESIZE_OPTS aOpts )
|
||||
{
|
||||
if( aOpts == SYNTHESIZE_OPTS::FIX_WIDTH )
|
||||
return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O );
|
||||
|
||||
if( aOpts == SYNTHESIZE_OPTS::FIX_SPACING )
|
||||
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O );
|
||||
|
||||
double Z0_e, Z0_o, ang_l_dest;
|
||||
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
|
||||
double eps = 1e-04;
|
||||
double w_h, s_h, le, lo;
|
||||
|
||||
/* required value of Z0_e and Z0_o */
|
||||
Z0_e = GetParameter( TCP::Z0_E );
|
||||
Z0_o = GetParameter( TCP::Z0_O );
|
||||
|
||||
ang_l_e = GetParameter( TCP::ANG_L );
|
||||
ang_l_o = GetParameter( TCP::ANG_L );
|
||||
ang_l_dest = GetParameter( TCP::ANG_L );
|
||||
|
||||
/* calculate width and use for initial value in Newton's method */
|
||||
synth_width();
|
||||
w_h = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::H );
|
||||
s_h = GetParameter( TCP::PHYS_S ) / GetParameter( TCP::H );
|
||||
f1 = f2 = 0;
|
||||
|
||||
int iters = 0;
|
||||
|
||||
/* rather crude Newton-Rhapson */
|
||||
do
|
||||
{
|
||||
++iters;
|
||||
|
||||
/* compute Jacobian */
|
||||
syn_fun( &ft1, &ft2, s_h + eps, w_h, Z0_e, Z0_o );
|
||||
j11 = ( ft1 - f1 ) / eps;
|
||||
j21 = ( ft2 - f2 ) / eps;
|
||||
syn_fun( &ft1, &ft2, s_h, w_h + eps, Z0_e, Z0_o );
|
||||
j12 = ( ft1 - f1 ) / eps;
|
||||
j22 = ( ft2 - f2 ) / eps;
|
||||
|
||||
/* compute next step; increments of s_h and w_h */
|
||||
d_s_h = ( -f1 * j22 + f2 * j12 ) / ( j11 * j22 - j21 * j12 );
|
||||
d_w_h = ( -f2 * j11 + f1 * j21 ) / ( j11 * j22 - j21 * j12 );
|
||||
|
||||
s_h += d_s_h;
|
||||
w_h += d_w_h;
|
||||
|
||||
/* compute the error with the new values of s_h and w_h */
|
||||
syn_fun( &f1, &f2, s_h, w_h, Z0_e, Z0_o );
|
||||
err = sqrt( f1 * f1 + f2 * f2 );
|
||||
|
||||
/* converged ? */
|
||||
} while( err > 1e-04 && iters < 250 );
|
||||
|
||||
if( err > 1e-04 )
|
||||
return false;
|
||||
|
||||
/* denormalize computed width and spacing */
|
||||
SetParameter( TCP::PHYS_S, s_h * GetParameter( TCP::H ) );
|
||||
SetParameter( TCP::PHYS_WIDTH, w_h * GetParameter( TCP::H ) );
|
||||
|
||||
/* calculate physical length */
|
||||
le = TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( er_eff_e ) * ang_l_dest / 2.0 / M_PI;
|
||||
lo = TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( er_eff_o ) * ang_l_dest / 2.0 / M_PI;
|
||||
SetParameter( TCP::PHYS_LEN, sqrt( le * lo ) );
|
||||
|
||||
Analyse();
|
||||
|
||||
SetParameter( TCP::ANG_L, ang_l_dest );
|
||||
SetParameter( TCP::Z0_E, Z0_e );
|
||||
SetParameter( TCP::Z0_O, Z0_o );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::SetAnalysisResults()
|
||||
{
|
||||
SetAnalysisResult( TCP::EPSILON_EFF_EVEN, er_eff_e );
|
||||
SetAnalysisResult( TCP::EPSILON_EFF_ODD, er_eff_o );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY_EVEN, prop_delay_e );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY_ODD, prop_delay_o );
|
||||
SetAnalysisResult( TCP::ATTEN_COND_EVEN, atten_cond_e );
|
||||
SetAnalysisResult( TCP::ATTEN_COND_ODD, atten_cond_o );
|
||||
SetAnalysisResult( TCP::ATTEN_DILECTRIC_EVEN, atten_dielectric_e );
|
||||
SetAnalysisResult( TCP::ATTEN_DILECTRIC_ODD, atten_dielectric_o );
|
||||
SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
SetAnalysisResult( TCP::Z_DIFF, Zdiff );
|
||||
|
||||
const double Z0_E = GetParameter( TCP::Z0_E );
|
||||
const double Z0_O = GetParameter( TCP::Z0_O );
|
||||
const double ANG_L = sqrt( ang_l_e * ang_l_o );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double S = GetParameter( TCP::PHYS_S );
|
||||
|
||||
const bool Z0_E_invalid = !std::isfinite( Z0_E ) || Z0_E <= 0;
|
||||
const bool Z0_O_invalid = !std::isfinite( Z0_O ) || Z0_O <= 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool S_invalid = !std::isfinite( S ) || S <= 0;
|
||||
|
||||
SetAnalysisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::SetSynthesisResults()
|
||||
{
|
||||
SetAnalysisResult( TCP::EPSILON_EFF_EVEN, er_eff_e );
|
||||
SetAnalysisResult( TCP::EPSILON_EFF_ODD, er_eff_o );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY_EVEN, prop_delay_e );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY_ODD, prop_delay_o );
|
||||
SetAnalysisResult( TCP::ATTEN_COND_EVEN, atten_cond_e );
|
||||
SetAnalysisResult( TCP::ATTEN_COND_ODD, atten_cond_o );
|
||||
SetAnalysisResult( TCP::ATTEN_DILECTRIC_EVEN, atten_dielectric_e );
|
||||
SetAnalysisResult( TCP::ATTEN_DILECTRIC_ODD, atten_dielectric_o );
|
||||
SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
SetAnalysisResult( TCP::Z_DIFF, Zdiff );
|
||||
|
||||
const double Z0_E = GetParameter( TCP::Z0_E );
|
||||
const double Z0_O = GetParameter( TCP::Z0_O );
|
||||
const double ANG_L = sqrt( ang_l_e * ang_l_o );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double S = GetParameter( TCP::PHYS_S );
|
||||
|
||||
const bool Z0_E_invalid = !std::isfinite( Z0_E ) || Z0_E <= 0;
|
||||
const bool Z0_O_invalid = !std::isfinite( Z0_O ) || Z0_O <= 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool S_invalid = !std::isfinite( S ) || S <= 0;
|
||||
|
||||
SetAnalysisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::delta_u_thickness_single( double u, double t_h )
|
||||
{
|
||||
double delta_u;
|
||||
|
||||
if( t_h > 0.0 )
|
||||
{
|
||||
delta_u = ( 1.25 * t_h / M_PI )
|
||||
* ( 1.0
|
||||
+ log( ( 2.0 + ( 4.0 * M_PI * u - 2.0 ) / ( 1.0 + exp( -100.0 * ( u - 1.0 / ( 2.0 * M_PI ) ) ) ) )
|
||||
/ t_h ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_u = 0.0;
|
||||
}
|
||||
return delta_u;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_u_thickness() - compute the thickness effect on normalized
|
||||
* width for coupled microstrips
|
||||
*
|
||||
* References: Rolf Jansen, "High-Speed Computation of Single and
|
||||
* Coupled Microstrip Parameters Including Dispersion, High-Order
|
||||
* Modes, Loss and Finite Strip Thickness", IEEE Trans. MTT, vol. 26,
|
||||
* no. 2, pp. 75-82, Feb. 1978
|
||||
*/
|
||||
void COUPLED_MICROSTRIP::delta_u_thickness()
|
||||
{
|
||||
double e_r, u, g, t_h;
|
||||
double delta_u, delta_t, delta_u_e, delta_u_o;
|
||||
|
||||
e_r = GetParameter( TCP::EPSILONR );
|
||||
u = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::H ); /* normalized line width */
|
||||
g = GetParameter( TCP::PHYS_S ) / GetParameter( TCP::H ); /* normalized line spacing */
|
||||
t_h = GetParameter( TCP::T ) / GetParameter( TCP::H ); /* normalized strip thickness */
|
||||
|
||||
if( t_h > 0.0 )
|
||||
{
|
||||
/* single microstrip correction for finite strip thickness */
|
||||
delta_u = delta_u_thickness_single( u, t_h );
|
||||
delta_t = t_h / ( g * e_r );
|
||||
/* thickness correction for the even- and odd-mode */
|
||||
delta_u_e = delta_u * ( 1.0 - 0.5 * exp( -0.69 * delta_u / delta_t ) );
|
||||
delta_u_o = delta_u_e + delta_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_u_e = delta_u_o = 0.0;
|
||||
}
|
||||
|
||||
w_t_e = GetParameter( TCP::PHYS_WIDTH ) + delta_u_e * GetParameter( TCP::H );
|
||||
w_t_o = GetParameter( TCP::PHYS_WIDTH ) + delta_u_o * GetParameter( TCP::H );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::compute_single_line()
|
||||
{
|
||||
/* prepare parameters for single microstrip computations */
|
||||
m_aux_microstrip.SetParameter( TCP::EPSILONR, GetParameter( TCP::EPSILONR ) );
|
||||
m_aux_microstrip.SetParameter( TCP::PHYS_WIDTH, GetParameter( TCP::PHYS_WIDTH ) );
|
||||
m_aux_microstrip.SetParameter( TCP::H, GetParameter( TCP::H ) );
|
||||
m_aux_microstrip.SetParameter( TCP::T, 0.0 );
|
||||
|
||||
//m_aux_microstrip.m_parameters[H_T ) = m_parameters[H_T );
|
||||
m_aux_microstrip.SetParameter( TCP::H_T, 1e12 ); /* arbitrarily high */
|
||||
m_aux_microstrip.SetParameter( TCP::FREQUENCY, GetParameter( TCP::FREQUENCY ) );
|
||||
m_aux_microstrip.SetParameter( TCP::MURC, GetParameter( TCP::MURC ) );
|
||||
m_aux_microstrip.microstrip_Z0();
|
||||
m_aux_microstrip.dispersion();
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::filling_factor_even( double u, double g, double e_r )
|
||||
{
|
||||
double v, v3, v4, a_e, b_e, q_inf;
|
||||
|
||||
v = u * ( 20.0 + g * g ) / ( 10.0 + g * g ) + g * exp( -g );
|
||||
v3 = v * v * v;
|
||||
v4 = v3 * v;
|
||||
a_e = 1.0 + log( ( v4 + v * v / 2704.0 ) / ( v4 + 0.432 ) ) / 49.0 + log( 1.0 + v3 / 5929.741 ) / 18.7;
|
||||
b_e = 0.564 * pow( ( ( e_r - 0.9 ) / ( e_r + 3.0 ) ), 0.053 );
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = pow( ( 1.0 + 10.0 / v ), -a_e * b_e );
|
||||
|
||||
return q_inf;
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::filling_factor_odd( double u, double g, double e_r )
|
||||
{
|
||||
double b_odd = 0.747 * e_r / ( 0.15 + e_r );
|
||||
double c_odd = b_odd - ( b_odd - 0.207 ) * exp( -0.414 * u );
|
||||
double d_odd = 0.593 + 0.694 * exp( -0.562 * u );
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
double q_inf = exp( -c_odd * pow( g, d_odd ) );
|
||||
|
||||
return q_inf;
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::delta_q_cover_even( double h2h )
|
||||
{
|
||||
double q_c;
|
||||
|
||||
if( h2h <= 39 )
|
||||
q_c = tanh( 1.626 + 0.107 * h2h - 1.733 / sqrt( h2h ) );
|
||||
else
|
||||
q_c = 1.0;
|
||||
|
||||
return q_c;
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::delta_q_cover_odd( double h2h )
|
||||
{
|
||||
double q_c;
|
||||
|
||||
if( h2h <= 7 )
|
||||
q_c = tanh( 9.575 / ( 7.0 - h2h ) - 2.965 + 1.68 * h2h - 0.311 * h2h * h2h );
|
||||
else
|
||||
q_c = 1.0;
|
||||
|
||||
return q_c;
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::er_eff_static()
|
||||
{
|
||||
double u_t_e, u_t_o, g, h2, h2h;
|
||||
double a_o, t_h, q, q_c, q_t, q_inf;
|
||||
double er_eff_single;
|
||||
double er;
|
||||
|
||||
er = GetParameter( TCP::EPSILONR );
|
||||
|
||||
/* compute zero-thickness single line parameters */
|
||||
compute_single_line();
|
||||
er_eff_single = m_aux_microstrip.er_eff_0;
|
||||
|
||||
h2 = GetParameter( TCP::H_T );
|
||||
u_t_e = w_t_e / GetParameter( TCP::H ); /* normalized even_mode line width */
|
||||
u_t_o = w_t_o / GetParameter( TCP::H ); /* normalized odd_mode line width */
|
||||
g = GetParameter( TCP::PHYS_S ) / GetParameter( TCP::H ); /* normalized line spacing */
|
||||
h2h = h2 / GetParameter( TCP::H ); /* normalized cover height */
|
||||
t_h = GetParameter( TCP::T ) / GetParameter( TCP::H ); /* normalized strip thickness */
|
||||
|
||||
/* filling factor, computed with thickness corrected width */
|
||||
q_inf = filling_factor_even( u_t_e, g, er );
|
||||
/* cover effect */
|
||||
q_c = delta_q_cover_even( h2h );
|
||||
/* thickness effect */
|
||||
q_t = m_aux_microstrip.delta_q_thickness( u_t_e, t_h );
|
||||
/* resultant filling factor */
|
||||
q = ( q_inf - q_t ) * q_c;
|
||||
/* static even-mode effective dielectric constant */
|
||||
er_eff_e_0 = 0.5 * ( er + 1.0 ) + 0.5 * ( er - 1.0 ) * q;
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = filling_factor_odd( u_t_o, g, er );
|
||||
/* cover effect */
|
||||
q_c = delta_q_cover_odd( h2h );
|
||||
/* thickness effect */
|
||||
q_t = m_aux_microstrip.delta_q_thickness( u_t_o, t_h );
|
||||
/* resultant filling factor */
|
||||
q = ( q_inf - q_t ) * q_c;
|
||||
|
||||
a_o = 0.7287 * ( er_eff_single - 0.5 * ( er + 1.0 ) ) * ( 1.0 - exp( -0.179 * u_t_o ) );
|
||||
|
||||
/* static odd-mode effective dielectric constant */
|
||||
er_eff_o_0 = ( 0.5 * ( er + 1.0 ) + a_o - er_eff_single ) * q + er_eff_single;
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::delta_Z0_even_cover( double g, double u, double h2h )
|
||||
{
|
||||
double f_e, g_e, delta_Z0_even;
|
||||
double x, y, A, B, C, D, E, F;
|
||||
|
||||
A = -4.351 / pow( 1.0 + h2h, 1.842 );
|
||||
B = 6.639 / pow( 1.0 + h2h, 1.861 );
|
||||
C = -2.291 / pow( 1.0 + h2h, 1.90 );
|
||||
f_e = 1.0 - atanh( A + ( B + C * u ) * u );
|
||||
|
||||
x = pow( 10.0, 0.103 * g - 0.159 );
|
||||
y = pow( 10.0, 0.0492 * g - 0.073 );
|
||||
D = 0.747 / sin( 0.5 * M_PI * x );
|
||||
E = 0.725 * sin( 0.5 * M_PI * y );
|
||||
F = pow( 10.0, 0.11 - 0.0947 * g );
|
||||
g_e = 270.0 * ( 1.0 - tanh( D + E * sqrt( 1.0 + h2h ) - F / ( 1.0 + h2h ) ) );
|
||||
|
||||
delta_Z0_even = f_e * g_e;
|
||||
|
||||
return delta_Z0_even;
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_MICROSTRIP::delta_Z0_odd_cover( double g, double u, double h2h )
|
||||
{
|
||||
double f_o, g_o, delta_Z0_odd;
|
||||
double G, J, K, L;
|
||||
|
||||
J = tanh( pow( 1.0 + h2h, 1.585 ) / 6.0 );
|
||||
f_o = pow( u, J );
|
||||
|
||||
G = 2.178 - 0.796 * g;
|
||||
|
||||
if( g > 0.858 )
|
||||
K = log10( 20.492 * pow( g, 0.174 ) );
|
||||
else
|
||||
K = 1.30;
|
||||
|
||||
if( g > 0.873 )
|
||||
L = 2.51 * pow( g, -0.462 );
|
||||
else
|
||||
L = 2.674;
|
||||
|
||||
g_o = 270.0 * ( 1.0 - tanh( G + K * sqrt( 1.0 + h2h ) - L / ( 1.0 + h2h ) ) );
|
||||
|
||||
delta_Z0_odd = f_o * g_o;
|
||||
|
||||
return delta_Z0_odd;
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::Z0_even_odd()
|
||||
{
|
||||
double er_eff, h2, u_t_e, u_t_o, g, h2h;
|
||||
double Q_1, Q_2, Q_3, Q_4, Q_5, Q_6, Q_7, Q_8, Q_9, Q_10;
|
||||
double delta_Z0_e_0, delta_Z0_o_0, Z0_single, er_eff_single;
|
||||
|
||||
h2 = GetParameter( TCP::H_T );
|
||||
u_t_e = w_t_e / GetParameter( TCP::H ); /* normalized even-mode line width */
|
||||
u_t_o = w_t_o / GetParameter( TCP::H ); /* normalized odd-mode line width */
|
||||
g = GetParameter( TCP::PHYS_S ) / GetParameter( TCP::H ); /* normalized line spacing */
|
||||
h2h = h2 / GetParameter( TCP::H ); /* normalized cover height */
|
||||
|
||||
Z0_single = m_aux_microstrip.Z0_0;
|
||||
er_eff_single = m_aux_microstrip.er_eff_0;
|
||||
|
||||
/* even-mode */
|
||||
er_eff = er_eff_e_0;
|
||||
Q_1 = 0.8695 * pow( u_t_e, 0.194 );
|
||||
Q_2 = 1.0 + 0.7519 * g + 0.189 * pow( g, 2.31 );
|
||||
Q_3 = 0.1975 + pow( ( 16.6 + pow( ( 8.4 / g ), 6.0 ) ), -0.387 )
|
||||
+ log( pow( g, 10.0 ) / ( 1.0 + pow( g / 3.4, 10.0 ) ) ) / 241.0;
|
||||
Q_4 = 2.0 * Q_1 / ( Q_2 * ( exp( -g ) * pow( u_t_e, Q_3 ) + ( 2.0 - exp( -g ) ) * pow( u_t_e, -Q_3 ) ) );
|
||||
/* static even-mode impedance */
|
||||
Z0_e_0 = Z0_single * sqrt( er_eff_single / er_eff ) / ( 1.0 - sqrt( er_eff_single ) * Q_4 * Z0_single / TC::ZF0 );
|
||||
/* correction for cover */
|
||||
delta_Z0_e_0 = delta_Z0_even_cover( g, u_t_e, h2h ) / sqrt( er_eff );
|
||||
|
||||
Z0_e_0 = Z0_e_0 - delta_Z0_e_0;
|
||||
|
||||
/* odd-mode */
|
||||
er_eff = er_eff_o_0;
|
||||
Q_5 = 1.794 + 1.14 * log( 1.0 + 0.638 / ( g + 0.517 * pow( g, 2.43 ) ) );
|
||||
Q_6 = 0.2305 + log( pow( g, 10.0 ) / ( 1.0 + pow( g / 5.8, 10.0 ) ) ) / 281.3
|
||||
+ log( 1.0 + 0.598 * pow( g, 1.154 ) ) / 5.1;
|
||||
Q_7 = ( 10.0 + 190.0 * g * g ) / ( 1.0 + 82.3 * g * g * g );
|
||||
Q_8 = exp( -6.5 - 0.95 * log( g ) - pow( g / 0.15, 5.0 ) );
|
||||
Q_9 = log( Q_7 ) * ( Q_8 + 1.0 / 16.5 );
|
||||
Q_10 = ( Q_2 * Q_4 - Q_5 * exp( log( u_t_o ) * Q_6 * pow( u_t_o, -Q_9 ) ) ) / Q_2;
|
||||
|
||||
/* static odd-mode impedance */
|
||||
Z0_o_0 = Z0_single * sqrt( er_eff_single / er_eff ) / ( 1.0 - sqrt( er_eff_single ) * Q_10 * Z0_single / TC::ZF0 );
|
||||
/* correction for cover */
|
||||
delta_Z0_o_0 = delta_Z0_odd_cover( g, u_t_o, h2h ) / sqrt( er_eff );
|
||||
|
||||
Z0_o_0 = Z0_o_0 - delta_Z0_o_0;
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::er_eff_freq()
|
||||
{
|
||||
double P_1, P_2, P_3, P_4, P_5, P_6, P_7;
|
||||
double P_8, P_9, P_10, P_11, P_12, P_13, P_14, P_15;
|
||||
double F_e, F_o;
|
||||
double er_eff, u, g, f_n;
|
||||
|
||||
u = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::H ); /* normalize line width */
|
||||
g = GetParameter( TCP::PHYS_S ) / GetParameter( TCP::H ); /* normalize line spacing */
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = GetParameter( TCP::FREQUENCY ) * GetParameter( TCP::H ) / 1e06;
|
||||
|
||||
er_eff = er_eff_e_0;
|
||||
P_1 = 0.27488 + ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) ) * u - 0.065683 * exp( -8.7513 * u );
|
||||
P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * GetParameter( TCP::EPSILONR ) ) );
|
||||
P_3 = 0.0363 * exp( -4.6 * u ) * ( 1.0 - exp( -pow( f_n / 38.7, 4.97 ) ) );
|
||||
P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( GetParameter( TCP::EPSILONR ) / 15.916, 8.0 ) ) );
|
||||
P_5 = 0.334 * exp( -3.3 * pow( GetParameter( TCP::EPSILONR ) / 15.0, 3.0 ) ) + 0.746;
|
||||
P_6 = P_5 * exp( -pow( f_n / 18.0, 0.368 ) );
|
||||
P_7 = 1.0 + 4.069 * P_6 * pow( g, 0.479 ) * exp( -1.347 * pow( g, 0.595 ) - 0.17 * pow( g, 2.5 ) );
|
||||
|
||||
F_e = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 * P_7 ) * f_n, 1.5763 );
|
||||
/* even-mode effective dielectric constant */
|
||||
er_eff_e = GetParameter( TCP::EPSILONR ) - ( GetParameter( TCP::EPSILONR ) - er_eff ) / ( 1.0 + F_e );
|
||||
prop_delay_e = UnitPropagationDelay( er_eff_e );
|
||||
|
||||
er_eff = er_eff_o_0;
|
||||
P_8 = 0.7168 * ( 1.0 + 1.076 / ( 1.0 + 0.0576 * ( GetParameter( TCP::EPSILONR ) - 1.0 ) ) );
|
||||
P_9 = P_8
|
||||
- 0.7913 * ( 1.0 - exp( -pow( f_n / 20.0, 1.424 ) ) )
|
||||
* atan( 2.481 * pow( GetParameter( TCP::EPSILONR ) / 8.0, 0.946 ) );
|
||||
P_10 = 0.242 * pow( GetParameter( TCP::EPSILONR ) - 1.0, 0.55 );
|
||||
P_11 = 0.6366 * ( exp( -0.3401 * f_n ) - 1.0 ) * atan( 1.263 * pow( u / 3.0, 1.629 ) );
|
||||
P_12 = P_9 + ( 1.0 - P_9 ) / ( 1.0 + 1.183 * pow( u, 1.376 ) );
|
||||
P_13 = 1.695 * P_10 / ( 0.414 + 1.605 * P_10 );
|
||||
P_14 = 0.8928 + 0.1072 * ( 1.0 - exp( -0.42 * pow( f_n / 20.0, 3.215 ) ) );
|
||||
P_15 = fabs( 1.0 - 0.8928 * ( 1.0 + P_11 ) * P_12 * exp( -P_13 * pow( g, 1.092 ) ) / P_14 );
|
||||
|
||||
F_o = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 ) * f_n * P_15, 1.5763 );
|
||||
/* odd-mode effective dielectric constant */
|
||||
er_eff_o = GetParameter( TCP::EPSILONR ) - ( GetParameter( TCP::EPSILONR ) - er_eff ) / ( 1.0 + F_o );
|
||||
prop_delay_o = UnitPropagationDelay( er_eff_o );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::conductor_losses()
|
||||
{
|
||||
double e_r_eff_e_0, e_r_eff_o_0, Z0_h_e, Z0_h_o, delta;
|
||||
double K, R_s, Q_c_e, Q_c_o, alpha_c_e, alpha_c_o;
|
||||
|
||||
e_r_eff_e_0 = er_eff_e_0;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
Z0_h_e = Z0_e_0 * sqrt( e_r_eff_e_0 ); /* homogeneous stripline impedance */
|
||||
Z0_h_o = Z0_o_0 * sqrt( e_r_eff_o_0 ); /* homogeneous stripline impedance */
|
||||
delta = GetParameter( TCP::SKIN_DEPTH );
|
||||
|
||||
if( GetParameter( TCP::FREQUENCY ) > 0.0 )
|
||||
{
|
||||
/* current distribution factor (same for the two modes) */
|
||||
K = exp( -1.2 * pow( ( Z0_h_e + Z0_h_o ) / ( 2.0 * TC::ZF0 ), 0.7 ) );
|
||||
/* skin resistance */
|
||||
R_s = 1.0 / ( GetParameter( TCP::SIGMA ) * delta );
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0 + ( ( 2.0 / M_PI ) * atan( 1.40 * pow( ( GetParameter( TCP::ROUGH ) / delta ), 2.0 ) ) );
|
||||
|
||||
/* even-mode strip inductive quality factor */
|
||||
Q_c_e = ( M_PI * Z0_h_e * GetParameter( TCP::PHYS_WIDTH ) * GetParameter( TCP::FREQUENCY ) )
|
||||
/ ( R_s * TC::C0 * K );
|
||||
/* even-mode losses per unit length */
|
||||
alpha_c_e = ( 20.0 * M_PI / log( 10.0 ) ) * GetParameter( TCP::FREQUENCY ) * sqrt( e_r_eff_e_0 )
|
||||
/ ( TC::C0 * Q_c_e );
|
||||
|
||||
/* odd-mode strip inductive quality factor */
|
||||
Q_c_o = ( M_PI * Z0_h_o * GetParameter( TCP::PHYS_WIDTH ) * GetParameter( TCP::FREQUENCY ) )
|
||||
/ ( R_s * TC::C0 * K );
|
||||
/* odd-mode losses per unit length */
|
||||
alpha_c_o = ( 20.0 * M_PI / log( 10.0 ) ) * GetParameter( TCP::FREQUENCY ) * sqrt( e_r_eff_o_0 )
|
||||
/ ( TC::C0 * Q_c_o );
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha_c_e = alpha_c_o = 0.0;
|
||||
}
|
||||
|
||||
atten_cond_e = alpha_c_e * GetParameter( TCP::PHYS_LEN );
|
||||
atten_cond_o = alpha_c_o * GetParameter( TCP::PHYS_LEN );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::dielectric_losses()
|
||||
{
|
||||
double e_r, e_r_eff_e_0, e_r_eff_o_0;
|
||||
double alpha_d_e, alpha_d_o;
|
||||
|
||||
e_r = GetParameter( TCP::EPSILONR );
|
||||
e_r_eff_e_0 = er_eff_e_0;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
|
||||
alpha_d_e = ( 20.0 * M_PI / log( 10.0 ) ) * ( GetParameter( TCP::FREQUENCY ) / TC::C0 )
|
||||
* ( e_r / sqrt( e_r_eff_e_0 ) ) * ( ( e_r_eff_e_0 - 1.0 ) / ( e_r - 1.0 ) ) * GetParameter( TCP::TAND );
|
||||
alpha_d_o = ( 20.0 * M_PI / log( 10.0 ) ) * ( GetParameter( TCP::FREQUENCY ) / TC::C0 )
|
||||
* ( e_r / sqrt( e_r_eff_o_0 ) ) * ( ( e_r_eff_o_0 - 1.0 ) / ( e_r - 1.0 ) ) * GetParameter( TCP::TAND );
|
||||
|
||||
atten_dielectric_e = alpha_d_e * GetParameter( TCP::PHYS_LEN );
|
||||
atten_dielectric_o = alpha_d_o * GetParameter( TCP::PHYS_LEN );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::attenuation()
|
||||
{
|
||||
SetParameter( TCP::SKIN_DEPTH, SkinDepth() );
|
||||
conductor_losses();
|
||||
dielectric_losses();
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::line_angle()
|
||||
{
|
||||
double e_r_eff_e, e_r_eff_o;
|
||||
double v_e, v_o, lambda_g_e, lambda_g_o;
|
||||
|
||||
e_r_eff_e = er_eff_e;
|
||||
e_r_eff_o = er_eff_o;
|
||||
|
||||
/* even-mode velocity */
|
||||
v_e = TC::C0 / sqrt( e_r_eff_e );
|
||||
/* odd-mode velocity */
|
||||
v_o = TC::C0 / sqrt( e_r_eff_o );
|
||||
/* even-mode wavelength */
|
||||
lambda_g_e = v_e / GetParameter( TCP::FREQUENCY );
|
||||
/* odd-mode wavelength */
|
||||
lambda_g_o = v_o / GetParameter( TCP::FREQUENCY );
|
||||
/* electrical angles */
|
||||
ang_l_e = 2.0 * M_PI * GetParameter( TCP::PHYS_LEN ) / lambda_g_e; /* in radians */
|
||||
ang_l_o = 2.0 * M_PI * GetParameter( TCP::PHYS_LEN ) / lambda_g_o; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::diff_impedance()
|
||||
{
|
||||
// Note that differential impedance is exactly twice the odd mode impedance.
|
||||
// Odd mode is not the same as single-ended impedance, so avoid approximations found
|
||||
// on websites that use static single ended impedance as the starting point
|
||||
|
||||
Zdiff = 2 * Z0_o_0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Z0_dispersion() - calculate frequency dependency of characteristic
|
||||
* impedances
|
||||
*/
|
||||
void COUPLED_MICROSTRIP::Z0_dispersion()
|
||||
{
|
||||
double Q_0;
|
||||
double Q_11, Q_12, Q_13, Q_14, Q_15, Q_16, Q_17, Q_18, Q_19, Q_20, Q_21;
|
||||
double Q_22, Q_23, Q_24, Q_25, Q_26, Q_27, Q_28, Q_29;
|
||||
double r_e, q_e, p_e, d_e, C_e;
|
||||
double e_r_eff_o_f, e_r_eff_o_0;
|
||||
double e_r_eff_single_f, e_r_eff_single_0, Z0_single_f;
|
||||
double f_n, g, u, e_r;
|
||||
double R_1, R_2, R_7, R_10, R_11, R_12, R_15, R_16, tmpf;
|
||||
|
||||
e_r = GetParameter( TCP::EPSILONR );
|
||||
|
||||
u = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::H ); /* normalize line width */
|
||||
g = GetParameter( TCP::PHYS_S ) / GetParameter( TCP::H ); /* normalize line spacing */
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = GetParameter( TCP::FREQUENCY ) * GetParameter( TCP::H ) / 1e06;
|
||||
|
||||
e_r_eff_single_f = m_aux_microstrip.GetParameter( TCP::EPSILON_EFF );
|
||||
e_r_eff_single_0 = m_aux_microstrip.er_eff_0;
|
||||
Z0_single_f = m_aux_microstrip.GetParameter( TCP::Z0 );
|
||||
|
||||
e_r_eff_o_f = er_eff_o;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
|
||||
Q_11 = 0.893 * ( 1.0 - 0.3 / ( 1.0 + 0.7 * ( e_r - 1.0 ) ) );
|
||||
Q_12 = 2.121 * ( pow( f_n / 20.0, 4.91 ) / ( 1.0 + Q_11 * pow( f_n / 20.0, 4.91 ) ) ) * exp( -2.87 * g )
|
||||
* pow( g, 0.902 );
|
||||
Q_13 = 1.0 + 0.038 * pow( e_r / 8.0, 5.1 );
|
||||
Q_14 = 1.0 + 1.203 * pow( e_r / 15.0, 4.0 ) / ( 1.0 + pow( e_r / 15.0, 4.0 ) );
|
||||
Q_15 = 1.887 * exp( -1.5 * pow( g, 0.84 ) ) * pow( g, Q_14 )
|
||||
/ ( 1.0 + 0.41 * pow( f_n / 15.0, 3.0 ) * pow( u, 2.0 / Q_13 ) / ( 0.125 + pow( u, 1.626 / Q_13 ) ) );
|
||||
Q_16 = ( 1.0 + 9.0 / ( 1.0 + 0.403 * pow( e_r - 1.0, 2 ) ) ) * Q_15;
|
||||
Q_17 = 0.394 * ( 1.0 - exp( -1.47 * pow( u / 7.0, 0.672 ) ) ) * ( 1.0 - exp( -4.25 * pow( f_n / 20.0, 1.87 ) ) );
|
||||
Q_18 = 0.61 * ( 1.0 - exp( -2.13 * pow( u / 8.0, 1.593 ) ) ) / ( 1.0 + 6.544 * pow( g, 4.17 ) );
|
||||
Q_19 = 0.21 * g * g * g * g
|
||||
/ ( ( 1.0 + 0.18 * pow( g, 4.9 ) ) * ( 1.0 + 0.1 * u * u ) * ( 1.0 + pow( f_n / 24.0, 3.0 ) ) );
|
||||
Q_20 = ( 0.09 + 1.0 / ( 1.0 + 0.1 * pow( e_r - 1, 2.7 ) ) ) * Q_19;
|
||||
Q_21 = fabs( 1.0 - 42.54 * pow( g, 0.133 ) * exp( -0.812 * g ) * pow( u, 2.5 ) / ( 1.0 + 0.033 * pow( u, 2.5 ) ) );
|
||||
|
||||
r_e = pow( f_n / 28.843, 12 );
|
||||
q_e = 0.016 + pow( 0.0514 * e_r * Q_21, 4.524 );
|
||||
p_e = 4.766 * exp( -3.228 * pow( u, 0.641 ) );
|
||||
d_e = 5.086 * q_e * ( r_e / ( 0.3838 + 0.386 * q_e ) ) * ( exp( -22.2 * pow( u, 1.92 ) ) / ( 1.0 + 1.2992 * r_e ) )
|
||||
* ( pow( e_r - 1.0, 6.0 ) / ( 1.0 + 10 * pow( e_r - 1.0, 6.0 ) ) );
|
||||
C_e = 1.0 + 1.275 * ( 1.0 - exp( -0.004625 * p_e * pow( e_r, 1.674 ) * pow( f_n / 18.365, 2.745 ) ) ) - Q_12 + Q_16
|
||||
- Q_17 + Q_18 + Q_20;
|
||||
|
||||
|
||||
R_1 = 0.03891 * pow( e_r, 1.4 );
|
||||
R_2 = 0.267 * pow( u, 7.0 );
|
||||
R_7 = 1.206 - 0.3144 * exp( -R_1 ) * ( 1.0 - exp( -R_2 ) );
|
||||
R_10 = 0.00044 * pow( e_r, 2.136 ) + 0.0184;
|
||||
tmpf = pow( f_n / 19.47, 6.0 );
|
||||
R_11 = tmpf / ( 1.0 + 0.0962 * tmpf );
|
||||
R_12 = 1.0 / ( 1.0 + 0.00245 * u * u );
|
||||
R_15 = 0.707 * R_10 * pow( f_n / 12.3, 1.097 );
|
||||
R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * ( 1.0 - exp( -pow( u / 15.0, 6.0 ) ) );
|
||||
Q_0 = R_7 * ( 1.0 - 1.1241 * ( R_12 / R_16 ) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
|
||||
/* even-mode frequency-dependent characteristic impedances */
|
||||
SetParameter( TCP::Z0_E, Z0_e_0 * pow( 0.9408 * pow( e_r_eff_single_f, C_e ) - 0.9603, Q_0 )
|
||||
/ pow( ( 0.9408 - d_e ) * pow( e_r_eff_single_0, C_e ) - 0.9603, Q_0 ) );
|
||||
|
||||
Q_29 = 15.16 / ( 1.0 + 0.196 * pow( e_r - 1.0, 2.0 ) );
|
||||
tmpf = pow( e_r - 1.0, 3.0 );
|
||||
Q_28 = 0.149 * tmpf / ( 94.5 + 0.038 * tmpf );
|
||||
tmpf = pow( e_r - 1.0, 1.5 );
|
||||
Q_27 = 0.4 * pow( g, 0.84 ) * ( 1.0 + 2.5 * tmpf / ( 5.0 + tmpf ) );
|
||||
tmpf = pow( ( e_r - 1.0 ) / 13.0, 12.0 );
|
||||
Q_26 = 30.0 - 22.2 * ( tmpf / ( 1.0 + 3.0 * tmpf ) ) - Q_29;
|
||||
tmpf = ( e_r - 1.0 ) * ( e_r - 1.0 );
|
||||
Q_25 = ( 0.3 * f_n * f_n / ( 10.0 + f_n * f_n ) ) * ( 1.0 + 2.333 * tmpf / ( 5.0 + tmpf ) );
|
||||
Q_24 = 2.506 * Q_28 * pow( u, 0.894 ) * pow( ( 1.0 + 1.3 * u ) * f_n / 99.25, 4.29 ) / ( 3.575 + pow( u, 0.894 ) );
|
||||
Q_23 = 1.0 + 0.005 * f_n * Q_27 / ( ( 1.0 + 0.812 * pow( f_n / 15.0, 1.9 ) ) * ( 1.0 + 0.025 * u * u ) );
|
||||
Q_22 = 0.925 * pow( f_n / Q_26, 1.536 ) / ( 1.0 + 0.3 * pow( f_n / 30.0, 1.536 ) );
|
||||
|
||||
/* odd-mode frequency-dependent characteristic impedances */
|
||||
SetParameter( TCP::Z0_O, Z0_single_f
|
||||
+ ( Z0_o_0 * pow( e_r_eff_o_f / e_r_eff_o_0, Q_22 ) - Z0_single_f * Q_23 )
|
||||
/ ( 1.0 + Q_24 + pow( 0.46 * g, 2.2 ) * Q_25 ) );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::syn_err_fun( double* f1, double* f2, double s_h, double w_h, double e_r, double w_h_se,
|
||||
double w_h_so )
|
||||
{
|
||||
double g, he;
|
||||
|
||||
g = cosh( 0.5 * M_PI * s_h );
|
||||
he = cosh( M_PI * w_h + 0.5 * M_PI * s_h );
|
||||
|
||||
*f1 = ( 2.0 / M_PI ) * acosh( ( 2.0 * he - g + 1.0 ) / ( g + 1.0 ) );
|
||||
*f2 = ( 2.0 / M_PI ) * acosh( ( 2.0 * he - g - 1.0 ) / ( g - 1.0 ) );
|
||||
|
||||
if( e_r <= 6.0 )
|
||||
*f2 += ( 4.0 / ( M_PI * ( 1.0 + e_r / 2.0 ) ) ) * acosh( 1.0 + 2.0 * w_h / s_h );
|
||||
else
|
||||
*f2 += ( 1.0 / M_PI ) * acosh( 1.0 + 2.0 * w_h / s_h );
|
||||
|
||||
*f1 -= w_h_se;
|
||||
*f2 -= w_h_so;
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::synth_width()
|
||||
{
|
||||
double Z0, e_r;
|
||||
double w_h_se, w_h_so, w_h, a, ce, co, s_h;
|
||||
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
|
||||
double eps = 1e-04;
|
||||
|
||||
f1 = f2 = 0;
|
||||
e_r = GetParameter( TCP::EPSILONR );
|
||||
|
||||
Z0 = GetParameter( TCP::Z0_E ) / 2.0;
|
||||
/* Wheeler formula for single microstrip synthesis */
|
||||
a = exp( Z0 * sqrt( e_r + 1.0 ) / 42.4 ) - 1.0;
|
||||
w_h_se = 8.0 * sqrt( a * ( ( 7.0 + 4.0 / e_r ) / 11.0 ) + ( ( 1.0 + 1.0 / e_r ) / 0.81 ) ) / a;
|
||||
|
||||
Z0 = GetParameter( TCP::Z0_O ) / 2.0;
|
||||
/* Wheeler formula for single microstrip synthesis */
|
||||
a = exp( Z0 * sqrt( e_r + 1.0 ) / 42.4 ) - 1.0;
|
||||
w_h_so = 8.0 * sqrt( a * ( ( 7.0 + 4.0 / e_r ) / 11.0 ) + ( ( 1.0 + 1.0 / e_r ) / 0.81 ) ) / a;
|
||||
|
||||
ce = cosh( 0.5 * M_PI * w_h_se );
|
||||
co = cosh( 0.5 * M_PI * w_h_so );
|
||||
/* first guess at m_parameters[PHYS_S )/h */
|
||||
s_h = ( 2.0 / M_PI ) * acosh( ( ce + co - 2.0 ) / ( co - ce ) );
|
||||
/* first guess at w/h */
|
||||
w_h = acosh( ( ce * co - 1.0 ) / ( co - ce ) ) / M_PI - s_h / 2.0;
|
||||
|
||||
SetParameter( TCP::PHYS_S, s_h * GetParameter( TCP::H ) );
|
||||
SetParameter( TCP::PHYS_WIDTH, w_h * GetParameter( TCP::H ) );
|
||||
|
||||
syn_err_fun( &f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so );
|
||||
|
||||
/* rather crude Newton-Rhapson; we need this because the estimate of */
|
||||
/* w_h is often quite far from the true value (see Akhtarzad S. et al.) */
|
||||
do
|
||||
{
|
||||
/* compute Jacobian */
|
||||
syn_err_fun( &ft1, &ft2, s_h + eps, w_h, e_r, w_h_se, w_h_so );
|
||||
j11 = ( ft1 - f1 ) / eps;
|
||||
j21 = ( ft2 - f2 ) / eps;
|
||||
syn_err_fun( &ft1, &ft2, s_h, w_h + eps, e_r, w_h_se, w_h_so );
|
||||
j12 = ( ft1 - f1 ) / eps;
|
||||
j22 = ( ft2 - f2 ) / eps;
|
||||
|
||||
/* compute next step */
|
||||
d_s_h = ( -f1 * j22 + f2 * j12 ) / ( j11 * j22 - j21 * j12 );
|
||||
d_w_h = ( -f2 * j11 + f1 * j21 ) / ( j11 * j22 - j21 * j12 );
|
||||
|
||||
//g_print("j11 = %e\tj12 = %e\tj21 = %e\tj22 = %e\n", j11, j12, j21, j22);
|
||||
//g_print("det = %e\n", j11*j22 - j21*j22);
|
||||
//g_print("d_s_h = %e\td_w_h = %e\n", d_s_h, d_w_h);
|
||||
|
||||
s_h += d_s_h;
|
||||
w_h += d_w_h;
|
||||
|
||||
/* check the error */
|
||||
syn_err_fun( &f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so );
|
||||
|
||||
err = sqrt( f1 * f1 + f2 * f2 );
|
||||
/* converged ? */
|
||||
} while( err > 1e-04 );
|
||||
|
||||
|
||||
SetParameter( TCP::PHYS_S, s_h * GetParameter( TCP::H ) );
|
||||
SetParameter( TCP::PHYS_WIDTH, w_h * GetParameter( TCP::H ) );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_MICROSTRIP::syn_fun( double* f1, double* f2, double s_h, double w_h, double Z0_e, double Z0_o )
|
||||
{
|
||||
SetParameter( TCP::PHYS_S, s_h * GetParameter( TCP::H ) );
|
||||
SetParameter( TCP::PHYS_WIDTH, w_h * GetParameter( TCP::H ) );
|
||||
|
||||
/* compute coupled microstrip parameters */
|
||||
Analyse();
|
||||
|
||||
*f1 = GetParameter( TCP::Z0_E ) - Z0_e;
|
||||
*f2 = GetParameter( TCP::Z0_O ) - Z0_o;
|
||||
}
|
202
common/transline_calculations/coupled_microstrip.h
Normal file
202
common/transline_calculations/coupled_microstrip.h
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATIONS_COUPLED_MICROSTRIP_H
|
||||
#define TRANSLINE_CALCULATIONS_COUPLED_MICROSTRIP_H
|
||||
|
||||
|
||||
#include <transline_calculations/transline_calculation_base.h>
|
||||
#include <transline_calculations/microstrip.h>
|
||||
|
||||
|
||||
class COUPLED_MICROSTRIP : public TRANSLINE_CALCULATION_BASE
|
||||
{
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
public:
|
||||
COUPLED_MICROSTRIP() :
|
||||
TRANSLINE_CALCULATION_BASE( { TCP::Z0_E,
|
||||
TCP::Z0_O,
|
||||
TCP::Z_DIFF,
|
||||
TCP::ANG_L,
|
||||
TCP::PHYS_WIDTH,
|
||||
TCP::PHYS_LEN,
|
||||
TCP::PHYS_S,
|
||||
TCP::H,
|
||||
TCP::T,
|
||||
TCP::H_T,
|
||||
TCP::FREQUENCY,
|
||||
TCP::EPSILONR,
|
||||
TCP::EPSILON_EFF_EVEN,
|
||||
TCP::EPSILON_EFF_ODD,
|
||||
TCP::UNIT_PROP_DELAY_EVEN,
|
||||
TCP::UNIT_PROP_DELAY_ODD,
|
||||
TCP::ATTEN_COND_EVEN,
|
||||
TCP::ATTEN_COND_ODD,
|
||||
TCP::ATTEN_DILECTRIC_EVEN,
|
||||
TCP::ATTEN_DILECTRIC_ODD,
|
||||
TCP::SKIN_DEPTH,
|
||||
TCP::MURC,
|
||||
TCP::SIGMA,
|
||||
TCP::ROUGH,
|
||||
TCP::TAND } )
|
||||
{
|
||||
}
|
||||
|
||||
/// Analyse track geometry parameters to output Z0 and Ang_L
|
||||
void Analyse() override;
|
||||
|
||||
/// Synthesis track geometry parameters to match given Z0
|
||||
bool Synthesize( SYNTHESIZE_OPTS aOpts ) override;
|
||||
|
||||
private:
|
||||
/// Sets the output values and status following analysis
|
||||
void SetAnalysisResults() override;
|
||||
|
||||
/// Sets the output values and status following synthesis
|
||||
void SetSynthesisResults() override;
|
||||
|
||||
/**
|
||||
* Computes the thickness effect on normalized width for a single microstrip line
|
||||
*
|
||||
* References: H. A. Atwater, "Simplified Design Equations for Microstrip Line Parameters", Microwave Journal,
|
||||
* pp. 109-115,November 1989.
|
||||
*/
|
||||
double delta_u_thickness_single( double, double );
|
||||
|
||||
/**
|
||||
* Compute the thickness effect on normalized width for coupled microstrips
|
||||
*
|
||||
* References: Rolf Jansen, "High-Speed Computation of Single and Coupled Microstrip Parameters Including
|
||||
* Dispersion, High-Order Modes, Loss and Finite Strip Thickness", IEEE Trans. MTT, vol. 26, no. 2, pp. 75-82,
|
||||
* Feb. 1978
|
||||
*/
|
||||
void delta_u_thickness();
|
||||
|
||||
/// Computes initial parameters for a single microstrip
|
||||
void compute_single_line();
|
||||
|
||||
/// Compute the filling factor for the coupled microstrip even mode without cover and zero conductor thickness
|
||||
double filling_factor_even( double, double, double );
|
||||
|
||||
/**
|
||||
* Compute the filling factor for the coupled microstrip odd mode without cover and zero conductor thickness
|
||||
*/
|
||||
double filling_factor_odd( double, double, double );
|
||||
|
||||
/// Compute the cover effect on filling factor for the even mode
|
||||
double delta_q_cover_even( double );
|
||||
|
||||
/// Compute the cover effect on filling factor for the odd mode
|
||||
double delta_q_cover_odd( double );
|
||||
|
||||
/**
|
||||
* Compute the static effective dielectric constants
|
||||
*
|
||||
* References: Manfred Kirschning and Rolf Jansen, "Accurate Wide-Range Design Equations for the Frequency-Dependent
|
||||
* Characteristic of Parallel Coupled Microstrip Lines", IEEE Trans. MTT, vol. 32, no. 1, Jan. 1984
|
||||
*/
|
||||
void er_eff_static();
|
||||
|
||||
/**
|
||||
* Compute the even mode impedance correction for a homogeneous microstrip due to the cover
|
||||
*
|
||||
* References: S. March, "Microstrip Packaging: Watch the Last Step", Microwaves, vol. 20, no. 13, pp. 83.94,
|
||||
* Dec. 1981.
|
||||
*/
|
||||
double delta_Z0_even_cover( double, double, double );
|
||||
|
||||
/**
|
||||
* Compute the odd mode impedance correction for a homogeneous microstrip due to the cover
|
||||
*
|
||||
* References: S. March, "Microstrip Packaging: Watch the Last Step", Microwaves, vol. 20, no. 13, pp. 83.94,
|
||||
* Dec. 1981.
|
||||
*/
|
||||
double delta_Z0_odd_cover( double, double, double );
|
||||
|
||||
/**
|
||||
* Compute the static even- and odd-mode static impedances
|
||||
*
|
||||
* References: Manfred Kirschning and Rolf Jansen, "Accurate Wide-Range Design Equations for the Frequency-Dependent
|
||||
* Characteristic of Parallel Coupled Microstrip Lines", IEEE Trans. MTT, vol. 32, no. 1, Jan. 1984
|
||||
*/
|
||||
void Z0_even_odd();
|
||||
|
||||
/// Compute er_eff as a function of frequency
|
||||
void er_eff_freq();
|
||||
|
||||
/// Compute conductor losses per unit length
|
||||
void conductor_losses();
|
||||
|
||||
/// Compute dielectric losses per unit length
|
||||
void dielectric_losses();
|
||||
|
||||
/// Compute attenuation
|
||||
void attenuation();
|
||||
|
||||
/// Compute electrical length in radians
|
||||
void line_angle();
|
||||
|
||||
/// Calculate the differential impedance of the coupled microstrips
|
||||
void diff_impedance();
|
||||
|
||||
/// Calculate frequency dependency of characteristic impedances
|
||||
void Z0_dispersion();
|
||||
|
||||
/// Error function to minimise when synthesising trace geometry
|
||||
void syn_err_fun( double*, double*, double, double, double, double, double );
|
||||
|
||||
/**
|
||||
* Calculate widths given Z0 and e_r
|
||||
*
|
||||
* From Akhtarzad S. et al., "The design of coupled microstrip lines", IEEE Trans. MTT-23, June 1975 and
|
||||
* Hinton, J.H., "On design of coupled microstrip lines", IEEE Trans. MTT-28, March 1980
|
||||
*/
|
||||
void synth_width();
|
||||
|
||||
void syn_fun( double*, double*, double, double, double, double );
|
||||
|
||||
/// Runs intermediate single-track calculations
|
||||
MICROSTRIP m_aux_microstrip;
|
||||
|
||||
double w_t_e{ 0.0 };
|
||||
double w_t_o{ 0.0 };
|
||||
double er_eff_e_0{ 0.0 };
|
||||
double er_eff_o_0{ 0.0 };
|
||||
double Z0_e_0{ 0.0 };
|
||||
double Z0_o_0{ 0.0 };
|
||||
double er_eff_e{ 0.0 };
|
||||
double er_eff_o{ 0.0 };
|
||||
double prop_delay_e{ 0.0 };
|
||||
double prop_delay_o{ 0.0 };
|
||||
double atten_cond_e{ 0.0 };
|
||||
double atten_cond_o{ 0.0 };
|
||||
double atten_dielectric_e{ 0.0 };
|
||||
double atten_dielectric_o{ 0.0 };
|
||||
double ang_l_e{ 0.0 };
|
||||
double ang_l_o{ 0.0 };
|
||||
double Zdiff{ 0.0 };
|
||||
};
|
||||
|
||||
|
||||
#endif //TRANSLINE_CALCULATIONS_COUPLED_MICROSTRIP_H
|
393
common/transline_calculations/coupled_stripline.cpp
Normal file
393
common/transline_calculations/coupled_stripline.cpp
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implements the calculations described in:
|
||||
*
|
||||
* [1] S. B. Cohn, "Characteristic Impedance of the Shielded-Strip Transmission Line," in Transactions of the IRE
|
||||
* Professional Group on Microwave Theory and Techniques, vol. 2, no. 2, pp. 52-57, July 1954
|
||||
* [2] S. B. Cohn, "Shielded Coupled-Strip Transmission Line," in IRE Transactions on Microwave Theory and Techniques,
|
||||
* vol. 3, no. 5, pp. 29-38, October 1955
|
||||
*/
|
||||
|
||||
#include <transline_calculations/coupled_stripline.h>
|
||||
#include <transline_calculations/units.h>
|
||||
#include <transline_calculations/units_scales.h>
|
||||
|
||||
|
||||
namespace TC = TRANSLINE_CALCULATIONS;
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::Analyse()
|
||||
{
|
||||
// Calculate skin depth
|
||||
SetParameter( TCP::SKIN_DEPTH, SkinDepth() );
|
||||
|
||||
// Get analysis parameters
|
||||
double w = GetParameter( TCP::PHYS_WIDTH );
|
||||
double t = GetParameter( TCP::T );
|
||||
double s = GetParameter( TCP::PHYS_S );
|
||||
double h = GetParameter( TCP::H );
|
||||
const double er = GetParameter( TCP::EPSILONR );
|
||||
|
||||
calcZeroThicknessCoupledImpedances( h, w, s, er );
|
||||
|
||||
// We've got the impedances now for an infinitely thin line
|
||||
if( t == 0.0 )
|
||||
{
|
||||
SetParameter( TCP::Z0_E, Z0_e_w_h_0_s_h );
|
||||
SetParameter( TCP::Z0_O, Z0_o_w_h_0_s_h );
|
||||
}
|
||||
else
|
||||
{
|
||||
calcSingleStripImpedances();
|
||||
calcFringeCapacitances( h, t, er );
|
||||
calcZ0EvenMode();
|
||||
calcZ0OddMode( t, s );
|
||||
}
|
||||
|
||||
calcLosses();
|
||||
calcDielectrics();
|
||||
}
|
||||
|
||||
|
||||
bool COUPLED_STRIPLINE::Synthesize( const SYNTHESIZE_OPTS aOpts )
|
||||
{
|
||||
if( aOpts == SYNTHESIZE_OPTS::FIX_WIDTH )
|
||||
return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O );
|
||||
|
||||
if( aOpts == SYNTHESIZE_OPTS::FIX_SPACING )
|
||||
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O );
|
||||
|
||||
// This synthesis approach is modified from wcalc, which is released under GPL version 2
|
||||
// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006 Dan McMahill
|
||||
// All rights reserved
|
||||
|
||||
double ze0 = 0;
|
||||
double zo0 = 0;
|
||||
|
||||
const double h = GetParameter( TCP::H );
|
||||
const double er = GetParameter( TCP::EPSILONR );
|
||||
|
||||
const double z0e_target = GetParameter( TCP::Z0_E );
|
||||
const double z0o_target = GetParameter( TCP::Z0_O );
|
||||
// Calculate Z0 and coupling, k
|
||||
const double z0 = sqrt( z0e_target * z0o_target );
|
||||
const double k = ( z0e_target - z0o_target ) / ( z0e_target + z0o_target );
|
||||
|
||||
int maxiters = 50;
|
||||
|
||||
// Initial guess at a solution. Note that this is an initial guess for coupled microstrip, not coupled stripline...
|
||||
static constexpr double ai[] = { 1, -0.301, 3.209, -27.282, 56.609, -37.746 };
|
||||
static constexpr double bi[] = { 0.020, -0.623, 17.192, -68.946, 104.740, -16.148 };
|
||||
static constexpr double ci[] = { 0.002, -0.347, 7.171, -36.910, 76.132, -51.616 };
|
||||
|
||||
const double AW = exp( z0 * sqrt( er + 1.0 ) / 42.4 ) - 1.0;
|
||||
const double F1 = 8.0 * sqrt( AW * ( 7.0 + 4.0 / er ) / 11.0 + ( 1.0 + 1.0 / er ) / 0.81 ) / AW;
|
||||
|
||||
double F2 = 0.0, F3 = 0.0;
|
||||
;
|
||||
|
||||
for( int i = 0; i <= 5; i++ )
|
||||
F2 = F2 + ai[i] * pow( k, i );
|
||||
|
||||
for( int i = 0; i <= 5; i++ )
|
||||
F3 = F3 + ( bi[i] - ci[i] * ( 9.6 - er ) ) * pow( ( 0.6 - k ), static_cast<double>( i ) );
|
||||
|
||||
double w = h * fabs( F1 * F2 );
|
||||
double s = h * fabs( F1 * F3 );
|
||||
|
||||
int iters = 0;
|
||||
bool done = false;
|
||||
double delta = 0.0;
|
||||
|
||||
delta = TC::UNIT_MIL * 1e-5;
|
||||
|
||||
const double cval = 1e-12 * z0e_target * z0o_target;
|
||||
|
||||
while( !done && iters < maxiters )
|
||||
{
|
||||
iters++;
|
||||
|
||||
// Compute impedances with initial solution guess
|
||||
SetParameter( TCP::PHYS_WIDTH, w );
|
||||
SetParameter( TCP::PHYS_S, s );
|
||||
Analyse();
|
||||
|
||||
// Check for convergence
|
||||
ze0 = GetParameter( TCP::Z0_E );
|
||||
zo0 = GetParameter( TCP::Z0_O );
|
||||
const double err = pow( ( ze0 - z0e_target ), 2.0 ) + pow( ( zo0 - z0o_target ), 2.0 );
|
||||
|
||||
if( err < cval )
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Approximate the first Jacobian
|
||||
SetParameter( TCP::PHYS_WIDTH, w + delta );
|
||||
SetParameter( TCP::PHYS_S, s );
|
||||
Analyse();
|
||||
|
||||
const double ze1 = GetParameter( TCP::Z0_E );
|
||||
const double zo1 = GetParameter( TCP::Z0_O );
|
||||
|
||||
SetParameter( TCP::PHYS_WIDTH, w );
|
||||
SetParameter( TCP::PHYS_S, s + delta );
|
||||
Analyse();
|
||||
|
||||
const double ze2 = GetParameter( TCP::Z0_E );
|
||||
const double zo2 = GetParameter( TCP::Z0_O );
|
||||
|
||||
const double dedw = ( ze1 - ze0 ) / delta;
|
||||
const double dodw = ( zo1 - zo0 ) / delta;
|
||||
const double deds = ( ze2 - ze0 ) / delta;
|
||||
const double dods = ( zo2 - zo0 ) / delta;
|
||||
|
||||
// Find the determinate
|
||||
const double d = dedw * dods - deds * dodw;
|
||||
|
||||
// Estimate the new solution, but don't change by more than 10% at a time to avoid convergence problems
|
||||
double dw = -1.0 * ( ( ze0 - z0e_target ) * dods - ( zo0 - z0o_target ) * deds ) / d;
|
||||
|
||||
if( fabs( dw ) > 0.1 * w )
|
||||
{
|
||||
if( dw > 0.0 )
|
||||
dw = 0.1 * w;
|
||||
else
|
||||
dw = -0.1 * w;
|
||||
}
|
||||
|
||||
w = fabs( w + dw );
|
||||
|
||||
double ds = ( ( ze0 - z0e_target ) * dodw - ( zo0 - z0o_target ) * dedw ) / d;
|
||||
|
||||
if( fabs( ds ) > 0.1 * s )
|
||||
{
|
||||
if( ds > 0.0 )
|
||||
ds = 0.1 * s;
|
||||
else
|
||||
ds = -0.1 * s;
|
||||
}
|
||||
|
||||
s = fabs( s + ds );
|
||||
}
|
||||
}
|
||||
|
||||
if( !done )
|
||||
return false;
|
||||
|
||||
// Recompute with the final parameters
|
||||
SetParameter( TCP::PHYS_WIDTH, w );
|
||||
SetParameter( TCP::PHYS_S, s );
|
||||
Analyse();
|
||||
|
||||
// Reset the impedances
|
||||
SetParameter( TCP::Z0_E, z0e_target );
|
||||
SetParameter( TCP::Z0_O, z0o_target );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::SetAnalysisResults()
|
||||
{
|
||||
SetAnalysisResult( TCP::EPSILON_EFF_EVEN, e_eff_e );
|
||||
SetAnalysisResult( TCP::EPSILON_EFF_ODD, e_eff_o );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY_EVEN, unit_prop_delay_e );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY_ODD, unit_prop_delay_o );
|
||||
SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
|
||||
const double Z0_E = GetParameter( TCP::Z0_E );
|
||||
const double Z0_O = GetParameter( TCP::Z0_O );
|
||||
const double Z_DIFF = GetParameter( TCP::Z_DIFF );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double S = GetParameter( TCP::PHYS_S );
|
||||
|
||||
const bool Z0_E_invalid = !std::isfinite( Z0_E ) || Z0_E <= 0;
|
||||
const bool Z0_O_invalid = !std::isfinite( Z0_O ) || Z0_O <= 0;
|
||||
const bool Z_DIFF_invalid = !std::isfinite( Z_DIFF ) || Z_DIFF <= 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ang_l ) || ang_l < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool S_invalid = !std::isfinite( S ) || S <= 0;
|
||||
|
||||
SetAnalysisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::Z_DIFF, Z_DIFF, Z_DIFF_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::ANG_L, ang_l, ANG_L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::SetSynthesisResults()
|
||||
{
|
||||
SetSynthesisResult( TCP::EPSILON_EFF_EVEN, e_eff_e );
|
||||
SetSynthesisResult( TCP::EPSILON_EFF_ODD, e_eff_o );
|
||||
SetSynthesisResult( TCP::UNIT_PROP_DELAY_EVEN, unit_prop_delay_e );
|
||||
SetSynthesisResult( TCP::UNIT_PROP_DELAY_ODD, unit_prop_delay_o );
|
||||
SetSynthesisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
|
||||
const double Z0_E = GetParameter( TCP::Z0_E );
|
||||
const double Z0_O = GetParameter( TCP::Z0_O );
|
||||
const double Z_DIFF = GetParameter( TCP::Z_DIFF );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double S = GetParameter( TCP::PHYS_S );
|
||||
|
||||
const bool Z0_E_invalid = !std::isfinite( Z0_E ) || Z0_E <= 0;
|
||||
const bool Z0_O_invalid = !std::isfinite( Z0_O ) || Z0_O <= 0;
|
||||
const bool Z_DIFF_invalid = !std::isfinite( Z_DIFF ) || Z_DIFF <= 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ang_l ) || ang_l < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool S_invalid = !std::isfinite( S ) || S <= 0;
|
||||
|
||||
SetSynthesisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::Z_DIFF, Z_DIFF, Z_DIFF_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::ANG_L, ang_l, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcFringeCapacitances( const double h, const double t, const double er )
|
||||
{
|
||||
// Reference [1], Eq. 2
|
||||
C_f_t_h = ( TC::E0 * er / M_PI )
|
||||
* ( ( 2.0 / ( 1.0 - t / h ) ) * log( ( 1.0 / ( 1.0 - t / h ) ) + 1.0 )
|
||||
- ( 1.0 / ( 1.0 - t / h ) - 1.0 ) * log( ( 1.0 / pow( 1.0 - t / h, 2.0 ) ) - 1.0 ) );
|
||||
|
||||
// Reference [2], Eq. 13
|
||||
C_f_0 = ( TC::E0 * er / M_PI ) * 2.0 * log( 2.0 );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcZeroThicknessCoupledImpedances( const double h, const double w, const double s,
|
||||
const double er )
|
||||
{
|
||||
// Reference [2], Eqs. 2 - 7
|
||||
const double k_e = tanh( M_PI * w / ( 2.0 * h ) ) * tanh( M_PI * ( w + s ) / ( 2.0 * h ) );
|
||||
const double k_o = tanh( M_PI * w / ( 2.0 * h ) ) * coth( M_PI * ( w + s ) / ( 2.0 * h ) );
|
||||
const double k_e_p = std::sqrt( 1 - std::pow( k_e, 2 ) );
|
||||
const double k_o_p = std::sqrt( 1 - std::pow( k_o, 2 ) );
|
||||
Z0_e_w_h_0_s_h = ( TC::ZF0 / ( 4.0 * std::sqrt( er ) ) )
|
||||
* ( EllipticIntegral( k_e_p ).first / EllipticIntegral( k_e ).first );
|
||||
Z0_o_w_h_0_s_h = ( TC::ZF0 / ( 4.0 * std::sqrt( er ) ) )
|
||||
* ( EllipticIntegral( k_o_p ).first / EllipticIntegral( k_o ).first );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcSingleStripImpedances()
|
||||
{
|
||||
const double er = GetParameter( TCP::EPSILONR );
|
||||
const double h = GetParameter( TCP::H );
|
||||
const double w = GetParameter( TCP::PHYS_WIDTH );
|
||||
|
||||
// Finite-thickness single strip impedance
|
||||
Z0_w_h_t_h = calcZ0SymmetricStripline();
|
||||
|
||||
// Zero-thickness single strip impedance
|
||||
// Reference [1], Eqs. 5 - 6 (corrected for sqrt(e_r))
|
||||
const double k = sech( M_PI * w / ( 2.0 * h ) );
|
||||
const double k_p = tanh( M_PI * w / ( 2.0 * h ) );
|
||||
Z0_w_h_0 =
|
||||
( TC::ZF0 / ( 4.0 * std::sqrt( er ) ) ) * ( EllipticIntegral( k ).first / EllipticIntegral( k_p ).first );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcZ0EvenMode()
|
||||
{
|
||||
// Reference [2], Eq. 18
|
||||
const double Z_e =
|
||||
1.0 / ( ( 1.0 / Z0_w_h_t_h ) - ( C_f_t_h / C_f_0 ) * ( ( 1.0 / Z0_w_h_0 ) - ( 1.0 / Z0_e_w_h_0_s_h ) ) );
|
||||
SetParameter( TCP::Z0_E, Z_e );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcZ0OddMode( const double t, const double s )
|
||||
{
|
||||
// Reference [2], Eq. 20
|
||||
const double Z_o_1 =
|
||||
1.0 / ( ( 1.0 / Z0_w_h_t_h ) + ( C_f_t_h / C_f_0 ) * ( ( 1.0 / Z0_o_w_h_0_s_h ) - ( 1.0 / Z0_w_h_0 ) ) );
|
||||
|
||||
// Reference [2], Eq. 22
|
||||
const double Z_o_2 =
|
||||
1.0
|
||||
/ ( ( 1.0 / Z0_o_w_h_0_s_h ) + ( ( 1.0 / Z0_w_h_t_h ) - ( 1.0 / Z0_w_h_0 ) )
|
||||
- ( 2.0 / TC::ZF0 ) * ( C_f_t_h / TC::E0 - C_f_0 / TC::E0 ) + ( 2.0 * t ) / ( TC::ZF0 * s ) );
|
||||
|
||||
const double Z_o = s / t >= 5.0 ? Z_o_1 : Z_o_2;
|
||||
|
||||
SetParameter( TCP::Z0_O, Z_o );
|
||||
SetParameter( TCP::Z_DIFF, 2.0 * Z_o );
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcLosses()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void COUPLED_STRIPLINE::calcDielectrics()
|
||||
{
|
||||
// We assume here that the dielectric is homogenous surrounding the strips - in this case, the odd or even modes
|
||||
// don't change the effective dielectric constant of the transmission mode. This would not be the case if the
|
||||
// dielectric were inhomogenous, as there is more electric field permeating the dielectric between the traces in
|
||||
// the odd mode compared to the even mode.
|
||||
const double e_r = GetParameter( TCP::EPSILONR );
|
||||
e_eff_e = e_r;
|
||||
e_eff_o = e_r;
|
||||
|
||||
// Both modes have the same propagation delay
|
||||
const double unitPropDelay = UnitPropagationDelay( e_r );
|
||||
unit_prop_delay_e = unitPropDelay;
|
||||
unit_prop_delay_o = unitPropDelay;
|
||||
|
||||
// Electrical length (in radians)
|
||||
const double v = TC::C0 / sqrt( e_r );
|
||||
const double lambda_g = v / GetParameter( TCP::FREQUENCY );
|
||||
ang_l = 2.0 * M_PI * GetParameter( TCP::PHYS_LEN ) / lambda_g;
|
||||
}
|
||||
|
||||
|
||||
double COUPLED_STRIPLINE::calcZ0SymmetricStripline()
|
||||
{
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, GetParameter( TCP::EPSILONR ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::T, GetParameter( TCP::T ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::STRIPLINE_A, GetParameter( TCP::H ) / 2.0 );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::H, GetParameter( TCP::H ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, GetParameter( TCP::PHYS_LEN ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, GetParameter( TCP::FREQUENCY ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::TAND, 0.0 );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, GetParameter( TCP::PHYS_WIDTH ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, 0 );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, GetParameter( TCP::SIGMA ) );
|
||||
m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::MURC, GetParameter( TCP::MURC ) );
|
||||
m_striplineCalc.Analyse();
|
||||
|
||||
return m_striplineCalc.GetParameter( TCP::Z0 );
|
||||
}
|
104
common/transline_calculations/coupled_stripline.h
Normal file
104
common/transline_calculations/coupled_stripline.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATIONS_COUPLED_STRIPLINE_H
|
||||
#define TRANSLINE_CALCULATIONS_COUPLED_STRIPLINE_H
|
||||
|
||||
|
||||
#include <transline_calculations/transline_calculation_base.h>
|
||||
#include <transline_calculations/stripline.h>
|
||||
|
||||
/*
|
||||
* This implements the calculations described in:
|
||||
*
|
||||
* [1] S. B. Cohn, "Characteristic Impedance of the Shielded-Strip Transmission Line," in Transactions of the IRE
|
||||
* Professional Group on Microwave Theory and Techniques, vol. 2, no. 2, pp. 52-57, July 1954
|
||||
* [2] S. B. Cohn, "Shielded Coupled-Strip Transmission Line," in IRE Transactions on Microwave Theory and Techniques,
|
||||
* vol. 3, no. 5, pp. 29-38, October 1955
|
||||
*/
|
||||
|
||||
class COUPLED_STRIPLINE : public TRANSLINE_CALCULATION_BASE
|
||||
{
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
public:
|
||||
COUPLED_STRIPLINE() :
|
||||
TRANSLINE_CALCULATION_BASE( { TCP::SKIN_DEPTH, TCP::Z0_E, TCP::Z0_O, TCP::Z_DIFF, TCP::PHYS_WIDTH,
|
||||
TCP::FREQUENCY, TCP::PHYS_LEN, TCP::H, TCP::PHYS_S, TCP::T, TCP::EPSILONR,
|
||||
TCP::MURC, TCP::SIGMA, TCP::ANG_L } )
|
||||
{
|
||||
}
|
||||
|
||||
/// Analyse track geometry parameters to output Z0 and Ang_L
|
||||
void Analyse() override;
|
||||
|
||||
/// Synthesis track geometry parameters to match given Z0
|
||||
bool Synthesize( SYNTHESIZE_OPTS aOpts ) override;
|
||||
|
||||
private:
|
||||
/// Sets the output values and status following analysis
|
||||
void SetAnalysisResults() override;
|
||||
|
||||
/// Sets the output values and status following synthesis
|
||||
void SetSynthesisResults() override;
|
||||
|
||||
/// Calculates the impedance of a finite-width single strip
|
||||
double calcZ0SymmetricStripline();
|
||||
|
||||
/// Calculate the coupling fringe capacitances
|
||||
void calcFringeCapacitances( double h, double t, double er );
|
||||
|
||||
/// Calculates impedances of finite- and zero-thickness single strips
|
||||
void calcSingleStripImpedances();
|
||||
|
||||
/// Calculates zero-thickness coupled strip impedances
|
||||
void calcZeroThicknessCoupledImpedances( double h, double w, double s, double er );
|
||||
|
||||
/// Calculates even mode Z0
|
||||
void calcZ0EvenMode();
|
||||
|
||||
/// Calculates odd mode Z0
|
||||
void calcZ0OddMode( double t, double s );
|
||||
|
||||
/// Calculates conductor and dielectric losses
|
||||
void calcLosses();
|
||||
|
||||
/// Calculate dialectric and propagation parameters
|
||||
void calcDielectrics();
|
||||
|
||||
double C_f_0{ 0.0 }; ///< Fringing capacitance from one edge to ground of zero thickness strip
|
||||
double C_f_t_h{ 0.0 }; ///< Fringing capacitance of single strip of finite width
|
||||
|
||||
double Z0_w_h_0{ 0.0 }; ///< Impedance of single strip of zero thickness
|
||||
double Z0_w_h_t_h{ 0.0 }; ///< Impedance of single strip of finite thickness
|
||||
double Z0_e_w_h_0_s_h{ 0.0 }; ///< Even mode impedance of coupled zero thickness strips
|
||||
double Z0_o_w_h_0_s_h{ 0.0 }; ///< Odd mode impedance of coupled zero thickness strips
|
||||
|
||||
double e_eff_e{ 0.0 }; ///< Even mode effective dielectric constant
|
||||
double e_eff_o{ 0.0 }; ///< Odd mode effective dielectric constant
|
||||
double ang_l{ 0.0 }; ///< Angular length (rad)
|
||||
double unit_prop_delay_e{ 0.0 }; ///< Even mode unit propagation delay (ps/cm)
|
||||
double unit_prop_delay_o{ 0.0 }; ///< Odd mode unit propagation delay (ps/cm)
|
||||
|
||||
/// Calculator used to determine single stripline values
|
||||
STRIPLINE m_striplineCalc;
|
||||
};
|
||||
|
||||
|
||||
#endif //TRANSLINE_CALCULATIONS_COUPLED_STRIPLINE_H
|
396
common/transline_calculations/microstrip.cpp
Normal file
396
common/transline_calculations/microstrip.cpp
Normal file
@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <transline_calculations/microstrip.h>
|
||||
#include <transline_calculations/units.h>
|
||||
|
||||
|
||||
namespace TC = TRANSLINE_CALCULATIONS;
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
|
||||
void MICROSTRIP::Analyse()
|
||||
{
|
||||
// Effective permeability
|
||||
mur_eff_ms();
|
||||
|
||||
// Static impedance
|
||||
microstrip_Z0();
|
||||
|
||||
// Calculate freq dependence of er and Z0
|
||||
dispersion();
|
||||
|
||||
// Calculate electrical lengths
|
||||
line_angle();
|
||||
|
||||
// Calculate losses
|
||||
attenuation();
|
||||
}
|
||||
|
||||
|
||||
bool MICROSTRIP::Synthesize( const SYNTHESIZE_OPTS aOpts )
|
||||
{
|
||||
const double z0_dest = GetParameter( TCP::Z0 );
|
||||
const double angl_dest = GetParameter( TCP::ANG_L );
|
||||
|
||||
// Calculate width and use for initial value in Newton's method
|
||||
SetParameter( TCP::PHYS_WIDTH, SynthesizeWidth() );
|
||||
|
||||
// Optimise Z0, varying width
|
||||
if( !MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0 ) )
|
||||
return false;
|
||||
|
||||
// Re-calculate with required output parameters
|
||||
SetParameter( TCP::Z0, z0_dest );
|
||||
SetParameter( TCP::ANG_L, angl_dest );
|
||||
double const er_eff = GetParameter( TCP::EPSILON_EFF );
|
||||
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( er_eff * mur_eff )
|
||||
* GetParameter( TCP::ANG_L ) / 2.0 / M_PI ); /* in m */
|
||||
Analyse();
|
||||
|
||||
// Set the output parameters
|
||||
SetParameter( TCP::Z0, z0_dest );
|
||||
SetParameter( TCP::ANG_L, angl_dest );
|
||||
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( er_eff * mur_eff )
|
||||
* GetParameter( TCP::ANG_L ) / 2.0 / M_PI ); /* in m */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::SetAnalysisResults()
|
||||
{
|
||||
SetAnalysisResult( TCP::EPSILON_EFF, GetParameter( TCP::EPSILON_EFF ) );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY, GetParameter( TCP::UNIT_PROP_DELAY ) );
|
||||
SetAnalysisResult( TCP::ATTEN_COND, GetParameter( TCP::ATTEN_COND ) );
|
||||
SetAnalysisResult( TCP::ATTEN_DILECTRIC, GetParameter( TCP::ATTEN_DILECTRIC ) );
|
||||
SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
|
||||
const double Z0 = GetParameter( TCP::Z0 );
|
||||
const double ANG_L = GetParameter( TCP::ANG_L );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
|
||||
const bool Z0_invalid = !std::isfinite( Z0 ) || Z0 < 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
|
||||
SetAnalysisResult( TCP::Z0, Z0, Z0_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::SetSynthesisResults()
|
||||
{
|
||||
SetSynthesisResult( TCP::EPSILON_EFF, GetParameter( TCP::EPSILON_EFF ) );
|
||||
SetSynthesisResult( TCP::UNIT_PROP_DELAY, GetParameter( TCP::UNIT_PROP_DELAY ) );
|
||||
SetSynthesisResult( TCP::ATTEN_COND, GetParameter( TCP::ATTEN_COND ) );
|
||||
SetSynthesisResult( TCP::ATTEN_DILECTRIC, GetParameter( TCP::ATTEN_DILECTRIC ) );
|
||||
SetSynthesisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
|
||||
const double Z0 = GetParameter( TCP::Z0 );
|
||||
const double ANG_L = GetParameter( TCP::ANG_L );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
|
||||
const bool Z0_invalid = !std::isfinite( Z0 ) || Z0 < 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
|
||||
SetSynthesisResult( TCP::Z0, Z0, Z0_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::SynthesizeWidth() const
|
||||
{
|
||||
const double e_r = GetParameter( TCP::EPSILONR );
|
||||
const double a = ( ( GetParameter( TCP::Z0 ) / TC::ZF0 / 2 / M_PI ) * sqrt( ( e_r + 1 ) / 2. ) )
|
||||
+ ( ( e_r - 1 ) / ( e_r + 1 ) * ( 0.23 + ( 0.11 / e_r ) ) );
|
||||
const double b = TC::ZF0 / 2 * M_PI / ( GetParameter( TCP::Z0 ) * sqrt( e_r ) );
|
||||
|
||||
double w_h;
|
||||
|
||||
if( a > 1.52 )
|
||||
{
|
||||
w_h = 8 * exp( a ) / ( exp( 2. * a ) - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
w_h = ( 2. / M_PI )
|
||||
* ( b - 1. - log( ( 2 * b ) - 1. )
|
||||
+ ( ( e_r - 1 ) / ( 2 * e_r ) ) * ( log( b - 1. ) + 0.39 - 0.61 / e_r ) );
|
||||
}
|
||||
|
||||
double width;
|
||||
|
||||
if( GetParameter( TCP::H ) > 0.0 )
|
||||
width = w_h * GetParameter( TCP::H );
|
||||
else
|
||||
width = 0;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::Z0_dispersion( double u, double e_r, double e_r_eff_0, double e_r_eff_f, double f_n )
|
||||
{
|
||||
const double R_1 = 0.03891 * pow( e_r, 1.4 );
|
||||
const double R_2 = 0.267 * pow( u, 7.0 );
|
||||
const double R_3 = 4.766 * exp( -3.228 * pow( u, 0.641 ) );
|
||||
const double R_4 = 0.016 + pow( 0.0514 * e_r, 4.524 );
|
||||
const double R_5 = pow( f_n / 28.843, 12.0 );
|
||||
const double R_6 = 22.2 * pow( u, 1.92 );
|
||||
const double R_7 = 1.206 - 0.3144 * exp( -R_1 ) * ( 1.0 - exp( -R_2 ) );
|
||||
const double R_8 = 1.0 + 1.275 * ( 1.0 - exp( -0.004625 * R_3 * pow( e_r, 1.674 ) * pow( f_n / 18.365, 2.745 ) ) );
|
||||
double tmpf = pow( e_r - 1.0, 6.0 );
|
||||
const double R_9 = 5.086 * R_4 * ( R_5 / ( 0.3838 + 0.386 * R_4 ) ) * ( exp( -R_6 ) / ( 1.0 + 1.2992 * R_5 ) )
|
||||
* ( tmpf / ( 1.0 + 10.0 * tmpf ) );
|
||||
const double R_10 = 0.00044 * pow( e_r, 2.136 ) + 0.0184;
|
||||
tmpf = pow( f_n / 19.47, 6.0 );
|
||||
const double R_11 = tmpf / ( 1.0 + 0.0962 * tmpf );
|
||||
const double R_12 = 1.0 / ( 1.0 + 0.00245 * u * u );
|
||||
const double R_13 = 0.9408 * pow( e_r_eff_f, R_8 ) - 0.9603;
|
||||
const double R_14 = ( 0.9408 - R_9 ) * pow( e_r_eff_0, R_8 ) - 0.9603;
|
||||
const double R_15 = 0.707 * R_10 * pow( f_n / 12.3, 1.097 );
|
||||
const double R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * ( 1.0 - exp( -pow( u / 15.0, 6.0 ) ) );
|
||||
const double R_17 = R_7 * ( 1.0 - 1.1241 * ( R_12 / R_16 ) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
|
||||
return pow( R_13 / R_14, R_17 );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::Z0_homogeneous( double u )
|
||||
{
|
||||
const double freq = 6.0 + ( 2.0 * M_PI - 6.0 ) * exp( -pow( 30.666 / u, 0.7528 ) );
|
||||
return ( TC::ZF0 / ( 2.0 * M_PI ) ) * log( freq / u + sqrt( 1.0 + 4.0 / ( u * u ) ) );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::delta_Z0_cover( double u, double h2h )
|
||||
{
|
||||
const double h2hp1 = 1.0 + h2h;
|
||||
const double P = 270.0 * ( 1.0 - tanh( 1.192 + 0.706 * sqrt( h2hp1 ) - 1.389 / h2hp1 ) );
|
||||
const double Q = 1.0109 - atanh( ( 0.012 * u + 0.177 * u * u - 0.027 * u * u * u ) / ( h2hp1 * h2hp1 ) );
|
||||
return P * Q;
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::filling_factor( double u, double e_r )
|
||||
{
|
||||
const double u2 = u * u;
|
||||
const double u3 = u2 * u;
|
||||
const double u4 = u3 * u;
|
||||
const double a = 1.0 + log( ( u4 + u2 / 2704 ) / ( u4 + 0.432 ) ) / 49.0 + log( 1.0 + u3 / 5929.741 ) / 18.7;
|
||||
const double b = 0.564 * pow( ( e_r - 0.9 ) / ( e_r + 3.0 ), 0.053 );
|
||||
return pow( 1.0 + 10.0 / u, -a * b );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::delta_q_cover( double h2h )
|
||||
{
|
||||
return tanh( 1.043 + 0.121 * h2h - 1.164 / h2h );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::delta_q_thickness( double u, double t_h )
|
||||
{
|
||||
return ( 2.0 * log( 2.0 ) / M_PI ) * ( t_h / sqrt( u ) );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::e_r_effective( double e_r, double q )
|
||||
{
|
||||
return 0.5 * ( e_r + 1.0 ) + 0.5 * q * ( e_r - 1.0 );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::delta_u_thickness( double u, double t_h, double e_r )
|
||||
{
|
||||
double delta_u;
|
||||
|
||||
if( t_h > 0.0 )
|
||||
{
|
||||
/* correction for thickness for a homogeneous microstrip */
|
||||
delta_u = ( t_h / M_PI ) * log( 1.0 + ( 4.0 * M_E ) * pow( tanh( sqrt( 6.517 * u ) ), 2.0 ) / t_h );
|
||||
/* correction for strip on a substrate with relative permettivity e_r */
|
||||
delta_u = 0.5 * delta_u * ( 1.0 + 1.0 / cosh( sqrt( e_r - 1.0 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_u = 0.0;
|
||||
}
|
||||
return delta_u;
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::e_r_dispersion( double u, double e_r, double f_n )
|
||||
{
|
||||
const double P_1 =
|
||||
0.27488 + u * ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) ) - 0.065683 * exp( -8.7513 * u );
|
||||
const double P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * e_r ) );
|
||||
const double P_3 = 0.0363 * exp( -4.6 * u ) * ( 1.0 - exp( -pow( f_n / 38.7, 4.97 ) ) );
|
||||
const double P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( e_r / 15.916, 8.0 ) ) );
|
||||
|
||||
return P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 ) * f_n, 1.5763 );
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::conductor_losses() const
|
||||
{
|
||||
double alpha_c;
|
||||
const double e_r_eff_0 = er_eff_0;
|
||||
const double delta = GetParameter( TCP::SKIN_DEPTH );
|
||||
|
||||
if( GetParameter( TCP::FREQUENCY ) > 0.0 )
|
||||
{
|
||||
/* current distribution factor */
|
||||
const double K = exp( -1.2 * pow( Z0_h_1 / TC::ZF0, 0.7 ) );
|
||||
/* skin resistance */
|
||||
double R_s = 1.0 / ( GetParameter( TCP::SIGMA ) * delta );
|
||||
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0 + ( ( 2.0 / M_PI ) * atan( 1.40 * pow( ( GetParameter( TCP::ROUGH ) / delta ), 2.0 ) ) );
|
||||
/* strip inductive quality factor */
|
||||
const double Q_c = ( M_PI * Z0_h_1 * GetParameter( TCP::PHYS_WIDTH ) * GetParameter( TCP::FREQUENCY ) )
|
||||
/ ( R_s * TC::C0 * K );
|
||||
alpha_c = ( 20.0 * M_PI / log( 10.0 ) ) * GetParameter( TCP::FREQUENCY ) * sqrt( e_r_eff_0 ) / ( TC::C0 * Q_c );
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha_c = 0.0;
|
||||
}
|
||||
|
||||
return alpha_c;
|
||||
}
|
||||
|
||||
|
||||
double MICROSTRIP::dielectric_losses() const
|
||||
{
|
||||
const double e_r = GetParameter( TCP::EPSILONR );
|
||||
const double e_r_eff_0 = er_eff_0;
|
||||
|
||||
return ( 20.0 * M_PI / log( 10.0 ) ) * ( GetParameter( TCP::FREQUENCY ) / TC::C0 ) * ( e_r / sqrt( e_r_eff_0 ) )
|
||||
* ( ( e_r_eff_0 - 1.0 ) / ( e_r - 1.0 ) ) * GetParameter( TCP::TAND );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::microstrip_Z0()
|
||||
{
|
||||
const double e_r = GetParameter( TCP::EPSILONR );
|
||||
const double h2 = GetParameter( TCP::H_T );
|
||||
const double h2h = h2 / GetParameter( TCP::H );
|
||||
double u = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::H );
|
||||
const double t_h = GetParameter( TCP::T ) / GetParameter( TCP::H );
|
||||
|
||||
/* compute normalized width correction for e_r = 1.0 */
|
||||
const double delta_u_1 = delta_u_thickness( u, t_h, 1.0 );
|
||||
/* compute homogeneous stripline impedance */
|
||||
Z0_h_1 = Z0_homogeneous( u + delta_u_1 );
|
||||
/* compute normalized width correction */
|
||||
const double delta_u_r = delta_u_thickness( u, t_h, e_r );
|
||||
u += delta_u_r;
|
||||
/* compute homogeneous stripline impedance */
|
||||
const double Z0_h_r = Z0_homogeneous( u );
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
const double q_inf = filling_factor( u, e_r );
|
||||
/* cover effect */
|
||||
const double q_c = delta_q_cover( h2h );
|
||||
/* thickness effect */
|
||||
const double q_t = delta_q_thickness( u, t_h );
|
||||
/* resultant filling factor */
|
||||
const double q = ( q_inf - q_t ) * q_c;
|
||||
|
||||
/* e_r corrected for thickness and non-homogeneous material */
|
||||
const double e_r_eff_t = e_r_effective( e_r, q );
|
||||
|
||||
/* effective dielectric constant */
|
||||
const double e_r_eff = e_r_eff_t * pow( Z0_h_1 / Z0_h_r, 2.0 );
|
||||
|
||||
/* characteristic impedance, corrected for thickness, cover */
|
||||
/* and non-homogeneous material */
|
||||
SetParameter( TCP::Z0, Z0_h_r / sqrt( e_r_eff_t ) );
|
||||
|
||||
w_eff = u * GetParameter( TCP::H );
|
||||
er_eff_0 = e_r_eff;
|
||||
Z0_0 = GetParameter( TCP::Z0 );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::dispersion()
|
||||
{
|
||||
const double e_r = GetParameter( TCP::EPSILONR );
|
||||
const double e_r_eff_0 = er_eff_0;
|
||||
const double u = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::H );
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
const double f_n = GetParameter( TCP::FREQUENCY ) * GetParameter( TCP::H ) / 1e06;
|
||||
|
||||
const double P = e_r_dispersion( u, e_r, f_n );
|
||||
/* effective dielectric constant corrected for dispersion */
|
||||
const double e_r_eff_f = e_r - ( e_r - e_r_eff_0 ) / ( 1.0 + P );
|
||||
|
||||
const double D = Z0_dispersion( u, e_r, e_r_eff_0, e_r_eff_f, f_n );
|
||||
const double Z0_f = Z0_0 * D;
|
||||
|
||||
SetParameter( TCP::UNIT_PROP_DELAY, UnitPropagationDelay( e_r_eff_f ) );
|
||||
SetParameter( TCP::EPSILON_EFF, e_r_eff_f );
|
||||
SetParameter( TCP::Z0, Z0_f );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::attenuation()
|
||||
{
|
||||
SetParameter( TCP::SKIN_DEPTH, SkinDepth() );
|
||||
SetParameter( TCP::ATTEN_COND, conductor_losses() * GetParameter( TCP::PHYS_LEN ) );
|
||||
SetParameter( TCP::ATTEN_DILECTRIC, dielectric_losses() * GetParameter( TCP::PHYS_LEN ) );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::mur_eff_ms()
|
||||
{
|
||||
const double mur = GetParameter( TCP::MUR );
|
||||
const double h = GetParameter( TCP::H );
|
||||
const double w = GetParameter( TCP::PHYS_WIDTH );
|
||||
mur_eff = ( 2.0 * mur ) / ( ( 1.0 + mur ) + ( ( 1.0 - mur ) * pow( ( 1.0 + ( 10.0 * h / w ) ), -0.5 ) ) );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::line_angle()
|
||||
{
|
||||
double e_r_eff = GetParameter( TCP::EPSILON_EFF );
|
||||
|
||||
// Velocity
|
||||
double v = TC::C0 / sqrt( e_r_eff * mur_eff );
|
||||
// Wavelength
|
||||
double lambda_g = v / GetParameter( TCP::FREQUENCY );
|
||||
// Electrical angles (rad)
|
||||
SetParameter( TCP::ANG_L, 2.0 * M_PI * GetParameter( TCP::PHYS_LEN ) / lambda_g );
|
||||
}
|
118
common/transline_calculations/microstrip.h
Normal file
118
common/transline_calculations/microstrip.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATIONS_MICROSTRIP_H
|
||||
#define TRANSLINE_CALCULATIONS_MICROSTRIP_H
|
||||
|
||||
|
||||
#include <transline_calculations/transline_calculation_base.h>
|
||||
|
||||
|
||||
class MICROSTRIP : public TRANSLINE_CALCULATION_BASE
|
||||
{
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
public:
|
||||
MICROSTRIP() :
|
||||
TRANSLINE_CALCULATION_BASE( { TCP::EPSILONR, TCP::H_T, TCP::H, TCP::PHYS_WIDTH, TCP::T, TCP::Z0,
|
||||
TCP::FREQUENCY, TCP::EPSILON_EFF, TCP::SKIN_DEPTH, TCP::SIGMA, TCP::ROUGH,
|
||||
TCP::TAND, TCP::PHYS_LEN, TCP::MUR, TCP::MURC, TCP::ANG_L,
|
||||
TCP::UNIT_PROP_DELAY, TCP::ATTEN_COND, TCP::ATTEN_DILECTRIC } )
|
||||
{
|
||||
}
|
||||
|
||||
friend class COUPLED_MICROSTRIP;
|
||||
|
||||
/// Analyse track geometry parameters to output Z0 and Ang_L
|
||||
void Analyse() override;
|
||||
|
||||
/// Synthesis track geometry parameters to match given Z0
|
||||
bool Synthesize( SYNTHESIZE_OPTS aOpts ) override;
|
||||
|
||||
private:
|
||||
/// Sets the output values and status following analysis
|
||||
void SetAnalysisResults() override;
|
||||
|
||||
/// Sets the output values and status following synthesis
|
||||
void SetSynthesisResults() override;
|
||||
|
||||
/// Calculates the width with the current set of parameters
|
||||
double SynthesizeWidth() const;
|
||||
|
||||
/// Calculates the dispersion correction factor for the characteristic impedance static
|
||||
static double Z0_dispersion( double, double, double, double, double );
|
||||
|
||||
/// Calculates the impedance for a stripline in a homogeneous medium, without cover effects
|
||||
static double Z0_homogeneous( double );
|
||||
|
||||
/// Calculates the cover effect on impedance for a stripline in a homogeneous medium
|
||||
static double delta_Z0_cover( double, double );
|
||||
|
||||
/// Calculates the filling factor for a microstrip without cover and zero conductor thickness
|
||||
static double filling_factor( double, double );
|
||||
|
||||
/// Calculates the cover effect on filling factor
|
||||
static double delta_q_cover( double );
|
||||
|
||||
/// Calculates the thickness effect on filling factor
|
||||
static double delta_q_thickness( double, double );
|
||||
|
||||
/// Calculates effective dielectric constant from material e_r and filling factor
|
||||
static double e_r_effective( double, double );
|
||||
|
||||
/// Calculates the thickness effect on normalized width
|
||||
static double delta_u_thickness( double, double, double );
|
||||
|
||||
/// Calculates the dispersion correction factor for the effective permeability
|
||||
static double e_r_dispersion( double, double, double );
|
||||
|
||||
/// Calculate the microstrip conductor losses per unit
|
||||
double conductor_losses() const;
|
||||
|
||||
/// Calculates the microstrip dielectric losses per unit
|
||||
double dielectric_losses() const;
|
||||
|
||||
/// Calculates the microstrip static impedance
|
||||
void microstrip_Z0();
|
||||
|
||||
/// Calculates frequency dependent parameters of the microstrip
|
||||
void dispersion();
|
||||
|
||||
/// Calculates the attenuation of the microstrip
|
||||
void attenuation();
|
||||
|
||||
/// Calculates the effective magnetic permeability
|
||||
void mur_eff_ms();
|
||||
|
||||
/// Calculates microstrip length in radians
|
||||
void line_angle();
|
||||
|
||||
double Z0_0{ 0.0 }; ///< static characteristic impedance
|
||||
double er_eff_0{ 0.0 }; ///< Static effective dielectric constant
|
||||
double mur_eff{ 0.0 }; ///< Effective mag. permeability
|
||||
double w_eff{ 0.0 }; ///< Effective width of line
|
||||
double Z0_h_1{ 0.0 }; ///< homogeneous stripline impedance
|
||||
};
|
||||
|
||||
|
||||
#endif //TRANSLINE_CALCULATIONS_MICROSTRIP_H
|
172
common/transline_calculations/stripline.cpp
Normal file
172
common/transline_calculations/stripline.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <transline_calculations/stripline.h>
|
||||
#include <transline_calculations/units.h>
|
||||
|
||||
|
||||
namespace TC = TRANSLINE_CALCULATIONS;
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
|
||||
void STRIPLINE::Analyse()
|
||||
{
|
||||
SetParameter( TCP::SKIN_DEPTH, SkinDepth() );
|
||||
SetParameter( TCP::EPSILON_EFF, GetParameter( TCP::EPSILONR ) ); // no dispersion
|
||||
|
||||
double ac1, ac2;
|
||||
double t = GetParameter( TCP::T );
|
||||
double a = GetParameter( TCP::STRIPLINE_A );
|
||||
double h = GetParameter( TCP::H );
|
||||
SetParameter( TCP::Z0,
|
||||
2.0 / ( 1.0 / lineImpedance( 2.0 * a + t, ac1 ) + 1.0 / lineImpedance( 2.0 * ( h - a ) - t, ac2 ) ) );
|
||||
SetParameter( TCP::LOSS_CONDUCTOR, GetParameter( TCP::PHYS_LEN ) * ( ac1 + ac2 ) );
|
||||
SetParameter( TCP::LOSS_DIELECTRIC, TC::LOG2DB * GetParameter( TCP::PHYS_LEN ) * ( M_PI / TC::C0 )
|
||||
* GetParameter( TCP::FREQUENCY ) * sqrt( GetParameter( TCP::EPSILONR ) )
|
||||
* GetParameter( TCP::TAND ) );
|
||||
|
||||
SetParameter( TCP::ANG_L, 2.0 * M_PI * GetParameter( TCP::PHYS_LEN ) * sqrt( GetParameter( TCP::EPSILONR ) )
|
||||
* GetParameter( TCP::FREQUENCY ) / TC::C0 ); // in radians
|
||||
|
||||
unit_prop_delay = UnitPropagationDelay( GetParameter( TCP::EPSILON_EFF ) );
|
||||
}
|
||||
|
||||
|
||||
bool STRIPLINE::Synthesize( const SYNTHESIZE_OPTS aOpts )
|
||||
{
|
||||
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0 );
|
||||
}
|
||||
|
||||
|
||||
void STRIPLINE::SetAnalysisResults()
|
||||
{
|
||||
SetAnalysisResult( TCP::EPSILON_EFF, GetParameter( TCP::EPSILON_EFF ) );
|
||||
SetAnalysisResult( TCP::UNIT_PROP_DELAY, unit_prop_delay );
|
||||
SetAnalysisResult( TCP::LOSS_CONDUCTOR, GetParameter( TCP::LOSS_CONDUCTOR ) );
|
||||
SetAnalysisResult( TCP::LOSS_DIELECTRIC, GetParameter( TCP::LOSS_DIELECTRIC ) );
|
||||
SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
|
||||
const double Z0 = GetParameter( TCP::Z0 );
|
||||
const double ANG_L = GetParameter( TCP::ANG_L );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
|
||||
const bool Z0_invalid = !std::isfinite( Z0 ) || Z0 < 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
|
||||
bool invalid = false;
|
||||
|
||||
if( GetParameter( TCP::STRIPLINE_A ) + GetParameter( TCP::T ) >= GetParameter( TCP::H ) )
|
||||
invalid = true;
|
||||
|
||||
SetAnalysisResult( TCP::Z0, Z0, Z0_invalid || invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::STRIPLINE_A, GetParameter( TCP::STRIPLINE_A ),
|
||||
invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::T, GetParameter( TCP::T ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::H, GetParameter( TCP::H ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetAnalysisResult( TCP::Z0, GetParameter( TCP::Z0 ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
void STRIPLINE::SetSynthesisResults()
|
||||
{
|
||||
SetSynthesisResult( TCP::EPSILON_EFF, GetParameter( TCP::EPSILON_EFF ) );
|
||||
SetSynthesisResult( TCP::UNIT_PROP_DELAY, unit_prop_delay );
|
||||
SetSynthesisResult( TCP::LOSS_CONDUCTOR, GetParameter( TCP::LOSS_CONDUCTOR ) );
|
||||
SetSynthesisResult( TCP::LOSS_DIELECTRIC, GetParameter( TCP::LOSS_DIELECTRIC ) );
|
||||
SetSynthesisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
|
||||
|
||||
const double Z0 = GetParameter( TCP::Z0 );
|
||||
const double ANG_L = GetParameter( TCP::ANG_L );
|
||||
const double L = GetParameter( TCP::PHYS_LEN );
|
||||
const double W = GetParameter( TCP::PHYS_WIDTH );
|
||||
|
||||
const bool Z0_invalid = !std::isfinite( Z0 ) || Z0 < 0;
|
||||
const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
|
||||
const bool L_invalid = !std::isfinite( L ) || L < 0;
|
||||
const bool W_invalid = !std::isfinite( W ) || W <= 0;
|
||||
|
||||
bool invalid = false;
|
||||
|
||||
if( GetParameter( TCP::STRIPLINE_A ) + GetParameter( TCP::T ) >= GetParameter( TCP::H ) )
|
||||
invalid = true;
|
||||
|
||||
SetSynthesisResult( TCP::Z0, Z0, Z0_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::PHYS_WIDTH, W, W_invalid || invalid ? TRANSLINE_STATUS::ERROR : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::STRIPLINE_A, GetParameter( TCP::STRIPLINE_A ),
|
||||
invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::T, GetParameter( TCP::T ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
SetSynthesisResult( TCP::H, GetParameter( TCP::H ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
|
||||
}
|
||||
|
||||
|
||||
double STRIPLINE::lineImpedance( double aHeight, double& aAc ) const
|
||||
{
|
||||
double ZL;
|
||||
const double hmt = aHeight - GetParameter( TCP::T );
|
||||
|
||||
aAc = sqrt( GetParameter( TCP::FREQUENCY ) / GetParameter( TCP::SIGMA ) / 17.2 );
|
||||
|
||||
if( GetParameter( TCP::PHYS_WIDTH ) / hmt >= 0.35 )
|
||||
{
|
||||
ZL = GetParameter( TCP::PHYS_WIDTH )
|
||||
+ ( 2.0 * aHeight * log( ( 2.0 * aHeight - GetParameter( TCP::T ) ) / hmt )
|
||||
- GetParameter( TCP::T ) * log( aHeight * aHeight / hmt / hmt - 1.0 ) )
|
||||
/ M_PI;
|
||||
ZL = TC::ZF0 * hmt / sqrt( GetParameter( TCP::EPSILONR ) ) / 4.0 / ZL;
|
||||
|
||||
aAc *= 2.02e-6 * GetParameter( TCP::EPSILONR ) * ZL / hmt;
|
||||
aAc *= 1.0 + 2.0 * GetParameter( TCP::PHYS_WIDTH ) / hmt
|
||||
+ ( aHeight + GetParameter( TCP::T ) ) / hmt / M_PI
|
||||
* log( 2.0 * aHeight / GetParameter( TCP::T ) - 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
double tdw = GetParameter( TCP::T ) / GetParameter( TCP::PHYS_WIDTH );
|
||||
|
||||
if( GetParameter( TCP::T ) / GetParameter( TCP::PHYS_WIDTH ) > 1.0 )
|
||||
tdw = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::T );
|
||||
|
||||
double de = 1.0 + tdw / M_PI * ( 1.0 + log( 4.0 * M_PI / tdw ) ) + 0.236 * pow( tdw, 1.65 );
|
||||
|
||||
if( GetParameter( TCP::T ) / GetParameter( TCP::PHYS_WIDTH ) > 1.0 )
|
||||
de *= GetParameter( TCP::T ) / 2.0;
|
||||
else
|
||||
de *= GetParameter( TCP::PHYS_WIDTH ) / 2.0;
|
||||
|
||||
ZL = TC::ZF0 / 2.0 / M_PI / sqrt( GetParameter( TCP::EPSILONR ) ) * log( 4.0 * aHeight / M_PI / de );
|
||||
|
||||
aAc *= 0.01141 / ZL / de;
|
||||
aAc *= de / aHeight + 0.5 + tdw / 2.0 / M_PI + 0.5 / M_PI * log( 4.0 * M_PI / tdw ) + 0.1947 * pow( tdw, 0.65 )
|
||||
- 0.0767 * pow( tdw, 1.65 );
|
||||
}
|
||||
|
||||
return ZL;
|
||||
}
|
64
common/transline_calculations/stripline.h
Normal file
64
common/transline_calculations/stripline.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATIONS_STRIPLINE_H
|
||||
#define TRANSLINE_CALCULATIONS_STRIPLINE_H
|
||||
|
||||
|
||||
#include <transline_calculations/transline_calculation_base.h>
|
||||
|
||||
|
||||
class STRIPLINE : public TRANSLINE_CALCULATION_BASE
|
||||
{
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
|
||||
public:
|
||||
STRIPLINE() :
|
||||
TRANSLINE_CALCULATION_BASE( { TCP::SKIN_DEPTH, TCP::EPSILON_EFF, TCP::EPSILONR, TCP::T, TCP::STRIPLINE_A,
|
||||
TCP::H, TCP::Z0, TCP::LOSS_CONDUCTOR, TCP::PHYS_LEN, TCP::LOSS_DIELECTRIC,
|
||||
TCP::FREQUENCY, TCP::TAND, TCP::PHYS_WIDTH, TCP::UNIT_PROP_DELAY, TCP::ANG_L,
|
||||
TCP::SIGMA, TCP::MURC } )
|
||||
{
|
||||
}
|
||||
|
||||
/// Analyse track geometry parameters to output Z0 and Ang_L
|
||||
void Analyse() override;
|
||||
|
||||
/// Synthesis track geometry parameters to match given Z0
|
||||
bool Synthesize( SYNTHESIZE_OPTS aOpts ) override;
|
||||
|
||||
private:
|
||||
/// Sets the output values and status following analysis
|
||||
void SetAnalysisResults() override;
|
||||
|
||||
/// Sets the output values and status following synthesis
|
||||
void SetSynthesisResults() override;
|
||||
|
||||
/// Calculate characteristic impedance and conductor loss (in db/meter)
|
||||
double lineImpedance( double aHeight, double& aAc ) const;
|
||||
|
||||
double unit_prop_delay;
|
||||
};
|
||||
|
||||
|
||||
#endif //TRANSLINE_CALCULATIONS_STRIPLINE_H
|
225
common/transline_calculations/transline_calculation_base.cpp
Normal file
225
common/transline_calculations/transline_calculation_base.cpp
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <transline_calculations/units.h>
|
||||
#include <transline_calculations/transline_calculation_base.h>
|
||||
|
||||
|
||||
using TCP = TRANSLINE_PARAMETERS;
|
||||
namespace TC = TRANSLINE_CALCULATIONS;
|
||||
|
||||
|
||||
void TRANSLINE_CALCULATION_BASE::InitProperties( const std::initializer_list<TRANSLINE_PARAMETERS>& aParams )
|
||||
{
|
||||
for( const TRANSLINE_PARAMETERS& param : aParams )
|
||||
m_parameters[param] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
|
||||
TRANSLINE_CALCULATION_BASE::GetAnalysisResults()
|
||||
{
|
||||
SetAnalysisResults();
|
||||
return m_analysisStatus;
|
||||
}
|
||||
|
||||
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
|
||||
TRANSLINE_CALCULATION_BASE::GetSynthesisResults()
|
||||
{
|
||||
SetSynthesisResults();
|
||||
return m_synthesisStatus;
|
||||
}
|
||||
|
||||
|
||||
void TRANSLINE_CALCULATION_BASE::SetAnalysisResult( const TRANSLINE_PARAMETERS aParam, const double aValue,
|
||||
const TRANSLINE_STATUS aStatus )
|
||||
{
|
||||
m_analysisStatus[aParam] = { aValue, aStatus };
|
||||
}
|
||||
|
||||
|
||||
void TRANSLINE_CALCULATION_BASE::SetSynthesisResult( const TRANSLINE_PARAMETERS aParam, const double aValue,
|
||||
const TRANSLINE_STATUS aStatus )
|
||||
{
|
||||
m_synthesisStatus[aParam] = { aValue, aStatus };
|
||||
}
|
||||
|
||||
|
||||
bool TRANSLINE_CALCULATION_BASE::MinimiseZ0Error1D( const TRANSLINE_PARAMETERS aOptimise,
|
||||
const TRANSLINE_PARAMETERS aMeasure )
|
||||
{
|
||||
double& var = GetParameterRef( aOptimise );
|
||||
double& Z0_param = GetParameterRef( aMeasure );
|
||||
double& ANG_L_param = GetParameterRef( TCP::ANG_L );
|
||||
|
||||
if( !std::isfinite( Z0_param ) )
|
||||
{
|
||||
var = NAN;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ( !std::isfinite( var ) ) || ( var == 0 ) )
|
||||
var = 0.001;
|
||||
|
||||
/* required value of Z0 */
|
||||
double Z0_dest = Z0_param;
|
||||
|
||||
/* required value of angl_l */
|
||||
double angl_l_dest = ANG_L_param;
|
||||
|
||||
/* Newton's method */
|
||||
int iteration = 0;
|
||||
|
||||
/* compute parameters */
|
||||
Analyse();
|
||||
double Z0_current = Z0_param;
|
||||
|
||||
double error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
while( error > m_maxError )
|
||||
{
|
||||
iteration++;
|
||||
double increment = var / 100.0;
|
||||
var += increment;
|
||||
|
||||
/* compute parameters */
|
||||
Analyse();
|
||||
double Z0_result = Z0_param;
|
||||
|
||||
// f(w(n)) = Z0 - Z0(w(n))
|
||||
// f'(w(n)) = -f'(Z0(w(n)))
|
||||
// f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw
|
||||
// w(n+1) = w(n) - f(w(n))/f'(w(n))
|
||||
double slope = ( Z0_result - Z0_current ) / increment;
|
||||
slope = ( Z0_dest - Z0_current ) / slope - increment;
|
||||
var += slope;
|
||||
|
||||
if( var <= 0.0 )
|
||||
var = increment;
|
||||
|
||||
/* find new error */
|
||||
/* compute parameters */
|
||||
Analyse();
|
||||
Z0_current = Z0_param;
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
if( iteration > 250 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute one last time, but with correct length */
|
||||
Z0_param = Z0_dest;
|
||||
ANG_L_param = angl_l_dest;
|
||||
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
|
||||
* ANG_L_param / 2.0 / M_PI ); /* in m */
|
||||
Analyse();
|
||||
|
||||
/* Restore parameters */
|
||||
Z0_param = Z0_dest;
|
||||
ANG_L_param = angl_l_dest;
|
||||
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
|
||||
* ANG_L_param / 2.0 / M_PI ); /* in m */
|
||||
|
||||
return error <= m_maxError;
|
||||
}
|
||||
|
||||
|
||||
double TRANSLINE_CALCULATION_BASE::SkinDepth() const
|
||||
{
|
||||
double depth = 1.0
|
||||
/ sqrt( M_PI * GetParameter( TCP::FREQUENCY ) * GetParameter( TCP::MURC )
|
||||
* TRANSLINE_CALCULATIONS::MU0 * GetParameter( TCP::SIGMA ) );
|
||||
return depth;
|
||||
}
|
||||
|
||||
|
||||
double TRANSLINE_CALCULATION_BASE::UnitPropagationDelay( const double aEpsilonEff )
|
||||
{
|
||||
return std::sqrt( aEpsilonEff ) * ( 1.0e10 / 2.99e8 );
|
||||
}
|
||||
|
||||
|
||||
std::pair<double, double> TRANSLINE_CALCULATION_BASE::EllipticIntegral( const double arg )
|
||||
{
|
||||
static constexpr double NR_EPSI = 2.2204460492503131e-16;
|
||||
int iMax = 16;
|
||||
|
||||
double k = 0.0, e = 0.0;
|
||||
|
||||
if( arg == 1.0 )
|
||||
{
|
||||
k = INFINITY; // infinite
|
||||
e = 0;
|
||||
}
|
||||
else if( std::isinf( arg ) && arg < 0 )
|
||||
{
|
||||
k = 0;
|
||||
e = INFINITY; // infinite
|
||||
}
|
||||
else
|
||||
{
|
||||
double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
|
||||
int i;
|
||||
|
||||
if( arg < 0 )
|
||||
{
|
||||
fk = 1 / sqrt( 1 - arg );
|
||||
fe = sqrt( 1 - arg );
|
||||
da = -arg / ( 1 - arg );
|
||||
}
|
||||
|
||||
a = 1;
|
||||
b = sqrt( 1 - da );
|
||||
c = sqrt( da );
|
||||
fr = 0.5;
|
||||
s = fr * c * c;
|
||||
|
||||
for( i = 0; i < iMax; i++ )
|
||||
{
|
||||
t = ( a + b ) / 2;
|
||||
c = ( a - b ) / 2;
|
||||
b = sqrt( a * b );
|
||||
a = t;
|
||||
fr *= 2;
|
||||
s += fr * c * c;
|
||||
|
||||
if( c / a < NR_EPSI )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i >= iMax )
|
||||
{
|
||||
k = 0;
|
||||
e = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = M_PI_2 / a;
|
||||
e = M_PI_2 * ( 1 - s ) / a;
|
||||
if( arg < 0 )
|
||||
{
|
||||
k *= fk;
|
||||
e *= fe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { k, e };
|
||||
}
|
227
common/transline_calculations/transline_calculation_base.h
Normal file
227
common/transline_calculations/transline_calculation_base.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATIONS_TRANSLINE_CALCULATION_BASE_H
|
||||
#define TRANSLINE_CALCULATIONS_TRANSLINE_CALCULATION_BASE_H
|
||||
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
/// All possible parameters used (as inputs or outputs) by the transmission line calculations
|
||||
enum class TRANSLINE_PARAMETERS : int
|
||||
{
|
||||
// The following parameters are accessible from the UI
|
||||
UNKNOWN_ID = -1,
|
||||
EPSILONR, // Dielectric constant
|
||||
TAND, // Dielectric Loss Tangent
|
||||
RHO, // Conductivity of conductor
|
||||
H, // Height of substrate
|
||||
H_T, // Height of top surface
|
||||
T, // Height of top conductor
|
||||
PHYS_WIDTH, // Width of trace
|
||||
PHYS_DIAM_IN, // Inner diameter of cable
|
||||
PHYS_S, // width of gap between line and ground
|
||||
PHYS_DIAM_OUT, // Outer diameter of cable
|
||||
PHYS_LEN, // Length of cable
|
||||
ROUGH, // Surface roughness
|
||||
MUR, // Magnetic permeability of substrate
|
||||
MURC, // magnetic permeability of conductor
|
||||
FREQUENCY, // Frequency of operation
|
||||
STRIPLINE_A, // Stripline : distance from track to top plane
|
||||
TWISTEDPAIR_TWIST, // Twists per length
|
||||
TWISTEDPAIR_EPSILONR_ENV, // Dielectric constant of environment
|
||||
Z0, // Characteristic impedance
|
||||
Z0_E, // Even-mode characteristic impedance
|
||||
Z0_O, // Odd-mode characteristic impedance
|
||||
ANG_L, // Electrical length in angle
|
||||
DUMMY_PRM,
|
||||
|
||||
// The following parameters are generated by calculations
|
||||
SIGMA, // Conductivity of the metal
|
||||
SKIN_DEPTH, // Skin depth
|
||||
LOSS_DIELECTRIC, // Loss in dielectric (dB)
|
||||
LOSS_CONDUCTOR, // Loss in conductors (dB)
|
||||
CUTOFF_FREQUENCY, // Cutoff frequency for higher order modes
|
||||
EPSILON_EFF, // Effective dielectric constant
|
||||
EPSILON_EFF_EVEN, // Even mode effective dielectric constant
|
||||
EPSILON_EFF_ODD, // Odd mode effective dielectric constant
|
||||
UNIT_PROP_DELAY, // The unit propagation delay (ps/cm)
|
||||
UNIT_PROP_DELAY_ODD, // The odd mode unit propagation delay (ps/cm)
|
||||
UNIT_PROP_DELAY_EVEN, // The even mode unit propagation delay (ps/cm)
|
||||
ATTEN_COND, // The attenuation of the conductor
|
||||
ATTEN_COND_EVEN, // The even mode attenuation of the conductor
|
||||
ATTEN_COND_ODD, // The odd mode attenuation of the conductor
|
||||
ATTEN_DILECTRIC, // The attenuation of the dilectric
|
||||
ATTEN_DILECTRIC_EVEN, // The even mode attenuation of the dilectric
|
||||
ATTEN_DILECTRIC_ODD, // The odd mode attenuation of the dilectric
|
||||
Z_DIFF, // The differential impedance
|
||||
EXTRAS_COUNT
|
||||
};
|
||||
|
||||
|
||||
/// Options for specifying synthesis inputs, targets, or strategies
|
||||
enum class SYNTHESIZE_OPTS
|
||||
{
|
||||
DEFAULT, // Use the default synthesis options for the calculation
|
||||
FIX_WIDTH, // Fixes the width of a differential pair
|
||||
FIX_SPACING // Fixes the spacing of a differential pair
|
||||
};
|
||||
|
||||
|
||||
/// Parameter status values
|
||||
enum class TRANSLINE_STATUS
|
||||
{
|
||||
OK,
|
||||
WARNING,
|
||||
ERROR
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The base class for all transmission line calculations. This is used by the PCB calculator, and by delay profiles
|
||||
*/
|
||||
class TRANSLINE_CALCULATION_BASE
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructs the transmission line calculation object.
|
||||
*
|
||||
* @aParameters all parameters that are used (as inputs or outputs) by the calculation
|
||||
*/
|
||||
TRANSLINE_CALCULATION_BASE( std::initializer_list<TRANSLINE_PARAMETERS> aParameters )
|
||||
{
|
||||
InitProperties( aParameters );
|
||||
}
|
||||
|
||||
virtual ~TRANSLINE_CALCULATION_BASE() {}
|
||||
|
||||
/// Sets the given calculation property
|
||||
void SetParameter( const TRANSLINE_PARAMETERS aParam, const double aValue ) { m_parameters.at( aParam ) = aValue; }
|
||||
|
||||
/// Gets the given calculation property
|
||||
double GetParameter( const TRANSLINE_PARAMETERS aParam ) const { return m_parameters.at( aParam ); }
|
||||
|
||||
/// Adds a constant to the given parameter
|
||||
double& GetParameterRef( const TRANSLINE_PARAMETERS aParam ) { return m_parameters[aParam]; }
|
||||
|
||||
/// Gets the output parameters following analysis
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& GetAnalysisResults();
|
||||
|
||||
/// Gets the output parameters following synthesis
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& GetSynthesisResults();
|
||||
|
||||
/// Analyses the transmission line using the current parameter set
|
||||
virtual void Analyse() = 0;
|
||||
|
||||
/// Synthesis the transmission line using the current parameter set target
|
||||
/// @returns true if the synthesis converged, otherwise false
|
||||
virtual bool Synthesize( SYNTHESIZE_OPTS aOpts ) = 0;
|
||||
|
||||
protected:
|
||||
/// Initialises the properties used (as inputs or outputs) by the calculation
|
||||
void InitProperties( const std::initializer_list<TRANSLINE_PARAMETERS>& aParams );
|
||||
|
||||
/// Sets values in the output analysis results structure
|
||||
virtual void SetAnalysisResults() = 0;
|
||||
|
||||
/// Sets values in the output synthesis results structure
|
||||
virtual void SetSynthesisResults() = 0;
|
||||
|
||||
/// Sets an analysis result
|
||||
void SetAnalysisResult( TRANSLINE_PARAMETERS aParam, const double aValue,
|
||||
const TRANSLINE_STATUS aStatus = TRANSLINE_STATUS::OK );
|
||||
|
||||
/// Sets a synthesis result
|
||||
void SetSynthesisResult( TRANSLINE_PARAMETERS aParam, const double aValue,
|
||||
const TRANSLINE_STATUS aStatus = TRANSLINE_STATUS::OK );
|
||||
|
||||
/**
|
||||
* minimizeZ0Error1D
|
||||
*
|
||||
* Tries to find a parameter that minimizes the error on Z0.
|
||||
* This function only works with a single parameter.
|
||||
* Calls @ref Analyse several times until the error is acceptable.
|
||||
*
|
||||
* This function does not change Z0 / Angl_L
|
||||
*
|
||||
* @param aOptimise Parameter to optimise
|
||||
* @param aMeasure The parameter to measure / optimise against
|
||||
* @returns true if error < MAX_ERROR, otherwise false
|
||||
*/
|
||||
bool MinimiseZ0Error1D( TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure );
|
||||
|
||||
/**
|
||||
* minimizeZ0Error2D
|
||||
*
|
||||
* Tries to find the parameters that minimizes the error on Z_Diff.
|
||||
* This function only works with two parameters.
|
||||
* Calls @ref Analyse several times until the error is acceptable.
|
||||
* While the error is unacceptable, changes slightly the parameter.
|
||||
*
|
||||
* This function does not change Z0 / Angl_L
|
||||
*
|
||||
* @param aParam1 First parameter to optimise
|
||||
* @param aParam2 Secpmd parameter to optimise
|
||||
* @returns true if error < MAX_ERROR, otherwise false
|
||||
*/
|
||||
bool MinimiseZ0Error2D( TRANSLINE_PARAMETERS aParam1, TRANSLINE_PARAMETERS aParam2 );
|
||||
|
||||
/**
|
||||
* Calculate skin depth
|
||||
*
|
||||
* \f$ \frac{1}{\sqrt{ \pi \cdot f \cdot \mu \cdot \sigma }} \f$
|
||||
*/
|
||||
double SkinDepth() const;
|
||||
|
||||
/**
|
||||
* Calculates the unit propagation delay (ps/cm) for the given effective permittivity
|
||||
*
|
||||
* @aEpsilonEff is the effective permittivity of the material
|
||||
*/
|
||||
static double UnitPropagationDelay( double aEpsilonEff );
|
||||
|
||||
/**
|
||||
* Computes the complete elliptic integral of first kind K() and the second kind E() using the
|
||||
* arithmetic-geometric mean algorithm (AGM) by Abramowitz and Stegun.
|
||||
*
|
||||
* @returns std::pair<K, E> where K = first kind integral, E = second kind integral
|
||||
*/
|
||||
static std::pair<double, double> EllipticIntegral( double arg );
|
||||
|
||||
/// Calculates cosh of the given argument
|
||||
static double coth( const double x ) { return ( std::exp( 2.0 * x ) + 1.0 ) / ( std::exp( 2.0 * x ) - 1.0 ); }
|
||||
|
||||
/// Calculates sech of the given argument
|
||||
static double sech( const double x ) { return 2.0 / ( std::exp( x ) + std::exp( -x ) ); }
|
||||
|
||||
/// All input and output properties used by the calculation
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, double> m_parameters;
|
||||
|
||||
/// Analysis results
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>> m_analysisStatus;
|
||||
|
||||
/// Synthesis results
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>> m_synthesisStatus;
|
||||
|
||||
/// The maximum error for Z0 optimisations
|
||||
static constexpr double m_maxError{ 0.000001 };
|
||||
};
|
||||
|
||||
#endif //TRANSLINE_CALCULATIONS_TRANSLINE_CALCULATION_BASE_H
|
74
common/transline_calculations/units.h
Normal file
74
common/transline_calculations/units.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 1992-2011 jean-pierre.charras
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATIONS_UNITS_H
|
||||
#define TRANSLINE_CALCULATIONS_UNITS_H
|
||||
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
#ifndef HAVE_CMATH_ASINH
|
||||
inline double asinh( double x )
|
||||
{
|
||||
return log( x + sqrt( x * x + 1 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_CMATH_ACOSH
|
||||
inline double acosh( double x )
|
||||
{
|
||||
// must be x>=1, if not return Nan (Not a Number)
|
||||
if( x < 1.0 )
|
||||
return sqrt( -1.0 );
|
||||
|
||||
// return only the positive result (as sqrt does).
|
||||
return log( x + sqrt( x * x - 1.0 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_CMATH_ATANH
|
||||
inline double atanh( double x )
|
||||
{
|
||||
// must be x>-1, x<1, if not return Nan (Not a Number)
|
||||
if( !( x > -1.0 && x < 1.0 ) )
|
||||
return sqrt( -1.0 );
|
||||
|
||||
return log( ( 1.0 + x ) / ( 1.0 - x ) ) / 2.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace TRANSLINE_CALCULATIONS
|
||||
{
|
||||
constexpr double MU0 = 12.566370614e-7; // magnetic constant
|
||||
constexpr double E0 = 8.854e-12; // permittivity of free space
|
||||
constexpr double C0 = 299792458.0; // speed of light in vacuum
|
||||
constexpr double ZF0 = 376.730313668; // wave resistance in vacuum
|
||||
|
||||
// const to convert a attenuation / loss from log (Neper) to decibel
|
||||
// (1 Np = 8.68589 dB)
|
||||
const double LOG2DB = 20.0 / log( 10.0 );
|
||||
|
||||
// ZF0 value update:
|
||||
// https://physics.nist.gov/cgi-bin/cuu/Value?z0
|
||||
}; // namespace TRANSLINE_CALCULATIONS
|
||||
|
||||
#endif // TRANSLINE_CALCULATIONS_UNITS_H
|
72
common/transline_calculations/units_scales.h
Normal file
72
common/transline_calculations/units_scales.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLINE_CALCULATION_UNITS_SCALES_H
|
||||
#define TRANSLINE_CALCULATION_UNITS_SCALES_H
|
||||
|
||||
|
||||
namespace TRANSLINE_CALCULATIONS
|
||||
{
|
||||
constexpr double UNIT_KM = 1e3; // km to meter
|
||||
constexpr double UNIT_M = 1; // m to meter
|
||||
constexpr double UNIT_CM = 1e-2; // cm to meter
|
||||
constexpr double UNIT_MM = 1e-3; // mm to meter
|
||||
constexpr double UNIT_MICRON = 1e-6; // um to meter
|
||||
constexpr double UNIT_INCH = ( 1e-2 * 2.54 ); // inch to meter
|
||||
constexpr double UNIT_MIL = ( 1e-5 * 2.54 ); // mil (or thou) to meter
|
||||
constexpr double UNIT_FEET = 0.3048; // feet to meter
|
||||
constexpr double UNIT_OZSQFT = ( 34.40 * UNIT_MICRON ); // 1 oz/ft^2 is 34.30 microns nominal, 30.90 minimum
|
||||
|
||||
constexpr double UNIT_GHZ = 1e9;
|
||||
constexpr double UNIT_MHZ = 1e6;
|
||||
constexpr double UNIT_KHZ = 1e3;
|
||||
|
||||
constexpr double UNIT_DEGREE = M_PI / 180.0; // degree to radian
|
||||
constexpr double UNIT_RADIAN = 1.0; // Radian to radian
|
||||
|
||||
constexpr double UNIT_OHM = 1.0; // Ohm to Ohm
|
||||
constexpr double UNIT_KOHM = 1e3; // KOhm to Ohm
|
||||
|
||||
constexpr double UNIT_OHM_PER_METER = 1.0; // Ohm per meter to Ohm per meter
|
||||
constexpr double UNIT_OHM_PER_KILOMETER = 1e-3; // Ohm per kilometer to Ohm per meter
|
||||
constexpr double UNIT_OHM_PER_FEET = 3.28084; // Ohm per feet to Ohm per meter
|
||||
constexpr double UNIT_OHM_PER_1000FEET = 3.28084e-3; // Ohm per 1000feet to Ohm per meter
|
||||
|
||||
constexpr double UNIT_KILOVOLT = 1e-3; // Kilovolt to Volt
|
||||
constexpr double UNIT_VOLT = 1.0; // Volt to Volt
|
||||
constexpr double UNIT_MILLIVOLT = 1e+3; // Millivolt to Volt
|
||||
|
||||
constexpr double UNIT_MEGAWATT = 1e-6; // Kilowatt to Watt
|
||||
constexpr double UNIT_KILOWATT = 1e-3; // Kilowatt to Watt
|
||||
constexpr double UNIT_WATT = 1.0; // Watt to Watt
|
||||
constexpr double UNIT_MILLIWATT = 1e+3; // Milliwatt to Watt
|
||||
|
||||
constexpr double UNIT_METER_PER_SECOND = 1.0; // meter per second to meter per second
|
||||
constexpr double UNIT_KILOMETER_PER_HOUR = ( 1 / 3.6 ); // km/h to m/s
|
||||
constexpr double UNIT_FEET_PER_SECOND = 0.3048; // ft/s to m/s
|
||||
constexpr double UNIT_MILES_PER_HOUR = 1609.34; // mi/h to m/s
|
||||
|
||||
constexpr double UNIT_SECOND = 1.0; // second to second
|
||||
constexpr double UNIT_MSECOND = 1e-3; // millisecond to second
|
||||
constexpr double UNIT_USECOND = 1e-6; // microsecond to second
|
||||
constexpr double UNIT_NSECOND = 1e-9; // nanosecond to second
|
||||
constexpr double UNIT_PSECOND = 1e-12; // picosecond to second
|
||||
}; // namespace TRANSLINE_CALCULATIONS
|
||||
|
||||
#endif // TRANSLINE_CALCULATION_UNITS_SCALES_H
|
@ -139,6 +139,7 @@ enum class BITMAPS : unsigned int
|
||||
copper_layers_setup,
|
||||
copy,
|
||||
copy_pad_settings,
|
||||
coupled_stripline,
|
||||
cpw,
|
||||
cpw_back,
|
||||
cursor,
|
||||
|
@ -57,6 +57,7 @@ set( PCB_CALCULATOR_SRCS
|
||||
transline/coax.cpp
|
||||
transline/rectwaveguide.cpp
|
||||
transline/stripline.cpp
|
||||
transline/c_stripline.cpp
|
||||
transline/twistedpair.cpp
|
||||
transline_dlg_funct.cpp
|
||||
attenuators/attenuator_classes.cpp
|
||||
|
@ -37,19 +37,11 @@ PANEL_TRANSLINE::PANEL_TRANSLINE( wxWindow* parent, wxWindowID id, const wxPoint
|
||||
|
||||
|
||||
// Populate transline list ordered like in dialog menu list
|
||||
const static TRANSLINE_TYPE_ID tltype_list[8] =
|
||||
{
|
||||
MICROSTRIP_TYPE,
|
||||
CPW_TYPE,
|
||||
GROUNDED_CPW_TYPE,
|
||||
RECTWAVEGUIDE_TYPE,
|
||||
COAX_TYPE,
|
||||
C_MICROSTRIP_TYPE,
|
||||
STRIPLINE_TYPE,
|
||||
TWISTEDPAIR_TYPE
|
||||
};
|
||||
const static TRANSLINE_TYPE_ID tltype_list[9] = { MICROSTRIP_TYPE, C_MICROSTRIP_TYPE, STRIPLINE_TYPE,
|
||||
C_STRIPLINE_TYPE, CPW_TYPE, GROUNDED_CPW_TYPE,
|
||||
RECTWAVEGUIDE_TYPE, COAX_TYPE, TWISTEDPAIR_TYPE };
|
||||
|
||||
for( int ii = 0; ii < 8; ii++ )
|
||||
for( int ii = 0; ii < 9; ii++ )
|
||||
m_transline_list.push_back( new TRANSLINE_IDENT( tltype_list[ii] ) );
|
||||
|
||||
m_EpsilonR_label->SetLabel( wxT( "εr" ) );
|
||||
|
@ -20,14 +20,22 @@ PANEL_TRANSLINE_BASE::PANEL_TRANSLINE_BASE( wxWindow* parent, wxWindowID id, con
|
||||
wxBoxSizer* bLeftSizer;
|
||||
bLeftSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxString m_TranslineSelectionChoices[] = { _("Microstrip Line"), _("Coplanar wave guide"), _("Coplanar wave guide w/ ground plane"), _("Rectangular Waveguide"), _("Coaxial Line"), _("Coupled Microstrip Line"), _("Stripline"), _("Twisted Pair") };
|
||||
int m_TranslineSelectionNChoices = sizeof( m_TranslineSelectionChoices ) / sizeof( wxString );
|
||||
m_TranslineSelection = new wxRadioBox( this, wxID_ANY, _("Transmission Line Type"), wxDefaultPosition, wxDefaultSize, m_TranslineSelectionNChoices, m_TranslineSelectionChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_TranslineSelection->SetSelection( 1 );
|
||||
bLeftSizer->Add( m_TranslineSelection, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
|
||||
wxString m_TranslineSelectionChoices[] = { _( "Microstrip Line" ),
|
||||
_( "Coupled Microstrip Line" ),
|
||||
_( "Stripline" ),
|
||||
_( "Coupled Stripline" ),
|
||||
_( "Coplanar wave guide" ),
|
||||
_( "Coplanar wave guide w/ ground plane" ),
|
||||
_( "Rectangular Waveguide" ),
|
||||
_( "Coaxial Line" ),
|
||||
_( "Twisted Pair" ) };
|
||||
int m_TranslineSelectionNChoices = sizeof( m_TranslineSelectionChoices ) / sizeof( wxString );
|
||||
m_TranslineSelection = new wxRadioBox( this, wxID_ANY, _("Transmission Line Type"), wxDefaultPosition, wxDefaultSize, m_TranslineSelectionNChoices, m_TranslineSelectionChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_TranslineSelection->SetSelection( 0 );
|
||||
bLeftSizer->Add( m_TranslineSelection, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, 5 );
|
||||
|
||||
|
||||
bLeftSizer->Add( 0, 5, 0, wxEXPAND, 5 );
|
||||
bLeftSizer->Add( 0, 5, 0, wxEXPAND, 5 );
|
||||
|
||||
m_translineBitmap = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bLeftSizer->Add( m_translineBitmap, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 10 );
|
||||
|
@ -87,7 +87,7 @@
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices">"Microstrip Line" "Coplanar wave guide" "Coplanar wave guide w/ ground plane" "Rectangular Waveguide" "Coaxial Line" "Coupled Microstrip Line" "Stripline" "Twisted Pair"</property>
|
||||
<property name="choices">"Microstrip Line" "Coupled Microstrip Line" "Stripline" "Coupled Stripline" "Coplanar wave guide" "Coplanar wave guide w/ ground plane" "Rectangular Waveguide" "Coaxial Line" "Twisted Pair"</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
@ -120,7 +120,7 @@
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="selection">1</property>
|
||||
<property name="selection">0</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxRA_SPECIFY_COLS</property>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2002 Claudio Girardi <in3otd@qsl.net>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modifications for Kicad: 2015 Jean-Pierre Charras
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -21,81 +22,28 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _C_MICROSTRIP_H_
|
||||
#define _C_MICROSTRIP_H_
|
||||
|
||||
#include "transline/microstrip.h"
|
||||
|
||||
#include "transline/transline.h"
|
||||
#include <transline_calculations/coupled_microstrip.h>
|
||||
|
||||
|
||||
class C_MICROSTRIP : public TRANSLINE
|
||||
{
|
||||
public:
|
||||
C_MICROSTRIP();
|
||||
~C_MICROSTRIP();
|
||||
|
||||
private:
|
||||
double h; // height of substrate
|
||||
double ht; // height to the top of box
|
||||
double t; // thickness of top metal
|
||||
double rough; // Roughness of top metal
|
||||
double w; // width of lines
|
||||
double w_t_e; // even-mode thickness-corrected line width
|
||||
double w_t_o; // odd-mode thickness-corrected line width
|
||||
double l; // length of lines
|
||||
double s; // spacing of lines
|
||||
double Z0_e_0; // static even-mode impedance
|
||||
double Z0_o_0; // static odd-mode impedance
|
||||
double Zdiff; // differential impedance
|
||||
double Z0e; // even-mode impedance
|
||||
double Z0o; // odd-mode impedance
|
||||
double c_e; // even-mode capacitance
|
||||
double c_o; // odd-mode capacitance
|
||||
double ang_l_e; // even-mode electrical length in angle
|
||||
double ang_l_o; // odd-mode electrical length in angle
|
||||
double er_eff_e; // even-mode effective dielectric constant
|
||||
double er_eff_o; // odd-mode effective dielectric constant
|
||||
double prop_delay_e; // even-mode unit propagation delay (ps/cm)
|
||||
double prop_delay_o; // odd-mode unit propagation delay (ps/cm)
|
||||
double er_eff_e_0; // static even-mode effective dielectric constant
|
||||
double er_eff_o_0; // static odd-mode effective dielectric constant
|
||||
double w_eff; // Effective width of line
|
||||
double atten_dielectric_e; // even-mode dielectric losses (dB)
|
||||
double atten_cond_e; // even-mode conductors losses (dB)
|
||||
double atten_dielectric_o; // odd-mode dielectric losses (dB)
|
||||
double atten_cond_o; // odd-mode conductors losses (dB)
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
void show_results() override;
|
||||
void getProperties() override;
|
||||
|
||||
private:
|
||||
double delta_u_thickness_single( double, double );
|
||||
void delta_u_thickness();
|
||||
void compute_single_line();
|
||||
double filling_factor_even( double, double, double );
|
||||
double filling_factor_odd( double, double, double );
|
||||
double delta_q_cover_even( double );
|
||||
double delta_q_cover_odd( double );
|
||||
void er_eff_static();
|
||||
double delta_Z0_even_cover( double, double, double );
|
||||
double delta_Z0_odd_cover( double, double, double );
|
||||
void Z0_even_odd();
|
||||
void er_eff_freq();
|
||||
void conductor_losses();
|
||||
void dielectric_losses();
|
||||
void attenuation();
|
||||
void line_angle();
|
||||
void diff_impedance();
|
||||
void syn_err_fun( double*, double*, double, double, double, double, double );
|
||||
void synth_width();
|
||||
void Z0_dispersion();
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
void show_results() override;
|
||||
void syn_fun( double*, double*, double, double, double, double );
|
||||
|
||||
|
||||
private:
|
||||
MICROSTRIP* aux_ms;
|
||||
COUPLED_MICROSTRIP m_calc;
|
||||
};
|
||||
|
||||
#endif // _C_MICROSTRIP_H_
|
||||
|
118
pcb_calculator/transline/c_stripline.cpp
Normal file
118
pcb_calculator/transline/c_stripline.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Claudio Girardi <claudio.girardi@ieee.org>
|
||||
* Copyright (C) 2005, 2006 Stefan Jahn <stefan@lkcc.org>
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "c_stripline.h"
|
||||
#include "transline.h"
|
||||
#include "units.h"
|
||||
|
||||
|
||||
C_STRIPLINE::C_STRIPLINE()
|
||||
{
|
||||
m_Name = "Coupled_MicroStrip";
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
void C_STRIPLINE::calcAnalyze()
|
||||
{
|
||||
m_calc.Analyse();
|
||||
}
|
||||
|
||||
|
||||
void C_STRIPLINE::calcSynthesize()
|
||||
{
|
||||
m_calc.Synthesize( SYNTHESIZE_OPTS::DEFAULT );
|
||||
}
|
||||
|
||||
|
||||
void C_STRIPLINE::showAnalyze()
|
||||
{
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
|
||||
m_calc.GetAnalysisResults();
|
||||
|
||||
setProperty( Z0_E_PRM, results[TRANSLINE_PARAMETERS::Z0_E].first );
|
||||
setProperty( Z0_O_PRM, results[TRANSLINE_PARAMETERS::Z0_O].first );
|
||||
setProperty( ANG_L_PRM, results[TRANSLINE_PARAMETERS::ANG_L].first );
|
||||
|
||||
setResult( 0, results[TRANSLINE_PARAMETERS::EPSILON_EFF_EVEN].first, "" );
|
||||
setResult( 1, results[TRANSLINE_PARAMETERS::EPSILON_EFF_ODD].first, "" );
|
||||
setResult( 2, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_EVEN].first, "ps/cm" );
|
||||
setResult( 3, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_ODD].first, "ps/cm" );
|
||||
setResult( 4, results[TRANSLINE_PARAMETERS::SKIN_DEPTH].first / UNIT_MICRON, "µm" );
|
||||
setResult( 5, results[TRANSLINE_PARAMETERS::Z_DIFF].first, "Ω" );
|
||||
|
||||
setErrorLevel( Z0_E_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0_E].second ) );
|
||||
setErrorLevel( Z0_O_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0_O].second ) );
|
||||
setErrorLevel( ANG_L_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::ANG_L].second ) );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second ) );
|
||||
setErrorLevel( PHYS_LEN_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_LEN].second ) );
|
||||
setErrorLevel( PHYS_S_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_S].second ) );
|
||||
}
|
||||
|
||||
|
||||
void C_STRIPLINE::showSynthesize()
|
||||
{
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
|
||||
m_calc.GetAnalysisResults();
|
||||
|
||||
setProperty( PHYS_WIDTH_PRM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first );
|
||||
setProperty( PHYS_S_PRM, results[TRANSLINE_PARAMETERS::PHYS_S].first );
|
||||
setProperty( PHYS_LEN_PRM, results[TRANSLINE_PARAMETERS::PHYS_LEN].first );
|
||||
|
||||
setResult( 0, results[TRANSLINE_PARAMETERS::EPSILON_EFF_EVEN].first, "" );
|
||||
setResult( 1, results[TRANSLINE_PARAMETERS::EPSILON_EFF_ODD].first, "" );
|
||||
setResult( 2, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_EVEN].first, "ps/cm" );
|
||||
setResult( 3, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_ODD].first, "ps/cm" );
|
||||
setResult( 4, results[TRANSLINE_PARAMETERS::SKIN_DEPTH].first / UNIT_MICRON, "µm" );
|
||||
setResult( 5, results[TRANSLINE_PARAMETERS::Z_DIFF].first, "Ω" );
|
||||
|
||||
setErrorLevel( Z0_E_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0_E].second ) );
|
||||
setErrorLevel( Z0_O_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0_O].second ) );
|
||||
setErrorLevel( ANG_L_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::ANG_L].second ) );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second ) );
|
||||
setErrorLevel( PHYS_LEN_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_LEN].second ) );
|
||||
setErrorLevel( PHYS_S_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_S].second ) );
|
||||
}
|
||||
|
||||
|
||||
void C_STRIPLINE::getProperties()
|
||||
{
|
||||
TRANSLINE::getProperties();
|
||||
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::Z0_E, m_parameters[Z0_E_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::Z0_O, m_parameters[Z0_O_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, m_parameters[EPSILONR_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, m_parameters[PHYS_WIDTH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, m_parameters[PHYS_LEN_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_S, m_parameters[PHYS_S_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::H, m_parameters[H_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::T, m_parameters[T_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, m_parameters[FREQUENCY_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::MURC, m_parameters[MURC_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, m_parameters[SKIN_DEPTH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, m_parameters[SIGMA_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, m_parameters[ANG_L_PRM] );
|
||||
}
|
||||
|
||||
void C_STRIPLINE::show_results()
|
||||
{
|
||||
}
|
44
pcb_calculator/transline/c_stripline.h
Normal file
44
pcb_calculator/transline/c_stripline.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this package; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef C_STRIPLINE_H_
|
||||
#define C_STRIPLINE_H_
|
||||
|
||||
|
||||
#include "transline/transline.h"
|
||||
#include <transline_calculations/coupled_stripline.h>
|
||||
|
||||
|
||||
class C_STRIPLINE : public TRANSLINE
|
||||
{
|
||||
public:
|
||||
C_STRIPLINE();
|
||||
|
||||
private:
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
void show_results() override;
|
||||
void getProperties() override;
|
||||
|
||||
COUPLED_STRIPLINE m_calc;
|
||||
};
|
||||
|
||||
#endif // C_STRIPLINE_H_
|
@ -30,512 +30,100 @@
|
||||
* Based on the original microstrip.c by Gopal Narayanan
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "microstrip.h"
|
||||
#include "transline.h"
|
||||
|
||||
#include "units.h"
|
||||
|
||||
MICROSTRIP::MICROSTRIP() : TRANSLINE(),
|
||||
h( 0.0 ), // height of substrate
|
||||
ht( 0.0 ), // height to the top of box
|
||||
t( 0.0 ), // thickness of top metal
|
||||
rough( 0.0 ), // Roughness of top metal
|
||||
mur( 0.0 ), // magnetic permeability of substrate
|
||||
w( 0.0 ), // width of line
|
||||
l( 0.0 ), // length of line
|
||||
Z0_0( 0.0 ), // static characteristic impedance
|
||||
Z0( 0.0 ), // characteristic impedance
|
||||
er_eff_0( 0.0 ), // Static effective dielectric constant
|
||||
mur_eff( 0.0 ), // Effective mag. permeability
|
||||
w_eff( 0.0 ), // Effective width of line
|
||||
atten_dielectric( 0.0 ), // Loss in dielectric (dB)
|
||||
atten_cond( 0.0 ), // Loss in conductors (dB)
|
||||
Z0_h_1( 0.0 ) // homogeneous stripline impedance
|
||||
|
||||
MICROSTRIP_UI::MICROSTRIP_UI()
|
||||
{
|
||||
m_Name = "MicroStrip";
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Z0_homogeneous() - compute the impedance for a stripline in a
|
||||
* homogeneous medium, without cover effects
|
||||
*/
|
||||
double MICROSTRIP::Z0_homogeneous( double u )
|
||||
void MICROSTRIP_UI::calcAnalyze()
|
||||
{
|
||||
double freq, Z0_value;
|
||||
|
||||
freq = 6.0 + ( 2.0 * M_PI - 6.0 ) * exp( -pow( 30.666 / u, 0.7528 ) );
|
||||
Z0_value = ( ZF0 / ( 2.0 * M_PI ) ) * log( freq / u + sqrt( 1.0 + 4.0 / ( u * u ) ) );
|
||||
return Z0_value;
|
||||
m_calc.Analyse();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_Z0_cover() - compute the cover effect on impedance for a
|
||||
* stripline in a homogeneous medium
|
||||
*/
|
||||
double MICROSTRIP::delta_Z0_cover( double u, double h2h )
|
||||
void MICROSTRIP_UI::showAnalyze()
|
||||
{
|
||||
double P, Q;
|
||||
double h2hp1;
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
|
||||
m_calc.GetAnalysisResults();
|
||||
|
||||
h2hp1 = 1.0 + h2h;
|
||||
P = 270.0 * ( 1.0 - tanh( 1.192 + 0.706 * sqrt( h2hp1 ) - 1.389 / h2hp1 ) );
|
||||
Q = 1.0109 - atanh( ( 0.012 * u + 0.177 * u * u - 0.027 * u * u * u ) / ( h2hp1 * h2hp1 ) );
|
||||
return P * Q;
|
||||
setProperty( Z0_PRM, results[TRANSLINE_PARAMETERS::Z0].first );
|
||||
setProperty( ANG_L_PRM, results[TRANSLINE_PARAMETERS::ANG_L].first );
|
||||
|
||||
setResult( 0, results[TRANSLINE_PARAMETERS::EPSILON_EFF].first, "" );
|
||||
setResult( 1, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].first, "ps/cm" );
|
||||
setResult( 2, results[TRANSLINE_PARAMETERS::ATTEN_COND].first, "dB" );
|
||||
setResult( 3, results[TRANSLINE_PARAMETERS::ATTEN_DILECTRIC].first, "dB" );
|
||||
setResult( 4, results[TRANSLINE_PARAMETERS::SKIN_DEPTH].first / UNIT_MICRON, "µm" );
|
||||
|
||||
setErrorLevel( Z0_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0].second ) );
|
||||
setErrorLevel( ANG_L_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::ANG_L].second ) );
|
||||
setErrorLevel( PHYS_LEN_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_LEN].second ) );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* filling_factor() - compute the filling factor for a microstrip
|
||||
* without cover and zero conductor thickness
|
||||
*/
|
||||
double MICROSTRIP::filling_factor( double u, double e_r )
|
||||
void MICROSTRIP_UI::showSynthesize()
|
||||
{
|
||||
double a, b, q_inf;
|
||||
double u2, u3, u4;
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
|
||||
m_calc.GetSynthesisResults();
|
||||
|
||||
u2 = u * u;
|
||||
u3 = u2 * u;
|
||||
u4 = u3 * u;
|
||||
a = 1.0 + log( ( u4 + u2 / 2704 ) / ( u4 + 0.432 ) ) / 49.0 + log( 1.0 + u3 / 5929.741 ) / 18.7;
|
||||
b = 0.564 * pow( ( e_r - 0.9 ) / ( e_r + 3.0 ), 0.053 );
|
||||
q_inf = pow( 1.0 + 10.0 / u, -a * b );
|
||||
return q_inf;
|
||||
setProperty( PHYS_WIDTH_PRM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first );
|
||||
setProperty( PHYS_LEN_PRM, results[TRANSLINE_PARAMETERS::PHYS_LEN].first );
|
||||
setProperty( Z0_PRM, results[TRANSLINE_PARAMETERS::Z0].first );
|
||||
setProperty( ANG_L_PRM, results[TRANSLINE_PARAMETERS::ANG_L].first );
|
||||
|
||||
setResult( 0, results[TRANSLINE_PARAMETERS::EPSILON_EFF].first, "" );
|
||||
setResult( 1, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].first, "ps/cm" );
|
||||
setResult( 2, results[TRANSLINE_PARAMETERS::ATTEN_COND].first, "dB" );
|
||||
setResult( 3, results[TRANSLINE_PARAMETERS::ATTEN_DILECTRIC].first, "dB" );
|
||||
setResult( 4, results[TRANSLINE_PARAMETERS::SKIN_DEPTH].first / UNIT_MICRON, "µm" );
|
||||
|
||||
setErrorLevel( Z0_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0].second ) );
|
||||
setErrorLevel( ANG_L_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::ANG_L].second ) );
|
||||
setErrorLevel( PHYS_LEN_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_LEN].second ) );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_q_cover() - compute the cover effect on filling factor
|
||||
*/
|
||||
double MICROSTRIP::delta_q_cover( double h2h )
|
||||
void MICROSTRIP_UI::getProperties()
|
||||
{
|
||||
double q_c;
|
||||
TRANSLINE::getProperties();
|
||||
|
||||
q_c = tanh( 1.043 + 0.121 * h2h - 1.164 / h2h );
|
||||
return q_c;
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, m_parameters[SIGMA_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::EPSILON_EFF, m_parameters[EPSILON_EFF_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, m_parameters[SKIN_DEPTH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, m_parameters[EPSILONR_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::H_T, m_parameters[H_T_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::H, m_parameters[H_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, m_parameters[PHYS_WIDTH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::T, m_parameters[T_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::Z0, m_parameters[Z0_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, m_parameters[FREQUENCY_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::ROUGH, m_parameters[ROUGH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::TAND, m_parameters[TAND_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, m_parameters[PHYS_LEN_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::MUR, m_parameters[MUR_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::MURC, m_parameters[MURC_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, m_parameters[ANG_L_PRM] );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_q_thickness() - compute the thickness effect on filling factor
|
||||
*/
|
||||
double MICROSTRIP::delta_q_thickness( double u, double t_h )
|
||||
void MICROSTRIP_UI::show_results()
|
||||
{
|
||||
double q_t;
|
||||
|
||||
q_t = ( 2.0 * log( 2.0 ) / M_PI ) * ( t_h / sqrt( u ) );
|
||||
return q_t;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* e_r_effective() - compute effective dielectric constant from
|
||||
* material e_r and filling factor
|
||||
*/
|
||||
double MICROSTRIP::e_r_effective( double e_r, double q )
|
||||
{
|
||||
double e_r_eff;
|
||||
|
||||
e_r_eff = 0.5 * ( e_r + 1.0 ) + 0.5 * q * ( e_r - 1.0 );
|
||||
return e_r_eff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* delta_u_thickness - compute the thickness effect on normalized width
|
||||
*/
|
||||
double MICROSTRIP::delta_u_thickness( double u, double t_h, double e_r )
|
||||
{
|
||||
double delta_u;
|
||||
|
||||
if( t_h > 0.0 )
|
||||
{
|
||||
/* correction for thickness for a homogeneous microstrip */
|
||||
delta_u = ( t_h / M_PI )
|
||||
* log( 1.0 + ( 4.0 * M_E ) * pow( tanh( sqrt( 6.517 * u ) ), 2.0 ) / t_h );
|
||||
/* correction for strip on a substrate with relative permettivity e_r */
|
||||
delta_u = 0.5 * delta_u * ( 1.0 + 1.0 / cosh( sqrt( e_r - 1.0 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_u = 0.0;
|
||||
}
|
||||
return delta_u;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* microstrip_Z0() - compute microstrip static impedance
|
||||
*/
|
||||
void MICROSTRIP::microstrip_Z0()
|
||||
{
|
||||
double e_r, h2, h2h, u, t_h;
|
||||
double Z0_h_r;
|
||||
double delta_u_1, delta_u_r, q_inf, q_c, q_t, e_r_eff, e_r_eff_t, q;
|
||||
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
h2 = m_parameters[H_T_PRM];
|
||||
h2h = h2 / m_parameters[H_PRM];
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM];
|
||||
t_h = m_parameters[T_PRM] / m_parameters[H_PRM];
|
||||
|
||||
/* compute normalized width correction for e_r = 1.0 */
|
||||
delta_u_1 = delta_u_thickness( u, t_h, 1.0 );
|
||||
/* compute homogeneous stripline impedance */
|
||||
Z0_h_1 = Z0_homogeneous( u + delta_u_1 );
|
||||
/* compute normalized width correction */
|
||||
delta_u_r = delta_u_thickness( u, t_h, e_r );
|
||||
u += delta_u_r;
|
||||
/* compute homogeneous stripline impedance */
|
||||
Z0_h_r = Z0_homogeneous( u );
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = filling_factor( u, e_r );
|
||||
/* cover effect */
|
||||
q_c = delta_q_cover( h2h );
|
||||
/* thickness effect */
|
||||
q_t = delta_q_thickness( u, t_h );
|
||||
/* resultant filling factor */
|
||||
q = ( q_inf - q_t ) * q_c;
|
||||
|
||||
/* e_r corrected for thickness and non homogeneous material */
|
||||
e_r_eff_t = e_r_effective( e_r, q );
|
||||
|
||||
/* effective dielectric constant */
|
||||
e_r_eff = e_r_eff_t * pow( Z0_h_1 / Z0_h_r, 2.0 );
|
||||
|
||||
/* characteristic impedance, corrected for thickness, cover */
|
||||
/* and non homogeneous material */
|
||||
m_parameters[Z0_PRM] = Z0_h_r / sqrt( e_r_eff_t );
|
||||
|
||||
w_eff = u * m_parameters[H_PRM];
|
||||
er_eff_0 = e_r_eff;
|
||||
Z0_0 = m_parameters[Z0_PRM];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* e_r_dispersion() - computes the dispersion correction factor for
|
||||
* the effective permeability
|
||||
*/
|
||||
double MICROSTRIP::e_r_dispersion( double u, double e_r, double f_n )
|
||||
{
|
||||
double P_1, P_2, P_3, P_4, P;
|
||||
|
||||
P_1 = 0.27488 + u * ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) )
|
||||
- 0.065683 * exp( -8.7513 * u );
|
||||
P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * e_r ) );
|
||||
P_3 = 0.0363 * exp( -4.6 * u ) * ( 1.0 - exp( -pow( f_n / 38.7, 4.97 ) ) );
|
||||
P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( e_r / 15.916, 8.0 ) ) );
|
||||
|
||||
P = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 ) * f_n, 1.5763 );
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Z0_dispersion() - computes the dispersion correction factor for the
|
||||
* characteristic impedance
|
||||
*/
|
||||
double MICROSTRIP::Z0_dispersion(
|
||||
double u, double e_r, double e_r_eff_0, double e_r_eff_f, double f_n )
|
||||
{
|
||||
double R_1, R_2, R_3, R_4, R_5, R_6, R_7, R_8, R_9, R_10, R_11, R_12, R_13, R_14, R_15, R_16,
|
||||
R_17, D, tmpf;
|
||||
|
||||
R_1 = 0.03891 * pow( e_r, 1.4 );
|
||||
R_2 = 0.267 * pow( u, 7.0 );
|
||||
R_3 = 4.766 * exp( -3.228 * pow( u, 0.641 ) );
|
||||
R_4 = 0.016 + pow( 0.0514 * e_r, 4.524 );
|
||||
R_5 = pow( f_n / 28.843, 12.0 );
|
||||
R_6 = 22.2 * pow( u, 1.92 );
|
||||
R_7 = 1.206 - 0.3144 * exp( -R_1 ) * ( 1.0 - exp( -R_2 ) );
|
||||
R_8 = 1.0
|
||||
+ 1.275
|
||||
* ( 1.0
|
||||
- exp( -0.004625 * R_3 * pow( e_r, 1.674 )
|
||||
* pow( f_n / 18.365, 2.745 ) ) );
|
||||
tmpf = pow( e_r - 1.0, 6.0 );
|
||||
R_9 = 5.086 * R_4 * ( R_5 / ( 0.3838 + 0.386 * R_4 ) )
|
||||
* ( exp( -R_6 ) / ( 1.0 + 1.2992 * R_5 ) ) * ( tmpf / ( 1.0 + 10.0 * tmpf ) );
|
||||
R_10 = 0.00044 * pow( e_r, 2.136 ) + 0.0184;
|
||||
tmpf = pow( f_n / 19.47, 6.0 );
|
||||
R_11 = tmpf / ( 1.0 + 0.0962 * tmpf );
|
||||
R_12 = 1.0 / ( 1.0 + 0.00245 * u * u );
|
||||
R_13 = 0.9408 * pow( e_r_eff_f, R_8 ) - 0.9603;
|
||||
R_14 = ( 0.9408 - R_9 ) * pow( e_r_eff_0, R_8 ) - 0.9603;
|
||||
R_15 = 0.707 * R_10 * pow( f_n / 12.3, 1.097 );
|
||||
R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * ( 1.0 - exp( -pow( u / 15.0, 6.0 ) ) );
|
||||
R_17 = R_7 * ( 1.0 - 1.1241 * ( R_12 / R_16 ) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
|
||||
D = pow( R_13 / R_14, R_17 );
|
||||
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dispersion() - compute frequency dependent parameters of
|
||||
* microstrip
|
||||
*/
|
||||
void MICROSTRIP::dispersion()
|
||||
{
|
||||
double e_r, e_r_eff_0;
|
||||
double u, f_n, P, e_r_eff_f, D, Z0_f;
|
||||
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
e_r_eff_0 = er_eff_0;
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM];
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = m_parameters[FREQUENCY_PRM] * m_parameters[H_PRM] / 1e06;
|
||||
|
||||
P = e_r_dispersion( u, e_r, f_n );
|
||||
/* effective dielectric constant corrected for dispersion */
|
||||
e_r_eff_f = e_r - ( e_r - e_r_eff_0 ) / ( 1.0 + P );
|
||||
|
||||
D = Z0_dispersion( u, e_r, e_r_eff_0, e_r_eff_f, f_n );
|
||||
Z0_f = Z0_0 * D;
|
||||
|
||||
// 1e10 factor is to convert from s/m to ps/cm
|
||||
unit_prop_delay = calcUnitPropagationDelay( e_r_eff_f );
|
||||
|
||||
m_parameters[EPSILON_EFF_PRM] = e_r_eff_f;
|
||||
m_parameters[Z0_PRM] = Z0_f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* conductor_losses() - compute microstrip conductor losses per unit
|
||||
* length
|
||||
*/
|
||||
double MICROSTRIP::conductor_losses()
|
||||
{
|
||||
double e_r_eff_0, delta;
|
||||
double K, R_s, Q_c, alpha_c;
|
||||
|
||||
e_r_eff_0 = er_eff_0;
|
||||
delta = m_parameters[SKIN_DEPTH_PRM];
|
||||
|
||||
if( m_parameters[FREQUENCY_PRM] > 0.0 )
|
||||
{
|
||||
/* current distribution factor */
|
||||
K = exp( -1.2 * pow( Z0_h_1 / ZF0, 0.7 ) );
|
||||
/* skin resistance */
|
||||
R_s = 1.0 / ( m_parameters[SIGMA_PRM] * delta );
|
||||
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0
|
||||
+ ( ( 2.0 / M_PI )
|
||||
* atan( 1.40 * pow( ( m_parameters[ROUGH_PRM] / delta ), 2.0 ) ) );
|
||||
/* strip inductive quality factor */
|
||||
Q_c = ( M_PI * Z0_h_1 * m_parameters[PHYS_WIDTH_PRM] * m_parameters[FREQUENCY_PRM] )
|
||||
/ ( R_s * C0 * K );
|
||||
alpha_c = ( 20.0 * M_PI / log( 10.0 ) ) * m_parameters[FREQUENCY_PRM] * sqrt( e_r_eff_0 )
|
||||
/ ( C0 * Q_c );
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha_c = 0.0;
|
||||
}
|
||||
|
||||
return alpha_c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dielectric_losses() - compute microstrip dielectric losses per unit
|
||||
* length
|
||||
*/
|
||||
double MICROSTRIP::dielectric_losses()
|
||||
{
|
||||
double e_r, e_r_eff_0;
|
||||
double alpha_d;
|
||||
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
e_r_eff_0 = er_eff_0;
|
||||
|
||||
alpha_d = ( 20.0 * M_PI / log( 10.0 ) ) * ( m_parameters[FREQUENCY_PRM] / C0 )
|
||||
* ( e_r / sqrt( e_r_eff_0 ) ) * ( ( e_r_eff_0 - 1.0 ) / ( e_r - 1.0 ) )
|
||||
* m_parameters[TAND_PRM];
|
||||
|
||||
return alpha_d;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* attenuation() - compute attenuation of microstrip
|
||||
*/
|
||||
void MICROSTRIP::attenuation()
|
||||
{
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
|
||||
atten_cond = conductor_losses() * m_parameters[PHYS_LEN_PRM];
|
||||
atten_dielectric = dielectric_losses() * m_parameters[PHYS_LEN_PRM];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mur_eff_ms() - returns effective magnetic permeability
|
||||
*/
|
||||
void MICROSTRIP::mur_eff_ms()
|
||||
{
|
||||
double* mur = &m_parameters[MUR_PRM];
|
||||
double* h = &m_parameters[H_PRM];
|
||||
double* w = &m_parameters[PHYS_WIDTH_PRM];
|
||||
mur_eff = ( 2.0 * *mur )
|
||||
/ ( ( 1.0 + *mur ) + ( ( 1.0 - *mur ) * pow( ( 1.0 + ( 10.0 * *h / *w ) ), -0.5 ) ) );
|
||||
}
|
||||
|
||||
|
||||
// synth_width - calculate width given Z0 and e_r
|
||||
double MICROSTRIP::synth_width()
|
||||
{
|
||||
double e_r, a, b;
|
||||
double w_h, width;
|
||||
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
|
||||
a = ( ( m_parameters[Z0_PRM] / ZF0 / 2 / M_PI ) * sqrt( ( e_r + 1 ) / 2. ) )
|
||||
+ ( ( e_r - 1 ) / ( e_r + 1 ) * ( 0.23 + ( 0.11 / e_r ) ) );
|
||||
b = ZF0 / 2 * M_PI / ( m_parameters[Z0_PRM] * sqrt( e_r ) );
|
||||
|
||||
if( a > 1.52 )
|
||||
{
|
||||
w_h = 8 * exp( a ) / ( exp( 2. * a ) - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
w_h = ( 2. / M_PI )
|
||||
* ( b - 1. - log( ( 2 * b ) - 1. )
|
||||
+ ( ( e_r - 1 ) / ( 2 * e_r ) ) * ( log( b - 1. ) + 0.39 - 0.61 / e_r ) );
|
||||
}
|
||||
|
||||
if( m_parameters[H_PRM] > 0.0 )
|
||||
width = w_h * m_parameters[H_PRM];
|
||||
else
|
||||
width = 0;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* line_angle() - calculate microstrip length in radians
|
||||
*/
|
||||
void MICROSTRIP::line_angle()
|
||||
{
|
||||
double e_r_eff;
|
||||
double v, lambda_g;
|
||||
|
||||
e_r_eff = m_parameters[EPSILON_EFF_PRM];
|
||||
|
||||
/* velocity */
|
||||
v = C0 / sqrt( e_r_eff * mur_eff );
|
||||
/* wavelength */
|
||||
lambda_g = v / m_parameters[FREQUENCY_PRM];
|
||||
/* electrical angles */
|
||||
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::calcAnalyze()
|
||||
{
|
||||
/* effective permeability */
|
||||
mur_eff_ms();
|
||||
/* static impedance */
|
||||
microstrip_Z0();
|
||||
/* calculate freq dependence of er and Z0 */
|
||||
dispersion();
|
||||
/* calculate electrical lengths */
|
||||
line_angle();
|
||||
/* calculate losses */
|
||||
attenuation();
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::show_results()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
setResult( 0, m_parameters[EPSILON_EFF_PRM], "" );
|
||||
setResult( 1, unit_prop_delay, "ps/cm" );
|
||||
setResult( 2, atten_cond, "dB" );
|
||||
setResult( 3, atten_dielectric, "dB" );
|
||||
|
||||
setResult( 4, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::showSynthesize()
|
||||
{
|
||||
setProperty( PHYS_WIDTH_PRM, m_parameters[PHYS_WIDTH_PRM] );
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || ( m_parameters[PHYS_LEN_PRM] < 0 ) )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || ( m_parameters[PHYS_WIDTH_PRM] <= 0 ) )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || ( m_parameters[Z0_PRM] < 0 ) )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || ( m_parameters[ANG_L_PRM] < 0 ) )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
void MICROSTRIP::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || ( m_parameters[Z0_PRM] < 0 ) )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || ( m_parameters[ANG_L_PRM] < 0 ) )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || ( m_parameters[PHYS_LEN_PRM] < 0 ) )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || ( m_parameters[PHYS_WIDTH_PRM] <= 0 ) )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
/*
|
||||
* synthesis function
|
||||
*/
|
||||
void MICROSTRIP::calcSynthesize()
|
||||
void MICROSTRIP_UI::calcSynthesize()
|
||||
{
|
||||
double z0_dest = m_parameters[Z0_PRM];
|
||||
double angl_dest = m_parameters[ANG_L_PRM];
|
||||
/* calculate width and use for initial value in Newton's method */
|
||||
m_parameters[PHYS_WIDTH_PRM] = synth_width();
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_WIDTH_PRM] ) );
|
||||
|
||||
m_parameters[Z0_PRM] = z0_dest;
|
||||
m_parameters[ANG_L_PRM] = angl_dest;
|
||||
double const er_eff = m_parameters[EPSILON_EFF_PRM];
|
||||
m_parameters[PHYS_LEN_PRM] = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff * mur_eff )
|
||||
* m_parameters[ANG_L_PRM] / 2.0 / M_PI; /* in m */
|
||||
calcAnalyze();
|
||||
|
||||
m_parameters[Z0_PRM] = z0_dest;
|
||||
m_parameters[ANG_L_PRM] = angl_dest;
|
||||
m_parameters[PHYS_LEN_PRM] = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff * mur_eff )
|
||||
* m_parameters[ANG_L_PRM] / 2.0 / M_PI; /* in m */
|
||||
m_calc.Synthesize( SYNTHESIZE_OPTS::DEFAULT );
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2001 Gopal Narayanan <gopal@astro.umass.edu>
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modified for Kicad: 2015 jean-pierre.charras
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -21,69 +22,30 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MICROSTRIP_H
|
||||
#define __MICROSTRIP_H
|
||||
|
||||
#include "transline/transline.h"
|
||||
|
||||
class MICROSTRIP : public TRANSLINE
|
||||
#include "transline/transline.h"
|
||||
#include <transline_calculations/microstrip.h>
|
||||
|
||||
|
||||
class MICROSTRIP_UI : public TRANSLINE
|
||||
{
|
||||
public:
|
||||
MICROSTRIP();
|
||||
MICROSTRIP_UI();
|
||||
|
||||
friend class C_MICROSTRIP;
|
||||
|
||||
private:
|
||||
double h; // height of substrate
|
||||
double ht; // height to the top of box
|
||||
double t; // thickness of top metal
|
||||
double rough; // Roughness of top metal
|
||||
double mur; // magnetic permeability of substrate
|
||||
double w; // width of line
|
||||
double l; // length of line
|
||||
double Z0_0; // static characteristic impedance
|
||||
double Z0; // characteristic impedance
|
||||
double er_eff_0; // Static effective dielectric constant
|
||||
double mur_eff; // Effective mag. permeability
|
||||
double w_eff; // Effective width of line
|
||||
double atten_dielectric; // Loss in dielectric (dB)
|
||||
double atten_cond; // Loss in conductors (dB)
|
||||
double unit_prop_delay; // Unit propagation delay (ps/cm)
|
||||
MICROSTRIP m_calc;
|
||||
|
||||
// private params
|
||||
double Z0_h_1; // homogeneous stripline impedance
|
||||
|
||||
private:
|
||||
double er_eff_freq();
|
||||
double alpha_c();
|
||||
double alpha_c_roughness();
|
||||
double alpha_dielectric();
|
||||
double char_impedance_ht();
|
||||
double synth_width();
|
||||
double ereff_dispersion();
|
||||
double Z0_dispersion();
|
||||
double Z0_homogeneous( double );
|
||||
double delta_Z0_cover( double, double );
|
||||
double filling_factor( double, double );
|
||||
double delta_q_cover( double );
|
||||
double delta_q_thickness( double, double );
|
||||
double e_r_effective( double, double );
|
||||
double delta_u_thickness( double, double, double );
|
||||
double e_r_dispersion( double, double, double );
|
||||
double Z0_dispersion( double, double, double, double, double );
|
||||
double conductor_losses();
|
||||
double dielectric_losses();
|
||||
void microstrip_Z0();
|
||||
void dispersion();
|
||||
void attenuation();
|
||||
void mur_eff_ms();
|
||||
void line_angle();
|
||||
void show_results() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void getProperties() override;
|
||||
void show_results() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
};
|
||||
|
||||
#endif // __MICROSTRIP_H
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2011 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
|
||||
* Modifications 2018 for Kicad: Jean-Pierre Charras
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -21,162 +22,97 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "stripline.h"
|
||||
#include "units.h"
|
||||
#include <units_scales.h>
|
||||
|
||||
STRIPLINE::STRIPLINE() : TRANSLINE(), unit_prop_delay( 0.0 )
|
||||
|
||||
STRIPLINE_UI::STRIPLINE_UI()
|
||||
{
|
||||
m_Name = "StripLine";
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// calculate characteristic impedance and conductor loss (in db/meter)
|
||||
double STRIPLINE::lineImpedance( double height, double& ac )
|
||||
void STRIPLINE_UI::calcAnalyze()
|
||||
{
|
||||
double ZL;
|
||||
double hmt = height - m_parameters[T_PRM];
|
||||
|
||||
ac = sqrt( m_parameters[FREQUENCY_PRM] / m_parameters[SIGMA_PRM] / 17.2 );
|
||||
|
||||
if( m_parameters[PHYS_WIDTH_PRM] / hmt >= 0.35 )
|
||||
{
|
||||
ZL = m_parameters[PHYS_WIDTH_PRM]
|
||||
+ ( 2.0 * height * log( ( 2.0 * height - m_parameters[T_PRM] ) / hmt )
|
||||
- m_parameters[T_PRM] * log( height * height / hmt / hmt - 1.0 ) )
|
||||
/ M_PI;
|
||||
ZL = ZF0 * hmt / sqrt( m_parameters[EPSILONR_PRM] ) / 4.0 / ZL;
|
||||
|
||||
ac *= 2.02e-6 * m_parameters[EPSILONR_PRM] * ZL / hmt;
|
||||
ac *= 1.0 + 2.0 * m_parameters[PHYS_WIDTH_PRM] / hmt
|
||||
+ ( height + m_parameters[T_PRM] ) / hmt / M_PI
|
||||
* log( 2.0 * height / m_parameters[T_PRM] - 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
double tdw = m_parameters[T_PRM] / m_parameters[PHYS_WIDTH_PRM];
|
||||
if( m_parameters[T_PRM] / m_parameters[PHYS_WIDTH_PRM] > 1.0 )
|
||||
tdw = m_parameters[PHYS_WIDTH_PRM] / m_parameters[T_PRM];
|
||||
double de = 1.0 + tdw / M_PI * ( 1.0 + log( 4.0 * M_PI / tdw ) ) + 0.236 * pow( tdw, 1.65 );
|
||||
if( m_parameters[T_PRM] / m_parameters[PHYS_WIDTH_PRM] > 1.0 )
|
||||
de *= m_parameters[T_PRM] / 2.0;
|
||||
else
|
||||
de *= m_parameters[PHYS_WIDTH_PRM] / 2.0;
|
||||
ZL = ZF0 / 2.0 / M_PI / sqrt( m_parameters[EPSILONR_PRM] )
|
||||
* log( 4.0 * height / M_PI / de );
|
||||
|
||||
ac *= 0.01141 / ZL / de;
|
||||
ac *= de / height + 0.5 + tdw / 2.0 / M_PI + 0.5 / M_PI * log( 4.0 * M_PI / tdw )
|
||||
+ 0.1947 * pow( tdw, 0.65 ) - 0.0767 * pow( tdw, 1.65 );
|
||||
}
|
||||
|
||||
return ZL;
|
||||
m_calc.Analyse();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::calcAnalyze()
|
||||
void STRIPLINE_UI::calcSynthesize()
|
||||
{
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
|
||||
m_parameters[EPSILON_EFF_PRM] = m_parameters[EPSILONR_PRM]; // no dispersion
|
||||
|
||||
double ac1, ac2;
|
||||
double t = m_parameters[T_PRM];
|
||||
double a = m_parameters[STRIPLINE_A_PRM];
|
||||
double h = m_parameters[H_PRM];
|
||||
m_parameters[Z0_PRM] = 2.0
|
||||
/ ( 1.0 / lineImpedance( 2.0 * a + t, ac1 )
|
||||
+ 1.0 / lineImpedance( 2.0 * ( h - a ) - t, ac2 ) );
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = m_parameters[PHYS_LEN_PRM] * ( ac1 + ac2 );
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = LOG2DB * m_parameters[PHYS_LEN_PRM]
|
||||
* ( M_PI / C0 ) * m_parameters[FREQUENCY_PRM]
|
||||
* sqrt( m_parameters[EPSILONR_PRM] )
|
||||
* m_parameters[TAND_PRM];
|
||||
|
||||
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM]
|
||||
* sqrt( m_parameters[EPSILONR_PRM] ) * m_parameters[FREQUENCY_PRM]
|
||||
/ C0; // in radians
|
||||
|
||||
unit_prop_delay = calcUnitPropagationDelay( m_parameters[EPSILON_EFF_PRM] );
|
||||
m_calc.Synthesize( SYNTHESIZE_OPTS::DEFAULT );
|
||||
}
|
||||
|
||||
|
||||
void STRIPLINE::showAnalyze()
|
||||
void STRIPLINE_UI::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
|
||||
m_calc.GetAnalysisResults();
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
setResult( 0, results[TRANSLINE_PARAMETERS::EPSILON_EFF].first, "" );
|
||||
setResult( 1, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].first, "ps/cm" );
|
||||
setResult( 2, results[TRANSLINE_PARAMETERS::LOSS_CONDUCTOR].first, "dB" );
|
||||
setResult( 3, results[TRANSLINE_PARAMETERS::LOSS_DIELECTRIC].first, "dB" );
|
||||
setResult( 4, results[TRANSLINE_PARAMETERS::SKIN_DEPTH].first / UNIT_MICRON, "µm" );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
setProperty( Z0_PRM, results[TRANSLINE_PARAMETERS::Z0].first );
|
||||
setProperty( ANG_L_PRM, results[TRANSLINE_PARAMETERS::ANG_L].first );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0 )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] < 0 )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( m_parameters[STRIPLINE_A_PRM] + m_parameters[T_PRM] >= m_parameters[H_PRM] )
|
||||
{
|
||||
setErrorLevel( STRIPLINE_A_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( T_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( H_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
void STRIPLINE::showSynthesize()
|
||||
{
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
setProperty( PHYS_WIDTH_PRM, m_parameters[PHYS_WIDTH_PRM] );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0 )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] < 0 )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( m_parameters[STRIPLINE_A_PRM] + m_parameters[T_PRM] >= m_parameters[H_PRM] )
|
||||
{
|
||||
setErrorLevel( STRIPLINE_A_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( T_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( H_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::show_results()
|
||||
{
|
||||
|
||||
setResult( 0, m_parameters[EPSILON_EFF_PRM], "" );
|
||||
setResult( 1, unit_prop_delay, "ps/cm" );
|
||||
setResult( 2, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
||||
setResult( 3, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
||||
|
||||
setResult( 4, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
setErrorLevel( Z0_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0].second ) );
|
||||
setErrorLevel( ANG_L_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::ANG_L].second ) );
|
||||
setErrorLevel( PHYS_LEN_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_LEN].second ) );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second ) );
|
||||
setErrorLevel( STRIPLINE_A_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::STRIPLINE_A].second ) );
|
||||
setErrorLevel( T_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::T].second ) );
|
||||
setErrorLevel( H_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::T].second ) );
|
||||
}
|
||||
|
||||
|
||||
#define MAX_ERROR 0.000001
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::calcSynthesize()
|
||||
void STRIPLINE_UI::showSynthesize()
|
||||
{
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_WIDTH_PRM] ) );
|
||||
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
|
||||
m_calc.GetSynthesisResults();
|
||||
|
||||
setResult( 0, results[TRANSLINE_PARAMETERS::EPSILON_EFF].first, "" );
|
||||
setResult( 1, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].first, "ps/cm" );
|
||||
setResult( 2, results[TRANSLINE_PARAMETERS::LOSS_CONDUCTOR].first, "dB" );
|
||||
setResult( 3, results[TRANSLINE_PARAMETERS::LOSS_DIELECTRIC].first, "dB" );
|
||||
setResult( 4, results[TRANSLINE_PARAMETERS::SKIN_DEPTH].first / UNIT_MICRON, "µm" );
|
||||
|
||||
setProperty( PHYS_LEN_PRM, results[TRANSLINE_PARAMETERS::PHYS_LEN].first );
|
||||
setProperty( PHYS_WIDTH_PRM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first );
|
||||
|
||||
setErrorLevel( Z0_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::Z0].second ) );
|
||||
setErrorLevel( ANG_L_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::ANG_L].second ) );
|
||||
setErrorLevel( PHYS_LEN_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_LEN].second ) );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second ) );
|
||||
setErrorLevel( STRIPLINE_A_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::STRIPLINE_A].second ) );
|
||||
setErrorLevel( T_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::T].second ) );
|
||||
setErrorLevel( H_PRM, convertParameterStatusCode( results[TRANSLINE_PARAMETERS::T].second ) );
|
||||
}
|
||||
|
||||
|
||||
void STRIPLINE_UI::show_results()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void STRIPLINE_UI::getProperties()
|
||||
{
|
||||
TRANSLINE::getProperties();
|
||||
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, m_parameters[SKIN_DEPTH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, m_parameters[EPSILONR_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::T, m_parameters[T_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::STRIPLINE_A, m_parameters[STRIPLINE_A_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::H, m_parameters[H_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::Z0, m_parameters[Z0_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, m_parameters[PHYS_LEN_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, m_parameters[FREQUENCY_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::TAND, m_parameters[TAND_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, m_parameters[PHYS_WIDTH_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, m_parameters[ANG_L_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, m_parameters[SIGMA_PRM] );
|
||||
m_calc.SetParameter( TRANSLINE_PARAMETERS::MURC, m_parameters[MURC_PRM] );
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2011 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
|
||||
* Modifications 2011 for Kicad: Jean-Pierre Charras
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -21,26 +22,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __STRIPLINE_H
|
||||
#define __STRIPLINE_H
|
||||
#ifndef STRIPLINE_UI_H
|
||||
#define STRIPLINE_UI_H
|
||||
|
||||
|
||||
#include "transline/transline.h"
|
||||
#include <transline_calculations/stripline.h>
|
||||
|
||||
class STRIPLINE : public TRANSLINE
|
||||
class STRIPLINE_UI : public TRANSLINE
|
||||
{
|
||||
public:
|
||||
STRIPLINE();
|
||||
STRIPLINE_UI();
|
||||
|
||||
private:
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
double lineImpedance( double, double& );
|
||||
void show_results() override;
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void show_results() override;
|
||||
void getProperties() override;
|
||||
|
||||
double unit_prop_delay;
|
||||
STRIPLINE m_calc;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif //STRIPLINE_UI_H
|
||||
|
@ -443,4 +443,17 @@ void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
|
||||
double TRANSLINE::calcUnitPropagationDelay( const double epsilonEff )
|
||||
{
|
||||
return std::sqrt( epsilonEff ) * ( 1.0e10 / 2.99e8 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char TRANSLINE::convertParameterStatusCode( TRANSLINE_STATUS aStatus )
|
||||
{
|
||||
switch( aStatus )
|
||||
{
|
||||
case TRANSLINE_STATUS::OK: return TRANSLINE_OK;
|
||||
case TRANSLINE_STATUS::WARNING: return TRANSLINE_WARNING;
|
||||
case TRANSLINE_STATUS::ERROR: return TRANSLINE_ERROR;
|
||||
}
|
||||
|
||||
return TRANSLINE_OK;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
||||
* Modifications 2018 for Kicad: Jean-Pierre Charras
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -25,6 +26,7 @@
|
||||
#define __TRANSLINE_H
|
||||
|
||||
#include <gal/color4d.h>
|
||||
#include <transline_calculations/transline_calculation_base.h>
|
||||
|
||||
#define TRANSLINE_OK 0
|
||||
#define TRANSLINE_WARNING 1
|
||||
@ -86,7 +88,7 @@ public:
|
||||
double getProperty( enum PRMS_ID aPrmId );
|
||||
|
||||
|
||||
void getProperties();
|
||||
virtual void getProperties();
|
||||
void checkProperties();
|
||||
void setResult( int, double, const char* );
|
||||
void setResult( int, const char* );
|
||||
@ -138,6 +140,9 @@ protected:
|
||||
|
||||
/// Calculates the unit propagation delay (in ps/cm) for the given effective dielectric constant
|
||||
static double calcUnitPropagationDelay( double epsilonEff );
|
||||
|
||||
/// Converts a TRANSLINE_PARAMETER status to a PCB Calculation status
|
||||
static char convertParameterStatusCode( TRANSLINE_STATUS aStatus );
|
||||
};
|
||||
|
||||
#endif /* __TRANSLINE_H */
|
||||
|
@ -106,7 +106,7 @@ void PANEL_TRANSLINE::TranslineTypeSelection( enum TRANSLINE_TYPE_ID aType )
|
||||
m_translineBitmap->SetBitmap( KiBitmapBundle( m_transline_list[m_currTransLineType]->m_BitmapName ) );
|
||||
|
||||
// This helper bitmap is shown for coupled microstrip only:
|
||||
m_bmCMicrostripZoddZeven->Show( aType == C_MICROSTRIP_TYPE );
|
||||
m_bmCMicrostripZoddZeven->Show( aType == C_MICROSTRIP_TYPE || aType == C_STRIPLINE_TYPE );
|
||||
m_bmCMicrostripZoddZeven->SetBitmap( KiBitmapBundle( BITMAPS::microstrip_zodd_zeven ) );
|
||||
|
||||
TRANSLINE_IDENT* tr_ident = m_transline_list[m_currTransLineType];
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "transline/c_microstrip.h"
|
||||
#include "transline/stripline.h"
|
||||
#include "transline/twistedpair.h"
|
||||
#include "transline/c_stripline.h"
|
||||
|
||||
#include "pcb_calculator_settings.h"
|
||||
#include "widgets/unit_selector.h"
|
||||
@ -113,7 +114,7 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
||||
switch( m_Type )
|
||||
{
|
||||
case MICROSTRIP_TYPE: // microstrip
|
||||
m_TLine = new MICROSTRIP();
|
||||
m_TLine = new MICROSTRIP_UI();
|
||||
m_BitmapName = BITMAPS::microstrip;
|
||||
|
||||
m_Messages.Add( wxString::Format( _( "Effective %s:" ), wxT( "εr" ) ) );
|
||||
@ -336,6 +337,37 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
"L", "L", _( "Line length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_E_PRM, "Zeven", _( "Zeven" ),
|
||||
_( "Even mode impedance (lines driven by common voltages)" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_O_PRM, "Zodd", _( "Zodd" ),
|
||||
_( "Odd mode impedance (lines driven by opposite "
|
||||
"(differential) voltages)" ),
|
||||
50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM, "Ang_l", "Ang_l", _( "Electrical length" ), 0.0, true ) );
|
||||
break;
|
||||
|
||||
case C_STRIPLINE_TYPE: // Coupled stripline
|
||||
m_TLine = new C_STRIPLINE();
|
||||
m_BitmapName = BITMAPS::coupled_stripline;
|
||||
m_HasPrmSelection = true;
|
||||
|
||||
m_Messages.Add( wxString::Format( _( "Effective %s (even):" ), wxT( "εr" ) ) );
|
||||
m_Messages.Add( wxString::Format( _( "Effective %s (odd):" ), wxT( "εr" ) ) );
|
||||
m_Messages.Add( _( "Unit propagation delay (even):" ) );
|
||||
m_Messages.Add( _( "Unit propagation delay (odd):" ) );
|
||||
m_Messages.Add( _( "Skin depth:" ) );
|
||||
m_Messages.Add( _( "Differential Impedance (Zd):" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_PRM, "H", "H", _( "Height of substrate" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, T_PRM, "T", "T", _( "Strip thickness" ), 0.035, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM, "mu rel C",
|
||||
wxString::Format( wxT( "μ(%s)" ), _( "conductor" ) ),
|
||||
_( "Relative permeability (mu) of conductor" ), 1, false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM, "W", "W", _( "Line width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM, "S", "S", _( "Gap width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM, "L", "L", _( "Line length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_E_PRM,
|
||||
"Zeven", _( "Zeven" ),
|
||||
_( "Even mode impedance (lines driven by common voltages)" ),
|
||||
@ -350,7 +382,7 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
||||
break;
|
||||
|
||||
case STRIPLINE_TYPE: // stripline
|
||||
m_TLine = new STRIPLINE();
|
||||
m_TLine = new STRIPLINE_UI();
|
||||
m_BitmapName = BITMAPS::stripline;
|
||||
|
||||
m_Messages.Add( wxString::Format( _( "Effective %s:" ), wxT( "εr" ) ) );
|
||||
|
@ -33,16 +33,18 @@
|
||||
enum class BITMAPS : unsigned int;
|
||||
|
||||
// An enum to handle muwave shapes:
|
||||
enum TRANSLINE_TYPE_ID {
|
||||
enum TRANSLINE_TYPE_ID
|
||||
{
|
||||
START_OF_LIST_TYPE = 0,
|
||||
DEFAULT_TYPE = START_OF_LIST_TYPE,
|
||||
MICROSTRIP_TYPE = DEFAULT_TYPE,
|
||||
C_MICROSTRIP_TYPE,
|
||||
STRIPLINE_TYPE,
|
||||
C_STRIPLINE_TYPE,
|
||||
CPW_TYPE,
|
||||
GROUNDED_CPW_TYPE,
|
||||
RECTWAVEGUIDE_TYPE,
|
||||
COAX_TYPE,
|
||||
C_MICROSTRIP_TYPE,
|
||||
STRIPLINE_TYPE,
|
||||
TWISTEDPAIR_TYPE,
|
||||
END_OF_LIST_TYPE
|
||||
};
|
||||
|
@ -720,6 +720,7 @@ set( BMAPS_OTHER
|
||||
color_code_tolerance
|
||||
color_code_value
|
||||
color_code_value_and_name
|
||||
coupled_stripline
|
||||
creepage_clearance
|
||||
cpw
|
||||
cpw_back
|
||||
|
BIN
resources/bitmaps_png/png/coupled_stripline.png
Normal file
BIN
resources/bitmaps_png/png/coupled_stripline.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
resources/bitmaps_png/png/coupled_stripline_dark.png
Normal file
BIN
resources/bitmaps_png/png/coupled_stripline_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
834
resources/bitmaps_png/sources/dark/coupled_stripline.svg
Normal file
834
resources/bitmaps_png/sources/dark/coupled_stripline.svg
Normal file
@ -0,0 +1,834 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="85mm"
|
||||
height="44mm"
|
||||
viewBox="0 0 85 44"
|
||||
version="1.1"
|
||||
id="svg19844"
|
||||
inkscape:version="1.4 (e7c3feb1, 2024-10-09)"
|
||||
sodipodi:docname="coupled_stripline.svg"
|
||||
inkscape:export-filename="/Users/jeff/kicad_dev/kicad/bitmaps_png/png_other/stripline.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<defs
|
||||
id="defs19838">
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12142"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12027"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleOutL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleOutL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path12151"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DistanceEnd"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="DistanceEnd"
|
||||
inkscape:isstock="true">
|
||||
<g
|
||||
id="g2301"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1.15;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,0 H -2"
|
||||
id="path2316" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-opacity:1"
|
||||
d="m 0,0 -13,4 4,-4 -4,-4 z"
|
||||
id="path2312" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,-4 V 40"
|
||||
id="path2314" />
|
||||
</g>
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DistanceStart"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="DistanceStart"
|
||||
inkscape:isstock="true">
|
||||
<g
|
||||
id="g2300"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1.15;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,0 H 2"
|
||||
id="path2306" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-opacity:1"
|
||||
d="M 0,0 13,4 9,0 13,-4 Z"
|
||||
id="path2302" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,-4 V 40"
|
||||
id="path2304" />
|
||||
</g>
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker21133"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path21131"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="RazorWire"
|
||||
id="RazorWire"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12241"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:0.1pt;stroke-opacity:1"
|
||||
d="m 0.02272727,-0.74009011 v 1.4375 L -7.7585227,3.0099099 H 10.678977 L 3.4914773,0.69740989 v -1.4375 L 10.741477,-2.8963401 H -7.7272727 Z" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12030"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleOutL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleOutL-9"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12151-0"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9-7"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6-1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7-2"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7-2" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9-5"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6-0"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7-9"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7-0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9-5-0"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6-0-1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7-9-3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7-0-7" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-7"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-5"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-5" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-7-1"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-5-0"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-6-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-5-3" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-0"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-61"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-5"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-54" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-74"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-52"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-54"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-74" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-74-0"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-52-7"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-54-8"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-74-6" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-8"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12142-8"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-52" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.80852013"
|
||||
inkscape:cx="337.03552"
|
||||
inkscape:cy="189.85303"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer8"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1960"
|
||||
inkscape:window-height="1178"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:snap-global="false"
|
||||
showguides="false"
|
||||
inkscape:document-rotation="0"
|
||||
lock-margins="true"
|
||||
fit-margin-top="2"
|
||||
fit-margin-left="2"
|
||||
fit-margin-right="2"
|
||||
fit-margin-bottom="2"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata19841">
|
||||
<rdf:RDF />
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer9"
|
||||
inkscape:label="Layer 4"
|
||||
style="display:inline"
|
||||
transform="translate(-50.901726,-151.02664)" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-50.901726,-151.02664)">
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 122.04879,192.51551 10.68381,-10.75397 -0.009,-2.92062"
|
||||
id="path20805"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.619834;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 54.199347,190.45327 -0.0034,2.392 67.339143,-1.9e-4 v -2.39132"
|
||||
id="path20803"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 54.041006,164.19702 64.50364,153.58053"
|
||||
id="path20805-1-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.629986;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 64.326232,153.65354 68.633098,0.008"
|
||||
id="path20805-1-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer8"
|
||||
inkscape:label="Layer 3"
|
||||
transform="translate(-50.901726,-151.02664)">
|
||||
<path
|
||||
style="fill:#fcb23c;fill-opacity:1;stroke:#545454;stroke-width:0.529167;stroke-linecap:round"
|
||||
d="m 54.195947,192.84527 67.339143,-1.9e-4 11.19751,-11.08354 0.11204,-2.74697 -78.682805,11.08537 z"
|
||||
id="path2" />
|
||||
<path
|
||||
style="fill:#fcb23c;fill-opacity:1;stroke:#545454;stroke-width:0.529167;stroke-linecap:round"
|
||||
d="m 54.040972,164.19705 10.462634,-10.61649 68.278984,-0.0652 0.0668,2.59461 -11.49568,10.89781 0.48952,-2.55692 z"
|
||||
id="path1" />
|
||||
<path
|
||||
style="display:inline;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 79.91759,167.00765 39.26361,1.66204 13.6126,-12.67526 -0.0702,22.84649 -10.60793,10.80566 z"
|
||||
id="path20574"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<rect
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:#474747;stroke-width:0.625544;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect20534"
|
||||
width="67.191879"
|
||||
height="23.092167"
|
||||
x="54.161835"
|
||||
y="167.00778" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.5037px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.187593"
|
||||
x="61.715302"
|
||||
y="186.69984"
|
||||
id="text21059"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057"
|
||||
x="61.715302"
|
||||
y="186.69984"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.187593">T</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 121.84323,164.45086 10.93939,-10.9355"
|
||||
id="path20805-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:9.15486px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.228872"
|
||||
x="56.627808"
|
||||
y="179.02429"
|
||||
id="text23789"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan23787"
|
||||
x="56.627808"
|
||||
y="179.02429"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.228872">H</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL);marker-end:url(#marker23801)"
|
||||
d="M 56.546083,188.04342 V 169.08263"
|
||||
id="path23791"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.250923;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-8);marker-end:url(#marker23801-3)"
|
||||
d="M 80.029497,181.46964 H 93.294174"
|
||||
id="path23791-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:transform-center-x="4.2335716"
|
||||
inkscape:transform-center-y="-8.4721688" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:9.15486px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.228872"
|
||||
x="87.574654"
|
||||
y="162.95206"
|
||||
id="text23789-9" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-7);marker-end:url(#marker23801-6)"
|
||||
d="m 89.639803,162.80003 7.50755,-7.7658"
|
||||
id="path23791-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.2411px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.156027"
|
||||
x="87.845589"
|
||||
y="159.39813"
|
||||
id="text21059-1-3-2"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057-1-0-2"
|
||||
x="87.845589"
|
||||
y="159.39813"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.156027">L</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 122.05054,190.09836 10.7941,-11.08379"
|
||||
id="path20538-6"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 132.84464,179.01457 0.0187,-23.86743"
|
||||
id="path20538-6-1"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="opacity:1;fill:#fcb23c;fill-opacity:1;stroke:#895502;stroke-width:0.614626;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6104"
|
||||
width="67.207901"
|
||||
height="2.1072214"
|
||||
x="54.151272"
|
||||
y="164.32817"
|
||||
ry="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 122.05054,167.00938 10.79885,-10.89941 0.008,-2.19227"
|
||||
id="path20805-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 78.447673,177.00008 9.624797,-9.8911"
|
||||
id="path20538-6-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 78.425464,179.66243 9.624797,-9.8911"
|
||||
id="path20538-6-8-0"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.760429,176.83271 9.624797,-9.8911"
|
||||
id="path20538-6-8-0-3"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 87.88075,170.06683 0.07597,-3.05506"
|
||||
id="path20538-6-8-0-6"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 111.28813,169.76512 0.076,-3.05506"
|
||||
id="path20538-6-8-0-6-9"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.561356,179.69463 -5.224783,0.0131"
|
||||
id="path23791-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.51701,176.88556 -5.224783,0.0131"
|
||||
id="path23791-7-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.5037px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.187593"
|
||||
x="71.381172"
|
||||
y="189.32043"
|
||||
id="text21059-5"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057-6"
|
||||
x="71.381172"
|
||||
y="189.32043"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.187593">W</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.5037px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.187593"
|
||||
x="84.089783"
|
||||
y="188.25977"
|
||||
id="text21059-5-7"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057-6-1"
|
||||
x="84.089783"
|
||||
y="188.25977"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.187593">S</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.648638,179.5799 -0.0097,2.66362"
|
||||
id="path23791-7-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 78.468682,179.60109 -0.0097,2.61685"
|
||||
id="path23791-7-9-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 94.848919,179.80535 -0.0097,2.61685"
|
||||
id="path23791-7-9-3-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-74);marker-end:url(#marker23801-54)"
|
||||
d="m 76.876847,181.51957 -3.624842,-0.0298"
|
||||
id="path23791-43"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="58.652298"
|
||||
y="173.61502"
|
||||
id="text15381" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer7"
|
||||
inkscape:label="Layer 2"
|
||||
transform="translate(-50.901726,-151.02664)">
|
||||
<rect
|
||||
style="opacity:1;fill:#fcb23c;fill-opacity:1;stroke:#895502;stroke-width:0.499178;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect20424"
|
||||
width="6.6496596"
|
||||
height="2.6584671"
|
||||
x="71.743835"
|
||||
y="176.97217" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 101.6132,176.95663 9.62485,-9.8911"
|
||||
id="path20538-6-8-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 101.98778,179.66243 9.62485,-9.8911"
|
||||
id="path20538-6-8-8-4"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 94.925946,176.78926 9.624824,-9.8911"
|
||||
id="path20538-6-8-0-3-0"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="fill:#fcb23c;fill-opacity:1;stroke:#895502;stroke-width:0.499178;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect20424-4"
|
||||
width="6.6496596"
|
||||
height="2.6584671"
|
||||
x="94.909355"
|
||||
y="176.92873" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
|
||||
d="m 68.396624,187.21173 v -5.41497"
|
||||
id="path21071"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL-9)"
|
||||
d="m 68.307853,169.42208 v 5.41497"
|
||||
id="path21071-8"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 32 KiB |
834
resources/bitmaps_png/sources/light/coupled_stripline.svg
Normal file
834
resources/bitmaps_png/sources/light/coupled_stripline.svg
Normal file
@ -0,0 +1,834 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="85mm"
|
||||
height="44mm"
|
||||
viewBox="0 0 85 44"
|
||||
version="1.1"
|
||||
id="svg19844"
|
||||
inkscape:version="1.4 (e7c3feb1, 2024-10-09)"
|
||||
sodipodi:docname="coupled_stripline.svg"
|
||||
inkscape:export-filename="/Users/jeff/kicad_dev/kicad/bitmaps_png/png_other/stripline.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<defs
|
||||
id="defs19838">
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12142"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12027"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleOutL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleOutL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path12151"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DistanceEnd"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="DistanceEnd"
|
||||
inkscape:isstock="true">
|
||||
<g
|
||||
id="g2301"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1.15;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,0 H -2"
|
||||
id="path2316" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-opacity:1"
|
||||
d="m 0,0 -13,4 4,-4 -4,-4 z"
|
||||
id="path2312" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,-4 V 40"
|
||||
id="path2314" />
|
||||
</g>
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DistanceStart"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="DistanceStart"
|
||||
inkscape:isstock="true">
|
||||
<g
|
||||
id="g2300"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1.15;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,0 H 2"
|
||||
id="path2306" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-opacity:1"
|
||||
d="M 0,0 13,4 9,0 13,-4 Z"
|
||||
id="path2302" />
|
||||
<path
|
||||
style="fill:#0081d5;fill-opacity:1;stroke:#0081d5;stroke-width:1;stroke-linecap:square;stroke-opacity:1"
|
||||
d="M 0,-4 V 40"
|
||||
id="path2304" />
|
||||
</g>
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker21133"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path21131"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="RazorWire"
|
||||
id="RazorWire"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12241"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:0.1pt;stroke-opacity:1"
|
||||
d="m 0.02272727,-0.74009011 v 1.4375 L -7.7585227,3.0099099 H 10.678977 L 3.4914773,0.69740989 v -1.4375 L 10.741477,-2.8963401 H -7.7272727 Z" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12030"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleOutL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleOutL-9"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12151-0"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9-7"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6-1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7-2"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7-2" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9-5"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6-0"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7-9"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7-0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-9-5-0"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-6-0-1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-7-9-3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-7-0-7" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-7"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-5"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-5" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-7-1"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-5-0"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-6-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-5-3" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-0"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-61"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-5"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-54" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-74"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-52"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-54"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-74" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-74-0"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12142-52-7"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-54-8"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-74-6" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="TriangleInL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="TriangleInL-8"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path12142-8"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="scale(-0.8)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker23801-3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
transform="scale(0.8)"
|
||||
style="fill:#0081d5;fill-opacity:1;fill-rule:evenodd;stroke:#0081d5;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 5.77,0 -2.88,5 V -5 Z"
|
||||
id="path23799-52" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.80852013"
|
||||
inkscape:cx="337.03552"
|
||||
inkscape:cy="189.85304"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer8"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1960"
|
||||
inkscape:window-height="1178"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:snap-global="false"
|
||||
showguides="false"
|
||||
inkscape:document-rotation="0"
|
||||
lock-margins="true"
|
||||
fit-margin-top="2"
|
||||
fit-margin-left="2"
|
||||
fit-margin-right="2"
|
||||
fit-margin-bottom="2"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata19841">
|
||||
<rdf:RDF />
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer9"
|
||||
inkscape:label="Layer 4"
|
||||
style="display:inline"
|
||||
transform="translate(-50.901726,-151.02664)" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-50.901726,-151.02664)">
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 122.04879,192.51551 10.68381,-10.75397 -0.009,-2.92062"
|
||||
id="path20805"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.619834;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 54.199347,190.45327 -0.0034,2.392 67.339143,-1.9e-4 v -2.39132"
|
||||
id="path20803"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 54.041006,164.19702 64.50364,153.58053"
|
||||
id="path20805-1-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.629986;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 64.326232,153.65354 68.633098,0.008"
|
||||
id="path20805-1-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer8"
|
||||
inkscape:label="Layer 3"
|
||||
transform="translate(-50.901726,-151.02664)">
|
||||
<path
|
||||
style="fill:#fcb23c;fill-opacity:1;stroke:#545454;stroke-width:0.529167;stroke-linecap:round"
|
||||
d="m 54.195947,192.84527 67.339143,-1.9e-4 11.19751,-11.08354 0.11204,-2.74697 -78.682805,11.08537 z"
|
||||
id="path2" />
|
||||
<path
|
||||
style="fill:#fcb23c;fill-opacity:1;stroke:#545454;stroke-width:0.529167;stroke-linecap:round"
|
||||
d="m 54.040972,164.19705 10.462634,-10.61649 68.278984,-0.0652 0.0668,2.59461 -11.49568,10.89781 0.48952,-2.55692 z"
|
||||
id="path1" />
|
||||
<path
|
||||
style="display:inline;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 79.91759,167.00765 39.26361,1.66204 13.6126,-12.67526 -0.0702,22.84649 -10.60793,10.80566 z"
|
||||
id="path20574"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<rect
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:#474747;stroke-width:0.625544;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect20534"
|
||||
width="67.191879"
|
||||
height="23.092167"
|
||||
x="54.161835"
|
||||
y="167.00778" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.5037px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.187593"
|
||||
x="61.715302"
|
||||
y="186.69984"
|
||||
id="text21059"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057"
|
||||
x="61.715302"
|
||||
y="186.69984"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.187593">T</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 121.84323,164.45086 10.93939,-10.9355"
|
||||
id="path20805-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:9.15486px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.228872"
|
||||
x="56.627808"
|
||||
y="179.02429"
|
||||
id="text23789"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan23787"
|
||||
x="56.627808"
|
||||
y="179.02429"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.228872">H</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL);marker-end:url(#marker23801)"
|
||||
d="M 56.546083,188.04342 V 169.08263"
|
||||
id="path23791"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.250923;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-8);marker-end:url(#marker23801-3)"
|
||||
d="M 80.029497,181.46964 H 93.294174"
|
||||
id="path23791-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:transform-center-x="4.2335716"
|
||||
inkscape:transform-center-y="-8.4721688" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:9.15486px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.228872"
|
||||
x="87.574654"
|
||||
y="162.95206"
|
||||
id="text23789-9" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-7);marker-end:url(#marker23801-6)"
|
||||
d="m 89.639803,162.80003 7.50755,-7.7658"
|
||||
id="path23791-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.2411px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.156027"
|
||||
x="87.845589"
|
||||
y="159.39813"
|
||||
id="text21059-1-3-2"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057-1-0-2"
|
||||
x="87.845589"
|
||||
y="159.39813"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.156027">L</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 122.05054,190.09836 10.7941,-11.08379"
|
||||
id="path20538-6"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 132.84464,179.01457 0.0187,-23.86743"
|
||||
id="path20538-6-1"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="opacity:1;fill:#fcb23c;fill-opacity:1;stroke:#895502;stroke-width:0.614626;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6104"
|
||||
width="67.207901"
|
||||
height="2.1072214"
|
||||
x="54.151272"
|
||||
y="164.32817"
|
||||
ry="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#895502;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 122.05054,167.00938 10.79885,-10.89941 0.008,-2.19227"
|
||||
id="path20805-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 78.447673,177.00008 9.624797,-9.8911"
|
||||
id="path20538-6-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 78.425464,179.66243 9.624797,-9.8911"
|
||||
id="path20538-6-8-0"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.760429,176.83271 9.624797,-9.8911"
|
||||
id="path20538-6-8-0-3"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 87.88075,170.06683 0.07597,-3.05506"
|
||||
id="path20538-6-8-0-6"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 111.28813,169.76512 0.076,-3.05506"
|
||||
id="path20538-6-8-0-6-9"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.561356,179.69463 -5.224783,0.0131"
|
||||
id="path23791-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.51701,176.88556 -5.224783,0.0131"
|
||||
id="path23791-7-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.5037px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.187593"
|
||||
x="71.381172"
|
||||
y="189.32043"
|
||||
id="text21059-5"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057-6"
|
||||
x="71.381172"
|
||||
y="189.32043"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.187593">W</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.5037px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0081d5;fill-opacity:1;stroke:none;stroke-width:0.187593"
|
||||
x="84.089783"
|
||||
y="188.25977"
|
||||
id="text21059-5-7"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan21057-6-1"
|
||||
x="84.089783"
|
||||
y="188.25977"
|
||||
style="fill:#0081d5;fill-opacity:1;stroke-width:0.187593">S</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 71.648638,179.5799 -0.0097,2.66362"
|
||||
id="path23791-7-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 78.468682,179.60109 -0.0097,2.61685"
|
||||
id="path23791-7-9-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.4, 0.3;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 94.848919,179.80535 -0.0097,2.61685"
|
||||
id="path23791-7-9-3-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-74);marker-end:url(#marker23801-54)"
|
||||
d="m 76.876847,181.51957 -3.624842,-0.0298"
|
||||
id="path23791-43"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="58.652298"
|
||||
y="173.61502"
|
||||
id="text15381" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer7"
|
||||
inkscape:label="Layer 2"
|
||||
transform="translate(-50.901726,-151.02664)">
|
||||
<rect
|
||||
style="opacity:1;fill:#fcb23c;fill-opacity:1;stroke:#895502;stroke-width:0.499178;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect20424"
|
||||
width="6.6496596"
|
||||
height="2.6584671"
|
||||
x="71.743835"
|
||||
y="176.97217" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 101.6132,176.95663 9.62485,-9.8911"
|
||||
id="path20538-6-8-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 101.98778,179.66243 9.62485,-9.8911"
|
||||
id="path20538-6-8-8-4"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#474747;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 94.925946,176.78926 9.624824,-9.8911"
|
||||
id="path20538-6-8-0-3-0"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:transform-center-x="0.65481035"
|
||||
inkscape:transform-center-y="7.4835468"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="fill:#fcb23c;fill-opacity:1;stroke:#895502;stroke-width:0.499178;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect20424-4"
|
||||
width="6.6496596"
|
||||
height="2.6584671"
|
||||
x="94.909355"
|
||||
y="176.92873" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
|
||||
d="m 68.396624,187.21173 v -5.41497"
|
||||
id="path21071"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0081d5;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL-9)"
|
||||
d="m 68.307853,169.42208 v 5.41497"
|
||||
id="path21071-8"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 32 KiB |
Loading…
x
Reference in New Issue
Block a user