pydy / pydy-tutorial-human-standing

PyDy tutorial materials for MASB 2014, PYCON 2014, and SciPy 2014/2015.
http://pydy.org
160 stars 70 forks source link

Linearization in control notebook doesn't work when equilibrium point is note all zeros #118

Open skruzic opened 3 years ago

skruzic commented 3 years ago

As the title says, when linearizing equations of motion in order to obtain control, the odd thing happens: if equilibrium point is not all zeros, the output from linearizer contains speed derivatives, e.g.

equilibrium_point = zeros(len(coordinates + speeds))
equilibrium_point[2] = deg2rad(5) # or any other value other than zero

equilibrium_dict = dict(zip(coordinates + speeds, equilibrium_point))

parameter_dict = dict(zip(constants, sympify(numerical_constants)))

linearizer = kane.to_linearizer()
linearizer.r = Matrix(specified)

A, B = linearizer.linearize(op_point=[equilibrium_dict, parameter_dict], A_and_B=True)

At this point, A has some speed derivatives left in some terms for unknown reason:

img-8307dc5ca022f4ce

Any idea how to resolve this issue?

moorepants commented 3 years ago

Likely, all qdots should be substituted with the associated u's before linearizing.

The linearizer or the Kanes/LagrangesMethod objects should likely do this. Please submit an issue to sympy and maybe we can develop a fix. Otherwise you need to manually prepare the input to the linearizer so that it works.

JonathanCamargo commented 3 years ago

@moorepants Can you please elaborate on this: "you need to manually prepare the input to the linearizer so that it works."?

I'm encountering the same issue. When creating a KanesMethod object and trying either to_linearizer and then linearize(), or just linearize() from the Kanes object. The A matrix from the linearization has udot terms.

moorepants commented 3 years ago

I think there may be some bugs with the linearizer related to the fact that it doesn't check whether all derivatives have been eliminated on the right hand side of the explicit odes. So KanesMethod has .mass_matrix_full and .forcing_full which are M and F of Mx'=F and x' are the derivatives of the coordinates and speeds. M and F should not have any Derivative terms present. M(q, p, t) x' = F(q, u, p, t) where q, u, p are the coordinates, speeds, and constants respectively. Here is a manual approach of linearization that you may want to use: https://nbviewer.jupyter.org/github/moorepants/mae223/blob/master/content/lecture-notebooks/mae223-l20.ipynb. Here is another example: https://pydy.readthedocs.io/en/latest/examples/astrobee.html

JonathanCamargo commented 3 years ago

Thanks for your quick reply. The manual approach works well. As you said, M and F do not have any derivatives. so linearizing the explicit Mx'=F is a fine solution. The method "to_linearizer()" is using fr and frstar instead of the explicit ode (M and F). The derivatives seem to be coming from the f_2 term in the Linearizer object.

moorepants commented 3 years ago

Here's an open issue on sympy: https://github.com/sympy/sympy/issues/20486.