opensim-core
opensim-core copied to clipboard
MATLAB MarkersReference crash when accessing marker values
I'm updating our NMSM Pipeline project to HEAD and found the following issue that crashes MATLAB.
fileName = 'simple_arm.trc';
import org.opensim.modeling.*
markerNames = ["r_humerus1", "r_humerus2", "r_humerus3", "r_radius1", "r_radius2", "r_radius3"];
markerWeightSet = SetMarkerWeights();
for i=1:length(markerNames)
markerWeightSet.cloneAndAppend(MarkerWeight(markerNames(i), 1.0));
end
markersReference = MarkersReference(fileName, markerWeightSet);
markersReference.get_marker_weights(1)
simple_arm.txt I'm using this file for a very simple .trc file (rename .txt to .trc). The trc file works as expected in OpenSim GUI.
For the record, this same API is exercised and tested in C++ here https://github.com/opensim-org/opensim-core/blob/2ef5732554db5671356b0d04364cbcbd4a4e5de8/OpenSim/Simulation/Test/testInverseKinematicsSolver.cpp#L171 but I'll dig into it further
It is a bit hard to see why this line get_marker_weights(1) have ever worked in the past considering the signature of the method SetMarkerWeights get_marker_weights(int i) While ideally we don't crash, the expected API call sequence is to get reference to the Set using get_marker_weights() then call get(i) to retrieve the ith element. I'll leave this issue open as we shouldn't crash but otherwise this seems to be an unexpected use of the API that has been there since 4.0. If I missed something about the context please let me know @CVHammond
Hmm, this is an interesting scenario. So I tried the script above in my 4.0 environment and it runs, albeit as you pointed out, perhaps as an unintended addition to the MATLAB API. The line that actually crashed the project in 4.4 beta but not in 4.0 is ikSolver.getNumMarkersInUse(). I thought involving the InverseKinematicsSolver object could obfuscate the bug. Here is a test case that most closely demonstrates the functionality that we have implemented and works in 4.0. If you have a better way to achieve the end goal of ikSolver.computeCurrentMarkerError(i) I'm all ears.
fileName = 'simple_arm.trc';
modelFileName = "simple_arm.osim";
import org.opensim.modeling.*
model = Model(modelFileName);
state = model.initSystem();
markerNames = ["r_humerus1", "r_humerus2", "r_humerus3", "r_radius1", ...
"r_radius2", "r_radius3"];
markerWeightSet = SetMarkerWeights();
for i=1:length(markerNames)
markerWeightSet.cloneAndAppend(MarkerWeight(markerNames(i), 1.0));
end
% markersReference = MarkersReference(fileName, markerWeightSet); % 4.4 beta
markersReference = MarkersReference(fileName); % 4.0
markersReference.setMarkerWeightSet(markerWeightSet); % 4.0
ikSolver = InverseKinematicsSolver(model, markersReference, ...
SimTKArrayCoordinateReference());
ikSolver.assemble(state);
error = zeros(1, ikSolver.getNumMarkersInUse());
for i=0:ikSolver.getNumMarkersInUse()-1
error(i+1) = ikSolver.computeCurrentMarkerError(i);
end
@CVHammond I'm trying to build a test case to exercise your code but missing the 'simple_arm.osim' model file. This is important since the marker names in trc file must match the names in the model. Please attach the model file here or send it by email. Thank you
Oops, sorry I didn't include it. GitHub doesn't let me submit .osim files, so here is the model as a .txt simple_arm.txt @aymanhab