Help building a PID example

Hi guys!

I am trying to use Flux.jl to build a PIDNN as shown here:

I started to code using only the proportional part. This, I need an input layer with 2 inputs and 1 output, and one output layer with 1 input and 1 output. This is my code so far:

struct Input
Input() = Input(param(randn(2)))
(m::Input)(x) = m.W[1]*x[1] + m.W[2]*x[2]
struct P
P() = P(param(randn()))
function (m::P)(x)
    # P
    if (x > 1)
        return m.W[1]
    elseif (x < -1)
        return -m.W[1]
        return x*m.W[1]
m = Chain(Input(), P())
function loss(x,y)
    # Simulate the system.
    t = 0:0.1:100
    o = x
    Δ =  0.0
    for k in t
        Δ = Δ + (y-o)^2
        r = m([y;o])
        o = o + r*0.1
    return Δ/length(t)
ps = Flux.params(m)
Tracker.gradient(()->loss(0,1), ps)

Which produces the following error:

julia> Tracker.gradient(()->loss(0,1), ps)
ERROR: MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type Float64

Can anyone please help me?

Btw, if the input layer only have one input, then it works fine.

The model only has one input, the input data, you are using the input and output.
It should be something like this:

r = m(o)

I think “y” is Float and “o” is a Vector:


In the loss function it is not clear who is the system to be controlled and I think there are errors in the controller, I think it should be something like this.

for k in t
       control_output = #control output
       out = model(control_output)  #model output
       Δ = Δ + (y - out)^2 # squared error (desired output - model output)
       o = [y, out] # update next input 

Obs: Vi que é brasileiro :slight_smile:, tem um grupo no telegram de usuários de julia no Brasil caso interesse. (

Hi @phelipe !

Thanks! With the help of some people on Slack, I managed to finally tune my PID Neural Network. I will write a tutorial on my website, something like a Hello World on machine learning using Julia for Control engineers :smiley:

P.S.: Já me adicionei!