Search code examples
drake

Recursion Error while evaluating contact information


I am trying to access the contact information of the plant as below, by declaring an AbstractInputPort following this comment.

self.DeclareAbstractInputPort('contact_force', AbstractValue.Make(ContactResults()))

Then I an trying to access the actual contact information from the declared input port (2) using,

contact_info = self.EvalAbstractInput(context, 2).get_value()

However, I get a RecursionError: maximum recursion depth exceeded, whenever I try to simulate the system.

Any idea what's going wrong?


Edit

Trying to evaluate the method outside the simulation loop by,

contact_info = plant.get_contact_results_output_port().Eval(plant_context)

returns expected results when querying for i^th contact force using,

contact_info.point_pair_contact_info(i).contact_force()

My simulation setup requires computing the contact force at each instant during the simulation. I have a custom system which has an abstract input port declared as mentioned above. The input port is then connected to get contact results by,

builder.Connect(plant.get_contact_results_output_port(), my_system.get_input_port(2))

Now, while trying to extract the value within my_system using get_value() as above, I get the recursion error.

Is the port I use to obtain contact results correct? Or is there a another way to get contact results during simulation?


Solution

  • Posting the solution provided in this comment as the answer for clarity.

    As mentioned, the contact force is an input into the simulation and are a "direct feedthrough", forming an algebraic loop (Have a look at this for a Matlab reference).

    The solution is to simply add a ZeroOrderHold as suggested:

    zoh = builder.AddSystem(ZeroOrderHold(time_step, AbstractValue.Make(ContactResults())))
    builder.Connect(plant.get_contact_results_output_port(), zoh.get_input_port())
    builder.Connect(zoh.get_output_port(), my_system.get_input_port())
    

    A corresponding GitHub issue is also linked in the comment.