Commit c277da41 authored by Bernardo Quaresma Dias's avatar Bernardo Quaresma Dias
Browse files

[INSTMPA-840]

+ criação de método especializado para validação de bloco média
+ criação de método para cálculo de média truncada
parent ab2b21ba
include('lib-list-1_1.mpam')
class{ id = "bloco_calculo", group = "Classes Abstratas",
bases = {},
description = [[]],
attributes = {
{ id = "intervalo", name = "Intervalo", type = "REAL", access = "gs", description =
[[Intervalo em que o ltimo resultado ainda pode ser considerado sem disparar uma nova execuo.]],
},
},
methods = {
{ id = "apagar", name = "Apagar",
description = [[Apaga resultados de clculos anteriores.]],
parameters = {
},
results = {
},
code = [===[ function(self)
self._t_ret = nil
self._ret = nil
end ]===],
},
{ id = "validar", name = "Validar", description =
[[Informa se o bloco tem amostras o suficiente para realizar uma execuo.]],
parameters = {
},
results = {
{ name = "Valido", type = "BOOLEAN" },
},
code = [===[ function(self)
return self:consultar() and true or false
end ]===],
},
{ id = "consultar", name = "Consultar", description =
[[Informa o valor do filtro na ltima execuo.]],
parameters = {
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self)
return self._ret
end ]===],
},
{ id = "executar", name = "Executar", description =
[[Executa o bloco para uma nova amostra respeitando o intervalo configurado.]],
parameters = {
{ name = "Valor", type = "REAL" },
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self, valor)
local t_atual = time()
if (not (self._t_ret and self.intervalo) )
or (t_atual - self._t_ret >= self.intervalo )
then
self._ret = self:calcular(valor)
self._t_ret = t_atual
end
return self._ret
end ]===],
},
},
}
class{ id = "bloco_filtro", name = "Bloco Filtro", group = "Blocos de Clculo",
bases = {"bloco_calculo"},
description = [[Bloco que recebe um valor e calcula o seu valor filtrado desde a ltima execuo.]],
attributes = {
{ id = "t",
name = "T",
type = "REAL",
access = "gs",
description = [[O valor da constante de tempo do processo.]],
},
{ id = "k",
name = "K",
type = "REAL",
access = "gs",
description = [[O valor da constante do processo.]],
},
{ id = "v_init",
name = "Valor Inicial",
type = "REAL",
access = "gs",
description = [[O valor do filtro em sua primeira execuo. Se no for definido o primeiro valor ser igual primeira leitura.]],
},
},
code = [====[
function _CLASS:init()
end
]====],
methods = {
{ id = "iniciar", name = "Iniciar",
description = [[Iniciar a execuo do filtro.]],
parameters = {
},
results = {
},
code = [===[ function(self)
self._y_1 = nil
self._t_0 = nil
self._t_1 = nil
self:apagar()
end ]===],
},
{ id = "validar", name = "Validar", description =
[[Informa se o bloco tem amostras o suficiente para realizar uma execuo.]],
parameters = {
},
results = {
{ name = "Valido", type = "BOOLEAN" },
},
code = [===[ function(self)
return self._t_ret and (self._t_ret + self.intervalo > time())
end ]===],
},
{ id = "consultar", name = "Consultar", description =
[[Informa o valor do filtro na ltima execuo.]],
parameters = {
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self)
return self._y_1 or self.v_init
end ]===],
},
{ id = "calcular", name = "Calcular", description =
[[Executa o filtro sobre o valor do processo.
O filtro de primeira ordem calcula a seguinte equao sobre o valor do processo:
f(x) = (K*x*dt+T*f[-1])/(T+dt)
Onde K a constante de ganho adimensional do processo, dt a diferena de
tempo, em segundos, entre a avaliao anterior e a atual, T a constante de
tempo do processo em segundos e f[-1] o valor do filtro calculado na
avaliao anterior.
Se o valor inicial for nulo, o filtro retorna o prprio valor na primeira vez
que executado.]],
parameters = {
{ name = "Valor", type = "REAL" },
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self, valor)
local t_atual = time()
self._t_1 = self._t_0
self._t_0 = t_atual
local y
if (self._y_1 == nil) then -- primeira execuo
if (self.x_0) then
y = self.v_init
else
y = valor
end
else
local K = self.k
local T = self.t
local dt = self._t_0 - self._t_1
y = (K*valor*dt+T*self._y_1)/(T+dt)
end
self._y_1 = y
return y
end ]===],
},
},
}
class{ id = "bloco_media", name = "Bloco Mdia", group = "Blocos de Clculo",
bases = {"bloco_calculo"},
description = [[Bloco que executa funo mdia sobre amostras informadas.]],
attributes = {
{ id = "amostras", name ="Amostras", type = "amostras", access ="g", description =
[[Histrico de valores inseridos.]],
},
{ id = "periodo", name = "Perodo", type = "REAL", access = "", description =
[[Perodo de amostras, em segundos, que deve ser considerado.]],
},
},
code = [====[
--function _CLASS:init() end
]====],
methods = {
{ id = "validar", name = "Validar",
description = [[Iniciar a execuo do filtro.]],
parameters = {
},
results = {
},
code = [===[ function(self)
return self.amostras:validar(self.periodo)
end ]===],
},
{ id = "iniciar", name = "Iniciar",
description = [[Iniciar a execuo do filtro.]],
parameters = {
},
results = {
},
code = [===[ function(self)
self.amostras:iniciar()
self:apagar()
end ]===],
},
{ id = "calcular", name = "Calcular", description =
[[Calcula a mdia dos valores informados.]],
parameters = {
{ name = "Valor", type = "REAL" },
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self, valor)
self.amostras:inserir(valor)
local historico = self.amostras:obter_historico(self.periodo)
return average(historico)
end ]===],
},
{ id = "calcular_truncada", name = "Calcular Mdia Truncada", description =
[[Calcula a mdia dos valores informados truncada N vezes. Cada vez que a mdia truncada, os maiores e menores so desconsiderados.]],
parameters = {
{ name = "N", type = "REAL" },
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self, n)
local historico = self.amostras:obter_historico(self.periodo)
lcoal truncado = truncate(historico, n)
return average(truncado)
end ]===],
},
{ id = "menor", name = "Avaliar Menor", description =
[[Avalia o menor valor informado.]],
parameters = {
},
results = {
{ name = "Menor Valor", type = "REAL" },
},
code = [===[ function(self, valor)
local historico = self.amostras:obter_historico(self.periodo)
return minimo(historico)
end ]===],
},
{ id = "maior", name = "Avaliar Maior", description =
[[Avalia o maior valor informado.]],
parameters = {
},
results = {
{ name = "Maior Valor", type = "REAL" },
},
code = [===[ function(self, valor)
local historico = self.amostras:obter_historico(self.periodo)
return maximo(historico)
end ]===],
},
},
}
class{ id = "bloco_tempo_morto", name = "Bloco Tempo Morto", group = "Blocos de Clculo",
bases = {"bloco_calculo"},
description = [[Bloco de clculo que retorna, ao executaro, o valor com atraso.]],
attributes = {
{ id = "atraso", name = "Atraso", type = "REAL", access = "gs", description =
[[O valor de tempo morto (em segundos).]],
},
{ id = "referencia", name = "Referncia", type = "REAL", access = "gs", description =
[[O valor inicial da funo at atingir o tempo morto.]],
},
},
methods = {
{ id = "iniciar", name = "Inicializar", description =
[[Inicializa o tempo morto, apagando quaisquer valores histricos que existam.]],
parameters = {
},
results = {
},
code = [===[ function(self)
self._oldest = nil
self._newest = nil
self:apagar()
end ]===],
},
{ id = "calcular", name = "Calcular", description =
[[Aplica o tempo morto ao valor de entrada.
Esta funo cria uma defasagem nos valores fornecidos, retornando a referncia
durante o tempo morto especificado.
Aps passado o tempo morto definido, os valores fornecidos anteriormente
comeam a ser retornados. O valor retornado o valor cujo momento de
incluso tenha sido o mais prximo, mas no menor, que o tempo morto.
Todos os valores armazenados associados a tempos anteriores ao valor
retornado so automaticamente descartados.
Dado esse critrio, caso a execuo desta funo seja feita em uma
freqncia varivel, valores armazenados podem ser descartados sem
nunca serem retornados.]],
parameters = {
{ name = "Valor", type = "REAL" },
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self, v)
local t_atual = time()
self:inserir(v, t_atual)
return self:consultar()
end ]===],
},
{ id = "inserir", name = "", description = [[]],
parameters = {
{ name = "Valor", type = "REAL" },
{ name = "Tempo", type = "REAL" },
},
results = {
},
code = [===[ function(self, v, t)
local amostra = {
valor = v,
tempo = t,
}
if self._oldest then
self._newest.next = amostra
else
self._oldest = amostra
end
self._newest = amostra
end ]===],
},
{ id = "consultar", name = "", description =
[[Varre as amostras coletadas da mais antiga para a mais recente at atingir o tempo mais prximo do atraso.]],
parameters = {
},
results = {
},
code = [===[ function(self)
local t_atual = time()
if (not self._oldest.tempo) or (t_atual - self._oldest.tempo < self.atraso) then
return self.referencia
else
local amostra = self._oldest.next
while (amostra and ( (t_atual - amostra.tempo) >= self.atraso) ) do
self._oldest = amostra
amostra = amostra.next
end
return self._oldest.valor
end
end ]===],
},
},
}
class{ id = "bloco_integrador", name = "Bloco Integrador", group = "Blocos de Clculo",
bases = {}, description =
[[]],
attributes = {
{ id = "k", name ="K", type = "REAL", access ="gs", description =
[[O valor da constante do processo.]],
},
{ id = "valor_referencia", name ="Valor Referncia", type = "REAL", access ="gs", description =
[[O valor de referncia do processo.]],
},
},
methods = {
{ id = "iniciar", name ="Iniciar", description =
[[Inicia o valor do somatrio]],
parameters = {
},
results = {
},
code = [===[ function(self)
self.y_1 = nil
end ]===],
},
{ id = "calcular", name ="Executar", description =
[[Executa o integrador sobre o valor do processo.
O integrador calcula a seguinte equao sobre o valor do processo:
f(x) = K*S((x-VR)*dt)
Onde K a constante de ganho adimensional do processo, S o somatrio, VR
o valor de referncia do processo e dt a diferena de tempo, em segundos,
entre cada duas avaliaes.]],
parameters = {
{ name = "Valor do Processo", type = "REAL" },
},
results = {
{ name = "Valor do Integrador", type = "REAL" },
},
code = [===[ function(self, x)
self:atualizar_tempos()
local y = 0
if (self.y_1 ~= nil) then
local VR = self.valor_referencia
local dt = self.t_0 - self.t_1
y = self.y_1+(x-VR)*dt
end
self.y_1 = y
local K = self.k
return K*y
end ]===],
},
{ id = "atualizar", name ="", description =
[[]],
parameters = {
},
results = {
},
code = [===[ function(self)
self.t_1 = self.t_0
self.t_0 = time()
end ]===],
},
},
}
class{ id = "bloco_derivador", name = "Bloco Derivador", group = "Blocos de Clculo",
bases = {}, description =
[[]],
attributes = {
{ id = "ganho", name ="K", type = "REAL", access ="gs", description =
[[O valor da constante do processo.]],
},
{ id = "amostras", name ="N", type = "REAL", access ="gs", description =
[[Nmero de amostras a serem consideradas para o clculo da derivada.]],
},
},
code = [[ function _CLASS:init()
self.values = {}
self.times = {}
end
]],
methods = {
{ id = "calcular", name ="Calcular", description =
[[Executa sobre o valor do processo.
O derivador calcula a seguinte equao sobre o valor do processo:
f(x) = K*(valor-valor_anterior)/dt
Onde K a constante de ganho adimensional do processo e dt a diferena de tempo, em segundos,
entre cada duas avaliaes.
Se for determinado um nmero de amostras o resultado ser a inclinao da reta de regresso linear para as amostras informadas.
Obs: A primeira execuo ir retornar 0, como se no houvesse variao no valor.]],
parameters = {
{ name = "Valor do Processo", type = "REAL" },
},
results = {
{ name = "Variao do Valor", type = "REAL" },
},
code = [===[ function(self, v)
self:armazena_amostra(v)
if #self.values <= 1 then
return 0
else
local K = self.ganho or 1
if self.amostras == nil then
local dv = self.values[1] - self.values[2]
local dt = self.times[1] - self.times[2]
self.resultado = K*dv/dt
else
self.resultado = K*slope(self.values, self.times)
end
return self.resultado
end
end ]===],
},
{ id = "informar_resultado", name ="Informar resultado", description =
[[Informa o resultado da ltima execuo do derivador.]],
parameters = {},
results = {
{ name = "Variao do Valor", type = "REAL" },
},
code = [===[ function(self)
return self.resultado
end ]===],
},
{ id = "armazena_amostra", name ="", description =
[[]],
parameters = {},
results = {},
code = [===[ function(self, value)
table.insert(self.values, 1, value)
table.insert(self.times, 1, time())
local amostras = self.amostras or 2
while #self.values > amostras do
table.remove(self.values)
table.remove(self.times)
end
end ]===],
},
{ id = "inicializar", name ="Inicializar", description =
[[Inicializa o derivador, apagando quaisquer valores histricos que existam.]],
parameters = {
},
results = {
},
code = [===[ function(self)
self.values = {}
self.times = {}
end ]===],
},
{ id = "verificar", name = "Verificar", description =
[[Verifica se o nmero de amostras e retorna verdadeiro caso esse nmero j tenha sido atingido.]],
parameters = {
},
results = {
{ name = "Preenchido", type = "BOOLEAN"},
},
code = [===[ function(self)
return #self.values >= (self.amostras or 2)
end ]===],
},
},
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment