10 #ifndef __SOT_INTEGRATOR_EULER_H__ 11 #define __SOT_INTEGRATOR_EULER_H__ 31 template <
class coefT>
50 template <
class sigT,
class coefT>
53 virtual const std::string &getClassName(
void)
const;
69 "sotIntegratorEuler(" + name +
70 ")::output(vector)::derivativesout") {
71 this->signalRegistration(derivativeSOUT);
75 setSamplingPeriod(0.005);
77 this->addCommand(
"setSamplingPeriod",
80 "Set the time during two sampling."));
81 this->addCommand(
"getSamplingPeriod",
84 "Get the time during two sampling."));
91 "Initialize internal memory from current value of input")));
107 sotDEBUG(15) <<
"# In {" << std::endl;
111 const std::vector<coefT> &num = numerator;
112 const std::vector<coefT> &denom = denominator;
115 tmp1 = inputMemory[0];
116 inputMemory[0] = SIN.access(time);
117 sum = num[0] * inputMemory[0];
121 int numsize = (int)num.size();
122 for (
int i = 1;
i < numsize; ++
i) {
123 tmp2 = inputMemory[
i - 1] - tmp1;
125 tmp1 = inputMemory[
i];
126 inputMemory[
i] = tmp2;
127 sum += (num[
i] * inputMemory[
i]);
132 int denomsize = (int)denom.size() - 1;
133 for (
int i = 0;
i < denomsize; ++
i) {
134 sum -= (denom[
i] * outputMemory[
i]);
140 outputMemory[denomsize] = sum;
141 for (
int i = denomsize - 1;
i >= 0; --
i) {
142 outputMemory[
i] += (outputMemory[
i + 1] *
dt);
146 inputMemory[0] = SIN.access(time);
147 res = outputMemory[0];
149 sotDEBUG(15) <<
"# Out }" << std::endl;
154 if (outputMemory.size() < 2)
157 "Integrator does not compute the derivative.");
159 SOUT.recompute(time);
160 res = outputMemory[1];
172 if (denominator.empty() || numerator.empty())
175 "The numerator or the denominator is empty.");
181 "The coefficient of the highest order derivative of denominator " 182 "should be 1 (the last pushDenomCoef should be the identity).");
184 std::size_t numsize = numerator.size();
185 inputMemory.resize(numsize);
187 inputMemory[0] = SIN.accessCopy();
188 for (std::size_t
i = 1;
i < numsize; ++
i) {
189 inputMemory[
i] = inputMemory[0];
192 std::size_t denomsize = denominator.size();
193 outputMemory.resize(denomsize);
194 for (std::size_t
i = 0;
i < denomsize; ++
i) {
195 outputMemory[
i] = inputMemory[0];
bool integratorEulerCoeffIsIdentity(const coefT c)
CommandVoid0< E > * makeCommandVoid0(E &entity, boost::function< void(void)> function, const std::string &docString)
std::string docCommandVoid0(const std::string &doc)
integrates an ODE. If Y is the output and X the input, the following equation is integrated: a_p * d(...
sigT & derivative(sigT &res, int time)
static const std::string CLASS_NAME
static std::string getTypeName(void)
dynamicgraph::SignalTimeDependent< sigT, int > derivativeSOUT
integrates an ODE using a naive Euler integration. TODO: change the integration method. For the moment, the highest derivative of the output signal is computed using the previous values of the other derivatives and the input signal, then integrated n times, which will most certainly induce a huge drift for ODEs with a high order at the denominator.
IntegratorEuler(const std::string &name)
double getSamplingPeriod() const
virtual ~IntegratorEuler(void)
void setSamplingPeriod(const double &period)
std::vector< sigT > inputMemory
std::vector< sigT > outputMemory
sigT & integrate(sigT &res, int time)