Hide code cell content
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
plt.style.use('fivethirtyeight')

CE 2120 Project - Knee Joint Model#

By Caroline Cook#

In this project, I will be creating a double pendulum to model the movement of walking. I will use the Newton-Euler derived equation of motion to predict various movements, and compare it to real life accelerometer data that I recorded of myself walking. We will be able to see the relationship between acceleration and time, and if my equation derived data and recorded data mirror each other.

Background#

The double pendulum model has two links and two degrees of freedom. Link 1 (L1) plays the role of the femur, and link 2 (L2) acts as the tibia. The knee will be point mass 1 (m1) and the foot/ankle will be point mass 2 (m2). I’ve drawn some rough free body diagrams of the system, and also broken it up into two for each link. Ultimately though, the reaction forces will not be needed in the equation of motion. IMG_0467.jpeg


Measurements#

I measured my own leg, and recorded my femur (l1) to be 16 inches and l2 to be 15 inches. As for the masses, the force you put on your knees when you walk on even ground is one and a half times your body weight. I weigh 135 lbs, so 1 1/2 times that is 202.5 lb, and to keep things simple I evenly distributed it amongst the two masses, so each is 101.25 lbs or roughly 46 kg. As for angles, we can begin in full flexion (peak of motion for walking, and both links are aligned), and assign them to each be 60º (or pi/3 rad). Initial angular velocity can be 0 rad/s.

g=9.81 #m/s^2
l1= 0.4 #m
l2= 0.38
m1= 46 #kg
m2= 46
theta1= np.linspace(0, np.pi/3)
theta2= np.pi/3
x1=l1*np.sin(theta1)
y1=-l1*np.cos(theta1)
x2=x1+l2*np.sin(theta2)
y2=y1-l2*np.cos(theta2)
dtheta=0#rad/sec
a=(l1*(dtheta^2)*np.sin(theta1-theta2)-g*np.sin(theta2))/(l2+l1*np.cos(theta1-theta2))
plt.plot(a,theta1)
plt.xlabel('theta1 (rad)')
plt.ylabel('$acceleration$ [m/s^2]')
plt.title('Acceleration VS Theta1')
Text(0.5, 1.0, 'Acceleration VS Theta1')
../_images/4b75df499260cbcb34569d7b33b4efb539bdb27f9728c79269f0b9714ff1db78.png
np.arcsin(0.6/(l1+l2))*180/np.pi
50.284862768173795
#Acceleration Data

accel_data = np.array([
[0,6.088439025878906],
[57,6.015989685058594],
[124,6.6276177978515625],
[191,6.831344146728516],
[257,5.952371978759766],
[324,6.048172760009766],
[391,6.569837951660157],
[457,7.891140289306641],
[524,7.355254669189454],
[591,7.687563629150391],
[658,6.846462707519532],
[724,5.8652531433105475],
[790,2.827320556640625],
[859,2.4285498046875],
[924,4.203109588623047],
[991,2.9063562011718753],
[1058,-1.6227754211425782],
[1124,-1.1536509704589843],
[1191,0.018112335205078125],
[1258,1.22625],
[1324,0.21345611572265627],
[1391,-0.29728179931640625],
[1458,5.462291107177735],
[1524,-0.2625540161132813],
[1591,0.5255570983886719],
[1659,0.45999343872070314],
[1724,0.7653584289550782],
[1791,0.8496331787109376],
[1859,-1.982776794433594],
[1924,-2.871179351806641],
[1991,0.2947370910644531],
[2058,-0.5355862426757813],
[2124,-1.7609381103515627],
[2191,-0.49172744750976566],
[2258,0.7605683898925781],
[2324,0.052690429687500005],
[2391,2.7331663513183595],
[2458,-0.12678634643554687],
[2524,1.414109344482422],
[2591,3.9439984130859376],
[2659,1.8408718872070313],
[2723,1.5705340576171876],
[2791,0.9348060607910157],
[2858,0.6608757019042969],
[2923,0.271834716796875],
[2991,2.366279296875],
[3058,-2.8262727355957034],
[3124,1.5356565856933595],
[3191,4.428989868164063],
[3258,6.99630111694336],
[3324,-3.5637890625],
[3391,2.4459136962890624],
[3457,0.6776408386230469],
[3524,-0.9943821716308594],
[3591,-1.0603948974609376],
[3657,2.012864227294922],
[3724,0.9659413146972656],
[3791,2.4507037353515626],
[3857,3.8601727294921875],
[3924,3.975283355712891],
[3991,1.253792724609375],
[4057,1.0783575439453126],
[4124,0.8780740356445313],
[4191,2.3787034606933597],
[4257,-1.803300018310547],
[4324,-2.7295738220214845],
[4391,3.579506378173828],
[4458,8.964707794189454],
[4524,-0.9575587463378906],
[4591,0.05059478759765625],
[4658,1.2243040466308595],
[4724,-0.7447013854980469],
[4791,-0.6192622375488281],
[4857,2.2504202270507814],
[4924,1.033151550292969],
[4991,1.4199472045898438],
[5058,2.8192373657226564],
[5124,4.0372544860839845],
[5191,1.3222004699707033],
[5258,1.1322454833984374],
[5324,1.8567388916015626],
[5391,1.0196795654296875],
[5458,1.1301498413085938],
[5524,-2.079775085449219],
[5591,3.393892364501953],
[5658,5.264402618408203],
[5724,5.975873107910156],
[5791,-1.2722044372558594],
[5858,2.7021807861328124],
[5924,1.4897021484375002],
[5991,-0.3864962768554688],
[6058,-1.0559042358398438],
[6124,1.9118243408203126],
[6191,1.6149916076660158],
[6258,2.7785220336914063],
[6324,1.4711407470703126],
[6391,4.279301147460938],
[6458,0.6807843017578126],
[6524,1.375938720703125],
[6591,1.038240966796875],
[6658,-0.05523513793945313],
[6724,0.8074209594726562],
[6791,-3.4194891357421877],
[6858,2.462828521728516],
[6924,6.651717681884766],
[6990,6.607709197998047],
[7058,-1.9749929809570312],
[7123,2.0372634887695313],
[7190,-0.3998185729980469],
[7258,-1.6516653442382814],
[7323,1.031205596923828],
[7390,0.2856060791015625],
[7458,1.8754499816894532],
[7523,1.906285858154297],
[7590,5.2558703613281255],
[7658,2.896776123046875],
[7724,-0.6475534057617188],
[7790,3.500021667480469],
[7858,0.8405021667480469],
[7924,-0.18546432495117188],
[7991,-2.2552102661132816],
[8058,2.5927583312988283],
[8124,7.535779266357422],
[8191,3.8886135864257816],
[8258,-1.7265097045898439],
[8324,2.3510110473632815],
[8391,-0.40071670532226566],
[8458,0.09624984741210937],
[8524,1.4718891906738283],
[8591,1.0234217834472656],
[8658,1.400787048339844],
[8724,1.3956976318359375],
[8791,3.750450897216797],
[8858,2.8163932800292972],
[8924,-0.47615982055664063],
[8991,0.9877958679199219],
[9057,0.30865814208984377],
[9124,2.1207897949218752],
[9191,-1.7640815734863282],
[9257,1.0044113159179688],
[9324,4.470603332519532],
[9391,6.392157440185547],
[9458,-0.20627105712890625],
[9524,2.2052142333984377],
[9591,0.6014492797851563],
[9658,-0.5774990844726563],
[9724,-0.5375321960449219],
[9791,2.0938458251953125],
[9857,-1.8345849609375],
[9924,1.0600955200195312],
[9991,2.325414276123047],
[10058,4.619543609619141],
[10124,1.3482463073730468],
[10191,0.6773414611816406],
[10258,0.5769003295898438],
[10324,0.24339385986328127],
[10391,2.9428802490234376],
[10456,-4.0899449157714844],
[10524,3.496279449462891],
[10591,8.412805480957031],
[10657,0.31524444580078126],
[10724,1.9484980773925782],
[10791,1.5277230834960938],
[10857,-0.2077679443359375],
[10924,-1.115929412841797],
[10991,2.433190155029297],
[11057,-1.3118719482421877],
[11124,0.8164022827148438],
[11191,3.0567933654785158],
[11257,3.247496795654297],
[11324,2.202370147705078],
[11391,0.29114456176757814],
[11457,2.2676344299316407],
[11523,1.9285894775390626],
[11591,1.1295510864257814],
[11657,-3.6717146301269534],
[11723,4.044439544677735],
[11791,8.632847900390626],
[11857,-1.9095790100097658],
[11924,0.5596861267089844],
[11991,1.485959930419922],
[12057,0.05882766723632813],
[12124,-1.2364288330078126],
[12191,1.5269746398925783],
[12257,-1.1187734985351563],
[12324,3.7979022216796876],
[12391,1.7284556579589845],
[12457,4.189038848876954],
[12523,2.1203407287597655],
[12590,0.9583071899414063],
[12657,1.156644744873047],
[12723,0.305364990234375],
[12790,1.3332774353027343],
[12857,-3.4750236511230472],
[12923,2.9154872131347656],
[12990,10.07105712890625],
[13057,6.455775146484375],
[13123,-0.6867718505859375],
[13190,0.2537223815917969],
[13257,0.19100280761718752],
[13324,-0.26689498901367187],
[13391,1.242715759277344],
[13457,-0.36539016723632817],
[13524,-2.661914520263672],
[13591,-0.4397854614257813],
[13657,2.245330810546875],
[13724,2.4231610107421875],
[13791,3.0135333251953127],
[13857,1.7965640258789064],
[13924,1.0606942749023438],
[13991,0.03547622680664063],
[14057,0.4076023864746094],
[14124,0.47256729125976565],
[14191,0.08382568359375],
[14257,-0.7824229431152344],
[14324,1.5362553405761719],
[14391,7.250921630859375],
[14457,1.9643650817871094],
[14524,1.515897674560547],
[14590,0.8942404174804688],
[14657,-0.011825408935546875],
[14724,0.026943969726562503],
[14791,0.09265731811523438],
[14857,1.8271005249023438],
[14924,0.2484832763671875],
[14991,-1.713486785888672],
[15057,0.056133270263671875],
[15124,3.006947021484375],
[15191,5.926326141357422],
[15257,6.840475158691406],
[15324,3.896397399902344],
[15391,3.133433990478516],
[15457,1.435664520263672],
[15524,0.38739440917968754],
[15591,0.2785707092285156],
[15657,1.0241702270507813],
[15724,1.3702505493164063],
[15791,1.999691619873047]])
accel_data = np.loadtxt('./Untitled Experiment - Recording 1.txt', skiprows= 1, delimiter= ',')
accel_data[i1:i2, :].shape
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[7], line 1
----> 1 accel_data[i1:i2, :].shape

NameError: name 'i1' is not defined
i1 = 50
i2 = 500
plt.plot(accel_data[i1:i2, 0], accel_data[i1:i2, 1])
plt.plot(accel_data[i1:i2, 0], accel_data[i1:i2, 2])
plt.plot(accel_data[i1:i2, 0], accel_data[i1:i2, 3])

# plt.plot(accel_data[i1:i2, 0], np.ones(i2-i1)*accel_data[i1:i2,1].mean())
plt.title('mean a_x = {:1.2f} m/s/s\na_y = {:1.2f}\na_z={:1.2f}'.format(
    accel_data[i1:i2,1].mean(),
    accel_data[i1:i2,2].mean(),
    accel_data[i1:i2,3].mean()))
Text(0.5, 1.0, 'mean a_x = 0.80 m/s/s\na_y = 9.33\na_z=2.50')
../_images/2c658f391b813357c9cb271d068a82caa480ecb94db724d3ccc097d91517e401.png
mag_a = np.sqrt(np.sum(accel_data[:, 1:3]**2, axis = 1))

plt.plot(accel_data[:,0], mag_a)
plt.title('mean |a| = {:1.2f} m/s/s'.format(mag_a.mean()))
Text(0.5, 1.0, 'mean |a| = 9.66 m/s/s')
../_images/78452c3df46a5457427f1670a49e24c550b54bbbb712f3eb5a19e31d02d6d43a.png

Proposed Outline:#

Background#

  • What are you trying to model?

  • How are you simplifying the model (here: aim for rigid bodies, massless springs, etc.)

  • Draw a free body diagram and show the motion

Model and method#

  • Show how you create your model: aim to explain to another student in CE2120

  • State your assumptions, constants, equations

  • Show your analysis

  • What is important about your result? Show a graph or two to demonstrate what’s important

Wrapping up#

  • What was the original goal in your background? How did you meet the goal?

  • What was an interesting fact you learned from this analysis? Did it change how you see this device?

  • Any next steps? were there missing parts to the analysis? how could you make it better?