Files
qad/mbricks/brick_math.cpp

243 lines
5.2 KiB
C++

#include "brick_math.h"
bool BrickMathSum::tick_body(double time) {
double t = 0.;
for (int i = 0; i < inputs_count; ++i)
t += inputs[i] * parameters[i].toFloat();
outputs[0] = t;
return true;
}
bool BrickMathMultiply::tick_body(double time) {
double t = 1.;
for (int i = 0; i < inputs_count; ++i)
t *= inputs[i];
outputs[0] = t;
return true;
}
BrickMathIntegral::BrickMathIntegral(double initial): BrickMathBase(4, 1, 1) {
type = "Integral";
setName(type);
inNames[1] = "Enable";
inNames[2] = "Reset";
inNames[3] = "Initial";
paramNames[0] = "Method";
note_ = "While \"Reset\" = 1 \"Output\" = \"Initial\", integrate while \"Enable\" = 1.\n";
note_ += "Methods description you can find in help content.";//PIMathSolver::methods_desc;
inputs[1] = 1.;
parameters[0].setValue(-1);
saveInputsToDefault();
started();
}
void BrickMathIntegral::started() {
TF.vector_Bm.resize(1); TF.vector_An.resize(2);
TF.vector_Bm[0] = 1.;
TF.vector_An[0] = 0.; TF.vector_An[1] = 1.;
KF.fromTF(TF);
KF.X[0] = inputs[Initial];
KF.setMethod((PIMathSolver::Method)parameters[0].toInt());
}
bool BrickMathIntegral::tick_body(double time) {
if (inputs[Reset] > 0.)
outputs[0] = KF.X[0] = inputs[Initial];
else {
if (inputs[Enable] > 0.) {
KF.setTime(time);
KF.solve(inputs[0], dt);
outputs[0] = KF.X[0];
}
}
return true;
}
bool BrickMathDerivate::tick_body(double time) {
outputs[0] = (inputs[0] - v) / dt;
v = inputs[0];
return true;
}
bool BrickMathDeadZone::tick_body(double time) {
if (fabs(inputs[Input]) < inputs[Zone]) {
outputs[Output] = 0.;
outputs[InZone] = 1.;
} else {
outputs[Output] = (fabs(inputs[Input]) - inputs[Zone]) * sign(inputs[Input]);
outputs[InZone] = 0.;
}
return true;
}
bool BrickMathSaturation::tick_body(double time) {
if (inputs[Input] > inputs[Max]) {
outputs[Output] = inputs[Max];
outputs[InMin] = 0.;
outputs[InMax] = 1.;
} else {
if (inputs[Input] < inputs[Min]) {
outputs[Output] = inputs[Min];
outputs[InMin] = 1.;
outputs[InMax] = 0.;
} else {
outputs[Output] = inputs[Input];
outputs[InMin] = 0.;
outputs[InMax] = 0.;
}
}
return true;
}
bool BrickMathRelay::tick_body(double time) {
if (inputs[Input] - v >= 0) {if (inputs[Input] >= inputs[Size]) outputs[0] = inputs[ActiveValue];}
else {if (inputs[Input] <= -inputs[Size]) outputs[0] = inputs[InactiveValue];}
v = inputs[Input];
return true;
}
bool BrickMathDelayTicks::tick_body(double time) {
if (parameters[0].toUInt() != v.size()) setDelay(parameters[0].toInt());
v.pop_back();
v.push_front(inputs[0]);
outputs[0] = v.back();
return true;
}
bool BrickMathDelaySeconds::tick_body(double time) {
t = piRound(parameters[0].toFloat() / dt) + 1;
if (t < 1) t = 1;
if (v.size() != t) {
v.resize(t);
v.assign(t, 0.);
}
v.pop_back();
v.push_front(inputs[0]);
outputs[0] = v.back();
return true;
}
BrickMathFunction::BrickMathFunction(): BrickMathBase(0, 2, 1) {
type = "Function";
setName(type);
paramNames[0] = "Function";
outNames[0] = "Re out";
outNames[1] = "Im out";
parameters[0].setValue("");
parameterChanged(0);
interactive = true;
}
void BrickMathFunction::parameterChanged(int index) {
eval.clearCustomVariables();
eval.check(parameters[0].toString());
PIStringList sl = eval.unknownVariables();
setInputsCount(sl.size());
for (uint i = 0; i < sl.size(); ++i) {
eval.setVariable(sl[i]);
inNames[i] = sl[i];
}
eval.check(parameters[0].toString());
note_ = "Your expression:\n" + eval.error() + "\n" + eval.expression();
}
bool BrickMathFunction::tick_body(double time) {
for (int i = 0; i < inputs_count; ++i)
eval.setCustomVariableValue(i, complexd(inputs[i], 0.));
res = eval.evaluate();
outputs[0] = res.real();
outputs[1] = res.imag();
return true;
}
BrickMathFFT::BrickMathFFT(): BrickMathBase(1, 1, 2) {
type = "FFT";
setName(type);
paramNames[0] = "Buffer size (2^n)";
paramNames[1] = "Inverse";
parameters[0].setValue(256);
parameters[1].setValue(0);
t = 0;
buffered = true;
}
bool BrickMathFFT::tick_body(double time) {
if (v.size() != parameters[0].toUInt()) {
t = parameters[0].toInt();
v.resize(t);
v.fill(complexd(0., 0.));
buffer.resize(t, 0.);
t = 0;
}
outputs[0] = (t >= 0 && t < o.size_s()) ? o[t].real() : 0.;
if (t >= v.size()) {
t = 0;
if (parameters[1].toInt() > 0.)
o = *fft.calcFFTinverse(v);
else
o = *fft.calcFFT(v);
for (uint i = 0; i < buffer.size(); ++i)
buffer[i] = abs(o[i]);
} else {
v[t] = inputs[0];
++t;
}
return true;
}
void BrickMathBessel::parameterChanged(int index) {
k = parameters[0].toInt();
o = parameters[1].toInt();
if (k == 0) outNames[0] = "J";
if (k == 1) outNames[0] = "Y";
if (k < 0 || k > 1) {
outNames[0] = "?";
return;
}
outNames[0] += PIString::fromNumber(o);
}
bool BrickMathBessel::tick_body(double time) {
k = parameters[0].toInt();
o = parameters[1].toInt();
if (k == 0) {
if (o == 0)
outputs[0] = piJ0(inputs[0]);
else {
if (o == 1)
outputs[0] = piJ1(inputs[0]);
else
outputs[0] = piJn(o, inputs[0]);
}
}
if (k == 1) {
if (o == 0)
outputs[0] = piY0(inputs[0]);
else {
if (o == 1)
outputs[0] = piY1(inputs[0]);
else
outputs[0] = piYn(o, inputs[0]);
}
};
return true;
}