Issue with nonlinear control variable

Hi everyone,

Do you have any idea why when I replace F by sign(F).*abs(F) in “pendulum_on_cart_model.m” equations, the minimal example does not work anymore ? The output is always 0 for any reference signal.
I also have the same behavior when using something like u.*u in a model with u the input/control variable.

I will be glad if you can help me to understand what happens.

Best regards,
Arda

Hi @ardayigit4,

I think both of the changes you made to the model, imply that the car can only move in one direction on the axis (positive direction).
This makes it intuitively impossible to stabilize the pendulum into the origin.

Moreover, I would try to avoid the functions sign and abs in an MPC formulation, because they are non differentiable.

Best,
Jonathan

Hi @FreyJo ,

Same problem happens with F^3. F^3 is differentiable, can have positive and negative values. For me, it seems to be an initial value issue. If the initial value of the input is 0, then nothing happens. But if you change slightly the inital value, then it works.

Maybe this is because if you linearize wrt the input variable, since the derivative is 0 at the inital point, the system behaves like an autonomous system, not controllable anymore. That would explain why it works when changing slightly the inital value.

I used F=sign(F).*abs(F) just to provide a simple example that should work. In my specific case, I need u.*abs(u), which is differentiable at u=0 (but not twice differentiable). It represents an aerodynamic friction force, proportional to the velocity squared. My workaround is using an initial value other than 0, but I don’t really understand why the solver cannot deal with it.

Best,
Arda

I cannot explain this better than you did here:

I think this function is actually a bit tricky.
Does the workaround to avoid zero initializations of the controls work for you?

Yes it works. Is it possible to show a compile-time warning when the partial derivative wrt the input variable is 0 ?

The derivative is only evaluated after compilation, so it is not possible to add a check for that on compile time.