Files
maszyna/TractionPower.cpp
2017-10-28 16:18:53 +02:00

159 lines
4.9 KiB
C++

/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
MaSzyna EU07 locomotive simulator component
Copyright (C) 2004 Maciej Czapkiewicz and others
*/
#include "stdafx.h"
#include "TractionPower.h"
#include "Logs.h"
//---------------------------------------------------------------------------
TTractionPowerSource::TTractionPowerSource( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
// legacy constructor
TTractionPowerSource::TTractionPowerSource( std::string Name ) {
m_name = Name;
}
void TTractionPowerSource::Init(double const u, double const i)
{ // ustawianie zasilacza przy braku w scenerii
NominalVoltage = u;
VoltageFrequency = 0;
MaxOutputCurrent = i;
};
bool TTractionPowerSource::Load(cParser *parser) {
parser->getTokens( 10, false );
*parser
>> m_area.center.x
>> m_area.center.y
>> m_area.center.z
>> NominalVoltage
>> VoltageFrequency
>> InternalRes
>> MaxOutputCurrent
>> FastFuseTimeOut
>> FastFuseRepetition
>> SlowFuseTimeOut;
std::string token { parser->getToken<std::string>() };
if( token == "recuperation" ) {
Recuperation = true;
}
else if( token == "section" ) {
// odłącznik sekcyjny
// nie jest źródłem zasilania, a jedynie informuje o prądzie odłączenia sekcji z obwodu
bSection = true;
}
// skip rest of the section
while( ( false == token.empty() )
&& ( token != "end" ) ) {
token = parser->getToken<std::string>();
}
if( InternalRes < 0.1 ) {
// coś mała ta rezystancja była...
// tak około 0.2, wg
// http://www.ikolej.pl/fileadmin/user_upload/Seminaria_IK/13_05_07_Prezentacja_Kruczek.pdf
InternalRes = 0.2;
}
return true;
};
bool TTractionPowerSource::Update(double dt)
{ // powinno być wykonane raz na krok fizyki
// iloczyn napięcia i admitancji daje prąd
if (NominalVoltage * TotalPreviousAdmitance > MaxOutputCurrent) {
FastFuse = true;
FuseCounter += 1;
if (FuseCounter > FastFuseRepetition) {
SlowFuse = true;
ErrorLog( "Power overload: \"" + m_name + "\" disabled for " + std::to_string( SlowFuseTimeOut ) + "s" );
}
else {
ErrorLog( "Power overload: \"" + m_name + "\" disabled for " + std::to_string( FastFuseTimeOut ) + "s" );
}
FuseTimer = 0;
}
if (FastFuse || SlowFuse)
{ // jeśli któryś z bezpieczników zadziałał
TotalAdmitance = 0;
FuseTimer += dt;
if (!SlowFuse)
{ // gdy szybki, odczekać krótko i załączyć
if (FuseTimer > FastFuseTimeOut)
FastFuse = false;
}
else if (FuseTimer > SlowFuseTimeOut)
{
SlowFuse = false;
FuseCounter = 0; // dajemy znów szansę
}
}
TotalPreviousAdmitance = TotalAdmitance; // używamy admitancji z poprzedniego kroku
if (TotalPreviousAdmitance == 0.0)
TotalPreviousAdmitance = 1e-10; // przynajmniej minimalna upływność
TotalAdmitance = 1e-10; // a w aktualnym kroku sumujemy admitancję
return true;
};
double TTractionPowerSource::CurrentGet(double res)
{ // pobranie wartości prądu przypadającego na rezystancję (res)
// niech pamięta poprzednią admitancję i wg niej przydziela prąd
if (SlowFuse || FastFuse)
{ // czekanie na zanik obciążenia sekcji
if (res < 100.0) // liczenie czasu dopiero, gdy obciążenie zniknie
FuseTimer = 0;
return 0;
}
if ((res > 0) || ((res < 0) && (Recuperation || true)))
TotalAdmitance +=
1.0 / res; // połączenie równoległe rezystancji jest równoważne sumie admitancji
float NomVolt = (TotalPreviousAdmitance < 0 ? NominalVoltage * 1.083 : NominalVoltage);
TotalCurrent = (TotalPreviousAdmitance != 0.0) ?
NomVolt / (InternalRes + 1.0 / TotalPreviousAdmitance) :
0.0; // napięcie dzielone przez sumę rezystancji wewnętrznej i obciążenia
OutputVoltage = NomVolt - InternalRes * TotalCurrent; // napięcie na obciążeniu
return TotalCurrent / (res * TotalPreviousAdmitance); // prąd proporcjonalny do udziału (1/res)
// w całkowitej admitancji
};
void TTractionPowerSource::PowerSet(TTractionPowerSource *ps)
{ // wskazanie zasilacza w obiekcie sekcji
if (!psNode[0])
psNode[0] = ps;
else if (!psNode[1])
psNode[1] = ps;
// else ErrorLog("nie może być więcej punktów zasilania niż dwa");
};
// legacy method, calculates changes in simulation state over specified time
void
powergridsource_table::update( double const Deltatime ) {
for( auto *powersource : m_items ) {
powersource->Update( Deltatime );
}
}
//---------------------------------------------------------------------------