Code covered by the BSD License  

Highlights from
Inverse Optimal Functions for Motoman HP-3 Tip Precision

image thumbnail

Inverse Optimal Functions for Motoman HP-3 Tip Precision

by

 

A population based optimization increases pointing precision for a planar robotic arm.

Clusters=ClusterGenerate_4(TestPoint,J,J_Grad,Y_Grad,Options)
function Clusters=ClusterGenerate_4(TestPoint,J,J_Grad,Y_Grad,Options)
%% Expand intervals as possible

% Set up outputs
X_Tips=[TestPoint,TestPoint];
Y_Tips=Options.Y([TestPoint,TestPoint]);
J_Tips=Options.J([TestPoint,TestPoint]);
Clusters.x=TestPoint;
Clusters.y=Options.Y(TestPoint);
Clusters.j=Options.J(TestPoint);
if isfield(Options,'Verbose')
    PrintOut=Options.Verbose;
else
    PrintOut=false;
end
OutputStr=repmat(' %g,',1,size(TestPoint,1));
OutputStr(end)=[];

% Check for lower extensions
Finished=false;
indy=0;

if PrintOut
fprintf(['\nForming Cluster about',OutputStr,'\n'],TestPoint);
end
while ~Finished
    indy=indy+1;
    Grad_Out1=Options.Grad_Y(TestPoint);
    tempF2=max(sum(Grad_Out1.^2,1).^.5,Options.MinGrad_Out);
    Grad_Out2=Grad_Out1./repmat(tempF2,size(TestPoint,1),1);
    Delta_X=-Options.Gamma_Out*Grad_Out2;
    % No need to perserve step direction exactly, so use simple method.
    % This does artifically reduce step length, corrected
    % This doesn't step to border and then along border, so isn't most efficient
    TestPoint_n=TestPoint+Delta_X;
    Adj_Delta_X=any((TestPoint_n<Options.X_range(:,1))|(TestPoint_n>Options.X_range(:,2)));
    if Adj_Delta_X
%         Delta_X=PullStepInside(TestPoint_n,Delta_X,Options.X_range);
        Delta_X((TestPoint_n<Options.X_range(:,1))|...
                (TestPoint_n>Options.X_range(:,2)))=0;
        Delta_X=Options.Gamma_Out*Delta_X/max(norm(Delta_X),Options.MinGrad_Out);
    end
    TestPoint=TestPoint+Delta_X;
    if PrintOut
        fprintf(['New Test Point:',OutputStr,'\n'],TestPoint);
    end
    TestPoint=max(min(TestPoint,Options.X_range(:,2)),Options.X_range(:,1));
    Settled=false;
    Options2=Options;
    for kim=1:Options.MaxTestSteps
        Delta_X=PSO_OptFun_CostDescent_Armijo_1(TestPoint,Options2.CostStepOpt);
        TestPoint_n=TestPoint+Delta_X;
%         disp(TestPoint_n.')
        Adj_Delta_X=any(TestPoint_n<Options.X_range(:,1))|...
            any(TestPoint_n>Options.X_range(:,2));
        if Adj_Delta_X
            [Delta_X,TestPoint]=PullStepInside3(TestPoint_n,J(TestPoint_n),J_Grad(TestPoint_n),...
                Delta_X,J,J_Grad,Y_Grad,Options2);
        else
            Particles_J_old=J(TestPoint); %NOT an vector
            [TestPoint,Particles_J,Delta_X]=ArmijoStep_1(...
                TestPoint,TestPoint+Delta_X,...
                Particles_J_old,J_Grad(TestPoint),Options2);
            % will not cross boundary, so no need to check
        end
% %         disp(Delta_X.')
%         TestPoint=TestPoint+Delta_X;
% %         disp(TestPoint.')
        if norm(Delta_X)<Options.MaxGradientSize
            Settled=true;
            break
        end
    end
    if Settled
        MiddleOutput=(Options.Y(TestPoint)-Y_Tips(1))<0;
        NearPoints=(norm(TestPoint-X_Tips(:,1))<Options.MaxClusterDist);
        TooNearPoints=(norm(TestPoint-X_Tips(:,1))<Options.MinClusterDist);
        OutOfRange=~(all(TestPoint>=Options.X_range(:,1)-...
            Options.BoundaryViolationAllowance)&&...
            all(TestPoint<=Options.X_range(:,2)+...
            Options.BoundaryViolationAllowance));
        if TooNearPoints||OutOfRange
            Finished=true;
            if PrintOut
            if TooNearPoints
            fprintf(['Point settled too near last point: Current',OutputStr,' Last',OutputStr,'\n'],...
                TestPoint, X_Tips(:,1));
            else
            fprintf(['Point settled out of range: Current',OutputStr,' Previous step',OutputStr,' Last Point',OutputStr,'\n'],...
                TestPoint, TestPoint-Delta_X, X_Tips(:,1));
            end
            end
        elseif MiddleOutput&&NearPoints
            Clusters.x=[...
                TestPoint,Clusters.x];
            Clusters.y=[...
                Options.Y(TestPoint),Clusters.y];
            Clusters.j=[...
                Options.J(TestPoint),Clusters.j];
            Y_Tips(1)=Clusters.y(1);
            X_Tips(:,1)=Clusters.x(:,1);
            J_Tips(1)=Clusters.j(1);
            if PrintOut
            fprintf(['New Cluster Point',OutputStr,'\n'],...
                Clusters.x(:,1));
            end
        else
            Finished=true;
            if PrintOut
            if ~NearPoints
            fprintf(['Point settled too far from last point: Current',OutputStr,' Last',OutputStr,'\n'],...
                TestPoint, X_Tips(:,1));
            else
            fprintf('Output no longer decreasing: Current %g; Previous %g\n',...
                Options.Y(TestPoint),Y_Tips(:,1));
            end
            end
        end
    else
        Finished=true;
        if PrintOut
        fprintf(['Point did not settle within max itterations for lower bound at',OutputStr,'\n'],TestPoint);
            fprintf(['Cost Gradient,',OutputStr,' Output Gradient',OutputStr,' Step',OutputStr,'\n'],...
            Options.Grad_J(TestPoint),Options.Grad_Y(TestPoint), ...
            Delta_X);
        end
    end
end
% Check for upper extensions
Finished=false;
indy=0;
TestPoint=X_Tips(:,2);
while ~Finished
    indy=indy+1;
    % Find step direction in output direction
    Grad_Out1=Options.Grad_Y(TestPoint);
    tempF2=max(sum(Grad_Out1.^2,1).^.5,Options.MinGrad_Out);
    Grad_Out2=Grad_Out1./repmat(tempF2,size(TestPoint,1),1);
    Delta_X=Options.Gamma_Out*Grad_Out2;
    % No need to perserve step direction exactly, so use simple method.
    % This does artifically reduce step length, corrected
    % This doesn't step to border and then along border, so isn't most efficient
    TestPoint_n=TestPoint+Delta_X;
    Adj_Delta_X=any((TestPoint_n<Options.X_range(:,1))|(TestPoint_n>Options.X_range(:,2)));
    if Adj_Delta_X
%         Delta_X=PullStepInside(TestPoint_n,Delta_X,Options.X_range);
        Delta_X((TestPoint_n<Options.X_range(:,1))|...
                (TestPoint_n>Options.X_range(:,2)))=0;
        Delta_X=Options.Gamma_Out*Delta_X/max(norm(Delta_X),Options.MinGrad_Out);
        % % % NOTE: this doesn't step right to edge % % % 
    end
    TestPoint=TestPoint+Delta_X;
    if PrintOut
        fprintf(['New Test Point:',OutputStr,'\n'],TestPoint);
    end
    TestPoint=max(min(TestPoint,Options.X_range(:,2)),Options.X_range(:,1));
    Settled=false;
    Options2=Options;
    for kim=1:Options.MaxTestSteps
        Delta_X=PSO_OptFun_CostDescent_Armijo_1(TestPoint,Options2.CostStepOpt);
        TestPoint_n=TestPoint+Delta_X;
%         if PrintOut
%             fprintf(['Test Point with step:',OutputStr,'\n'],TestPoint_n);
%         end
        Adj_Delta_X=any(TestPoint_n<Options.X_range(:,1))|...
            any(TestPoint_n>Options.X_range(:,2));
        if Adj_Delta_X
            temp_nan=Delta_X;
            [Delta_X,TestPoint]=PullStepInside3(TestPoint_n,J(TestPoint_n),J_Grad(TestPoint_n),...
                Delta_X,J,J_Grad,Y_Grad,Options2);
            if any(isnan(Delta_X))
                fprintf(['Faulty TestPoint:',OutputStr,'\n'],TestPoint_n);
                fprintf(['Faulty Delta_X:',OutputStr,'\n'],temp_nan);
                fprintf(['Resultant Delta_X:',OutputStr,'\n'],Delta_X);
                return
            end
        else
            Particles_J_old=J(TestPoint); %NOT an vector
            [TestPoint,Particles_J,Delta_X]=ArmijoStep_1(...
                TestPoint,TestPoint+Delta_X,...
                Particles_J_old,J_Grad(TestPoint),Options2);
            % will not cross boundary, so no need to check
        end
%         if PrintOut
%             fprintf(['Adj Test Point step :',OutputStr,'\n'],TestPoint);
%         end
        if norm(Delta_X)<Options.MaxGradientSize
            Settled=true;
            break
        end
    end
    if Settled
        MiddleOutput=...
            (Options.Y(TestPoint)-Y_Tips(:,2))>0;
        NearPoints=(norm(TestPoint-X_Tips(:,2))<Options.MaxClusterDist);
        TooNearPoints=(norm(TestPoint-X_Tips(:,2))<Options.MinClusterDist);
        OutOfRange=~(all(TestPoint>=Options.X_range(:,1)-...
            Options.BoundaryViolationAllowance)&&...
            all(TestPoint<=Options.X_range(:,2)+...
            Options.BoundaryViolationAllowance));
        if TooNearPoints||OutOfRange
            Finished=true;
            if PrintOut
            if TooNearPoints
            fprintf(['Point settled too near last point: Current',OutputStr,' Last',OutputStr,'\n'],...
                TestPoint, X_Tips(:,2));
            else
            fprintf(['Point settled out of range: Current',OutputStr,' Previous step',OutputStr,' Last Point',OutputStr,'\n'],...
                TestPoint, TestPoint-Delta_X, X_Tips(:,2));
            end
            end
        elseif MiddleOutput&&NearPoints
            Clusters.x=[...
                Clusters.x,TestPoint];
            Clusters.y=[...
                Clusters.y,Options.Y(TestPoint)];
            Clusters.j=[...
                Clusters.j,Options.J(TestPoint)];
            Y_Tips(2)=Clusters.y(end);
            X_Tips(:,2)=Clusters.x(:,end);
            J_Tips(2)=Clusters.j(end);
            if PrintOut
            fprintf(['New Cluster Point',OutputStr,'\n'],...
                Clusters.x(:,end));
            end
        else
            Finished=true;
            if PrintOut
            if ~NearPoints
            fprintf(['Point settled too far from last point: Current',OutputStr,' Last',OutputStr,'\n'],...
                TestPoint, X_Tips(:,2));
            else
            fprintf('Output no longer decreasing: Current %g; Previous %g\n',...
                Options.Y(TestPoint),Y_Tips(:,2));
            end
            end
        end
    else
        Finished=true;
        if PrintOut
        fprintf(['Point did not settle within max itterations for lower bound at',OutputStr,'\n'],TestPoint);
        fprintf(['Cost Gradient',OutputStr,' Output Gradient',OutputStr,' Step',OutputStr,'\n'],...
            Options.Grad_J(TestPoint),Options.Grad_Y(TestPoint), ...
            Delta_X);
        end
    end
end

Contact us