243 lines
5.2 KiB
C++
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;
|
|
}
|