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?
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?
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.