# TikZ signal flow graphs illustrating Mason's rule

I'm trying to make some Automatic Control charts illustrating Mason's rule, but couldn't find any suitable library. Is there any way to ease the process of creating these with TikZ?

An example can be found on this page in section sfg.m4: Signal-flow graphs

I found this way to make one of the flows, however, I wonder if there is any clearer or simpler way to do this drawing, using any library (as when making circuits or blocks with the libraries a \usepackage{blocks} or \usepackage{schemabloc} or \usepackage{circuitikz}) so that the code is not as large and is more clear and clean the program?

\begin{tikzpicture}
\begin{pgfonlayer}{nodelayer}
\node [style=none] (0) at (1, 1) {};
\node [style=none] (1) at (-4, 0.5) {$\frac{1}{K}$};
\node [style=none] (2) at (-2, 0.5) {$\frac{K}{M}$};
\node [style=none] (3) at (0, 0.5) {$s^{-1}$};
\node [style=none] (4) at (2, 0.5) {$s^{-1}$};
\node [style=none] (5) at (-5, -0) {};
\node [style=none] (6) at (-4, -0) {};
\node [style=none] (7) at (-3, -0) {};
\node [style=none] (8) at (-2, -0) {};
\node [style=none] (9) at (-1, -0) {};
\node [style=none] (10) at (0, -0) {};
\node [style=none] (11) at (1, -0) {};
\node [style=none] (12) at (2, -0) {};
\node [style=none] (13) at (3, -0) {};
\node [style=none] (14) at (0, -0.75) {};
\node [style=none] (15) at (0, -1.5) {};
\end{pgfonlayer}
\begin{pgfonlayer}{edgelayer}
\draw [-triangle 60] (9.center) to (10.center);
\draw [bend right] (0.center) to (9.center);
\draw [-triangle 60, bend left, looseness=0.75] (11.center) to (14.center);
\draw [-triangle 60, bend left] (0.center) to (13.center);
\draw [-triangle 60] (11.center) to (12.center);
\draw [-triangle 60] (5.center) to (6.center);
\draw [bend right] (7.center) to (15.center);
\draw [bend left] (14.center) to (9.center);
\draw (6.center) to (7.center);
\draw [-triangle 60] (7.center) to (8.center);
\draw [-triangle 60, bend right] (15.center) to (13.center);
\draw (10.center) to (11.center);
\draw (12.center) to (13.center);
\draw (8.center) to (9.center);
\end{pgfonlayer}
\end{tikzpicture}
-
Welcome to TeX.sx! You don't have to sign with your name since it automatically appears in the lower right corner of your post. – Torbjørn T. Apr 19 '12 at 5:05
Please check the automata library examples in the manual. – percusse Apr 19 '12 at 6:07

Here is another one with slightly more complicated definition but still easy to use. I have defined some styles to make it a little easier to read the code. Also I defined a label placing option label revd to switch the location of the label above or below. The amark is for placing an arrow and a node at the middle (hi-jacked from one of my earlier answers ) .

The reason for weird names is to avoid the clash with other libraries and I am not sure about terminal. Please test with circuit library (or related packages) and change those instances if so. You can automate even more but it should give you a head start.

I tried to use as many different options as possible to show the variety and you can always search in the manual what each option does (apart from the ones I have defined).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\newif\iflabrev
\begin{document}
\begin{tikzpicture}
[
label revd/.is if=labrev,
%label revd/.default=true,
amark/.style={
decoration={
markings,
mark=at position {0.5} with {
\arrow{stealth},
\iflabrev \node[above] {#1};\else \node[below] {#1};\fi
}
},
postaction={decorate}
},
terminal/.style 2 args={draw,circle,inner sep=2pt,label={#1:#2}},
]

%Place the nodes
\node[terminal={below}{$f(t)$}] (a) at (0,0) {};
\node[terminal={below left}{$y_1$}] (b) at (3cm,0) {};
\node[terminal={below left}{$\ddot{y}_2$}] (c) at (6cm,0) {};
\node[terminal={[xshift=-4mm]below right}{$\dot{y}_2=x_2$}] (d) at (9cm,0) {};
\node[terminal={below right}{$y_2=x_1$}] (e) at (12cm,0) {};
%Draw the connections
\draw[amark=$1/K$] (a) to (b);
\draw[amark=$K/M$] (b) to (c);
\draw[amark=$s^{-1}$] (c) to (d);
\draw[amark=$s^{-1}$] (d) to (e);
\draw[amark=$-B/M$] (d) to[bend left=45] (c);
\draw[amark=$1$,label revd] (e) to[bend left=50] (b);
\draw[amark=$-K/M$,label revd] (e) to[bend right=50] (c);
\end{tikzpicture}
\end{document}

-
thank you very much, this has been very useful for my – Carlos E. Apr 21 '12 at 0:28

Here are some usefull things:

• In this question Caramdir shows nicely how to put arrows to the middle of a line. I used this to define the midarrow style.

• I placed the nodes manually, three units apart. You could also use relative positioning, see section 3.8 of the TikZ/PGF manual.

• An edge from a node to it self might be done using (a) to (a). You can use in=degree and out=degree to specify where the lines leave and enter.

• In Order to get the loops smaller or bigger, you can play with the looseness key.

• To draw bent lines, you can use the straight forward notion bend left=degrees or bend right=degrees.

An example, the bottom left one:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,arrows}

\begin{document}

\begin{tikzpicture}[midarrow/.style={decoration={markings, mark=at position 0.5 with {\arrow{stealth}}},postaction={decorate}}]
\node[draw,circle,label=90:$r_2$] (r2) at (0,0) {};
\node[draw,circle,label=90:$r_1$] (r1) at (0,3) {};
\node[draw,circle,label=0:$x_2$] (x2) at (3,0) {};
\node[draw,circle,label=0:$x_1$] (x1) at (3,3) {};

\draw[midarrow] (r1) -- node[above] {1} (x1);
\draw[midarrow] (r2) -- node[above] {1} (x2);

\draw[midarrow,looseness=20] (x1) to[out=50,in=130] node[above] {$q_{11}$} (x1);
\draw[midarrow,looseness=40] (x1) to[out=40,in=-40] node[right] {$a_{11}$} (x1);
\draw[midarrow,looseness=20] (x2) to[out=230,in=310] node[below] {$q_{22}$} (x2);

\draw[midarrow,bend right=30] (x1) to node[left] {$a_{21}$} (x2);
\draw[midarrow,bend right=30] (x2) to node[right] {$a_{12}$} (x1);
\end{tikzpicture}

\end{document}

-
thank you very much, this has been very useful for my – Carlos E. Apr 21 '12 at 0:21

Here an answer with tkz-graph. This example is funny because I use decoration to compute the labels. I need to update vey quickly tkz-graph because there are a lot of codes insubstantial.

\documentclass[11pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[upright]{fourier}
\usepackage{tkz-graph}
\usetikzlibrary{arrows,decorations.markings}

\begin{document}
% the next 4 lines are define labels and arrows
\newcounter{indice}
\setcounter{indice}{1}
\def\letter{G}\def\myarrow{>}
\tikzset{position/.style = {below}}

\tikzset{VertexStyle/.append style = {% set the style of vertices
shape        = circle,
fill         = lightgray!50,
text         = black,
inner sep    = 2pt,
outer sep    = 0pt,
minimum size= 32 pt}}

\begin{tikzpicture} [decoration={% I place the arrow and the label and step the indice
markings,
mark= at position .5 with {\arrow[>=latex',line width=1.8 pt]{\myarrow},
\node[position]{$\letter_\theindice$};\stepcounter{indice}
}}]

\Vertices[unit=3]{line}{1,2,3,4} % I get the vertices with one macro

\tikzset{EdgeStyle/.style = {postaction={decorate}}}
\Edges(1,2,3,4)%

\def\letter{F}\def\myarrow{<}\setcounter{indice}{2}

\tikzset{EdgeStyle/.append style = {-,out=45,in=135}}
\Edge(1)(2)

\tikzset{EdgeStyle/.append style = {-,out=80,in=100}}
\Edge(1)(3)

\tikzset{position/.style = {above}}
\def\letter{P} \setcounter{indice}{1}

\foreach \v in {1,...,4}
{\Loop[dist=3cm,dir=SO,style={-}](\v) }
\end{tikzpicture}
\end{document}

-