tikz-pgf – How to Draw Multi-Blocks Block Diagram in TikZ?

blocktikz-pgftikz-styles

I am trying to draw this block diagram
enter image description here

I am a beginner and I started with this code

\begin{figure}
\centering
\tikzstyle{block} = [draw, fill=white, rectangle, 
minimum height=3em, minimum width=6em]
\tikzstyle{sum} = [draw, fill=white, circle, node distance=1cm]
\tikzstyle{input} = [coordinate]
\tikzstyle{output} = [coordinate]
\tikzstyle{pinstyle} = [pin edge={to-,thin,black}]

\begin{tikzpicture}[auto, node distance=2cm,>=latex']
    
    \node [input, name=input] {};
    \node [sum, right of=input] (sum) {};
    \node [block, right of=sum] (controller) {Controller};
    \node [block, right of=controller, pin={[pinstyle]above:D},
    node distance=3cm] (system) {System};
    
    \draw [->] (controller) -- node[name=u] {$u$} (system);
    \node [output, right of=system] (output) {};
    \node [block, below of=u] (measurements) {Measurements};
    
    \draw [draw,->] (input) -- node {$r$} (sum);
    \draw [->] (sum) -- node {$e$} (controller);
    \draw [->] (system) -- node [name=y] {$y$}(output);
    \draw [->] (y) |- (measurements);
    \draw [->] (measurements) -| node[pos=0.99] {$-$} 
    node [near end] {$y_m$} (sum);
\end{tikzpicture}
\caption{Caption}
\label{fig:my_label}
\end{figure}

which results in

enter image description here

Kindly help me out here. I need to understand this multi sumer block diagram. Appreciate any help!

Best Answer

As I like to use TikzEdt to quick draw my diagrams in TikZ, my style converged to defining nodes previously in a scope and then another scope to all connections.

As a control Eng. myself, I have already created my own styles with tikzset and I reuse them as often as I can. So please, don't bother with my custom styles: addCross, mySimpleArrow and myBlockOpacity. The main tip I can give is to create flexible commands (with args) and define a default style. That's a huge improvement from the basic usage.

Notice I didn't displaced to labels exactly where your example presents; I used my addCross, you may change it to display the symbols in other positions, or just use a circle and manually displace the symbols. I also didn't change any font since I don't know which one you would like to use. You may check fonts here.

To give a good example of how some parameters interacts, I let colors red and purple in the code. Just change them as you need.

Same is true for commands minimum height and minimum width. Change them to better fit your document.

To start and finish arrows side by side, I used a technique with[yshift=<measure>] provided by This answer.

Edit note: I corrected e_2 to u_0 after the Non-linear block. My mistake while copying the diagram.

The MWE follows:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{addCross/.style n args={6}{
    minimum size={#5 mm}, %minimum height=10mm,
    path picture={
      \draw[#6]
      (path picture bounding box.south east) -- (path picture bounding box.north west)
      (path picture bounding box.south west) -- (path picture bounding box.north east);
      \node at ($(path picture bounding box.south)!0.4!(path picture bounding box.center)$) {#1};
      \node at ($(path picture bounding box.west)!0.4!(path picture bounding box.center)$)  {#2};
      \node at ($(path picture bounding box.north)!0.4!(path picture bounding box.center)$) {#3};
      \node at ($(path picture bounding box.east)!0.4!(path picture bounding box.center)$)  {#4};
    }
  },
  addCross/.default={}{}{}{}{10}{}
}
\tikzset{mySimpleArrow/.style n args={2}{
    >={latex[#1]},
    every path/.style={draw=#2}
  },
  mySimpleArrow/.default={black}{black}
}
\tikzset{myBlockOpacity/.style n args={2}{
    every node/.style={rectangle,draw,
      minimum width=1cm, minimum height=1cm,
      text=black,
      fill opacity=#1, text opacity=#2}
  },
  myBlockOpacity/.default={0.4}{1}
}

\begin{document}
\begin{tikzpicture}[very thick]
  \begin{scope}[blue]
    \node[circle,draw,addCross={$-$}{$+$}{}{}{10}{red}] (S1) at (-2,2) {};
    \node[circle,draw,addCross={$-$}{$+$}{}{}{10}{blue}] (S2) at (-0.5,1) {};
    \node[circle,draw,addCross={$-$}{$+$}{}{}{10}{purple}] (S3) at (5.5,1.5) {};
  \end{scope}
  
  \begin{scope}[myBlockOpacity, rounded corners, align=center]
    \node[fill=orange, minimum height=80pt, minimum width=60pt] (T) at (-5.5,1.5) 
    {Transient \\Profile \\Generator};
    \node[fill=blue] (P) at (10.5,1.5) {Plant};
    \node[fill=green, minimum height=80pt] (N) at (2.5,1.5)
    {Non-linear \\ State Error \\Feedback};
    \node[fill=yellow, minimum height=80pt] (E) at (7,-2)
    {Extended \\ State \\Observer};
  \end{scope}
  
  \begin{scope}[blue,mySimpleArrow={blue}{blue}]
    \path[->] (-7.5,1.5) node[above]{$r$} -- (T);
    
    \path[->] ([yshift=5mm] T.east) -- (S1) node[above, midway]{$r_1$};
    \path[->] ([yshift=-5mm] T.east) -- (S2) node[above, midway]{$r_2$};
    
    \path[->] (S1) -- ([yshift=5mm] N.west) node[midway, above] {$e_1$};
    \path[->] (S2) -- ([yshift=-5mm] N.west) node[midway, above] {$e_2$};
    
    \path[->] (N) -- (S3) node[midway, below] {$u_0$};
    \path[->] (S3) -- ++(3,0) coordinate(u) -- (P);
    \path[->] (u) |- ([yshift=10pt]E.east) node[above right, midway]{$u$};
    
    \path[->] (P) -- ++(1,0) coordinate(y) |- ([yshift=-10pt]E.east);
    \path[->] (y) -- ++(1,0) node[above]{$y$};
    
    \path[->,red] ([yshift=-20pt] E.west) -| (S1) node[above right, midway]{$z_1$};
    \path[->] (E) -| (S2) node[above right, midway]{$z_2$};
    \path[->,purple] ([yshift=20pt] E.west) -| (S3) node[above right, midway]{$z_3$};
  \end{scope}
\end{tikzpicture}
\end{document}

enter image description here