!pip freeze
Cython==0.19.1 -e git+git@github.com:moorepants/DynamicistToolKit.git@e2c559bfae33a6bacacfb773818e106ccb3a9940#egg=DynamicistToolKit-dev Jinja2==2.7.1 MarkupSafe==0.18 argparse==1.2.1 ipython==1.0.0 matplotlib==1.3.0 nose==1.3.0 numpy==1.7.1 pandas==0.12.0 pyparsing==2.0.1 python-dateutil==2.1 pytz==2013b pyzmq==13.1.0 scipy==0.12.0 six==1.3.0 sympy==0.7.3 tornado==3.1 wsgiref==0.1.2
%pylab inline
Populating the interactive namespace from numpy and matplotlib
Here is some data that was collected for a paper which is about to be published. Proofs and supplementary documentation are attached.
This is from a 77 kg male, 30 seconds of walking preceded by 1 second of standing. The treadmill speed increases gradually in the beginning, at t=6.0 it is at its final constant speed to best to ignore anything that happens before that time.
The dof file contains the generalized coordinates, dofvel the generalized velocities. The jointmoment file the corresponding generalized forces. First line has the names of the generalized coordinates. The grf file has the ground reaction forces, which you would use to determine where you are in the gait cycle (from heelstrike to heelstrike).
CAREN_Trial04.txt is the raw data (mocap and force plate). You could actually load that file in D-Flow to produce the variables that are on the other files, if you wanted to.
ls ../data
CAREN_Trial04_dof.txt CAREN_Trial04_grf.txt CAREN_Trial04.txt obinna-walking.txt CAREN_Trial04_dofvel.txt CAREN_Trial04_jointmoment.txt example_vertical_grf.csv
import pandas
coordinates = pandas.read_csv('../data/CAREN_Trial04_dof.txt', delimiter='\t', index_col="TimeStamp")
speeds = pandas.read_csv('../data/CAREN_Trial04_dofvel.txt', delimiter='\t', index_col="TimeStamp")
generalized_forces = pandas.read_csv('../data/CAREN_Trial04_jointmoment.txt', delimiter='\t', index_col="TimeStamp")
ground_reaction_forces = pandas.read_csv('../data/CAREN_Trial04_grf.txt', delimiter='\t', index_col="TimeStamp")
raw_data = pandas.read_csv('../data/CAREN_Trial04.txt', delimiter='\t', index_col="TimeStamp")
for df in [coordinates, speeds, generalized_forces, ground_reaction_forces, raw_data]:
print(df)
print('=' * 50)
<class 'pandas.core.frame.DataFrame'> Index: 3100 entries, 0.0 to 30.99 Data columns (total 47 columns): FrameNumber 3100 non-null values PelvisX 3100 non-null values PelvisY 3100 non-null values PelvisZ 3100 non-null values PelvisYaw 3100 non-null values PelvisForwardPitch 3100 non-null values PelvisRightRoll 3100 non-null values TrunkFlexion 3100 non-null values TrunkRightBend 3100 non-null values TrunkLeftTwist 3100 non-null values HeadFlexion 3100 non-null values HeadRightBend 3100 non-null values HeadLeftTwist 3100 non-null values RShoulderUp 3100 non-null values LShoulderUp 3100 non-null values RShoulderForward 3100 non-null values LShoulderForward 3100 non-null values RShoulderInward 3100 non-null values LShoulderInward 3100 non-null values RShoulderFlexion 3100 non-null values LShoulderFlexion 3100 non-null values RShoulderAbduction 3100 non-null values LShoulderAbduction 3100 non-null values RShoulderInternalRotation 3100 non-null values LShoulderInternalRotation 3100 non-null values RElbowFlexion 3100 non-null values LElbowFlexion 3100 non-null values RForeArmPronation 3100 non-null values LForeArmPronation 3100 non-null values RWristFlexion 3100 non-null values LWristFlexion 3100 non-null values RHandAbduction 3100 non-null values LHandAbduction 3100 non-null values RHipFlexion 3100 non-null values LHipFlexion 3100 non-null values RHipAbduction 3100 non-null values LHipAbduction 3100 non-null values RHipInternalRotation 3100 non-null values LHipInternalRotation 3100 non-null values RKneeFlexion 3100 non-null values LKneeFlexion 3100 non-null values RAnklePlantarFlexion 3100 non-null values LAnklePlantarFlexion 3100 non-null values RFootPronation 3100 non-null values LFootPronation 3100 non-null values RToeFlexion 3100 non-null values LToeFlexion 3100 non-null values dtypes: float64(46), int64(1) ================================================== <class 'pandas.core.frame.DataFrame'> Index: 3100 entries, 0.0 to 30.99 Data columns (total 47 columns): FrameNumber 3100 non-null values PelvisX 3100 non-null values PelvisY 3100 non-null values PelvisZ 3100 non-null values PelvisYaw 3100 non-null values PelvisForwardPitch 3100 non-null values PelvisRightRoll 3100 non-null values TrunkFlexion 3100 non-null values TrunkRightBend 3100 non-null values TrunkLeftTwist 3100 non-null values HeadFlexion 3100 non-null values HeadRightBend 3100 non-null values HeadLeftTwist 3100 non-null values RShoulderUp 3100 non-null values LShoulderUp 3100 non-null values RShoulderForward 3100 non-null values LShoulderForward 3100 non-null values RShoulderInward 3100 non-null values LShoulderInward 3100 non-null values RShoulderFlexion 3100 non-null values LShoulderFlexion 3100 non-null values RShoulderAbduction 3100 non-null values LShoulderAbduction 3100 non-null values RShoulderInternalRotation 3100 non-null values LShoulderInternalRotation 3100 non-null values RElbowFlexion 3100 non-null values LElbowFlexion 3100 non-null values RForeArmPronation 3100 non-null values LForeArmPronation 3100 non-null values RWristFlexion 3100 non-null values LWristFlexion 3100 non-null values RHandAbduction 3100 non-null values LHandAbduction 3100 non-null values RHipFlexion 3100 non-null values LHipFlexion 3100 non-null values RHipAbduction 3100 non-null values LHipAbduction 3100 non-null values RHipInternalRotation 3100 non-null values LHipInternalRotation 3100 non-null values RKneeFlexion 3100 non-null values LKneeFlexion 3100 non-null values RAnklePlantarFlexion 3100 non-null values LAnklePlantarFlexion 3100 non-null values RFootPronation 3100 non-null values LFootPronation 3100 non-null values RToeFlexion 3100 non-null values LToeFlexion 3100 non-null values dtypes: float64(46), int64(1) ================================================== <class 'pandas.core.frame.DataFrame'> Index: 3100 entries, 0.0 to 30.99 Data columns (total 47 columns): FrameNumber 3100 non-null values PelvisX 3100 non-null values PelvisY 3100 non-null values PelvisZ 3100 non-null values PelvisYaw 3100 non-null values PelvisForwardPitch 3100 non-null values PelvisRightRoll 3100 non-null values TrunkFlexion 3100 non-null values TrunkRightBend 3100 non-null values TrunkLeftTwist 3100 non-null values HeadFlexion 3100 non-null values HeadRightBend 3100 non-null values HeadLeftTwist 3100 non-null values RShoulderUp 3100 non-null values LShoulderUp 3100 non-null values RShoulderForward 3100 non-null values LShoulderForward 3100 non-null values RShoulderInward 3100 non-null values LShoulderInward 3100 non-null values RShoulderFlexion 3100 non-null values LShoulderFlexion 3100 non-null values RShoulderAbduction 3100 non-null values LShoulderAbduction 3100 non-null values RShoulderInternalRotation 3100 non-null values LShoulderInternalRotation 3100 non-null values RElbowFlexion 3100 non-null values LElbowFlexion 3100 non-null values RForeArmPronation 3100 non-null values LForeArmPronation 3100 non-null values RWristFlexion 3100 non-null values LWristFlexion 3100 non-null values RHandAbduction 3100 non-null values LHandAbduction 3100 non-null values RHipFlexion 3100 non-null values LHipFlexion 3100 non-null values RHipAbduction 3100 non-null values LHipAbduction 3100 non-null values RHipInternalRotation 3100 non-null values LHipInternalRotation 3100 non-null values RKneeFlexion 3100 non-null values LKneeFlexion 3100 non-null values RAnklePlantarFlexion 3100 non-null values LAnklePlantarFlexion 3100 non-null values RFootPronation 3100 non-null values LFootPronation 3100 non-null values RToeFlexion 3100 non-null values LToeFlexion 3100 non-null values dtypes: float64(46), int64(1) ================================================== <class 'pandas.core.frame.DataFrame'> Index: 3100 entries, 0.0 to 30.99 Data columns (total 13 columns): FrameNumber 3100 non-null values RFx 3100 non-null values RFy 3100 non-null values RFz 3100 non-null values RCOPx 3100 non-null values RCOPz 3100 non-null values RMy' 3100 non-null values LFx 3100 non-null values LFy 3100 non-null values LFz 3100 non-null values LCOPx 3100 non-null values LCOPz 3100 non-null values LMy' 3100 non-null values dtypes: float64(12), int64(1) ================================================== <class 'pandas.core.frame.DataFrame'> Index: 3100 entries, 0.0 to 30.99 Columns: 186 entries, FrameNumber to FP2.MomZ dtypes: float64(185), int64(1) ==================================================
coordinates['RKneeFlexion'].plot(figsize=(12.0, 8.0))
<matplotlib.axes.AxesSubplot at 0x45f2b90>
raw_data['TreadmillSpeed'].plot(figsize=(12.0, 8.0))
<matplotlib.axes.AxesSubplot at 0x461e210>
ground_reaction_forces['LFx'][500:1000].plot(figsize=(12.0, 8.0))
<matplotlib.axes.AxesSubplot at 0x461e2d0>
The vertical ground reaction force is in the $Y$ direction, positive is up. So if you press down on the force plate you get a positive vertical ground reaction force.
ground_reaction_forces['LFy'][500:1000].plot(figsize=(12.0, 8.0))
<matplotlib.axes.AxesSubplot at 0x4a5a590>
ground_reaction_forces['LFz'][500:1000].plot(figsize=(12.0, 8.0))
<matplotlib.axes.AxesSubplot at 0x4a45f10>
coordinates['RKneeFlexion'].plot(figsize=(12.0, 8.0))
<matplotlib.axes.AxesSubplot at 0x4a5a5d0>
raw_data['TreadmillSpeed'].to_csv('treadmill-speed.csv')
!head treadmill-speed.csv
0.0,0.0 0.01,0.0 0.02,0.0 0.03,0.0 0.04,0.0 0.05,0.0 0.06,0.0 0.07,0.0 0.08,0.0 0.09,0.0
import numpy as np
speed_array = np.loadtxt('treadmill-speed.csv', delimiter=',')
speed_array[:, 0]
array([ 0.00000000e+00, 1.00000000e-02, 2.00000000e-02, ..., 3.09700000e+01, 3.09800000e+01, 3.09900000e+01])
from dtk import walk
reload(walk)
<module 'dtk.walk' from '/home/moorepants/src/DynamicistTK/dtk/walk.pyc'>
walk.gait_landmarks_from_grf(ground_reaction_forces.index.values.astype(float),
ground_reaction_forces['RFy'], ground_reaction_forces['LFy'], do_plot=True, min_time=15.0, threshold=5.0)
(array([ 15.36, 16.52, 17.68, 18.83, 19.97, 21.12, 22.28, 23.42, 24.59, 25.72, 26.87, 28.01, 29.17, 30.33]), array([ 15.6 , 16.75, 20.2 , 25.95, 28.25, 29.39, 30.59]), array([ 15.01, 16.16, 17.33, 18.47, 19.62, 20.78, 21.93, 23.06, 24.22, 25.37, 26.51, 27.66, 28.8 , 29.96]), array([ 15.57, 16.74, 20.19, 25.94, 28.23, 29.36, 30.53]))
obinna = pandas.read_csv('../data/obinna-walking.txt', delimiter='\t', index_col="TimeStamp", na_values='0.000000')
obinna.head()
<class 'pandas.core.frame.DataFrame'> Index: 5 entries, 534.133513 to 534.173667 Columns: 617 entries, FrameNumber to HBM.COM.Z dtypes: float64(616), int64(1)
[col for col in obinna.columns if col.endswith('.Ang') or col.endswith('ForY') or col.endswith('.Mom')]
['FP1.ForY', 'FP2.ForY', 'PelvisX.Ang', 'PelvisX.Mom', 'PelvisY.Ang', 'PelvisY.Mom', 'PelvisZ.Ang', 'PelvisZ.Mom', 'PelvisYaw.Ang', 'PelvisYaw.Mom', 'PelvisForwardPitch.Ang', 'PelvisForwardPitch.Mom', 'PelvisRightRoll.Ang', 'PelvisRightRoll.Mom', 'TrunkFlexion.Ang', 'TrunkFlexion.Mom', 'TrunkRightBend.Ang', 'TrunkRightBend.Mom', 'TrunkLeftTwist.Ang', 'TrunkLeftTwist.Mom', 'HeadFlexion.Ang', 'HeadFlexion.Mom', 'HeadRightBend.Ang', 'HeadRightBend.Mom', 'HeadLeftTwist.Ang', 'HeadLeftTwist.Mom', 'RShoulderUp.Ang', 'RShoulderUp.Mom', 'LShoulderUp.Ang', 'LShoulderUp.Mom', 'RShoulderForward.Ang', 'RShoulderForward.Mom', 'LShoulderForward.Ang', 'LShoulderForward.Mom', 'RShoulderInward.Ang', 'RShoulderInward.Mom', 'LShoulderInward.Ang', 'LShoulderInward.Mom', 'RShoulderFlexion.Ang', 'RShoulderFlexion.Mom', 'LShoulderFlexion.Ang', 'LShoulderFlexion.Mom', 'RShoulderAbduction.Ang', 'RShoulderAbduction.Mom', 'LShoulderAbduction.Ang', 'LShoulderAbduction.Mom', 'RShoulderInternalRotation.Ang', 'RShoulderInternalRotation.Mom', 'LShoulderInternalRotation.Ang', 'LShoulderInternalRotation.Mom', 'RElbowFlexion.Ang', 'RElbowFlexion.Mom', 'LElbowFlexion.Ang', 'LElbowFlexion.Mom', 'RForeArmPronation.Ang', 'RForeArmPronation.Mom', 'LForeArmPronation.Ang', 'LForeArmPronation.Mom', 'RWristFlexion.Ang', 'RWristFlexion.Mom', 'LWristFlexion.Ang', 'LWristFlexion.Mom', 'RHandAbduction.Ang', 'RHandAbduction.Mom', 'LHandAbduction.Ang', 'LHandAbduction.Mom', 'RHipFlexion.Ang', 'RHipFlexion.Mom', 'LHipFlexion.Ang', 'LHipFlexion.Mom', 'RHipAbduction.Ang', 'RHipAbduction.Mom', 'LHipAbduction.Ang', 'LHipAbduction.Mom', 'RHipInternalRotation.Ang', 'RHipInternalRotation.Mom', 'LHipInternalRotation.Ang', 'LHipInternalRotation.Mom', 'RKneeFlexion.Ang', 'RKneeFlexion.Mom', 'LKneeFlexion.Ang', 'LKneeFlexion.Mom', 'RAnklePlantarFlexion.Ang', 'RAnklePlantarFlexion.Mom', 'LAnklePlantarFlexion.Ang', 'LAnklePlantarFlexion.Mom', 'RFootPronation.Ang', 'RFootPronation.Mom', 'LFootPronation.Ang', 'LFootPronation.Mom', 'RToeFlexion.Ang', 'RToeFlexion.Mom', 'LToeFlexion.Ang', 'LToeFlexion.Mom']
obinna['FP2.ForY'][1000:2000].plot(figsize=(12,10))
<matplotlib.axes.AxesSubplot at 0x516d050>
start = 1100
stop = 2000
right_strikes, left_strikes, right_toe_off, left_toe_off = \
walk.gait_landmarks_from_grf(obinna.index.values.astype(float)[start:stop],
obinna['FP1.ForY'][start:stop],
obinna['FP2.ForY'][start:stop],
do_plot=True, min_time=15.0, threshold=28.0)
obinna['FP2.ForY'].to_csv('../data/example_vertical_grf.csv')
first_foot_down = obinna[right_strikes[0]:right_toe_off[1]]
second_foot_down = obinna[right_strikes[1]:right_toe_off[2]]
first_foot_down['FP1.ForY'].shape
(79,)
second_foot_down['FP1.ForY'].shape
(77,)
from dtk import process
# this is giving different answers depending on the guess value
process.find_timeshift(first_foot_down['FP1.ForY'][:-2].values,
second_foot_down['FP1.ForY'].values,
100,
guess=0.01,
plot=True)
The minimun of the error landscape is 0.01. Optimization terminated successfully. Current function value: 1.077503 Iterations: 10 Function evaluations: 21
array([ 0.002625])
figure(figsize=(10, 8))
right_steps = {}
for i, heel in enumerate(right_strikes[:-1]):
right_steps[i] = obinna[heel:right_toe_off[i + 1]]
print(len(right_steps[i]))
time = process.time_vector(len(right_steps[i]), 100)
right_steps[i].index = time
plot(time, right_steps[i]['FP1.ForY'],)
#right_steps = pandas.Panel(right_steps)
79 77 78 77 75 79 79
right_steps = pandas.Panel(right_steps)
mean_right_steps = right_steps.mean(axis='items')
mean_right_steps['FP1.ForY'].plot()
<matplotlib.axes.AxesSubplot at 0x61a2f50>
right_steps = right_steps.fillna(method='pad')
from dtk import walk
solver = walk.SimpleControlSolver(right_steps)
sensors = ['RKneeFlexion.Ang', 'RHipFlexion.Ang','RAnklePlantarFlexion.Ang']
sensors = ['RKneeFlexion.Ang', 'RAnklePlantarFlexion.Ang']
controls = ['RKneeFlexion.Mom', 'RHipFlexion.Mom', 'RAnklePlantarFlexion.Mom']
gains, sensors = solver.solve(sensors, controls)
gains.shape
(79, 3, 2)
figure(figsize=(10, 8))
plot(gains.reshape(79, 6))
[<matplotlib.lines.Line2D at 0x6823ed0>, <matplotlib.lines.Line2D at 0x6823310>, <matplotlib.lines.Line2D at 0x6823a10>, <matplotlib.lines.Line2D at 0x6823790>, <matplotlib.lines.Line2D at 0x6823d50>, <matplotlib.lines.Line2D at 0x68238d0>]