addController made error in calling Manager

The Question and Answer and Support Forum for the 2017 Fall Virtual Workshop.
User avatar
Hide Kimpara
Posts: 135
Joined: Mon Sep 19, 2016 5:12 am

addController made error in calling Manager

Post by Hide Kimpara » Thu Oct 26, 2017 9:22 am

Hello Experts,

I made a simple framework for our simple sample model. But I have still issues.

I have 3 issues.

1) adding actuator into osimModel made an error in calling Manager.
Once I defined a PrescribedController, then I added it with addController method as this:

Code: Select all

osimModel.addController(ActuatorController);
Then I got an error when I call Manager:

Code: Select all

K>> simulationManager = Manager(osimModel);
Java exception occurred:
java.lang.RuntimeException: Component has no underlying System.
You must call initSystem() on the top-level Component (i.e. Model) first.
	In object 'TwoLinkArm' of type Model.
	In file C:\opensim-core-source\OpenSim\Common\Component.cpp:784
	In function 'getStateVariableNames'

	at org.opensim.modeling.opensimSimulationJNI.new_Manager__SWIG_1(Native Method)

	at org.opensim.modeling.Manager.<init>(Manager.java:43)
2) setPropertiesFromState.
As my previous post (viewtopicPhpbb.php?f=1398&t=8360), setPropertiesFromState made serious crash. Only executing this method made MATLAB crash.

3) a series of Reporter belonging Analysis, such as ForceReporter.
Even I could not manage time intervals for ForceReporter, I plan to use it to monitor forces in MATLAB. However, these stored data did not export recorded data into sto files. I am wondering ForceReporter is still storing data in 4.0.

This time, I attach my sample MATLAB codes for convenience.
Your suggestions are very helpful for us.

Thank you,
Hide
Attachments
ForwardOsimFunction_171026.zip
(9.02 KiB) Downloaded 12 times

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: addController made error in calling Manager

Post by Christopher Dembia » Thu Oct 26, 2017 9:35 am

You must call `initSystem()` before constructing the Manager:

Code: Select all

osimModel.initSystem();
simulationManager = Manager(osimModel);
Try using the methods `getForceStorage()`, `getForcesTable()`, or `printResults()` on ForceReporter.

User avatar
Hide Kimpara
Posts: 135
Joined: Mon Sep 19, 2016 5:12 am

Re: addController made error in calling Manager

Post by Hide Kimpara » Thu Oct 26, 2017 10:07 am

Hello Christopher,

Thank you for your suggestion and very prompt response.
chrisdembia wrote:You must call `initSystem()` before constructing the Manager:
Calling 'initSystem()' allowed me to use Manager with addController. I don't know the reason of second calling 'initSystem', but it works!

In the meanwhile, MATLAB has frozen again during the run-time. Then I enforced to exit MATLAB. However, I got another error of Java exception at calling s.getQ, again... In case of this kind error, what is the best solution for recovery?

Code: Select all

Error using main_20171026 (line 117)
Java exception occurred:
java.lang.NoClassDefFoundError: Could not initialize class org.opensim.modeling.Vector

	at org.opensim.modeling.State.getQ(State.java:339)
After recovery, I'd like to try other methods for storage.

Thank you,
Hide

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

Re: addController made error in calling Manager

Post by Ayman Habib » Thu Oct 26, 2017 10:31 am

Hide,

Can you provide the code snippet causing the crash/Exception so we can help?

Thank you,
-Ayman

User avatar
Hide Kimpara
Posts: 135
Joined: Mon Sep 19, 2016 5:12 am

Re: addController made error in calling Manager

Post by Hide Kimpara » Thu Oct 26, 2017 11:11 am

Dear Ayman,

I don't know what is the code snippet in MATLAB. So far, I published "main_20171026.m" and zipped into published_html.zip.
Is it good for seek some error causes?
aymanh wrote: Can you provide the code snippet causing the crash/Exception so we can help?
Thank you,
Hide

published_html.zip
(5.05 KiB) Downloaded 9 times
JavaError.png
JavaError.png (306.24 KiB) Viewed 1097 times

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

Re: addController made error in calling Manager

Post by Ayman Habib » Thu Oct 26, 2017 11:31 am

Hide,

Sorry I didn't expect to see the code in html file but I found it!.

I don't know if the model you have contains constraints but it's probably safer to call
osimModel.realizeVelocity(osimState)

before asking for the Qs and Us.

Ideally you get a meaningful error message but I'm not sure if that gets passed out properly in Matlab.

If you can send the m file instead of html in the future that would be better so we can refer to line numbers.

Please let me know how that goes,
-Ayman

User avatar
Hide Kimpara
Posts: 135
Joined: Mon Sep 19, 2016 5:12 am

Re: addController made error in calling Manager

Post by Hide Kimpara » Thu Oct 26, 2017 12:03 pm

Dear Ayman,

Thank you so much for your suggestion. I will use realizeVelocity method before calling Qs or Us.
aymanh wrote: Sorry I didn't expect to see the code in html file but I found it!.

I don't know if the model you have contains constraints but it's probably safer to call
osimModel.realizeVelocity(osimState)

before asking for the Qs and Us.
The code was already attached on the first post. But in case I past it as raw.

But the Java exception error has not removed even I used realizeVelocity method. I assume a fatal access might break serious part of OpenSim 4.0.
The first time, I found when I used setPropertiesFromState.
Then this time, I got similar error when the MATLAB had too much memory usage(?).

Have you ever had similar error like this?

main_20171026.m (a little changed)

Code: Select all

% ----------------------------------------------------------------------- %
% main_YYYYMMDD.m
%
% Author: Hideyuki Kimpara, Worcester Polytechnic Institute
%
% This code uses the Matlab interface to the OpenSim API to run a trial
% to connect simulink simulator and OpenSim analysis. 
% This example borrows from other Matlab and C++ examples avaiable from
% the OpenSim project written by several people including, but not limited
% to: Brian Umberger and OpenSim team members at Stanford University.
% ----------------------------------------------------------------------- %

clear

% Node and timing information
System_StartTim  = 0.00;
System_End_Time  = 020.00;
System_Frequency = fix(20.);

if System_Frequency < 1
    System_Frequency = 1.;
end


System_timestep = 1./System_Frequency;

System_Num_step = fix((System_End_Time-System_StartTim)*System_Frequency);


% Import the OpenSim modeling classes
import org.opensim.modeling.*

% Create an OpenSim model from an OSIM file
Model_In = ['TwoLinkArmModel.osim'];
osimModel = Model(Model_In);

% Prepare temporary export model file for debug
fileoutpath = [Model_In(1:end-5),'_Monitor_01.osim'];


% Add Analyses to the model: ForceReporter and BodyKinematics 
aActuation = Actuation(osimModel);
aBodyKinematics = BodyKinematics(osimModel);
aForceReporter = ForceReporter(osimModel);
aJointReaction = JointReaction(osimModel);
aKinematics = Kinematics(osimModel);
aStatesReporter = StatesReporter(osimModel);
osimModel.addAnalysis(aActuation);
osimModel.addAnalysis(aBodyKinematics);
osimModel.addAnalysis(aForceReporter);
osimModel.addAnalysis(aJointReaction);
osimModel.addAnalysis(aKinematics);
osimModel.addAnalysis(aStatesReporter);


% Initialize the model (build the system and intialize the state)
osimState = osimModel.initSystem();

% Get the number of states from the model;
% in this case the number of controls equals the number of muscles

kp = 100;
kv = 20;

Num_Cent_Cnt = 2;
CentStruct = struct();
CentStruct.Number = Num_Cent_Cnt;
CentStruct.Cent_val_name = cell(1, Num_Cent_Cnt);
CentStruct.Cent_cor_name = cell(1, Num_Cent_Cnt);
CentStruct.Cent_act_name = cell(1, Num_Cent_Cnt);
CentStruct.ValAd = zeros(1, Num_Cent_Cnt);
CentStruct.Q_des = zeros(1, Num_Cent_Cnt);
CentStruct.U_des = zeros(1, Num_Cent_Cnt);
CentStruct.Q_ini = zeros(1, Num_Cent_Cnt);
CentStruct.U_ini = zeros(1, Num_Cent_Cnt);
CentStruct.ContV = zeros(1, Num_Cent_Cnt);
CentStruct.kp = kp * ones(1, Num_Cent_Cnt);
CentStruct.kv = kv * ones(1, Num_Cent_Cnt);

CentStruct.Cent_cor_name(1,1) = cell({'joint_1'});
CentStruct.Cent_cor_name(1,2) = cell({'joint_2'});
CentStruct.Cent_act_name(1,1) = cell({'joint_1_actuator'});
CentStruct.Cent_act_name(1,2) = cell({'joint_2_actuator'});

CentStruct.Q_des(1,1) =  80. * pi / 180.;
CentStruct.U_des(1,1) =  0.0 * pi / 180.;
CentStruct.Q_des(1,2) = -80. * pi / 180.;
CentStruct.U_des(1,2) =  0.0 * pi / 180.;

Control_Func.time = zeros(1, System_Num_step*2+1);
Control_Func.data = zeros(Num_Cent_Cnt, System_Num_step*2+1);
Control_Func.name = CentStruct.Cent_act_name;
Control_Func.time(1) = System_StartTim;
for i=1:System_Num_step
    Control_Func.time(i*2)   = System_StartTim + System_timestep * (i-1) + System_timestep*0.01;
    Control_Func.time(i*2+1) = System_StartTim + System_timestep * (i);
end

for i=1:Num_Cent_Cnt
    Coord = osimModel.getCoordinateSet().get(CentStruct.Cent_cor_name(1,i));
    CentStruct.Q_ini(1,i) = Coord.getValue(osimState);
    CentStruct.U_ini(1,i) = Coord.getSpeedValue(osimState);
    Coord.setValue(osimState, 0.0);
    Coord.setSpeedValue(osimState, 0.0);
end

% If I need to change initial joint angles, input values here.
CentStruct.Q_ini(1,1) = 90. * pi / 180.;
CentStruct.Q_ini(1,2) = 60. * pi / 180.;

% Solve difference of variable orders between osimModel and osimState.
osimModel.realizeVelocity(osimState);
for i=1:Num_Cent_Cnt
    Coord = osimModel.getCoordinateSet().get(CentStruct.Cent_cor_name(1,i));
    Coord.setValue(osimState, 1.);
    Coord.setSpeedValue(osimState, 10.);
    osimModel.realizeVelocity(osimState);
    tempQ = osimState.getQ;
    tempU = osimState.getU;
    for j=1:size(tempQ)
        if tempU.get(j-1)==10.
            j
            CentStruct.ValAd(1,i) = j;
            break;
        end
    end
    Coord.setValue(osimState, 0.0);
    Coord.setSpeedValue(osimState, 0.0);
    osimState.getQ
end

% Return initial state variables into osimModel.
for i=1:Num_Cent_Cnt
    Coord = osimModel.getCoordinateSet().get(CentStruct.Cent_cor_name(1,i));
    Coord.setValue ( osimState, CentStruct.Q_ini(1,i) );
    Coord.setSpeedValue ( osimState, CentStruct.U_ini(1,i) );
end

JointSet = osimModel.getJointSet();
CoordSet = osimModel.getCoordinateSet();
StateValNames      = osimModel.getStateVariableNames();

InitStruct = struct();
InitStruct.JointSet  = cell(JointSet.getSize,1);
InitStruct.CoordSet  = cell(CoordSet.getSize,1);
InitStruct.StateLabl = cell(StateValNames.getSize,1);
InitStruct.StateVals = zeros(StateValNames.getSize,1);

for i = 1:StateValNames.getSize
    InitStruct.StateLabl(i,1) = cell(StateValNames.getitem(i-1));
end

for i = 1:CoordSet.getSize
    InitStruct.CoordSet(i,1) = cell(CoordSet.get(i-1));
end

for i = 1:JointSet.getSize
    InitStruct.JointSet(i,1) = cell(JointSet.get(i-1));
end




% Parameters to be passed in to the forward function
params.model  = osimModel;
params.state  = osimState;
params.CentSt = CentStruct;
params.Control = Control_Func;

stateStorage = aStatesReporter.getStatesStorage();

% start a timer
tic;

for i = 1:System_Num_step
    time_start = System_StartTim + System_timestep * (i-1);
    time_end = System_StartTim + System_timestep * (i);

    disp(['Cycle [' int2str(i) ']/[' int2str(System_Num_step) '] : Calculating from ' num2str(time_start) ' to ' num2str(time_end)]);

    ForwardOsimFunction_171026(time_start,time_end,params,InitStruct);


    % Use last state variables for next step initial states
    AA = stateStorage.getColumnLabels;
    AB = stateStorage.getLastStateVector().getData;
    for k=1:AB.getSize
        for j = 1:size(InitStruct.StateLabl,1)
           if (strcmp(InitStruct.StateLabl(j),AA.getitem(k)))
               InitStruct.StateVals(j) = AB.getitem(k-1);
           end
        end
    end
    
    clear AA AB;
    
end

clear  stateStorage ;


% stop the timer
runtime = toc;
disp(['The runtime was ' num2str(runtime)]);



% Write out storage files containing the states and excitations
outputpath = '.\Result\';  % use current directory
bufferstamp = char(datetime,'yy_MM_dd-HH_mm');
osimModel.printControlStorage(['SimOut_',bufferstamp,'_excitations.sto']);

% Also write out the results of the analyses to storage files
aActuation.printResults(['SimOut_',bufferstamp],outputpath,0.01,'.sto');
aBodyKinematics.printResults(['SimOut_',bufferstamp],outputpath,0.01,'.sto');
aForceReporter.printResults(['SimOut_',bufferstamp],outputpath,0.01,'.sto');
aJointReaction.printResults(['SimOut_',bufferstamp],outputpath,0.01,'.sto');
aKinematics.printResults(['SimOut_',bufferstamp],outputpath,0.01,'.sto');
aStatesReporter.printResults(['SimOut_',bufferstamp],outputpath,0.01,'.sto');
aStatesReporter.printResults(['SimOut_',bufferstamp],'.\.',-1,'.sto');



% Reset the analyses so everything starts fresh for the next
% call to this function
aActuation.getForceStorage.reset(0);
aActuation.getPowerStorage.reset(0);
aActuation.getSpeedStorage.reset(0);
aBodyKinematics.getPositionStorage.reset(0);
aBodyKinematics.getVelocityStorage.reset(0);
aBodyKinematics.getAccelerationStorage.reset(0);
aForceReporter.getForceStorage.reset(0);
aKinematics.getAccelerationStorage.reset(0);
aKinematics.getPositionStorage.reset(0);
aKinematics.getVelocityStorage.reset(0);
aStatesReporter.getStatesStorage.reset(0);
Java_Error2.png
Java_Error2.png (309.29 KiB) Viewed 1085 times

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

Re: addController made error in calling Manager

Post by Ayman Habib » Thu Oct 26, 2017 1:55 pm

Hide,

I had no problem loading the model, setting Coordinate (Value, SpeedValue) and then calling getQ, getU.

This suggests that there's nothing fundamentally wrong with your API usage, I just didn't follow your book-keeping to keep names in cells etc.

In fact I just stepped through your code as provided below and had no crashes or exceptions until I called
ForwardOsimFunction_171026(time_start,time_end,params,InitStruct); which I don't think is related.

-Ayman

User avatar
Thomas Uchida
Posts: 1793
Joined: Wed May 16, 2012 11:40 am

Re: addController made error in calling Manager

Post by Thomas Uchida » Thu Oct 26, 2017 2:04 pm

I think the line

Code: Select all

if (strcmp(InitStruct.StateLabl(j),AA.getitem(k)))
needs to be

Code: Select all

if (strcmp(InitStruct.StateLabl(j),AA.getitem(k-1)))

User avatar
Hide Kimpara
Posts: 135
Joined: Mon Sep 19, 2016 5:12 am

Re: addController made error in calling Manager

Post by Hide Kimpara » Thu Oct 26, 2017 4:03 pm

Hello Ayman,

Thank you so much for taking your time. I feel happy that main_YYYYMMDD.m has no significant errors in current.


Hello Tom,

Thank you for notification. I checked the stateStorage.getColumnLabels. Since this labels start by "time" and name of state variables follows. Therefore, getitem(k) can work in this case.


Thank you and Best regards,
Hide

POST REPLY