I want to analyze, how a certain model behaves with and without external forces. First, I generate a movement without external loads by using the TaskSpace planner https://simtk.org/projects/task-space. I use the TaskBasedTorqueController, which uses CoordinateActuators on each joint to generate the movement. The muscle forces are kept 0 for all muscles in this case. The outputs of this are written to a storage file using the OpenSim::ForceReporter.
To see how external forces change the movement, I load the same model in Matlab and copy all the the CoordinateActuators from the first model in the following way
Code: Select all
% Load the force data from .sto file
storageData = Storage("output/actuator_forces.sto");
% Get the number of states (time points) in the storageData
numStates = storageData.getSize();
% Extract the time data from the storageData
for i = 0:numStates-1
stateVec = storageData.getStateVector(i);
timeData(i+1) = stateVec.getTime();
end
% Get the column labels
labelsArray = storageData.getColumnLabels();
numLabels = labelsArray.getSize();
labels = cell(1, numLabels);
for i = 0:numLabels-1
labels{i+1} = char(labelsArray.get(i));
end
% Create a CoordinateActuator for each force ending in "_control"
% (TaskBasedController) uses this naming for its CoordinateActuators.
% Add all of the actuators to a controller
controlled_actuator_names = []; % list of actuators used by the controller
for i = 1:length(labels)
if endsWith(labels{i}, "_control")
% find corresponding corrdinate
coordName = erase(labels{i}, "_control");
coordinate = model.getCoordinateSet().get(coordName);
% Create a CoordinateActuator for this coordinate
actuator = CoordinateActuator();
actuator.setCoordinate(coordinate);
actuator.setName(labels{i});
actuator.setOptimalForce(1); % TODO: check if this is the correct value (seems like forces get multiplied by this factor)
model.addForce(actuator);
controller.addActuator(actuator)
% add actuator to the list
controlled_actuator_names = [controlled_actuator_names; string(labels{i})];
% initialize actuator forces
controller.prescribeControlForActuator(labels{i}, Constant(0));
end
end
Code: Select all
manager = Manager(model);
manager.initialize(state);
for tIndex = 1:length(timeData)
% Set the time for the state
state.setTime(timeData(tIndex));
% Copy forces from file
for i = 1:length(controlled_actuator_names)
aName = controlled_actuator_names(i);
storageIndexArray = storageData.getColumnIndicesForIdentifier(aName);
if storageIndexArray.size() ~= 1
disp("Warning: found multiple indices for given name. Results may be skewed");
end
% get the index of the column for this actuator in the storage
storageIndex = storageIndexArray(1).getLast() - 1;
forceValue = storageData.getStateVector(tIndex-1).getData().get(storageIndex);
controller.prescribeControlForActuator(aName, Constant(forceValue));
end
% Integrate to the next time step
manager.integrate(timeData(tIndex));
% % Write forces to the storage file
% forceTable = forceReporter.getForcesTable();
% STOFileAdapter.write(forceTable, output_dir + "/actuator_forces_matlab.sto")
end
I have already verified, that the actuator forces are copied correctly from the storage file to the second model. The other model forces (PotentialEnergy and ligament/damping forces) show a big difference to the first model, which (as far as I understand) makes sense, as they result from the movement in the model.
Where is my mistake? Shouldn't the second model show the same movement pattern as the first, if all the Actuators have the same force?
Edit:
One thing I forgot to mention. When copying the actuators, I initialize the force to be 0 in the first time step. As the storage file contains in timesteps of 0.01 seconds, this means that the forces in the first and second model are differing for the first 0.01 seconds, but after this, the same actuator forces are applied to both models. Is this enough to change the movement drastically?