Raw File
drawmodel.m
function [h, jntlocs, comlocs] = drawmodel(w,x,posnoffset,h,varargin)
% drawmodel(w, x, posnoffset) draws the 2-d walking model with trunk,
% with the model offset relative to the origin by posnoffset (x and y)
% h = drawmodel(w) draws the model at its fixed point and a position zero
%   and returns the handle to the graphic
% drawmodel(w, x, posnoffset, h) takes the graphics handle h and redraws the
%   model in that handle (useful for animation)
% drawmodel(w, x, posnoffset, h, 'modellinewidth', 4) applies the named
%   options to the model.
%
% Available options: 
%   modellinewidth   thickness of lines for feet and legs, in points
%   footn            number of segments to draw for foot
%   jointsize        size of hip joint circle, in points
%   showgrfs         (0,1) draw arrows for ground reaction force
%   showcomvel       (0,1) draw arrows for COM velocity

% Art Kuo

if nargin < 2 || isempty(x)
  x = get(w, 'xstar'); % assume fixed point if no other info
end

if nargin < 3 || isempty(posnoffset)
  posnoffset = [0; 0]; % if nothing specified, draw it at origin
end

%parms = get(w,'parms'); 
L = 1; R = 0; % Simplest model has few parameters


% drawing parameters
footn = 10; % how many segments to draw in the curved foot
modellinewidth = 4; % how wide are the line segments, in points
jointsize = 10; % how big is the marker at each joint, in points
footsize = 6; % how big are the feet, in points

% arrow parameters
aang = pi/6; scale = 0.05; scale2 = 2; vx2 = 0.4; vy2 = 1.2;

showcomvel = 0; showgrfs = 0;

% Check for options
if nargin > 4
  property_argin = varargin;
  secondargument = property_argin{1};
  % Step through the optional arguments
  while length(property_argin) >= 2,
    prop = property_argin{1};
    val = property_argin{2};
    property_argin = property_argin(3:end);
    switch prop
      case 'modellinewidth'
        modellinewidth = val;
      case 'footn'
        footn = val;
      case 'jointsize'
        jointsize = val;
      case 'footsize'
        footsize = val;
      case 'showgrfs'
        showgrfs = val;
      case 'showcomvel'
        showcomvel = val;

    end % switch
  end % looping through arguments
end % if there are optional arguments


% angles of stance leg, swing leg 
q1 = x(1); q2 = x(1)-x(2); u1 = x(3); u2 = x(3)-x(4);

contactpoint = -q1*R;
%Rot1 = [cos(q1) -sin(q1); sin(q1) cos(q1)];
%Rot2 = [cos(q2) -sin(q2); sin(q2) cos(q2)];

% A foot
%alpha = 0.45; % need to decide on foot length
% generic foot goes from -alpha to +alpha
%footang = linspace(-alpha, +alpha, footn);
%foot = R*[sin(footang); -cos(footang)];

% Points of interest, arranged as [x;y] locations

stfoot = [contactpoint; 0] + posnoffset;
hip = stfoot + [-L*sin(q1); L*cos(q1)];   % hip is where legs and trunk meet
swfoot = hip + [L*sin(q2); -L*cos(q2)];   % heel is end of leg at curved foot

% Leg segments, arranged as [x row; y row]
legs = [stfoot hip swfoot];
feet = [stfoot swfoot];

if showcomvel
  comloc = hip;
  comvel = [-cos(q1) -sin(q1)]*u1;
end

if showgrfs
  [grf,grt,cop] = groundreactionforces(w, x, 0);
  grfloc = stfoot + [cop;0];
end

% form matrices of the x and y positions of line segments, 
% first row is x, second is y, and
% each column is another point on the line

if nargin < 4 || isempty(h) % no handle exists, so create new lines
  h(1) = line(legs(1,:),legs(2,:),'color','b','LineWidth',modellinewidth,'EraseMode','normal');
  h(2) = line(feet(1,:),feet(2,:), 'MarkerSize', footsize, ...
    'MarkerFaceColor', 'k', 'MarkerEdgeColor', 'none', 'Marker', 'o','LineStyle','none' );
  h(3) = line(hip(1), hip(2), 'MarkerFaceColor', 'k', 'MarkerEdgeColor', ...
    'none', 'MarkerSize', jointsize, 'Marker', 'o'); % mark the hip
  if showcomvel
    h(4) = drawcomvel(comvel, comloc);
  end
  if showgrfs
    h(5) = drawgrf(grf, grfloc);
  end
  
else
  set(h(1),'Xdata',legs(1,:),'Ydata',legs(2,:));
  set(h(2),'Xdata',feet(1,:),'Ydata',feet(2,:));
  set(h(3),'Xdata',hip(1,:),'Ydata',hip(2,:));
  if showcomvel
    drawcomvel(comvel, comloc, h(4));
  end
  if showgrfs
    drawgrf(grf, grfloc, h(5));
  end
end % if

end % function

function hgrf = drawgrf(grf, endpt, h, varargin) 
% Draws a grf arrow, with the vector grf
% and with the arrow drawn ending at position endpt
% Also can update the coordinates in an existing handle for the
% arrow, if supplied. Otherwise it draws it from scratch and
% returns the handle.
%
% Optional arguments:
%   gap (0.02)           gap between start of arrow and its origin
%   headsize (0.05)   size of arrowhead
%   arrowang (pi/8)   angle of arrow relative to body   
%   scale (0.5)       determines length of arrow

% optional parameters
gap = 0.02; headsize = 0.05; % headsize determines size of arrowhead
arrowang = pi/8;          % angle of arrow head relative to body
scale = 0.5;     % scale determines length of arrow

if nargin > 3 % we have options
  property_argin = varargin;
  % Step through the optional arguments
  while length(property_argin) >= 2,
    prop = property_argin{1};
    val = property_argin{2};
    property_argin = property_argin(3:end);
    switch prop
      case 'gap'
        numsteps = val;
      case 'scale'
        scale = val;
      case 'arrowang'
        arrowang = val;
      case 'headsize'
        headsize = val;
    end
  end
end

forceang = atan2(grf(2), grf(1));
grf = grf*scale;

gx = -gap*cos(forceang) + endpt(1); gy = -gap*sin(forceang) + endpt(2);

arrowx = gx + [-grf(1) 0 -headsize*cos(forceang+arrowang) NaN 0 -headsize*cos(forceang-arrowang)];
arrowy = gy + [-grf(2) 0 -headsize*sin(forceang+arrowang) NaN 0 -headsize*sin(forceang-arrowang)];

if nargin < 3 || isempty(h),
  hgrf = line(arrowx, arrowy, 'LineWidth',2,'Color','Green');
else
  set(h, 'Xdata', arrowx, 'Ydata', arrowy);
end

end % function hgrf

function hvel = drawcomvel(vel, startpt, h, varargin) 
% Draws a com velocity arrow, with the velocity vel
% and with the arrow drawn starting at position startpt
% Also can update the coordinates in an existing handle for the
% arrow, if supplied. Otherwise it draws it from scratch and
% returns the handle.
%
% Optional arguments:
%   gap (0)           gap between start of arrow and its origin (unused)
%   headsize (0.05)   size of arrowhead
%   arrowang (pi/8)   angle of arrow relative to body   
%   scale (0.5)       determines length of arrow

% optional parameters
gap = 0; headsize = 0.05; % headsize determines size of arrowhead
arrowang = pi/8;          % angle of arrow head relative to body
scale = 0.5;     % scale determines length of arrow

if nargin > 3 % we have options
  property_argin = varargin;
  % Step through the optional arguments
  while length(property_argin) >= 2,
    prop = property_argin{1};
    val = property_argin{2};
    property_argin = property_argin(3:end);
    switch prop
      case 'gap'
        numsteps = val;
      case 'scale'
        scale = val;
      case 'arrowang'
        arrowang = val;
      case 'headsize'
        headsize = val;
    end
  end
end

velang = atan2(vel(2), vel(1));
vel = vel*scale;

arrowx = startpt(1) + [0 vel(1) vel(1)-headsize*cos(velang+arrowang) NaN vel(1) vel(1)-headsize*cos(velang-arrowang)];
arrowy = startpt(2) + [0 vel(2) vel(2)-headsize*sin(velang+arrowang) NaN vel(2) vel(2)-headsize*sin(velang-arrowang)];

if nargin < 3 || isempty(h),
  hvel = line(arrowx, arrowy, 'LineWidth',2,'Color','Black');
else
  set(h, 'Xdata', arrowx, 'Ydata', arrowy);
end

end % function drawcomvel

function out = draw_arrow(startpoint,endpoint,headsize)
%by Ryan Molecke
% accepts two [x y] coords and one double headsize

v1 = headsize*(startpoint-endpoint)/2.5;

theta = 22.5*pi/180;
theta1 = -1*22.5*pi/180;
rotMatrix = [cos(theta)  -sin(theta) ; sin(theta)  cos(theta)];
rotMatrix1 = [cos(theta1)  -sin(theta1) ; sin(theta1)  cos(theta1)];

v2 = v1*rotMatrix;
v3 = v1*rotMatrix1;
x1 = endpoint;
x2 = x1 + v2;
x3 = x1 + v3;
hold on;
fill([x1(1) x2(1) x3(1)],[x1(2) x2(2) x3(2)],[0 0 0]);     % this fills the arrowhead (black)
plot([startpoint(1) endpoint(1)],[startpoint(2) endpoint(2)],'linewidth',2,'color',[0 0 0]);
end
back to top