%% %% 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'.