Code covered by the BSD License

### Jedediah Frey (view profile)

Solves for two unknowns in a mechanical linkage system.

```function varargout=link_solver(varargin)
%
% Generic linkage solver. Most common use is for four bar linkages.
%
% Given a guess, the solver will attempt to start from the guessed
% position. There are linked systems where there may be more than one valid
% solution.
%
% Returns:
%   unknown1: the first unknown given
%   unknown2: the second unknown given
%   all_linkages: a struct with all linkages and angles corrected to 0-360
%
% To solve for any two unknowns, input all other given parameters. Unknown
% information should be inputted as either an empty string ('') or
% empty array ([]). All solutions will be returned with angles between
% 0-360 and linkage lengths positive.
%
% To keep signs and angles correct, select one point and work around clockwise or counter clockwise
% using the length as a positive number and the angle as the absolute angle
% from the horizon. If you wish to input the angle of the linkage from
% 'end' to 'beginning' then you should give the length of the linkage as
% negative.
%
% Example:
% Consider this simple five bar linkage with shown unknowns.
% %
% %          O
% %         / \ ?*
% %        /   \
% %   (5) /     \ (?)
% %      /       \
% %     / 53.87*  \
% %    O           O
% %    |           |
% %    |           |
% %(6) |           | (6)
% %    |           |
% %    | 90*   90* |
% %    O - - - - - O
% %         (6)
%
% %Working clockwise:
%
% %  Linkage 1 is of length 5 and is at 90 degrees.
% %  Linkage 2 is unknown.
% %  Linkage 3 is of length 5 and at 270 degrees.
% %  Linkage 4 is of length 5 and at 180 degrees.
% % Alternative ways to call link_solver that will get the correct solution:
%
% % Inputs can also be given in vector format to simultaneously solve for
% % multiple vector input.
%
% % Supplying a guess for the unknown variables is not manditory, however it
% % is suggested as certain input configurations the solver will correctly
% % solve for the unknowns, although the linkage may not look as expected.
% % No guesses
% % Guesses
%
% % Guesses for multiple solutions to the same linkage measurements

% Author: Jedediah Frey
% Created: May 2010
% Change to enabled to show the results after each loop.
verbose=false;
warning('off','MATLAB:DELETE:FileNotFound'); % Disable warning from tryin to delete temp file name if it doesn't exist.

%% Determine and assign unknown variables.
unknown_idx=find(cellfun('isempty',varargin));
if length(unknown_idx)<2
error('Over constrained system. At least two inputs should be empty.');
elseif length(unknown_idx)>2
error('Under constrained system. Only two inputs should be empty.');
end
% Assign the guessed variables
for i=1:2
if mod(unknown_idx(i),2)
unknown{i}=sprintf('length_%d',floor((unknown_idx(i)+1)/2));
else
unknown{i}=sprintf('angle_%d',floor((unknown_idx(i)+1)/2));
end
if mod(nargin,2)
varargin{unknown_idx(i)}=varargin{end}(:,i)';
else
% Nothing guessed, guess a a positive, non zero, non identical
% number
varargin{unknown_idx(i)}=i;
end
end
%% Determine and assign the given link angles and lengths.
% Create a structure of the bar lengths and input angles
angle=sprintf('angle_%d',i);
end
%% Create the function to calculate the delta & setup loop variables
% Create the static delta function for the given unknown variables.
% Cuts down on symbolic library time.
% Print header if verbrosity is turned on.
if verbose
fprintf('%10s%10s%10s%10s%10s\n','Loop',unknown{1},unknown{2},'Delta 1','Delta 2');
end
%%
% Once the deltas are smaller than the stop criterion, the function exits.
% How accurate should the model be.
stop_criterion=1E-10;
delta_u1=inf;delta_u2=inf; % Set initial stop criterion large.
i=1;
%% Process data.
% While the change is larger than the stop critera (both).
while(stop_criterion<max(abs((delta_u1))) && stop_criterion<max(abs((delta_u2))))
if (mod(i,10000)==0)
error('%d loops executed with no solution, canceleing.',i);
end
% Calculate the changes to the guesses.
if any(isinf([delta_u1,delta_u2])|isnan([delta_u1,delta_u2]))
error('Inf or NaN returned as a delta. Current solution could be unsolveable an indeterminate system.');
end
% If verbose, print current loop.
if verbose
% If the field is an angle, convert it to degrees.
for j=1:2
if strcmp(unknown{j}(1:5),'angle')
else
end
end
% Print the current loop calculations.
fprintf('%10d%10.3f%10.3f%10.3f%10.3f\n',i,tmp{1},tmp{2},delta_u1,delta_u2);
end
% Add the old guess and the delta to form the new guess and repeat.
i=i+1;
end
%% Post processing cleanup.
% If more than one solution was solved for.
% For each of the solutions
for i=1:numel(f);
end
end
end
end
% Orient the bars so that all lengths are positive and all angles are
% 0-360.
% Convert radians back to degrees.
a=sprintf('angle_%d',i);
end

%% Output Processing.
% Assign the variables to return.
switch nargout
case {0,1}
% If there was more than one unknown position solved for (matrix
% input) then create an array of structures for each given input.
% For each of the solved linkage solutions
% For each length/angle
for i=1:numel(f);
end
end
end
case 2
% Put into
angle=sprintf('angle_%d',i);
end
otherwise
error('Incorrect number of outputs');
end
% Delete the temporary function.
delete([m_file '.m']);
end

%% Helper Functions.
% Orient the bars so that all lengths are positive and all angles are
% 0-360.
% If any is less than 0
angle=sprintf('angle_%d',i);
% And rotate the angle by 180 degrees still (in radians)
% Orient bar with positive length.
end
end
end

function lon = wrapTo360(lon)
% wrapTo360 Wrap angle in degrees to [0 360]
%
%   lonWrapped = wrapTo360(LON) wraps angles in LON, in degrees, to the
%   interval [0 360] such that zero maps to zero and 360 maps to 360.
%   (In general, positive multiples of 360 map to 360 and negative
%   multiples of 360 map to zero.)
%