Vary Inverse Kinematics weights at each time point

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Tylan Templin
Posts: 40
Joined: Mon Jan 15, 2018 10:55 am

Vary Inverse Kinematics weights at each time point

Post by Tylan Templin » Thu Oct 13, 2022 9:48 am

Hello,

I am interested in updating the weights assigned to each marker in IK at every timepoint during a trial using the python API and InverseKinematicsSolver.

My current solution is to update the marker weights in the loop that is calling iksolver.track() for each timepoint. This solution seems to work but requires that I call iksolver.assemble() after changing the weight at each time point which slows down the time to run IK.

Is it possible to instantiate the iksolver with a weights file that changes over time? Or is there a way to update the weights such that you do not need to call the assemble function?

Thanks!

Ty

Tags:

User avatar
Ayman Habib
Posts: 2235
Joined: Fri Apr 01, 2005 12:24 pm

Re: Vary Inverse Kinematics weights at each time point

Post by Ayman Habib » Sun Oct 16, 2022 8:04 pm

Hello,

The documentation suggests that you can call InverseKinematicsSolver's method

Code: Select all

updateMarkerWeight
and the change will take effect next time you call assemble or track
https://simtk.org/api_docs/opensim/api_ ... 6281960df5

Please try this out and let us know if it doesn't work as expected so we can update the documentation.

Best regards,
-Ayman

User avatar
Tylan Templin
Posts: 40
Joined: Mon Jan 15, 2018 10:55 am

Re: Vary Inverse Kinematics weights at each time point

Post by Tylan Templin » Mon Oct 17, 2022 8:20 am

Hi Ayman,

Thank you for the response! I am currently attempting to use UpdateMarkerWeight with the following code:

Code: Select all

ikSolver.assemble(s)
for i in range(self.nFrames):
            # UpdateWeights
            for mark in self.marker_list:
                markweight = self.weight[mark][i] 
                ikSolver.updateMarkerWeight(mark, markweight)
            
            # Set the time
            s.setTime(startTime+i*dt)
            
            # ikSolver.assemble(s)
            
            # Run the iksolver for the time
            ikSolver.track(s)
This code works as written but when I uncomment the line that calls assemble I get an error saying:

'RuntimeError: std::exception in 'void OpenSim::AssemblySolver::track(SimTK::State &)': AssemblySolver::track() failed: assemble() must be called first.'

Should I be able to call track without calling assemble each time?

Thanks!

Ty

User avatar
Ayman Habib
Posts: 2235
Joined: Fri Apr 01, 2005 12:24 pm

Re: Vary Inverse Kinematics weights at each time point

Post by Ayman Habib » Mon Oct 17, 2022 10:10 am

Hi Ty,

Yes, you can (and should try to) call track after the first frame. That's assuming the desired configuration hasn't changed much as described in the doxygen documentation:
https://simtk.org/api_docs/opensim/api_ ... f768536812

Hope this helps,
-Ayman

User avatar
Tylan Templin
Posts: 40
Joined: Mon Jan 15, 2018 10:55 am

Re: Vary Inverse Kinematics weights at each time point

Post by Tylan Templin » Wed Oct 19, 2022 12:52 pm

Hi Ayman,

I am realizing now I misspoke in my last comment. My hope is to only call track (not assemble) after the first frame for all subsequent frames. I am able to do so when I do not make any calls to updateMarkerWeight. However when I do update the marker weight I get the error:

'RuntimeError: std::exception in 'void OpenSim::AssemblySolver::track(SimTK::State &)': AssemblySolver::track() failed: assemble() must be called first.'

When I add in assemble() call the error goes away but the code runs much slower.

Based on the documents you referenced it seems like I shouldn't need to make the assemble() call. Is it possible something changed?

Thanks again,

Ty

POST REPLY