jonniedie / SimulationLogs.jl

Signal logging and scoping for DifferentialEquations.jl simulations.
MIT License
22 stars 2 forks source link

Namespacing #7

Open jonniedie opened 3 years ago

jonniedie commented 3 years ago

It would be nice to have some namespacing for logged variables. Taking the cruise control example.

using ComponentArrays, DifferentialEquations, SimulationLogs

function car!(D, x, p, t; u=0.0)
    @log forces.drag drag = p.c*x.vel^2
    D.pos = x.vel
    D.vel = (-drag*sign(x.vel) + u)/p.m
end

function feedback_car!(D, vars, p, t)
    @log r = p.control.ref(t)
    @log e = r - vars.car.vel
    @log forces.u u = p.control.kp*e + p.control.ki*vars.∫e

    car!(D.car, vars.car, p.car, t; u)
    D.∫e = e
end

 .
 .
 .

sol = solve(prob)

We could now just call scope for :forces and it will plot both the drag force and the throttle.

scope(sol, :forces)

forces

jonniedie commented 3 years ago

I guess it's even possible to do things like

@log forces drag = p.c*x.vel^2
...
@log forces u = p.control.kp*e + p.control.ki*vars.∫e

but that seems a little too magical for me. Plus that means that any time you wanted to make a logged variable a on an assignment b = ... with @log a b = ..., it would create a namespaced a.b, which seems surprising.

bgroenks96 commented 3 years ago

I would prefer something like

@lognamespace forces
@log drag = p.c*x.vel^2

or maybe @loggroup or something. Basically something which would set the context for all subsequent @log calls until changed again. Then maybe @log could have an override:

@log forces drag = p.c*x.vel^2

which would ignore the current context (assume it's something other than forces) and use that namespace instead.

bgroenks96 commented 3 years ago

But I agree, this would be very useful for my use-case. At the moment, I'm going to try to use prefixes to accomplish this... but that's not ideal.

jonniedie commented 3 years ago

I think I'd rather have namespacing be explicit rather than implicit with a top-level declaration. One of the reasons is I'd like to have arbitrarily nested namespaces. So like with the @lognamespace example, if you did something like this:

@lognamespace forces
@log drag = p.c*x.vel^2

@lognamespace control
@log u = p.control.kp*e + p.control.ki*vars.∫e

Would it make a forces.control.u or control.u? I'd like the ability to do either one, and for that I think you need explicit declaration like

@log forces.control.u u = p.control.kp*e + p.control.ki*vars.∫e

or

@log control.u u = p.control.kp*e + p.control.ki*vars.∫e

And while we're on the subject, I don't think I really love the above syntax either. It feels redundant to have to do @log control.u followed by u = .... I don't like having it open-ended either with something like @log control u = ... or @log control. u = ... and we can't just do @log control.u = ... because that means something different. Although maybe logging a control.u should make a namespaced control.u automatically?