I usually start by positioning the nodes, not worrying about spacing. Just place them approximately how you want them to be. I will use the following styles:
\tikzset{
module/.style = {draw, thick, rectangle, align = center},
mux/.style = {fill=black, minimum width=0.1cm, minimum height = 1.2cm, inner sep = 0cm},
sum/.style = {draw, thick, circle, inner sep = 0cm, minimum size = 0.5cm},
tip/.style = {->, >=stealth', thick},
rtip/.style = {<-, >=stealth', thick}
}
I use \tikzset
and /.style
since it's more common and the tikzstyle
option is not documented in the manual (maybe old style command? I don't know).
Straightforwardly written down, this yields:
\begin{tikzpicture}
\node[module] (uncertain) { Uncertain System };
\node[module, right = of uncertain] (int) { $\displaystyle\int$ };
\node[mux, right = of int] (mux) { };
\node[sum, below left = of uncertain] (sum1) { };
\node[module, right = of sum1] (K) { $K_{long}$ };
\node[module, below right = of K] (long1) { Longitudinal Adaptive\\Control };
\node[module, right = of long1] (long2) { Longitudinal Weight\\Update Law };
\node[module, above right = of long1] (long3) { Longitudinal Reference System };
\node[sum, right = of long3] (sum2) { };
\end{tikzpicture}
No we fine-tune the spacing of the nodes. The integration block is a bit lower in your example, so we will use a border anchor for the placement (note that with the positiong library, the right=
key will use the west
anchor as placement anchor.) By using a border anchor, the spacing in x-direction does not change (since the west
anchor also lies on the border) but we can shift the node down. I used the 150
anchor.
The same holds for the mux block, but here we want to shift the node up, so we will use the 260
anchor (i tried out some values).
This yields
using
\node[module] (uncertain) { Uncertain System };
\node[module, right = of uncertain, anchor = 150] (int) { $\displaystyle\int$ };
\node[mux, right = of int, anchor = 260] (mux) { };
The relative positioning is fine, now we need to tune the spacing. We will do this by using the node distance
key, but with two values:
\begin{tikzpicture}[node distance = 2cm and 1.5cm]
With this, we get
Not bad! What remains is a little shift of the 'Longitudinal Reference System' and the 'Klong' node. For the first, we will just use a different reference anchor. Currently, we are using north east
of the reference node, since we are using above right
. We will change this by stating the anchor explicitly. Also, we will change the spacing since this node should be closer to the others:
\node[module, above right = 1cm and 1.0cm of long1.north west] (long3) { Longitudinal Reference System };
Again, i try out these values until i like the result. Note that we will have to shift the second summing point, but this is easy:
\node[sum, right = 3cm of long3] (sum2) { };
We will use the same approach for the 'Klong' node:
\node[module, right = 1cm of sum1] (K) { $K_{long}$ };
And here i made a mistake: we are positioning the lower nodes relative to 'Klong', so we can't just push that node around. Doesn't matter, easy to fix:
\node[module, below right = 2cm and 3.5cm of sum1] (long1) { Longitudinal Adaptive\\Control };
We have to manually adapt the spacings, but that's it (and, of course, the new reference node 'sum1').
The final result is:
Ok, very nice. I tweaked some values, so the final code is this:
\begin{tikzpicture}[node distance = 1.5cm and 1.5cm] % note the change here
\node[module] (uncertain) { Uncertain System };
\node[module, right = of uncertain, anchor = 150] (int) { $\displaystyle\int$ };
\node[mux, right = of int, anchor = 260] (mux) { };
\node[sum, below left = of uncertain] (sum1) { };
\node[module, right = 2.5cm of sum1] (K) { $K_{long}$ };
\node[module, below right = 2cm and 3.5cm of sum1] (long1) { Longitudinal Adaptive\\Control };
\node[module, right = of long1] (long2) { Longitudinal Weight\\Update Law };
\node[module, above right = 1cm and 1.0cm of long1.north west] (long3) { Longitudinal Reference System };
\node[sum, right = 3cm of long3] (sum2) { };
\end{tikzpicture}
The wiring is quite straightforward: the nodes are placed in a way that allows using implicit anchors. Just take the nodes as coordinates and you're ready to go. The labels and the +-signs are just placed as nodes on the paths:
\draw[tip] (K) -- node[pos=0.9, above] {$+$} (sum1);
\draw[tip] (sum1) |- node[pos=0.8, above] {$\delta_e(t)$} (uncertain);
\draw[tip] (long1) -| node[pos=0.95, right] { $+$ } node[pos=0.15, above] { $u_{along}(t)$ } (sum1);
\draw[tip] (uncertain) -- node[pos=0.3, above] { $\alpha(t)$, $q(t)$ } (int.150);
\draw[rtip] (int.210) -- ++(-2, 0);
These are the first five connections, the others work the same (make sure to use the right anchors for the mux node).
There are three lines that don't start at a node but on another line. The first one (connecting the input of the integration node and the longitudinal ref. system) is drawn by using a shift:
\draw[tip] ([xshift=-3cm] int.210) |- (long3);
Neat! The second line is the line connecting the output of the mux and the 'Update Law' Module. We could use the same approach as for the first line, but we will need some coordinates for this line (we will see this in a minute). We will use the line connecting the mux and the right summing point:
\draw[tip] (mux) -| coordinate[pos=0.35] (c0) node[pos=0.2, above] { $x_{long}(t)$ } (sum2);
Note how i used two nodes, one for the label, one as coordinate (a coordinate is a special node). I'm not very creative with coordinate names, mine are always enumerated (ci)'s.
Ok, now we have the coordinate, so we can draw the second line:
\draw[tip] (c0) |- (long2);
The last line is tricky: we need the starting coordinate, which lies exactly at the height of the Klong node. How do we do this? We could first draw this line and define the corner as coordinate, then draw the line to the 'Update Law' node. Works, but not elegant and we need another coordinate. I can do it without a new coordinate: by using the great syntax of specifying two nodes in a coordinate:
\draw[tip] (c0 |- K.east) -- (K);
So, what's going on here? We draw a line from some point to K. Ok, but where is this some point? It lies at the point where the two imaginary lines through c0
(vertically) and K.east
(horizontly) meet. How cool is this?
Currently, we have this:
For the line drawn over the lower right node we will use the calc library:
\draw[tip] (sum2.south) |- node[pos=0.2, right] { $e_{long}(t)$ } ($(long2.south east)+(-0.5, -0.5)$) -- ($(long2.north west)+(0.5, 0.5)$);
So we start at the summing point, draw a vertical and a horizontal line to a point near the node, than cross it to the other side. Looks like much, but i think it is quite clear.
One more thing to solve: how do we get the look that the line 'overlap' each other? This one is tricky, and my solution is not perfect. There is a key which allows you to do this very easy: double
. It draws the line twice, one thin one, one thicker one, in different colors. This yields the desired effect. From the tikzmanual:
\draw (0, 0) -- (1, 1);
\draw[draw=white, double = red, very thick] (0, 1) -- (1, 0);
Ok, this has the desired effect (think of the background as white). Let's use this:
\draw[tip, white, double = black] ([xshift=-3cm] int.210) |- (long3);
The result of this is:
Well, looks ok, but the arrow is gone! Hm, how do we solve this? Here comes the trick: we will just draw the line twice per hand. Let's introduce a new style:
\tikzset{
doubletip/.style = {white, line width=2.5pt, line cap = butt}
}
The line cap
option tells the line to 'stop' where it should stop. With the values rect
or round
there will we an extension. Not using this draws some white paint on the line where it starts. We don't want that.
Let's draw both lines:
\draw[doubletip] ([xshift=-3cm] int.210) |- (long3.west);
\draw[tip] ([xshift=-3cm] int.210) |- (long3);
\draw[doubletip] (long3) -- (sum2);
\draw[tip] (long3) -- node[pos=0.9, above] { $-$ } (sum2);
There is still one problem:
Although we used the line cap
option, we still have some overlapping. This is ugly! We could shorten the line in some way, but easier is just to draw the black line (from left to right) after to white line.
The final image is:
If you followed my code step-by-step, you will see that you won't get the exact same result. While drawing i'm always tweaking some values here and there since i always encounter some positioning problems etc. So here's the full code:
\documentclass[landscape]{article}
\usepackage[ngerman]{babel}
\usepackage{tikz}
\usetikzlibrary{arrows, positioning, calc}
\tikzset{
module/.style = {draw, thick, rectangle, align = center},
mux/.style = {fill=black, minimum width=0.1cm, minimum height = 1.2cm, inner sep = 0cm},
sum/.style = {draw, thick, circle, inner sep = 0cm, minimum size = 0.5cm},
tip/.style = {->, >=stealth', thick},
doubletip/.style = {white, line width=3pt, line cap=butt},
rtip/.style = {<-, >=stealth', thick} % reverse tip
}
\begin{document}
\begin{tikzpicture}[node distance = 1.5cm and 1.5cm]
% modules
\node[module] (uncertain) { Uncertain System };
\node[module, right = 4cm of uncertain, anchor = 150] (int) { $\displaystyle\int$ };
\node[mux, right = of int, anchor = 260] (mux) { };
\node[sum, below left = of uncertain] (sum1) { };
\node[module, right = 2.5cm of sum1] (K) { $K_{long}$ };
\node[module, below right = 2cm and 3.5cm of sum1] (long1) { Longitudinal Adaptive\\Control };
\node[module, right = of long1] (long2) { Longitudinal Weight\\Update Law };
\node[module, above right = 1cm and 2.5cm of long1.north west] (long3) { Longitudinal Reference System };
\node[sum, right = 4cm of long3] (sum2) { };
% connections
\draw[tip] (K) -- node[pos=0.9, above] {$+$} node[pos=0.4, above] { $u_{nlong}(t)$ } (sum1);
\draw[tip] (sum1) |- node[pos=0.8, above] {$\delta_e(t)$} (uncertain);
\draw[tip] (long1) -| node[pos=0.95, right] { $+$ } node[pos=0.15, above] { $u_{along}(t)$ } (sum1);
\draw[tip] (uncertain) -- node[pos=0.3, above] { $\alpha(t)$, $q(t)$ } (int.150);
\draw[tip] (int) -- (mux.260);
\draw[tip] ($(uncertain.east)!0.8!(int.150)$) |- (mux.100);
\draw[tip] (mux) -| coordinate[pos=0.35] (c0) node[pos=0.2, above] { $x_{long}(t)$ } (sum2);
\draw[tip] (long2) -- node[above] { $W_{long}(t)$ } (long1);
\draw[tip] (c0) |- (long2);
\draw[tip] (c0 |- K.east) -- (K);
\draw[doubletip] ([xshift=-3cm] int.210) |- (long3.west);
\draw[tip] ([xshift=-3cm] int.210) |- (long3);
\draw[tip] (sum2.south) |- node[pos=0.2, right] { $e_{long}(t)$ } ($(long2.south east)+(-0.5, -0.5)$) -- ($(long2.north west)+(0.5, 0.5)$);
\draw[doubletip] (long3) -- (sum2);
\draw[tip] (long3) -- node[pos=0.9, above] { $-$ } (sum2);
\draw[rtip] (int.210) -- node[pos=0.85, below left] { $c_{long}(t)$ } ++(-3.5, 0);
\end{tikzpicture}
\end{document}