|
a |
|
b/Docs/anymocap/grf-prediction.md |
|
|
1 |
# Ground Reaction force prediction |
|
|
2 |
|
|
|
3 |
## Background |
|
|
4 |
|
|
|
5 |
Motion capture data is often recorded without force plates. In traditional |
|
|
6 |
inverse dynamics, this would make it impossible to perform a dynamic analysis. |
|
|
7 |
However, AnyBody has the possibility to predict ground reaction forces (GRF), so |
|
|
8 |
you can make inverse dynamics models based on recorded motion without GRF force |
|
|
9 |
measurement (Fluit et al., 2014; Jung et al., 2014). |
|
|
10 |
|
|
|
11 |
GRF prediction relies on conditional contacts added to the feet of the model. |
|
|
12 |
The conditional contacts work as force actuators to generate the normal and |
|
|
13 |
frictional forces necessary to balance model. Mathematically, the actuators are |
|
|
14 |
modeled similarly to muscles, and the muscle recruitment optimization determines |
|
|
15 |
the contact forces. The effect is that the model will utilize the ground |
|
|
16 |
reactions if that can minimize the muscle activity. |
|
|
17 |
|
|
|
18 |
Adding conditional contacts to a model can be rather complex, but we have |
|
|
19 |
created an AnyScript class template that makes the process much easier. The |
|
|
20 |
class template will generate all the necessary AnyScript code. Thus, adding GRF |
|
|
21 |
prediction is similar to adding force plates to a model. |
|
|
22 |
|
|
|
23 |
This new functionality is now part of the AnyBody Managed Model Repository |
|
|
24 |
(AMMR). |
|
|
25 |
|
|
|
26 |
## Adding ground force prediction to a model |
|
|
27 |
|
|
|
28 |
The {ref}`GRF example model <example_mocap_grf_prediction>` |
|
|
29 |
is already preconfigured to use the GRF prediction. But |
|
|
30 |
if you need to add GRF prediction to new model the following outlines the |
|
|
31 |
procedure. |
|
|
32 |
|
|
|
33 |
### Including the class templates |
|
|
34 |
|
|
|
35 |
The class template is already included in the AnyMoCap framework, so this step |
|
|
36 |
can be skipped. However, when using GRF prediction in other models it is |
|
|
37 |
necessary to include the following line at the beginning of the model: |
|
|
38 |
|
|
|
39 |
```AnyScriptDoc |
|
|
40 |
#include "<ANYBODY_PATH_AMMR>/Tools/GRFPrediction/FootPlateConditionalContact.any" |
|
|
41 |
``` |
|
|
42 |
|
|
|
43 |
### Adding the GRF prediction classes |
|
|
44 |
|
|
|
45 |
In the AnyMoCap models GRF prediction is enabled by setting the following |
|
|
46 |
setting: |
|
|
47 |
|
|
|
48 |
```AnyScriptDoc |
|
|
49 |
#define MOCAP_USE_GRF_PREDICTION ON |
|
|
50 |
``` |
|
|
51 |
|
|
|
52 |
The next step is to add the class template to generate the AnyScript code for |
|
|
53 |
GRF prediction. These classes replaces the Force plate classes in the AnyMoCap |
|
|
54 |
model. |
|
|
55 |
|
|
|
56 |
```AnyScriptDoc |
|
|
57 |
// EXCLUDE THE EXISTING C3D FORCE PLATES |
|
|
58 |
// ForcePlateAutoDetection Plate1( |
|
|
59 |
// PLATE_NO=1, |
|
|
60 |
// HeightTolerance = 0.07, |
|
|
61 |
// VelThreshold = 2.2, |
|
|
62 |
// FORCEPLATE_TYPE = 4, |
|
|
63 |
// ALLOW_MULTI_LIMB_CONTACT = OFF |
|
|
64 |
// ) = { }; |
|
|
65 |
|
|
|
66 |
|
|
|
67 |
FootPlateConditionalContact GRF_Prediction_Right( |
|
|
68 |
NORMAL_DIRECTION = "Y", |
|
|
69 |
NUMBER_OF_NODES = 25, |
|
|
70 |
NODES_FOLDER = FootNodes, |
|
|
71 |
PLATE_BASE_FRAME = Main.EnvironmentModel.GlobalRef |
|
|
72 |
) = { |
|
|
73 |
CreateFootContactNodes25 FootNodes( |
|
|
74 |
foot_ref=Main.HumanModel.BodyModel.Right.Leg.Seg.Foot |
|
|
75 |
) = {}; |
|
|
76 |
}; |
|
|
77 |
``` |
|
|
78 |
|
|
|
79 |
See below for more information on the GRF prediction classes. |
|
|
80 |
|
|
|
81 |
### Setting up new residuals (Hand of God) |
|
|
82 |
|
|
|
83 |
Adding conditional contacts to the feet is not enough. The AnyMoCap model comes |
|
|
84 |
reactions forces applied to the pelvis. These are the reactions that carry any |
|
|
85 |
inconsistencies between the model and force plate data, and they must be removed |
|
|
86 |
for ground reaction force prediction. |
|
|
87 |
|
|
|
88 |
Instead, we apply another type of residuals to the model, so the solver does not |
|
|
89 |
fail if the model fails to balance. These residuals are implemented as |
|
|
90 |
recruitment actuators from pelvis to the global reference frame. These actuators |
|
|
91 |
are implemented similarly to how muscles work. However, they are very weak, so |
|
|
92 |
the recruitment solver will only activate them if nothing else can balance the |
|
|
93 |
model. |
|
|
94 |
|
|
|
95 |
In the AnyMoCap models the new residuals are activated by default when |
|
|
96 |
`MOCAP_USE_GRF_PREDICTION` is set to `ON`. So no need to do anything. |
|
|
97 |
|
|
|
98 |
In other models the Weak residuals must be added manually, or by including the |
|
|
99 |
following file in your model: |
|
|
100 |
|
|
|
101 |
```AnyScriptDoc |
|
|
102 |
Main.ModelEnvironmentConnection = { |
|
|
103 |
#include "<ANYBODY_PATH_AMMR>/Tools/GRFPrediction/WeakResiduals.any" |
|
|
104 |
}; |
|
|
105 |
``` |
|
|
106 |
|
|
|
107 |
The file `WeakResiduals.any` does the job of removing the ‘Hand of God’ and adding |
|
|
108 |
the new, weak residuals. Again this is handled automatically in the AnyMoCap |
|
|
109 |
based models. |
|
|
110 |
|
|
|
111 |
## Running the model |
|
|
112 |
|
|
|
113 |
The model is run in the same way as other models. The only difference is that it |
|
|
114 |
now uses GRF prediction instead of force plates data. |
|
|
115 |
|
|
|
116 |
:::{figure} /anymocap/grf_output.png |
|
|
117 |
:align: center |
|
|
118 |
::: |
|
|
119 |
|
|
|
120 |
It may be necessary to adjust the parameters of the GRF prediction class to |
|
|
121 |
obtain a good prediction of the ground reactions. This is especially important |
|
|
122 |
around heel strike and toe-off, where the model can have problems. |
|
|
123 |
|
|
|
124 |
## GRF prediction trouble shooting |
|
|
125 |
|
|
|
126 |
Here are some things to check if a GRF prediction model fails running inverse |
|
|
127 |
dynamic: |
|
|
128 |
|
|
|
129 |
- Direction of gravity is it specified correctly? this needs to be correct in |
|
|
130 |
two places the Gravity property of the study in the LabSpecific.any data and in |
|
|
131 |
the definition of the force plates setting the variable `NORMAL_DIRECTION`. |
|
|
132 |
- In the file Forceplate_GRFprediction.any try to increase the property `LimitDistHigh`, |
|
|
133 |
this controls when contact can occur so if the number is higher the foot do |
|
|
134 |
not need to be as close to the ground before contact can occur, see also |
|
|
135 |
LimitVelHigh it controls speed limit. |
|
|
136 |
- Unrealistic accelerations of the model could be the reason if your data are |
|
|
137 |
not filtered correctly |
|
|
138 |
- The model is using a weak residual to the ground that helps holding the balance |
|
|
139 |
in the model if the feet contact are not enough, this is defined in the file |
|
|
140 |
"Tools/GRFPrediction/Weakresidual.any" here you can increase the strength |
|
|
141 |
of the artificial muscles, but this will lead to higher residuals so be |
|
|
142 |
careful. |
|
|
143 |
|
|
|
144 |
## A closer look at the GRF template |
|
|
145 |
|
|
|
146 |
Finally, we can take a closer look at the `FootPlateConditionalContact` template. |
|
|
147 |
|
|
|
148 |
```AnyScriptDoc |
|
|
149 |
FootPlateConditionalContact GRF_Prediction_Right( |
|
|
150 |
NORMAL_DIRECTION = "Y", |
|
|
151 |
NUMBER_OF_NODES = 25, |
|
|
152 |
NODES_FOLDER = FootNodes, |
|
|
153 |
PLATE_BASE_FRAME = Main.EnvironmentModel.GlobalRef |
|
|
154 |
) = { |
|
|
155 |
CreateFootContactNodes25 FootNodes( |
|
|
156 |
foot_ref=Main.HumanModel.BodyModel.Right.Leg.Seg.Foot |
|
|
157 |
) = {}; |
|
|
158 |
}; |
|
|
159 |
``` |
|
|
160 |
|
|
|
161 |
It consists of two parts; a top level class template |
|
|
162 |
(`FootPlateConditionalContact`) that generate the conditional-contact code. |
|
|
163 |
This code needs a few important arguments. The ground plane |
|
|
164 |
(`PLATE_BASE_FRAME`) is a reference system where the ground plane is located. |
|
|
165 |
|
|
|
166 |
Together with arguments `NORMAL_DIRECTION` this specifies the surface the |
|
|
167 |
model is walking on. Another important argument is the `NODES_FOLDER`, which |
|
|
168 |
is a folder that contains all the contacts points. |
|
|
169 |
|
|
|
170 |
The contact points can be created manually, but to avoid this we use another |
|
|
171 |
class-template (`CreateFootContactNodes25`) to create the nodes automatically. |
|
|
172 |
As the name says it creates 25 nodes in the foot coordinate system. This part is |
|
|
173 |
specific to the model implementation. One could also imagine class-templates |
|
|
174 |
that produce a higher number of nodes or nodes in positions that corresponds to |
|
|
175 |
particular shoes or on other body parts. |
|
|
176 |
|
|
|
177 |
Of course, there are also many options that can be tweaked and adjusted. |
|
|
178 |
|
|
|
179 |
### Class templates: FootPlateConditionalContact |
|
|
180 |
|
|
|
181 |
Obligatory members are marked with `< >` and optional values are marked with |
|
|
182 |
`[ ]`. Default values are **bold**: |
|
|
183 |
|
|
|
184 |
**Usage:** |
|
|
185 |
|
|
|
186 |
```AnyScriptDoc |
|
|
187 |
FootPlateConditionalContact <Object_name>( |
|
|
188 |
NORMAL_DIRECTION = "<X|Y|*Z>", |
|
|
189 |
NUMBER_OF_NODES = [*1..200], |
|
|
190 |
NODES_BASE_FOLDER = <AnyFolder> , |
|
|
191 |
PLATE_BASE_FRAME = <AnyRefFrame>, |
|
|
192 |
SHOW_TRIGGER_VOLUME = [*0|1] ) = |
|
|
193 |
{ |
|
|
194 |
Settings = |
|
|
195 |
{ |
|
|
196 |
[ LimitDistLow = -0.10; ] |
|
|
197 |
[ LimitDistHigh = 0.04; ] |
|
|
198 |
[ LimitVelHigh = 0.8; ] |
|
|
199 |
[ GroundVelocity = {0.0, 0.0, 0.0}; ] |
|
|
200 |
[ Strength = 200; ] |
|
|
201 |
[ FrictionCoefficient = 0.5; ] |
|
|
202 |
[ ScaleFactor = 1; ] |
|
|
203 |
[ ForceVectorDrawScaleFactor = 0.0005;] |
|
|
204 |
}; |
|
|
205 |
``` |
|
|
206 |
|
|
|
207 |
**Class arguments:** |
|
|
208 |
|
|
|
209 |
`PLATE_BASE_FRAME`: |
|
|
210 |
|
|
|
211 |
: Is a AnyRefFrame object where the ground planes is attached. |
|
|
212 |
|
|
|
213 |
`NORMAL_DIRECTION`: |
|
|
214 |
|
|
|
215 |
: Defines the normal direction of the ground plane |
|
|
216 |
the in PLATE_BASE_FRAME coordinate system. |
|
|
217 |
|
|
|
218 |
`NODES_BASE_FOLDER` : |
|
|
219 |
|
|
|
220 |
: The folder where all contact nodes are located below. |
|
|
221 |
contact nodes must be AnyRefNodes named must be named `Node#` |
|
|
222 |
where `#` is a number. Eg. ``` Node1` ...``Node24 ``` |
|
|
223 |
|
|
|
224 |
`NUMBER_OF_NODES`: |
|
|
225 |
|
|
|
226 |
: The number of contact nodes to expect within `NODE_BASE_FRAME` |
|
|
227 |
|
|
|
228 |
`SHOW_TRIGGER_VOLUME`: |
|
|
229 |
|
|
|
230 |
: Visualize the volume where contacts may be triggered. |
|
|
231 |
|
|
|
232 |
`GLOBAL_REF`: |
|
|
233 |
|
|
|
234 |
: The global reference. This must be set if the global reference is not |
|
|
235 |
`Main.EnvironmentModel.GlobalRef` |
|
|
236 |
|
|
|
237 |
**Optional initialization:** |
|
|
238 |
|
|
|
239 |
`Settings.LimitDistLow`: |
|
|
240 |
|
|
|
241 |
: Lower bound of the contact detection volume. |
|
|
242 |
|
|
|
243 |
`Settings.LimitDistHigh`: |
|
|
244 |
|
|
|
245 |
: Upper bound of the contact detection volume. |
|
|
246 |
|
|
|
247 |
`Settings.LimitVelHigh`: |
|
|
248 |
|
|
|
249 |
: Velocity threshold for contact detection. |
|
|
250 |
|
|
|
251 |
`Settings.Strength`: |
|
|
252 |
|
|
|
253 |
: Strength of the contact elements. |
|
|
254 |
|
|
|
255 |
`Settings.FrictionCoefficient`: |
|
|
256 |
|
|
|
257 |
: Friction coeficient of the contact elements. This adds limits to the amount of |
|
|
258 |
friction force which can be recruited. |
|
|
259 |
|
|
|
260 |
`Settings.ForceVectorDrawScaleFactor`: |
|
|
261 |
|
|
|
262 |
: Scale factor for the drawing of the GRF force vector |