#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 = round(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] = o[t].real(); if (t >= v.size()) { t = 0; //fft(o.data(), log2((double)v.size()), parameters[1].toInt() > 0.); 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; }