I was happy to see that OpenSim 4.2 now includes ezc3d, but Matlab crashes when I try to read a C3D file.
It crashes on on line 68 in osimC3D.m: tables = c3dAdapter.read(path2c3d);
The Matlab and Java crash reports are attached. This was with Matlab R2020a on Windows. I also did a clean install of Matlab R2021a and the same thing happens.
Before installing OpenSim 4.2, I was already working with the ezc3d toolbox and it was working fine on its own. To prevent conflicts, I removed it completely (including all previously installed copies of ezc3d.dll) to make sure that it only uses the ezc3d from OpenSim 4.2. And indeed it seems to do that:
>> !where ezc3d.dll
C:\OpenSim 4.2\bin\ezc3d.dll
>>
OpenSim 4.2\bin is the first folder in my Windows path.
Any idea how to get this working?
As a workaround, I can go back to using the ezc3d toolbox outside of the OpenSim API, but I prefer to do it through OpenSim.
Ton van den Bogert
OpenSim 4.2: Matlab crash when reading C3D
- Ton van den Bogert
- Posts: 164
- Joined: Thu Apr 27, 2006 11:37 am
OpenSim 4.2: Matlab crash when reading C3D
- Attachments
-
- Mathworks Crash Reporter.txt
- (48.01 KiB) Downloaded 12 times
-
- hs_error_pid18596.log
- (43.9 KiB) Downloaded 10 times
Tags:
- Ayman Habib
- Posts: 2238
- Joined: Fri Apr 01, 2005 12:24 pm
Re: OpenSim 4.2: Matlab crash when reading C3D
Hello Ton,
We execute very similar call sequence in our test suite here
https://github.com/opensim-org/opensim- ... er.java#L6
Could it be that the file path for the C3D file is problematic, or that the version embedded in OpenSim 4.2 is a bit older than the one you were using independently and so can't handle the reading? I'd try to isolate the problem by reading a small c3d file placed near the top of the directory structure, then move from there. An example file is located here: https://github.com/opensim-org/opensim- ... sts/shared
Please let us know what you find out, as osimC3D is not regularly included in our test suite but we're in the process of adding it in.
Best regards,
-Ayman
We execute very similar call sequence in our test suite here
https://github.com/opensim-org/opensim- ... er.java#L6
Could it be that the file path for the C3D file is problematic, or that the version embedded in OpenSim 4.2 is a bit older than the one you were using independently and so can't handle the reading? I'd try to isolate the problem by reading a small c3d file placed near the top of the directory structure, then move from there. An example file is located here: https://github.com/opensim-org/opensim- ... sts/shared
Please let us know what you find out, as osimC3D is not regularly included in our test suite but we're in the process of adding it in.
Best regards,
-Ayman
- Ton van den Bogert
- Posts: 164
- Joined: Thu Apr 27, 2006 11:37 am
Re: OpenSim 4.2: Matlab crash when reading C3D
Ayman,
Thanks for the quick response.
I downloaded walking2.c3d and no crashing happens with that one, no matter where I place it.
So it's my file that is the problem. We export C3D files from Cortex (Motion Analysis Corp.).
In case you need to test this, the (33 MB) file is here: https://drive.google.com/file/d/13uH67i ... sp=sharing.
The current version of ezc3d (which I built from source 2-3 weeks ago) can read this file without problems.
I tried putting my own ezc3d.dll in the opensim bin folder but that crashes also.
In the meantime I will just use ezc3d outside of the OpenSim API.
Ton
Thanks for the quick response.
I downloaded walking2.c3d and no crashing happens with that one, no matter where I place it.
So it's my file that is the problem. We export C3D files from Cortex (Motion Analysis Corp.).
In case you need to test this, the (33 MB) file is here: https://drive.google.com/file/d/13uH67i ... sp=sharing.
The current version of ezc3d (which I built from source 2-3 weeks ago) can read this file without problems.
I tried putting my own ezc3d.dll in the opensim bin folder but that crashes also.
In the meantime I will just use ezc3d outside of the OpenSim API.
Ton
- Benjamin Michaud
- Posts: 31
- Joined: Mon May 03, 2010 6:35 am
Re: OpenSim 4.2: Matlab crash when reading C3D
Dear Ton and Ayman,
I have had a look at the provided file and found that the reason it fails is because Motion Analyses did not provide a calibration matrix (the parameter is present in the C3D, but is completely empty). Since I did not face this problem before, it was not taken into account in ezc3d. I've pushed a fix (Release1.4.3). Also I PR the new version to opensim!
I suspect the reason Ton did not experience the bug is because you probably did not extract the force platforms while opensim does it by default.
Ton, if you compile ezc3d with the latest version and replace the dll as you did before, it should work![Smile :)](./images/smilies/icon_e_smile.gif)
I have had a look at the provided file and found that the reason it fails is because Motion Analyses did not provide a calibration matrix (the parameter is present in the C3D, but is completely empty). Since I did not face this problem before, it was not taken into account in ezc3d. I've pushed a fix (Release1.4.3). Also I PR the new version to opensim!
I suspect the reason Ton did not experience the bug is because you probably did not extract the force platforms while opensim does it by default.
Ton, if you compile ezc3d with the latest version and replace the dll as you did before, it should work
![Smile :)](./images/smilies/icon_e_smile.gif)
- Ton van den Bogert
- Posts: 164
- Joined: Thu Apr 27, 2006 11:37 am
Re: OpenSim 4.2: Matlab crash when reading C3D
Benjamin,
Thanks, that explains it perfectly and your fix worked!
For some reason, our force plate data is in the analog section of the C3D file, and the previous OpenSim C3D reader somehow figured that out and gave us the the forces. Now it has the same behavior again which is good.
I will still use the MEX version of ezc3d, though, because it is quite a bit faster than with the OpenSim API. Our files are large, so it makes a difference. Here are the timings for reading the 90-second C3D with 47 markers at 100 fps and 77 analog channels at 1000 Hz:
ezc3dRead.mexw64: 1.2 seconds
OpenSim 4.2 (ezc3d): 8-10 seconds
OpenSim 4.1 (BTK): 5-10 minutes
In the MEX version, I don't see any force plate data still, but I can get it from the analog channels instead (see code below). A sign change is needed to get a positive vertical GRF.
Ton
Thanks, that explains it perfectly and your fix worked!
For some reason, our force plate data is in the analog section of the C3D file, and the previous OpenSim C3D reader somehow figured that out and gave us the the forces. Now it has the same behavior again which is good.
I will still use the MEX version of ezc3d, though, because it is quite a bit faster than with the OpenSim API. Our files are large, so it makes a difference. Here are the timings for reading the 90-second C3D with 47 markers at 100 fps and 77 analog channels at 1000 Hz:
ezc3dRead.mexw64: 1.2 seconds
OpenSim 4.2 (ezc3d): 8-10 seconds
OpenSim 4.1 (BTK): 5-10 minutes
In the MEX version, I don't see any force plate data still, but I can get it from the analog channels instead (see code below). A sign change is needed to get a positive vertical GRF.
Ton
Code: Select all
% read the C3D file with the ezc3d toolbox, if it is installed
tic;
if which('ezc3dRead')
fprintf('Reading %s...\n (will take 1-2 seconds for a 90-second trial)...\n', c3d_filename);
c3d = ezc3dRead(c3d_filename);
c3dMarkerNames = c3d.parameters.POINT.LABELS.DATA;
c3dMarkerData = 0.001 * c3d.data.points; % convert from mm to m
c3dFy = -c3d.data.analogs(:,[3 9]); % vertical force in force plate 1 and 2
else
% ezc3d not installed, so use Opensim
import org.opensim.modeling.*
fprintf('Reading %s...\n (will take 8-10 seconds for a 90-second trial)...\n', c3d_filename);
c3d = osimC3D(c3d_filename,0);
[markerStruct, forceStruct] = c3d.getAsStructs();
c3dMarkerNames = fieldnames(markerStruct);
c3dMarkerNames = c3dMarkerNames(1:end-1); % remove the last one, which is time
for i = 1:numel(c3dMarkerNames)
c3dMarkerdata(:,i,:) = 0.001 * markerStruct.(c3dMarkerNames{i})';
end
% extract the two vertical forces
c3dFy = [forceStruct.f1(:,2) forceStruct.f2(:,2)];
end
fprintf('...it took %.1f seconds\n',toc);
- Benjamin Michaud
- Posts: 31
- Joined: Mon May 03, 2010 6:35 am
Re: OpenSim 4.2: Matlab crash when reading C3D
Hi Ton!
First, I am pleased to see this amazing improvement in loading time. The small C3D files are not long enough to load so I never had the chance to really see the difference with BTK![Smile :)](./images/smilies/icon_e_smile.gif)
I do not want to pollute the OpenSim forum, but I can still answer your question (because it is a short answer)
The C3D format only has POINTS and ANALOGS has data type. So the force platforms are always stored in ANALOGS. That said, the force platforms specs are also stored in the C3D file parameters. This means that it is possible to dynamically analyze the ANALOGS and format them for the user (that is, mostly, projecting the data into the global reference frame). Ezc3d can indeed do that too in Matlab, you just have to have two outputs when you call the read function :
`c3d, forcePlatforms = ezc3dRead('your_nice_c3d_file.c3d');`
Like that you don't have to worry about the orientation and position of the force platforms, since they are reoriented for you (by making the assumption that the force platforms are on the floor)
Thanks for your feedback!
First, I am pleased to see this amazing improvement in loading time. The small C3D files are not long enough to load so I never had the chance to really see the difference with BTK
![Smile :)](./images/smilies/icon_e_smile.gif)
I do not want to pollute the OpenSim forum, but I can still answer your question (because it is a short answer)
The C3D format only has POINTS and ANALOGS has data type. So the force platforms are always stored in ANALOGS. That said, the force platforms specs are also stored in the C3D file parameters. This means that it is possible to dynamically analyze the ANALOGS and format them for the user (that is, mostly, projecting the data into the global reference frame). Ezc3d can indeed do that too in Matlab, you just have to have two outputs when you call the read function :
`c3d, forcePlatforms = ezc3dRead('your_nice_c3d_file.c3d');`
Like that you don't have to worry about the orientation and position of the force platforms, since they are reoriented for you (by making the assumption that the force platforms are on the floor)
Thanks for your feedback!