openma / openma Goto Github PK
View Code? Open in Web Editor NEWLibrary to explore, process, and analyze movement acquisition data
License: Other
Library to explore, process, and analyze movement acquisition data
License: Other
I got this warning in the mokka logger :
2016-10-05 22:56:12 - Unknown unit. Impossible to scale correctly the data in the 3D views
when i create a c3d from scratch :
root = ma.Node('root') trial = ma.Trial('my_analysis',root) trial.setProperty('MY_GROUP:MY_PARAMETER',10.0) angle = ma.TimeSequence('LHipAngles.Left', 4, 101, 1.0, 0.0, ma.TimeSequence.Type_Angle, 'deg', trial.timeSequences()) angle.setData(np.random.rand(101,4)) ma.io.write(root,"test.c3d")
This binding must work with Python 2.7 and possibly with Python 3.
The length for the following segments is missing:
look inside this c3d.
generally, i identify kinetics cycle through general events.
At frame 253, i have defined both foot strike and general event.
I am surprised event.times are different when i called the convenient openMA event method.
cheers
Fabien
Currently, only the joint kinetics for the lower limbs is computed. Is interesting to add the computation of the upper limbs? The computation for each kind of limbs (upper and lower) could enabled and disabled.
Note: This is related to the question posted on the forum: What kind of post-processing would be done on joint kinetics with a loading but no force plate?. You can discuss in this issue, but it is advised to answer directly in the forum.
Briefly, joint kinetics computed during loading phase without force plates should be set to invalid. But in which way to do it?
After the implementations of issues #31 and #32, the definition of these probes could be something like the following lines:
new JointEulerProbe("L.Hip.Angle", EulerDescriptor::YXZ, {{-1.,-1.,-1.}}, jnt);
new JointKineticsProbe("L.Hip.Kinetics", "L.Hip", {{0,1,2,1,0,2,0,1,2}}, {{1.,1.,1.,1.,1.,1.,1.,1.,-1.}}, jnt);
Still the API looks not clear about the usage of the axes orders and the scaling. Instead it is proposed to replace the static arrays in the EulerDescriptor
class (i.e. XYZ
etc). by a new class with static method. For example, the previous class can be replaced by
new JointEulerProbe("L.Hip.Angle", AxesOrder::xyz{-1.,-1.,-1.}, jnt);
new JointKineticsProbe("L.Hip.Kinetics", "L.Hip", AxesOrder::xyz{}, AxesOrder::yxz{}, AxesOrder::xyz{1.,1.,-1.}, jnt);
The same class explains the Euler sequence to use for the joint angles but also the storage order for the joint kinetics (force, moment, power). The content of the constructor of this classe correspond to scale factors for each axis (usually 1. and -1. to take the opposite for clinical interpretation).
Might be worth to compute the joint Moment contribution for CGA.
a joint moment can be splited as follow ๐
the foot pitch angle is an absolute angle assessing heel rise.
the woltring processions known as GCSV
https://isbweb.org/resources/software-resources/137-signal-processing-software
is a method used in some nexus for either filtering your data or computing linear velocity/acceleration.
So as to be closed Vicon pipeline output, it should be great openMA embeds this method,
cheers
Based on the entry What is the Plug-in Gait 'Progression Frame' and how is it used, the computation of the progression direction is different in case the distance between the first and last frame is less than 800mm.
It seems not necessary to store the file extension in the trial's name.
Currently, the class ma::body:: InverseDynamicsMatrix
uses central/forward/backward methods to compute 1st and 2nd derivate with a 2nd order of accuracy. However, other methods can be used for that (central method + mirroring on the boundaries, cascaded 1st derivate), The possibility to choose the finite derivate method will help to validate the inverse dynamic part. Indeed, no reference data correspond to the implementation of the class ma::body:: InverseDynamicsMatrix
.
If the helper class ma::body::PluginGait
is calibrated several times, several relative ma::body::ReferenceFrame
objects are created instead of being replaced. Thus, the new relative objects are never used.
The noun descriptor is not well adapted as its definition is (from merriam-webster)
something (as a word or characteristic feature) that serves to describe or identify; especially : a word or phrase (as an index term) used to identify an item (as a subject or document) in an information retrieval system
Instead the noun probe might be better. From merriam-webster:
a careful examination or investigation of something
The noun probe is also used by the project OpenSim.
A node object should have a setProperties method so as to input a list of data instead of to add them though SetProperty.
There is no way to access to the geometry of the force plate nor the computed wrenches in the language bindings.
No warnings come up if extract_kinetics run without gravity vectors and mass within subject properties
The current code assumes that the vertical axis is always the Z-axis in the Plug-in Gait Model. The implementation of a ma::LaboratorySettings
as discussed in the issue #16 should fix the problem.
whereas addParent exist, the node s method addChildren doas exist yet.
This method should exist, shouldn t you ?
The code is available but was not tested nor validated.
All the reverse-engineering work was realized in an old branch of the project Biomechanical ToolKit. This code must be translated to OpenMA and verified against original results.
Few improvements are necessary to generate the content of an empty C3D file from scratch.
Note : The issue #23 is related.
In case of we want extract only Moment from a trial, i suggest to alter the statement :
kineticAnalysis.findChildren(ma.T_TimeSequence ,".*",[["type",ma.TimeSequence.Type_Moment]])
by a quite simple method :
kineticAnalysis.findChildren(ma.T_TimeSequence ,ma.TimeSequence.Type_Moment)
Curiously
i get Spine Angless although my code called a lower limb PIG:
ma.body.PluginGait(ma.body.Region_Lower, ma.body.Side_Both)
Some joint centres are defined using formula (i.e hip joint centre, shoulder joint centre, lumbar joint centre). Currently, these definitions are hardcoded in the skeleton helper (e.g. ma::body::PluginGait
) and it is only possible to pass a ma::body::Point
to create a custom centre.This needs to be improved by creating external classes corresponding to joint centre definition published in the literature.
The FORCE_PLATFORM:ZERO parameter can be used to provide a range of frames where the force plate is unloaded and that can be used to determine a zero baseline for each plate, see here.
As many force plates output some residual force values even after zeroing the amplifier, it would be useful if OpenMA could read the frame numbers and apply them accordingly.
No baseline subtraction should be performed if the parameter does not exist or is set to an array containing [0,0].
The bindings use a reference counting mechanism to determine the lifetime of an object. This helps to know if an object is linked to a variable. If this is the case, the latest parent in the internal C++ must not delete this object.
However, the current implementation in SWIG is not enough. The following code crashes as the reference counter did not increase correctly
% This code crashes when the command 'clear all' is used or it is called in a function.
% The reason is because the landmark translator is added internally to the models
% but its is not increased
staticTrials = ma.io.read('myfile1.c3d');
motionTrials = ma.io.read('myfile1.c3d');
translator = ma.body.LandmarksTranslator('CGM', {...}, helper); % MISSING TRANSLATIONS INTENDED
helper = ma.body.PluginGait(ma.body.Region_Full,ma.body.Side_Both);
ma.body.calibrate(helper, staticTrials);
models1 = ma.body.reconstruct(helper, staticTrials);
models2 = ma.body.reconstruct(helper, motionTrials);
% Crash due to the next line
models3 = ma.body.reconstruct(helper, motionTrials);
Of course, we can specify which wrapped methods take the ownership of a node in SWIG. However, this must be done manually for each method. This is too much unreliable and easily forgettable.
In consequence a new reference counting mechanism must be implemented called directly at the core level and not the SWIG level.
The deletion has be applied also on the associated joint (and chain?).
Moreover, this is model definition dependent. If the relative segment needs informations from ancestors that is deleted, it should be deleted too.
For example:
The goal of the ma::body::Joint
class is to define a link between two ma::body::Segment
objects. For that, two ma::body::Anchor
objects (one for each segment) are used to define the location of the joint. The following lines show the definition of a joint.
// The joint is defined between the segments pelvis and leftThigh
// The location of the joint is at the point L.HJC defined by the pelvis for both anchor
jnt = new Joint("L.Hip", pelvis, Anchor::point("L.HJC"), leftThigh, Anchor::point("L.HJC", pelvis), joints);
The problem with this behaviour is there is no reference frame associated with each extremity of the joint. Instead, they are chosen independently depending of the definition of the model (for example ma::body::EulerDescriptor
ma::body::JointEulerProbe
. This behaviour is complex to understand and requires to correctly set the name of the reference frames to use. Several indirect links needs to be done to find the good objects.
It is proposed to redesign the definition of a joint to be linked directly to reference frames instead of segments. This gives several advantages when designing a model. Moreover, it removes some steps to compute joint kinematics and kinetics. The new code could be for example
// The joint is defined between the segment coordinate system of the pelvis and leftThigh
// The location of the joint is at the point L.HJC defined by the pelvis for both anchor
// The anchor will come the children of the joint
jnt = new Joint("L.Hip",
new Anchor("L.Hip.Anchor.Prox", pelvisSCS, pelvisLeftHJC),
new Anchor("L.Hip.Anchor.Dist", leftThighSCS, pelvisLeftHJC),
joints);
The new design attaches directly the reference frame of interest as well as the location. This means that when the model is setup all the relative elements (reference frame and position) has to be defined.
Graphically, the new behaviour should look like the following figure.
Hi! I'm having some trouble building OpenMA. After successfully configuring a base build with CMake (3.7.1), and running make (GNU Make 4.1), it continuously finds fabs and isnan out of scope. I'm solving it by adding #include <cmath>
and changing isnan by std::isnan each time, but this is clearly not the right way to do this. What am I missing here?
uname -a
Linux DEBIAN-MARCOS 4.8.0-2-amd64 #1 SMP Debian 4.8.11-1 (2016-12-02) x86_64 GNU/Linux
gcc --version
gcc (Debian 6.2.1-5) 6.2.1 20161124
Currently it is possible to downsample a math::XprBase
expression with an integer ratio by taking only a sample every ratio samples. However, this is not complete to create a decimation by an integer factor.
In general, it will be more interesting to implement a resampling function to be able to downsample and upsample a signal. As mentioned in this post, this resampling function would use a method similar to the resample function proposed in Scipy.
Currently, these methods give access to a block of the values (i.e. a Eigen::Block
template expression).
This class compute joint forces, moments and power in a specific reference frame. This class might do too many operations and need to be split.
It might be better to separate some computation into children descriptors probes. For example, the class DynamicDescriptor
can be replaced by the class JointKineticsProbe
. This class will define children. Each of them will compute a specific component (i.e. force, moment and power). The classes for these children could be:
JointForceProbe
JointMomentProbe
JointPowerProbe
Important: This means that the Probe
class has to implement a generic processing mechanism to look for children and update them.
The class EulerDescriptor
is able to compute Euler angles for joint and segment. Instead two classes should be created:
JointEulerProbe
SegmentEulerProbe
impossible to use findChild with custom object inherit from node.
The oxford foot model is a wide spread model of the foot. It should be implemented in openMA.
A v3d doc can be used as guideline.
The line 70 in the file dempstertable.cpp should not only create and set a new ma::body::InertialParameters
object but instead update an existing one.
This problem might be also true for other tables.
Currently the gravity must be set for eachma::body::SkeletonHelper
object as a property. This could be improved and simplified. As already commented for the issue #16, the implementation of the class ma::LaboratorySettings
would be a good way to set the gravity and store supplementary information on the experiment setup.
i want to add openMA time sequence to a c3d aleready including vicon model outputs
The attached code works fine. But Mokka fails to open it.
If i remove all model outputs from my gait c3d, then i can open it in Mokka.
Currently, OpenMA stores units as strings for time sequences and assumes them for other objects (like force plate geometry). This gives virtually the possibility to store any kind of units. However, the major draw back is that people can mix data with different units (e.g. markers with coordinates in millimeters and meters). The problem is worst for algorithms that need to know inputs' unit to correctly set outputs' unit (e.g. moment units from force units and distance units). The question is how to have a generic storage unit (e.g. for position, forces, acceleration, moment, power, etc.) but ensure it will not wrongly influence computation.
It is proposed to keep only one kind of unit by physical quantity. Internally, this will simplify the checking of data as well as the creation of new time sequences. However, this means that each data stored within OpenMA objects must be converted (scales) to fit with the units used by OpenMA (i.e. file format, data entered manually).
If this is accepted, what should be the units to be used? The International System of Quantities might be the best choice. If users prefer their outputs to a different format, they will have to scale them in consequence.
This post on the OpenMA forum mentioned an issue with the loading of the EMG data with BTK. This needs to be fixed in OpenMA. Some data are requested to improve the parser.
In case a model is set as a ma::body::Region::Full
, the computation of the total center of mass should be proposed (or automatically done during the computation of the inverse dynamics). The projection on the ground might also be done at the same time.
This issue is related to SWIG and need to be corrected upstream: https://github.com/jaeandersson/swig.
Even if its not a priority right now, this could prove really handy for newcomers such as myself. This could include some project manager's tips on how they set up their own environments, IDEs they use (if any) and such.
There is currently two implementations in conflict in the code. Most of the modules were updated. The work still to be done for the ma::body module.
The parsers in the BTK project is a good start to implement the parsers of the Elite file formats.
Compared to BTK, OpenMA will manage all the Elite file in the same plugin with one handler by file format. The data provided in the project BTKData will be used for the validation (see the subfolder EliteSamples). However, these data came from 2010. New data would be necessary to verify that BTS does or does not change their file format (see issue #47).
Thigh offset, shank offset and tibialRotation angle are optional parameter , they can get closer the model with anatomy.
These parameters are calculated during static calibration with the Knee Aligmenent device.
Well established gait labs use the KAD :-)
In consequence,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.