%%
%% This is file `robotarm.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% robotarm.dtx  (with options: `robotarm-package')
%%
%% This is a generated file.
%%
%% Copyright (C) 2021 by M.J.W. Snippe
%% -----------------------------------
%%
%% This file may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either
%% version 1.3 of this license or (at your option) any later
%% version. The latest version of this license is in:
%%
%%     http://www.latex-project.org/lppl.txt
%%
%% and version 1.3 or later is part of all distributions of
%% LaTeX version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status
%% `author-maintained'.
%%
%% This work consists of the files found at github.com/max-sn/robotarm.
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{robotarm}
 [2022/03/08 v0.1 Tikz commands to draw planar robot arms]

\RequirePackage{tikz}

\usetikzlibrary{patterns}

\makeatletter

\newif\ifRA@robotarm@drawannotations

\pgfkeys{
 /robotarm/base link/.cd,
   width/.code={\pgfmathsetmacro\RA@baselink@width{#1}},
   width=0.6,
   height/.code={\pgfmathsetmacro\RA@baselink@height{#1}},
   height=0.3,
   world width/.code={\pgfmathsetmacro\RA@baselink@worldwidth{#1}},
   world width=1.0,
   world height/.code={\pgfmathsetmacro\RA@baselink@worldheight{#1}},
   world height=0.3,
   draw base link/.code={%
     \path[link style]
       (-1/2*\RA@baselink@width,0)
       arc (180:0:1/2*\RA@baselink@width)
       -- ++ (0, -\RA@baselink@height)
       -- ++ (-\RA@baselink@width, 0)
       -- cycle;
   },
   draw world/.code={%
     \path[world style]
       (-1/2*\RA@baselink@worldwidth,-\RA@baselink@height)
       arc (180:360:{1/2*\RA@baselink@worldwidth}
         and {\RA@baselink@worldheight}) -- cycle;
     \path[draw, world style]
       (-1/2*\RA@baselink@worldwidth,-\RA@baselink@height)
       -- ++(\RA@baselink@worldwidth,0);
   },
 /robotarm/link/.cd,
   width/.code={\pgfmathsetmacro\RA@link@width{#1}},
   width=0.4,
   length/.code={\pgfmathsetmacro\RA@link@length{#1}},
   length=2.0,
   joint radius/.code={\pgfmathsetmacro\RA@link@jointradius{#1}},
   joint radius=0.25,
   draw link/.code={%
     \path[link style]
       (0,1/2*\RA@link@width)
       -- ++ ( \RA@link@length, 0)
       arc (90:-90:1/2*\RA@link@width)
       -- ++ (-\RA@link@length, 0)
       arc (270:90:1/2*\RA@link@width)
       -- cycle;
   },
   draw joint/.code={%
     \path[link style]
       (0,0) circle (\RA@link@jointradius);
     \path[link style]
       (0,0) circle (1/3*\RA@link@jointradius);
   },
 /robotarm/end effector/.cd,
   width/.code={\pgfmathsetmacro\RA@endeff@width{#1}},
   width=0.4,
   length/.code={\pgfmathsetmacro\RA@endeff@length{#1}},
   length=2,
   joint radius/.code={\pgfmathsetmacro\RA@endeff@jointradius{#1}},
   joint radius=0.25,
   gripper radius/.code={\pgfmathsetmacro\RA@endeff@gripperradius{#1}},
   gripper radius=0.3,
   gripper opening angle/.code={%
     \pgfmathsetmacro\RA@endeff@gripperopeningangle{#1}},
   gripper opening angle=60,
   draw joint/.code={%
     \path[link style]
       (0,0) circle (\RA@endeff@jointradius);
     \path[link style]
       (0,0) circle (1/3*\RA@endeff@jointradius);
   },
   draw link/.code={%
     \pgfmathsetmacro{\link@startangle}{%
       180-asin(1/2*\RA@endeff@width/\RA@endeff@gripperradius)}
     \pgfmathsetmacro{\link@endangle}{%
       180+asin(1/2*\RA@endeff@width/\RA@endeff@gripperradius)}

     \path[link style]
       (\RA@endeff@length, 0)
       ++ (\link@startangle:\RA@endeff@gripperradius)
       arc (\link@startangle:\link@endangle:\RA@endeff@gripperradius)
       -- (0,0|-0,-1/2*\RA@endeff@width)
       arc (-90:90:1/2*\RA@endeff@width)
       -- cycle;
   },
   draw end effector/.code={
     \draw[link style]
       (\RA@endeff@length, 0)
       ++ (-1/2*\RA@endeff@gripperopeningangle:%
           \RA@endeff@gripperradius)
       arc [start angle=-1/2*\RA@endeff@gripperopeningangle,
            delta angle=-360+\RA@endeff@gripperopeningangle,
            radius=\RA@endeff@gripperradius]
       -- ++(180+1/2*\RA@endeff@gripperopeningangle:%
             0.4*\RA@endeff@gripperradius)
       arc [start angle=1/2*\RA@endeff@gripperopeningangle,
            delta angle=360-\RA@endeff@gripperopeningangle,
            radius=0.6*\RA@endeff@gripperradius]
       -- ++(-1/2*\RA@endeff@gripperopeningangle:%
             0.4*\RA@endeff@gripperradius)
       -- cycle;
   },
 /robotarm/.cd,
   draw annotations/.is if=RA@robotarm@drawannotations,
   draw annotations=true,
   every annotation/.style={},
   every length annotation/.style={},
   every length annotation arrow/.style={draw,->},
   every length annotation node/.style={circle,inner sep=0.5pt},
   every length annotation help line/.style={draw,help lines},
   every angle annotation/.style={},
   every angle annotation arrow/.style={draw,->},
   every angle annotation node/.style={},
   every angle annotation help line/.style={draw,help lines},
   base link/.code=\pgfkeys{/robotarm/base link/.cd,#1},
   link/.code=\pgfkeys{/robotarm/link/.cd,#1},
   end effector/.code=\pgfkeys{/robotarm/end effector/.cd,#1},
   geometry/.code=\pgfkeys{/robotarm/geometry/.cd,#1},
   config/.code=\pgfkeys{/robotarm/config/.cd,#1},
   spacing/.code=\pgfkeys{/robotarm/annotations/spacing/.cd,#1},
   labels/.code=\pgfkeys{/robotarm/annotations/labels/.cd,#1},
   styles/.code=\pgfkeys{/robotarm/styles/.cd,#1},
 /robotarm/geometry/.cd,
   a0/.initial=0,
   a/.initial=2,
   r/.initial=0.25,
   w/.initial=0.4,
 /robotarm/config/q/.initial=0,
 /robotarm/frames/.cd,
   in link 0/.style={},
   in end effector/.style={
     /robotarm/frames/in link \RA@robotarm@numlinks,
     shift={%
       (\pgfkeysvalueof{/robotarm/geometry/a\RA@robotarm@numlinks},0)},
   },
   in world/.style={
     shift={(0,-\RA@baselink@height)}
   },
 /robotarm/styles/.cd,
   world/.style={pattern=north west lines},
   link/.style={
     draw,
     fill=lightgray,
   },
   link 0/.style={/robotarm/styles/link},
 /robotarm/annotations/.cd,
   spacing/.cd,
     a/.initial=3,
     q/.initial=1/2,
 /robotarm/annotations/.cd,
   labels/.cd,
     a/.initial=a,
     q/.initial=q,
}
\tikzset{
 link style/.style={/robotarm/styles/link},
 world style/.style={/robotarm/styles/world},
}
\newcommand\robotarmset[1]{%
 \pgfkeys{/robotarm/.cd,#1}%
}
\newcommand\robotArmLink[1][]{
 \begingroup
   \pgfkeys{/robotarm/link/.cd,#1}

   \pgfkeys{/robotarm/link/draw link}
   \pgfkeys{/robotarm/link/draw joint}
 \endgroup
}
\newcommand\robotArmEndEffector[1][]{
 \begingroup
   \pgfkeys{/robotarm/end effector/.cd,#1}

   \pgfkeys{/robotarm/end effector/draw link}
   \pgfkeys{/robotarm/end effector/draw joint}
   \pgfkeys{/robotarm/end effector/draw end effector}

 \endgroup
}
\newcommand\robotArmBaseLink[1][]{
 \begingroup
   \pgfkeys{/robotarm/base link/.cd,#1}

   \pgfkeys{/robotarm/base link/draw world}
   \pgfkeys{/robotarm/base link/draw base link}
 \endgroup
}
\newcommand\robotArm[2][]{
 \pgfmathtruncatemacro\RA@robotarm@numlinks{#2}
 \def\@tmpkeys{}
 \foreach \@link [remember=\@link as \@prevlink (initially 0)] in %
   {1,...,\RA@robotarm@numlinks}{
   \xdef\@tmpkeys{\@tmpkeys%
     /robotarm/geometry/a\@link/.initial=%
       \pgfkeysvalueof{/robotarm/geometry/a},%
     /robotarm/geometry/r\@link/.initial=%
       \pgfkeysvalueof{/robotarm/geometry/r},%
     /robotarm/geometry/w\@link/.initial=%
       \pgfkeysvalueof{/robotarm/geometry/w},%
     /robotarm/config/q\@link/.initial=%
       \pgfkeysvalueof{/robotarm/config/q},%
     /robotarm/styles/link \@link/.style={/robotarm/styles/link},%
     /robotarm/annotations/labels/a\@link/.initial={%
       $\pgfkeysvalueof{/robotarm/annotations/labels/a}_{\@link}$},%
     /robotarm/annotations/labels/q\@link/.initial={%
       $\pgfkeysvalueof{/robotarm/annotations/labels/q}_{\@link}$},%
     /robotarm/annotations/spacing/a\@link/.initial={%
       \pgfkeysvalueof{/robotarm/annotations/spacing/a}},%
     /robotarm/annotations/spacing/q\@link/.initial={%
       \pgfkeysvalueof{/robotarm/annotations/spacing/q}},%
   }
 }
 \expandafter\pgfkeys\expandafter{\@tmpkeys}
 \pgfkeys{/robotarm/.cd,#1}
 \def\@tmpkeys{}
 \foreach \@link [remember=\@link as \@prevlink (initially 0)] in %
   {1,...,\RA@robotarm@numlinks}{
   \xdef\@tmpkeys{\@tmpkeys%
     /robotarm/frames/in link \@link/.style={%
       /robotarm/frames/in link \@prevlink,
       /tikz/shift={%
         (\pgfkeysvalueof{/robotarm/geometry/a\@prevlink},0)},
       /tikz/rotate={\pgfkeysvalueof{/robotarm/config/q\@link}},
     },
   }
 }
 \expandafter\pgfkeys\expandafter{\@tmpkeys}

 \begin{scope}[/robotarm/frames/in link 0,
               link style/.style={/robotarm/styles/link 0}]
   \robotArmBaseLink
 \end{scope}

 \foreach\link@num in {1,...,\RA@robotarm@numlinks}{
   \begin{scope}[/robotarm/frames/in link \link@num,
                 link style/.style={/robotarm/styles/link \link@num}]

     \ifnum\link@num<\RA@robotarm@numlinks
       \robotArmLink[
         joint radius=\pgfkeysvalueof{/robotarm/geometry/r\link@num},
         length=\pgfkeysvalueof{/robotarm/geometry/a\link@num},
         width=\pgfkeysvalueof{/robotarm/geometry/w\link@num},
       ]
     \else
       \robotArmEndEffector[
         joint radius=\pgfkeysvalueof{/robotarm/geometry/r\link@num},
         length=\pgfkeysvalueof{/robotarm/geometry/a\link@num},
         width=\pgfkeysvalueof{/robotarm/geometry/w\link@num},
       ]
     \fi
   \end{scope}
 }
 \foreach\link@num in {1,...,\RA@robotarm@numlinks}{
   \begin{scope}[/robotarm/frames/in link \link@num]
     \pgfmathsetmacro\link@length{\pgfkeysvalueof{%
       /robotarm/geometry/a\link@num}}
     \pgfmathsetmacro\link@angle{\pgfkeysvalueof{%
       /robotarm/config/q\link@num}}

     \ifRA@robotarm@drawannotations
       \pgfmathsetmacro\link@lengthannotspacing{%
         \pgfkeysvalueof{/robotarm/annotations/spacing/a\link@num}*
           \pgfkeysvalueof{/robotarm/geometry/r\link@num}}
       \pgfmathsetmacro\link@angleannotspacing{%
         \pgfkeysvalueof{/robotarm/annotations/spacing/q\link@num}*
           \link@length}

       % Length annotation help lines
       \path[/robotarm/every annotation,
             /robotarm/every length annotation,
             /robotarm/every length annotation help line]
         (0,0) -- (\link@length,0);
       \path[/robotarm/every annotation,
             /robotarm/every length annotation,
             /robotarm/every length annotation help line]
         (0,0) -- ++ (0,{\link@lengthannotspacing +
           0.1*sign(\link@lengthannotspacing)});
       \path[/robotarm/every annotation,
             /robotarm/every length annotation,
             /robotarm/every length annotation help line]
         (\link@length,0) -- ++ (0,{\link@lengthannotspacing +
           0.1*sign(\link@lengthannotspacing)});
       \path (0,\link@lengthannotspacing)
         -- coordinate[pos=0.5] (coor) ++ (\link@length,0);
       \node[/robotarm/every annotation,
             /robotarm/every length annotation,
             /robotarm/every length annotation node]
         at (coor) (tag)
         {\pgfkeysvalueof{/robotarm/annotations/labels/a\link@num}};
       \path[/robotarm/every annotation,
             /robotarm/every length annotation,
             /robotarm/every length annotation arrow]
         (tag) -- (0,\link@lengthannotspacing);
       \path[/robotarm/every annotation,
             /robotarm/every length annotation,
             /robotarm/every length annotation arrow]
         (tag) -- (\link@length,\link@lengthannotspacing);

       \pgfmathsetmacro\angleannotationcase{%
         ifthenelse(\link@angle==0.0, 0, 1)}
       \ifnum\angleannotationcase>0
         % Angle annotation help lines
         \path[/robotarm/every annotation,
               /robotarm/every angle annotation,
               /robotarm/every angle annotation help line]
           (0,0) -- ++(-\link@angle:{\link@angleannotspacing+0.1});
         \path[/robotarm/every annotation,
               /robotarm/every angle annotation,
               /robotarm/every angle annotation help line]
           (0,0) -- ++(0:{\link@angleannotspacing+0.1});

         % Angle annotation arrow
         \path[/robotarm/every annotation,
               /robotarm/every angle annotation,
               /robotarm/every angle annotation arrow]
           (0,0) ++ (-\link@angle:\link@angleannotspacing)
           arc (-\link@angle:0:\link@angleannotspacing);

         % Angle annotation node
         \node[/robotarm/every annotation,
               /robotarm/every angle annotation,
               /robotarm/every angle annotation node]
           at (-\link@angle/2:\link@angleannotspacing+0.3)
           {\pgfkeysvalueof{/robotarm/annotations/labels/q\link@num}};
       \fi
     \fi
   \end{scope}
 }
 \tikzset{
   in link/.style={/robotarm/frames/in link #1},
   in base link/.style={/robotarm/frames/in link 0},
   in end effector/.style={/robotarm/frames/in end effector},
   in world/.style={/robotarm/frames/in world},
 }
}
\makeatother
\endinput
%%
%% End of file `robotarm.sty'.