2

I am working with a diagram which includes a MultiBodyPlant with a Propeller connected to it. The Propeller actually realizes numerous physical propellers which are distributed among the bodies of the MultiBodyPlant.

I am able to simulate the dynamics of the combined system by setting the prop forces with FixValue, so I'm on the right track.

What I'd like to be able to do is, given a configuration for the system (i.e. the MultiBodyPlant context) and a chosen propeller command, compute the generalized forces acting on the system. My sense is that this is not immediately available since the simulation is actually using the RNEA, and so does not aggregate the forces all together in that way. For what I'm doing (and even just as a sanity check), I would like to compute the forces directly, not just their effect on the evolution of the state.

Is there an existing method to compute this built into Drake, or should I compute it manually using the spatial jacobian of each propeller frame and the applied SpatialForce of the corresponding propeller? (Something along the lines of this question: How to get the matrix that maps external forces to generalized forces?)

Many thanks for your help.

jwelde
  • 25
  • 3

2 Answers2

1

I understand better now. It's a very reasonable request! You have two systems at play: the Propeller and MultibodyPlant. Unfortunately, the quantity you want is all of Propeller and just a piece of MultibodyPlant. We don't offer direct access to the B(q) matrix in that case.

What you can do is call with either AutoDiffXd or symbolic::Expression, call CalcImplicitTimeDerivativesResidual on the Diagram to get the entire dynamics in implicit form (to avoid taking M(q) inverse). You could call it twice -- once with the Propeller inputs set up via FixValue as AutoDiffXd and/or symbolic::Variable and again with them as zero, then subtract the difference.

Note: CalcImplicitTimeDerivativesResidual is relatively new; I haven't pushed the python bindings for it yet (but it's been on my list). Do you need it from python?

Russ Tedrake
  • 4,703
  • 1
  • 7
  • 10
  • Makes sense, thanks for clearing things up! I was able to compute B(q) by computing J^T f for each prop in the Propeller, which wasn't so hard since I located each of them at a physical joint, so could use CalcJacobianSpatialVelocity directly on the FixedOffset frame associated with the joint. – jwelde Aug 09 '21 at 14:14
  • I would like to try out your other suggestion as well if possible, but yes I am working from Python. If you have the time to push the python bindings when you have a chance that would be awesome :) Being able to compute B(q) symbolically would be especially helpful for my sanity check. I haven't fully understood how symbolics in Drake work yet though, so will need to check into that. Thanks again for your help! – jwelde Aug 09 '21 at 14:15
0

I think that perhaps you are looking for the MultibodyPlant reaction_forces output port?

Russ Tedrake
  • 4,703
  • 1
  • 7
  • 10
  • Thanks for your reply! I'm trying to understand how I would use this to solve my problem. Maybe I'm missing something, but I'm hoping to compute how the propeller commands map to external generalized forces, and it seems to me like this would let me compute the reaction forces on each body also due to e.g. Coriolis effects in the system of articulated bodies. – jwelde Aug 06 '21 at 13:55
  • Just to make sure I'm explaining clearly, let's assume there are no JointActuators in my system, and I'm essentially looking for a way to compute the allocation matrix B in the manipulator equations M(q) v' + C(q,v) v + g(q) = B(q) u, where u are the Propeller commands – jwelde Aug 06 '21 at 15:02
  • I understand if you may not have time to read external references, but the method I'm referring to that I would use to compute this manually is the same as what is described in section 3.5.3 in this text: https://ethz.ch/content/dam/ethz/special-interest/mavt/robotics-n-intelligent-systems/rsl-dam/documents/RobotDynamics2016/RD2016script.pdf but I'm wondering if Drake has this functionality built in already in a way that I can access, or if the efficient implementations avoid ever directly computing this quantity. Thanks again for your help! – jwelde Aug 06 '21 at 15:15