Hi Chiho Ng,
I've had similar issues with C3D data from Qualisys. I'm not sure what the issue is for your screenshot of the "X" force, but I do know what the issue is in the screenshot on the right: OpenSim's C3D converter calculates center of pressure from the raw force data (I think that's the ground_force_px component you have highlighted; that'd be the X component of the center of pressure) for
all frames of data, even though the center of pressure is undefined when the vertical ground reaction force is undefined. Because center of pressure calculations involve dividing by the vertical ground reaction force (Fy), when Fy is really small you get wild oscillations in the center of pressure, because Fy is oscillating around zero because of noise.
The right way to do it is to first filter the
raw force data (Fx Fy Fz Mx My Mz components as recorded by the origin of the plate), then set a threshold for the vertical ground reaction force (maybe 20 N or something), below which you will set the force to be exactly zero in all components. At these points the CoP is undefined, and you can usually just set it to [0,0,0]. There is some good discussion on this issue at
this GitHub issue.
A few technical points I've learned when grappling with getting Qualisys data into OpenSim:
Something worth pointing out is that it is not necessary to calculate CoP at all, and the best possible approach from a numerical stability perspective is to avoid doing so entirely (
see Ton van den Bogert's comment here). You can just apply the Fx Fy Fz Mx My Mz components to the model, from the origin of the force plate. In practice I still find it more useful to transform the raw force components into Fx Fy Fz CoPx CoPy and Tz (free moment) components because then you can actually visualize them in the OpenSim GUI to make sure they line up with your experimental data. OpenSim's osimC3D matlab function is supposed to support this way of treating the ground reaction force through the
ForceLocation parameter but I couldn't get it to work with my data.
To make sure the QTM data line up with what OpenSim is calculating, you can export the force plate data to a TSV file and compare them to your calculated .mot file. Just disable filtering before you do this, and the calculated CoP should line up exactly with what QTM calculates. Be careful with the "local" vs "global" coordinate export option if you have more than one force plate, or if you have a force plate whose origin is not the lab coordinate origin. Also be careful if the origin of the plate is not at ground level; this need to be taken into account during the CoP calculations.
Young-Hoo Kwon's website is very useful for all of this.
Ajay Seth has said that sometimes setting the CoP to be [0,0,0] during the swing phase of gait can cause issues at initial contact and toe-off because of OpenSim's splining routine. He recommends a trick where the CoP location is linearly interpolated from the last valid force measurement from one step to the CoP location for the first valid force measurement for the next step. By "valid force measurement" here I just mean frames of data where Fy is above your threshold.
I ended up just avoiding C3D exports completely and wrote some custom MATLAB code to go from TSV files exported from QTM to opensim-compatible .mot files. I can share this code with you if you'd like but it's heavily customized for the preprocessing I'm doing, so it has intermediate steps for assigning footstrikes and combining data from multiple force plates. I think the best solution would be to use the functions in the
ezc3d package to extract the raw analog data and preprocess it. What I have in MATLAB works, but is a bit hacky.
Hope this is helpful! Getting GRF data from Qualisys into OpenSim was one of the most challenging parts of moving my analysis to OpenSim.