Hello,
I am trying to create a custom controller in python, and I had no luck going through the forum so far.
I have compiled opensim 4 with the python wrapper and the example file "build_simple_arm_model.py" runs fine, it uses a prescribed controller with a stepfunction on over 2 seconds that gadually increases the excitation to its maximum.
I would like to use a probe or reporter to get the information on a specific muscle at each step, and then calculate an excitation to send back to the muscle.
I have seen the tutorial "creating a controller" in the documentation but am unable to do this in python:
do you know any example creating a custom controller?
Thank you
python custom controller
- Andrew Stolin
- Posts: 12
- Joined: Thu Mar 05, 2015 9:41 am
- Christopher Dembia
- Posts: 506
- Joined: Fri Oct 12, 2012 4:09 pm
Re: python custom controller
Our existing examples for creating controllers are for C++. Typically, defining a custom controller means creating a C++ class that derives from OpenSim's Controller class. You cannot currently create new OpenSim components in Python.
As a workaround, you could integrate forward a small amount of time (e.g., 1ms), compute controls, set them with, `model.setDefaultControls()`, and start integrating again.
As a workaround, you could integrate forward a small amount of time (e.g., 1ms), compute controls, set them with, `model.setDefaultControls()`, and start integrating again.
- Christopher Dembia
- Posts: 506
- Joined: Fri Oct 12, 2012 4:09 pm
Re: python custom controller
Ayman mentioned to me that you may be able to create a Controller subclass in Python if you add the following line in the appropriate place in the SWIG interface files (and rebuild the bindings):
Here's an example of where we've used the SWIG director feature: https://github.com/opensim-org/opensim- ... tors.i#L21
You may want to read the SWIG documentation about the director feature.
Code: Select all
%feature("director") OpenSim::Controller;
You may want to read the SWIG documentation about the director feature.
- Andrew Stolin
- Posts: 12
- Joined: Thu Mar 05, 2015 9:41 am
Re: python custom controller
Christopher, thank you very much for your answer. I will update this post as soon as possible
- Andrew Stolin
- Posts: 12
- Joined: Thu Mar 05, 2015 9:41 am
Re: python custom controller
I am struggling here as I am missing a few key pieces to make sense of all this. So the small forward integration goes like this :
And we can get the state of activation and excitation of the muscle after the integration
As you suggested, setting the controls with arm.setDefaultControls :
1st option:
setActivation works
setExcitation (which is what I am interested about) does not have any effect:
2nd option:
Or, in order to have all the controls, I see in the API (html_developer/classOpenSim_1_1ControlSet.html#details) that in python we have to use the cObj = ControlSet.safeDownCast(obj).
which does not work either.
I have seen in opensim-rl (https://github.com/stanfordnmbl/osim-rl ... nv/osim.py) that they use a prescribeControlForActuator with a Constant instead of a stepfunction :
Then actualise the controller with the content of getControllerSet, and change the value of the prescribedcontroller, before re-integrating. I tried:
It runs however I am not confident that the second integration is in continuity with the first one (that the controls do not reset), and that they are all based on arbitrary excitations (0.5 then 1).
Would you be able to confirm this?
I will try later on to spend some time learning how to create a custom controller by rebuilding the bindings as you suggested
Many thanks in advance
Code: Select all
manager = osim.Manager(arm)
state.setTime(0)
manager.initialize(state)
state = manager.integrate(0.1)
Code: Select all
print(biceps.getActivation(state))
print(biceps.getExcitation(state))
1st option:
setActivation works
Code: Select all
biceps.setActivation(state, 0.1111111111111111))
Code: Select all
biceps.setExcitation(state, 0.1111111111111111)
Or, in order to have all the controls, I see in the API (html_developer/classOpenSim_1_1ControlSet.html#details) that in python we have to use the cObj = ControlSet.safeDownCast(obj).
Code: Select all
cObj = osim.ControlSet.safeDownCast(biceps)
arm.setDefaultControls(cObj)
I have seen in opensim-rl (https://github.com/stanfordnmbl/osim-rl ... nv/osim.py) that they use a prescribeControlForActuator with a Constant instead of a stepfunction :
Code: Select all
func = osim.Constant(1.0)
brain.prescribeControlForActuator("biceps", func)
Code: Select all
brain = osim.PrescribedController.safeDownCast(arm.getControllerSet().get(0))
func.setValue( float(1) ) # arbitrary value
arm.initializeState()
state.setTime(0)
state = manager.integrate(1.0)
Would you be able to confirm this?
I will try later on to spend some time learning how to create a custom controller by rebuilding the bindings as you suggested
Many thanks in advance
- Attachments
-
- test_controller.py.txt
- (6.71 KiB) Downloaded 36 times