mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
149 lines
5.2 KiB
C++
149 lines
5.2 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"
|
|
#include "Ground.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TTractionPowerSource::TTractionPowerSource(TGroundNode const *node) :
|
|
gMyNode( node )
|
|
{
|
|
psNode[0] = nullptr; // sekcje zostaną podłączone do zasilaczy
|
|
psNode[1] = nullptr;
|
|
};
|
|
|
|
TTractionPowerSource::~TTractionPowerSource(){};
|
|
|
|
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)
|
|
{
|
|
std::string token;
|
|
// AnsiString str;
|
|
// str= Parser->GetNextSymbol()LowerCase();
|
|
// asName= str;
|
|
parser->getTokens(5);
|
|
*parser >> NominalVoltage >> VoltageFrequency >> InternalRes >> MaxOutputCurrent >>
|
|
FastFuseTimeOut;
|
|
parser->getTokens();
|
|
*parser >> FastFuseRepetition;
|
|
parser->getTokens();
|
|
*parser >> SlowFuseTimeOut;
|
|
parser->getTokens();
|
|
*parser >> token;
|
|
if (token.compare("recuperation") == 0)
|
|
Recuperation = true;
|
|
else if (token.compare("section") == 0) // odłącznik sekcyjny
|
|
bSection = true; // nie jest źródłem zasilania, a jedynie informuje o prądzie odłączenia
|
|
// sekcji z obwodu
|
|
parser->getTokens();
|
|
*parser >> token;
|
|
if (token.compare("end") != 0)
|
|
Error("tractionpowersource end statement missing");
|
|
// if (!bSection) //odłącznik sekcji zasadniczo nie ma impedancji (0.01 jest OK)
|
|
if (InternalRes < 0.1) // coś mała ta rezystancja była...
|
|
InternalRes = 0.2; // tak około 0.2, wg
|
|
// http://www.ikolej.pl/fileadmin/user_upload/Seminaria_IK/13_05_07_Prezentacja_Kruczek.pdf
|
|
return true;
|
|
};
|
|
|
|
bool TTractionPowerSource::Render()
|
|
{
|
|
return true;
|
|
};
|
|
|
|
bool TTractionPowerSource::Update(double dt)
|
|
{ // powinno być wykonane raz na krok fizyki
|
|
// if (NominalVoltage * TotalPreviousAdmitance >
|
|
// MaxOutputCurrent * 0.00000005) // iloczyn napięcia i admitancji daje prąd
|
|
// ErrorLog("Power overload: \"" + gMyNode->asName + "\" with current " + AnsiString(NominalVoltage * TotalPreviousAdmitance) + "A");
|
|
if (NominalVoltage * TotalPreviousAdmitance >
|
|
MaxOutputCurrent) // iloczyn napięcia i admitancji daje prąd
|
|
{
|
|
FastFuse = true;
|
|
FuseCounter += 1;
|
|
if (FuseCounter > FastFuseRepetition)
|
|
{
|
|
SlowFuse = true;
|
|
ErrorLog("Power overload: \"" + gMyNode->asName + "\" disabled for " +
|
|
std::to_string(SlowFuseTimeOut) + "s");
|
|
}
|
|
else
|
|
ErrorLog("Power overload: \"" + gMyNode->asName + "\" 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");
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|