Hello,
I am a researcher in the field of engineering design. My knowledge on multi body dynamics is limited to what is taught in undergraduate lectures. I am using Opensim for virtual ergonomic testing (user-product interaction) which is done employing optimal control. In this context I am interested in linearizing the dynamics of a system with respect to its state an actuating forces around a given trajectory. If x(t) is the state vector of the system and u(t) the vector of actuating forces, I am looking for a representation like: x_dot(t)=A(t)*x(t)+B(t)*u(t) which is a locally linear system. Currently this is done naively with the help of numerical differentiation.
Now I wonder if the partial derivatives of x_dot with respect to x and u can be obtained directly from the multi body system. Numerical differentiation is terribly slow....
I am grateful for every hint.
Best regards, Daniel
Simbody: Linearization of dynamics ?
- Michael Sherman
- Posts: 807
- Joined: Fri Apr 01, 2005 6:05 pm
Re: Simbody: Linearization of dynamics ?
Hi, Daniel. Hopefully someone else will have deeper thoughts on this than me. But here's my 2 cents. I don't know of a way to avoid numerical linearization of the model but you might be able to speed it up by various tricks, including:
Whether these ideas are practical for you will depend on your skill set and also how desperate you are for a faster method! Here's what I have in mind:
Partitioning
OpenSim's kinematic state variables are partitioned into positions q (generalized coordinates) and velocities v (generalized speeds), with qdot=N(q)*v where N is block diagonal, in fact mostly the identity matrix (except for Ball joints and the 6-dof Free connection to ground). So partial(qdot)/partial(v) is N(q), and partial(qdot)/partial(q) is zero except for a few analytically-calculable 3x3 blocks for Balls and Free joints. And partial(qdot)/partial(anything else) is zero. If you could construct your model so that it uses only mobilizers (joints) for which qdot=v (pins, sliders, U-joints, gimbals) then half of the A matrix would be trivial.
Also if some of your inputs u are actually joint torques, then partial(vdot)/partial(u) for those would just be a column of the inverse mass matrix which you can get analytically from OpenSim.
Parallelizing
Since every column of A and B is independent of every other, you can calculate all of them in parallel. You might be able to pick up a 4X or 8X speedup just by running multiple threads.
Approximating
Since adjacent steps usually involve only small configuration changes, the linear system is likely to change slowly so you might only need to relinearize occasionally rather than every step. This could give a substantial speedup; the tricky part is knowing when to relinearize which might take some experimentation. One idea would be to relinearize whenever any joint angle changes by more than some threshold angle.
Regards,
Sherm
P.S. A note on notation: in multibody dynamics it is common to use q for generalized coordinates (positions) and u for generalized speeds (velocities). In controls u often means an input. To avoid confusion I used v above for generalized speeds but in most OpenSim and Simbody documentation you'll see u used to mean generalized speeds. An alternative that might avoid trouble is to use x for control inputs.
- partitioning into easy and hard parts
- parallelizing
- approximating by delaying relinearization
Whether these ideas are practical for you will depend on your skill set and also how desperate you are for a faster method! Here's what I have in mind:
Partitioning
OpenSim's kinematic state variables are partitioned into positions q (generalized coordinates) and velocities v (generalized speeds), with qdot=N(q)*v where N is block diagonal, in fact mostly the identity matrix (except for Ball joints and the 6-dof Free connection to ground). So partial(qdot)/partial(v) is N(q), and partial(qdot)/partial(q) is zero except for a few analytically-calculable 3x3 blocks for Balls and Free joints. And partial(qdot)/partial(anything else) is zero. If you could construct your model so that it uses only mobilizers (joints) for which qdot=v (pins, sliders, U-joints, gimbals) then half of the A matrix would be trivial.
Also if some of your inputs u are actually joint torques, then partial(vdot)/partial(u) for those would just be a column of the inverse mass matrix which you can get analytically from OpenSim.
Parallelizing
Since every column of A and B is independent of every other, you can calculate all of them in parallel. You might be able to pick up a 4X or 8X speedup just by running multiple threads.
Approximating
Since adjacent steps usually involve only small configuration changes, the linear system is likely to change slowly so you might only need to relinearize occasionally rather than every step. This could give a substantial speedup; the tricky part is knowing when to relinearize which might take some experimentation. One idea would be to relinearize whenever any joint angle changes by more than some threshold angle.
Regards,
Sherm
P.S. A note on notation: in multibody dynamics it is common to use q for generalized coordinates (positions) and u for generalized speeds (velocities). In controls u often means an input. To avoid confusion I used v above for generalized speeds but in most OpenSim and Simbody documentation you'll see u used to mean generalized speeds. An alternative that might avoid trouble is to use x for control inputs.