- /
-
Simplest Passive Dynamic Walker - Unstable
on 16 Oct 2024
- 16
- 124
- 0
- 1
- 1597
Cite your audio source here (if applicable):
drawframe(1);
Write your drawframe function below
function drawframe(f)
% Simulation of the "Simplest Walking Model"
%
% See:
% https://github.com/horchler/Passive-Dynamic-Walking
% https://www.mathworks.com/matlabcentral/fileexchange/56859-passive-dynamic-walking
%
% Based on:
%
% M. Garcia, A. Chatterjee, A. Ruina, and M. Coleman, "The Simplest
% Walking Model: Stability, Complexity, and Scaling," ASME Journal of
% Biomedical Engineering, Vol. 120, No. 2, pp. 281-288, 1998.
% http://dx.doi.org/10.1115/1.2798313
% Incline slope angle in radians
gam = 0.027; % Values < 0.0151 are period-1 stable, values > 0.019 are unstable
% Use persisent variable to state of dynamic system between frames
persistent y0
if isempty(y0)
% Calculate stable initial conditions
y0(1) = 0.970956*gam^(1/3)-0.270837*gam;
y0(2) = -1.045203*y0(1)+1.062895*gam;
y0(3) = 2*y0(1);
y0(4) = y0(2)*(1-cos(y0(3)));
% Initialize drawing
plotwalker(y0, false, gam);
return;
end
% TFINAL integration time in seconds
tf = 0.3;
% Turn on collision detection
opts = odeset('Events', @collision);
% Integrate to TFINAL or collision condition
[t, y] = ode45(@(t, y)eom(t, y, gam), [0 tf], y0, opts);
% Determine if integration stopped due to collision
iscollision = (t(end) ~= tf);
% Update persistent y0 to last state of integration
y0 = y(end, :);
% Draw walker
plotwalker(y0, iscollision, gam);
% Mapping to calculate new initial conditions after collision
if iscollision
c2y1 = cos(2*y0(1));
y0 = [-y0(1); c2y1*y0(2); -2*y0(1); c2y1*(1-c2y1)*y0(2)];
end
end
function ydot = eom(~, y, gam)
% First order differential equations for Simplest Walking Model
% y(1): theta
% y(2): thetadot
% y(3): phi
% y(4): phidot
ydot2 = sin(y(1)-gam);
ydot = [y(2); ydot2; y(4); ydot2+sin(y(3))*(y(2)^2-cos(y(1)-gam))];
end
function [val, ist, dir] = collision(~, y)
% Check for heelstrike collision using zero-crossing detection
val = y(3)-2*y(1); % Geometric collision condition, when = 0
ist = 1; % Stop integrating if collision found
dir = 1; % Condition only true when passing from - to +
end
function plotwalker(y, iscollision, gam)
% Simple drawing routine to animate passive dynamic walker
% Leg length
L = 1.5;
persistent xst stleg swleg hip
if isempty(xst)
xst = [0; 0];
[xm, xsw] = kinematics(y, xst, gam, L);
% Set up plot
figure('Color', 'w', 'Renderer', 'painters'); %#ok<FGREN>
w = 4.221;
axis([0 1.5*w -1.5*xm(2) 1.5*xm(2)]);
axis off;
set(gca, 'LooseInset', get(gca, 'TightInset'));
% Draw incline
line([xsw(1) 0.85*w], [xsw(2) (xsw(1)-0.85*w)*tan(gam)], 'Color', [0.55 0.27 0.08]);
% Set line and marker colors and styles
stleg = line('Color', [0 0 0.6], 'LineWidth', 1);
swleg = line('Color', [0 0 1], 'LineWidth', 2);
hip = line('Color', [0 0.2 0.6], 'LineStyle', 'none', 'Marker', '.', 'MarkerSize', 30);
end
% Calculate hip and swing foot positions
[xm, xsw] = kinematics(y, xst, gam, L);
% Update locations of hip and swing foot
set(stleg, 'XData', [xst(1) xm(1)], 'YData', [xst(2) xm(2)]);
set(swleg, 'XData', [xsw(1) xm(1)], 'YData', [xsw(2) xm(2)]);
set(hip, 'XData', xm(1), 'YData', xm(2));
% On collision switch stance and swing legs
if iscollision
xst = xsw;
h = stleg;
stleg = swleg;
swleg = h;
end
end
function [xm, xsw] = kinematics(y, xst, gam, L)
% Calculate forward kinematics for hip (xm) and swing foot (xsw) positions
y1g = y(1)-gam;
xm = xst+L*[-sin(y1g); cos(y1g)];
xsw = xm-L*[sin(y(3)-y1g); cos(y(3)-y1g)];
end
Movie
Audio
This submission does not have audio.