opensim-core
opensim-core copied to clipboard
Maintain support for workflow using `PrescribedController::prescribeControlForActuator()` with model and controller loaded from file
A workflow for PrescribedController
is to load a model with a controller and update a Function
using prescribeControlForActuator()
. Updating the PrescribedContoller
class to use sockets has changed how this use case works, as prescribeControlForActuator()
appends the function to the end of the ControlFunctions
property, which can cause a couple issues (files attached that can be used to replicate these):
- Appending an additional function means that the number of control functions is not equal to the number of socket connectees, throwing here.
- In the case where the
Function
name is already the actuator name, usingprescribeControlForActuator()
with the actuator name will still append anotherFunction
(and nowControlFunctions
will have 2Functions
s of the same name)
PrescribedControllerExample.zip using 4.5-2024-03-11-765d625
A couple of ideas chatted about:
- Relax the check (to allow for more control functions than actuators.
-
prescribeControlForActuator()
could try to use the map to see if an actuator exists and update the associatedFunction
(I'm a little surprised this doesn't happen here, perhaps there's a mix between just using the actuator name vs full path in the map?)
cc @nickbianco
(I'm a little surprised this doesn't happen here, perhaps there's a mix between just using the actuator name vs full path in the map?)
Yes, I think that is the issue. A user could have the label /forceset/soleus_r
in the map, but if they provide the label soleus_r
with a new Function
it will not overwrite the function in ControlFunctions
. We should also clarify in the docs, that while Socket
s generally allow specifying components with the same name as long as they have different paths (i.e., /forceset/actuator
vs /actuator
), PrescribedController
will not since we're still supporting legacy naming behavior here.