Что вы думаете о моем коде:
ControlSystemBlock.h
#ifndef CONTROLSYSTEMBLOCK_H
#define CONTROLSYSTEMBLOCK_H
#include <vector>
#include <deque>
#include "Polynomial.h"
#include "PolynomialFraction.h"
class ControlSystemBlock
{
public:
enum SIGNAL_TYPE
{
ST_DISCRETE = 1,
ST_CONTINUOUS = 2
};
ControlSystemBlock( long double dbSamplingPeriod = 0.001);
ControlSystemBlock( const std::vector<long double> & NominatorCoefficients,
const std::vector<long double> & DenominatorCoefficients,
SIGNAL_TYPE SignalType = SIGNAL_TYPE::ST_CONTINUOUS,
long double dbSamplingPeriod = 0.001);
ControlSystemBlock( const Polynomial<long double> & NominatorPolynomial,
const Polynomial<long double> & DenominatorPolynomial,
SIGNAL_TYPE SignalType = SIGNAL_TYPE::ST_CONTINUOUS,
long double dbSamplingPeriod = 0.001);
ControlSystemBlock( const PolynomialFraction<long double> & TransferFunction,
SIGNAL_TYPE SignalType = SIGNAL_TYPE::ST_CONTINUOUS,
long double dbSamplingPeriod = 0.001);
// Sends a new input to the system block
// Assuming that this input is sent just after m_dbSamplingPeriod seconds after the last input
// Returns the the new output value
long double SendInput(long double dbInput);
long double GetOutput() const;
protected:
long double m_dbSamplingPeriod;
std::deque<long double> m_InputMemory;
std::deque<long double> m_OutputMemory;
void SetTransferFunction(const PolynomialFraction<long double> & TransferFunction, SIGNAL_TYPE SignalType);
PolynomialFraction<long double> m_TransferFunction;
private:
PolynomialFraction<long double> ContinuousTimeToDiscreteTime(const PolynomialFraction<long double> & ContinuousTimeTransferFunction);
PolynomialFraction<long double> ContinuousTimeToDiscreteTime(const Polynomial<long double> & NominatorPolynomial,
const Polynomial<long double> & DenominatorPolynomial);
PolynomialFraction<long double> ContinuousTimeToDiscreteTime(const std::vector<long double> & NominatorCoefficients,
const std::vector<long double> & DenominatorCoefficients);
void ShiftMemoryRegisters(long double dbNewInput);
};
#endif
ControlSystemBlock.cpp
#include "ControlSystemBlock.h"
ControlSystemBlock::ControlSystemBlock( long double dbSamplingPeriod /*= 0.001*/)
{
m_dbSamplingPeriod = dbSamplingPeriod;
std::vector<long double> Coefficients;
Coefficients.push_back(1.0);
PolynomialFraction<long double> TransferFunction(Coefficients, Coefficients);
SetTransferFunction(TransferFunction, SIGNAL_TYPE::ST_DISCRETE);
}
ControlSystemBlock::ControlSystemBlock( const std::vector<long double> & NominatorCoefficients,
const std::vector<long double> & DenominatorCoefficients,
SIGNAL_TYPE SignalType /*= SIGNAL_TYPE::ST_CONTINUOUS*/,
long double dbSamplingPeriod /*= 0.001*/)
{
m_dbSamplingPeriod = dbSamplingPeriod;
PolynomialFraction<long double> TransferFunction = PolynomialFraction<long double>(NominatorCoefficients, DenominatorCoefficients);
SetTransferFunction(TransferFunction, SignalType);
}
ControlSystemBlock::ControlSystemBlock( const Polynomial<long double> & NominatorPolynomial,
const Polynomial<long double> & DenominatorPolynomial,
SIGNAL_TYPE SignalType /*= SIGNAL_TYPE::ST_CONTINUOUS*/,
long double dbSamplingPeriod /*= 0.001*/ )
{
m_dbSamplingPeriod = dbSamplingPeriod;
PolynomialFraction<long double> TransferFunction = PolynomialFraction<long double>(NominatorPolynomial, DenominatorPolynomial);
SetTransferFunction(TransferFunction, SignalType);
}
ControlSystemBlock::ControlSystemBlock( const PolynomialFraction<long double> & TransferFunction,
ControlSystemBlock::SIGNAL_TYPE SignalType /*= SIGNAL_TYPE::ST_CONTINUOUS*/,
long double dbSamplingPeriod /*= 0.001*/)
{
m_dbSamplingPeriod = dbSamplingPeriod;
if (SignalType == SIGNAL_TYPE::ST_CONTINUOUS)
SetTransferFunction(TransferFunction, SignalType);
}
long double ControlSystemBlock::SendInput(long double dbInput)
{
ShiftMemoryRegisters(dbInput);
long double dbSumX = 0.0, dbSumY = 0.0;
for (uint64_t i=0; i<m_TransferFunction.GetNominatorDegree()+1; i++)
{
dbSumX += m_TransferFunction.GetNominator().GetCoefficientAt(i) * m_InputMemory.at(i);
}
for (uint64_t i=1; i<m_TransferFunction.GetDenominatorDegree()+1; i++)
{
dbSumY += m_TransferFunction.GetDenominator().GetCoefficientAt(i) * m_OutputMemory.at(i);
}
return m_OutputMemory.at(0) = (dbSumX - dbSumY) / m_TransferFunction.GetDenominator().GetCoefficientAt(0);
}
long double ControlSystemBlock::GetOutput() const
{
return m_OutputMemory.at(0);
}
PolynomialFraction<long double> ControlSystemBlock::ContinuousTimeToDiscreteTime(const PolynomialFraction<long double> & ContinuousTimeTransferFunction)
{
// Generate an "s" term in terms of "z^(-1)" terms
std::vector<long double> nom, den;
nom.push_back(1);
nom.push_back(-1);
den.push_back(1);
den.push_back(1);
PolynomialFraction<long double> STerm(nom, den);
STerm *= static_cast<long double>(2) / m_dbSamplingPeriod;
// Define nominator and denominator terms of the discrete time transfer function separately
nom.clear();
den.clear();
nom.push_back(0);
nom.push_back(1);
PolynomialFraction<long double> NominatorOfDiscreteTimeTransferFunction(nom, den);
PolynomialFraction<long double> DenominatorOfDiscreteTimeTransferFunction(nom, den);
// Generate the nominator and denominator terms of the resulting discrete time transfer function
for (uint64_t i=0; i<ContinuousTimeTransferFunction.GetNominatorDegree()+1; i++)
{
NominatorOfDiscreteTimeTransferFunction += STerm.GetPower(i) * ContinuousTimeTransferFunction.GetNominator().GetCoefficientAt(i);
}
for (uint64_t i=0; i<ContinuousTimeTransferFunction.GetDenominatorDegree()+1; i++)
{
NominatorOfDiscreteTimeTransferFunction += STerm.GetPower(i) * ContinuousTimeTransferFunction.GetDenominator().GetCoefficientAt(i);
}
return NominatorOfDiscreteTimeTransferFunction / DenominatorOfDiscreteTimeTransferFunction;
}
PolynomialFraction<long double> ControlSystemBlock::ContinuousTimeToDiscreteTime(const Polynomial<long double> & NominatorPolynomial,
const Polynomial<long double> & DenominatorPolynomial)
{
PolynomialFraction<long double> ContinuousTimeTransferFunction(NominatorPolynomial, DenominatorPolynomial);
return ContinuousTimeToDiscreteTime(ContinuousTimeTransferFunction);
}
PolynomialFraction<long double> ControlSystemBlock::ContinuousTimeToDiscreteTime(const std::vector<long double> & NominatorCoefficients,
const std::vector<long double> & DenominatorCoefficients)
{
PolynomialFraction<long double> ContinuousTimeTransferFunction(NominatorCoefficients, DenominatorCoefficients);
return ContinuousTimeToDiscreteTime(ContinuousTimeTransferFunction);
}
void ControlSystemBlock::SetTransferFunction( const PolynomialFraction<long double> & TransferFunction, SIGNAL_TYPE SignalType)
{
if (SignalType == SIGNAL_TYPE::ST_CONTINUOUS)
{
m_TransferFunction = ContinuousTimeToDiscreteTime(TransferFunction);
}
else
{
m_TransferFunction = TransferFunction;
}
m_InputMemory.resize(m_TransferFunction.GetNominatorDegree() + 1, 0.0);
m_OutputMemory.resize(m_TransferFunction.GetDenominatorDegree() + 1, 0.0);
}
void ControlSystemBlock::ShiftMemoryRegisters(long double dbNewInput)
{
m_InputMemory.push_back(dbNewInput);
m_InputMemory.pop_front();
m_OutputMemory.push_back(0.0);
m_OutputMemory.pop_front();
}
Я только что закончил.
Я собираюсь проверить это в ближайшее время.