gpt4 book ai didi

c++ - 如何在 C++ 中实现传递函数的控制系统 block ?

转载 作者:行者123 更新时间:2023-11-30 03:08:51 25 4
gpt4 key购买 nike

我想定义一个控制系统 block :

class ControlSystemBlock
{
public:
ControlSystemBlock()
{
m_dbTimeStep = 0.001; // time between two consequential inputs
}

// this method can be called anytime,
// but the object will assume
// that it was called
// after m_dbTimeStep before the last call
void LoadNewInput(double dbInputValue);

double GetCurrentOutput();
// ...
private:
double m_dbTimeStep;
// ...
};

系统将接收输入,并根据这些输入和其中用户定义的传递函数,其输出值将随时间变化。

例如,假设我想实现传递函数H(s) = 1/(s + 2)。我该怎么做?有什么算法吗?

最佳答案

你觉得我的代码怎么样:

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();
}

我刚做完。
我很快就会测试它。

关于c++ - 如何在 C++ 中实现传递函数的控制系统 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4542837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com