-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaking-control-diagrams-in-dot.html
270 lines (238 loc) · 23.4 KB
/
making-control-diagrams-in-dot.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2022-W11-4 02:13 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Making Control Block Diagrams in DOT</title>
<meta name="author" content="Inanna" />
<meta name="description" content="A tutorial on implementing control block diagrams for the beginner." />
<meta name="generator" content="Org Mode" />
<link href="/site.css" rel="stylesheet" type="text/css" /><link href="images/website-icon.png" rel="icon" />
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
displayAlign: "center",
displayIndent: "0em",
"HTML-CSS": { scale: 100,
linebreaks: { automatic: "false" },
webFont: "TeX"
},
SVG: {scale: 100,
linebreaks: { automatic: "false" },
font: "TeX"},
NativeMML: {scale: 100},
TeX: { equationNumbers: {autoNumber: "AMS"},
MultLineWidth: "85%",
TagSide: "right",
TagIndent: ".8em"
}
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="preamble" class="status">
<div><a href="/index.html"><img alt="An abstract logo representing a series of three assembly line stamping machines with the words CONS, DEV, and embalzoned in white on each machine." id="site-logo" src="/images/website-logo.png" /></a></div>
</div>
<div id="content" class="content">
<h1 class="title">Making Control Block Diagrams in DOT</h1>
<div id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgdb59666">Introduction</a></li>
<li><a href="#org7a63534">Styling Setup</a></li>
<li><a href="#org805c53b">Basic Control Diagram</a></li>
</ul>
</div>
</div>
<div id="outline-container-orgdb59666" class="outline-2">
<h2 id="orgdb59666">Introduction</h2>
<div class="outline-text-2" id="text-orgdb59666">
<p>
Control diagrams are vitally important for modeling the interaction of various control systems, but at the same time drawing them is often a bit of a pain. You either have to fire up \(\displaystyle \LaTeX\) which always sucks the joy right out of every room it is contained in or you have to.
</p>
</div>
</div>
<div id="outline-container-org7a63534" class="outline-2">
<h2 id="org7a63534">Styling Setup</h2>
<div class="outline-text-2" id="text-org7a63534">
<p>
This is styled according to the color schemes in my <a href="control-block-diagram-syntax.html#ID-f33796f7-2cdb-4110-81ee-be035021659b">Control Block Diagram Syntax</a> document. There is no official standard for control block diagram syntax coloring (or, indeed, much of the design of control diagrams), so I decided to create my own little approach for this blog. If you want to use it, feel free to do so.
</p>
</div>
</div>
<div id="outline-container-org805c53b" class="outline-2">
<h2 id="org805c53b">Basic Control Diagram</h2>
<div class="outline-text-2" id="text-org805c53b">
<p>
A basic control diagram representing the output of a system might be drawn as follows:
</p>
<div class="org-src-container">
<pre class="src src-dot" id="org0d492d6"><span style="color: #E53935; font-style: italic;">digraph</span> <span style="font-weight: bold; font-style: italic;">feedfowards</span> <span style="color: #494949;">{</span>
<span style="font-style: italic;">splines=</span>ortho;
<span style="font-style: italic;">size=</span><span style="color: #494949;">"15,15!"</span>
<span style="font-style: italic;">fontpath=</span><span style="color: #494949;">"~/.local/share/fonts"</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #bbb;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">record</span>,
<span style="font-style: italic;">fontname=</span><span style="color: #494949;">"Jura Bold"</span>
<span style="font-style: italic;">penwidth=</span>0,
<span style="font-style: italic;">style=</span><span style="color: #E53935;">filled</span>,
<span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #000000; background-color: #f5f5f5;">#f5f5f5</span><span style="color: #494949;">"</span><span style="color: #bbb;">]</span>
<span style="color: #E53935; font-style: italic;">edge</span><span style="color: #bbb;">[</span><span style="font-style: italic;">penwidth=</span>3<span style="color: #bbb;">]</span>
sp<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">white</span>, <span style="font-style: italic;">label=</span><span style="color: #494949;">"set point"</span>, <span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #bbb;">]</span>
out<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">white</span>, <span style="font-style: italic;">label=</span><span style="color: #494949;">"output"</span><span style="color: #bbb;">]</span>
actuator<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span>,<span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">white</span><span style="color: #bbb;">]</span>
<span style="color: #bbb;">{</span>
<span style="font-style: italic;">rank=</span><span style="color: #E53935;">min</span>;
sp->controller<span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #E53935;">#E53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>
controller->actuator
actuator->process<span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>
process -> out
<span style="color: #bbb;">}</span>
<span style="color: #494949;">}</span>
</pre>
</div>
<p>
Which will output:
</p>
<div id="org1e80488" class="figure">
<p><img src="images/feedforward-diagram_bafbaf01-494c-453d-9a3b-819dcc678a14.png" alt="feedforward-diagram_bafbaf01-494c-453d-9a3b-819dcc678a14.png" />
</p>
</div>
<p>
Here there are a few tricks. To indicate an input (or indeed an output) to the control system we use an arrow coming in without a box. To give it a nice color scheme we also adjust
</p>
<p>
A more complex system might look like this:
</p>
<div class="org-src-container">
<pre class="src src-dot" id="org708a105"><span style="color: #E53935; font-style: italic;">digraph</span> <span style="font-weight: bold; font-style: italic;">feedback</span> <span style="color: #494949;">{</span>
<span style="font-style: italic;">splines=</span>ortho;
<span style="font-style: italic;">size=</span><span style="color: #494949;">"15,15!"</span>;
<span style="font-style: italic;">fontpath=</span><span style="color: #494949;">"~/.local/share/fonts"</span>;
<span style="font-style: italic;">labeldistance=</span>2;
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #bbb;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">record</span>,
<span style="font-style: italic;">fontname=</span><span style="color: #494949;">"Jura Bold"</span>
<span style="font-style: italic;">penwidth=</span>0,
<span style="font-style: italic;">style=</span><span style="color: #E53935;">filled</span>,
<span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #000000; background-color: #f5f5f5;">#f5f5f5</span><span style="color: #494949;">"</span><span style="color: #bbb;">]</span>;
<span style="color: #E53935; font-style: italic;">edge</span><span style="color: #bbb;">[</span><span style="font-style: italic;">penwidth=</span>3<span style="color: #bbb;">]</span>;
<span style="color: #bbb;">{</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #494949;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">white</span>, <span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>;
disturbances;
sp<span style="color: #494949;">[</span><span style="font-style: italic;">label=</span><span style="color: #494949;">"set point"</span><span style="color: #494949;">]</span>;
<span style="color: #bbb;">}</span>
out<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">white</span>, <span style="font-style: italic;">label=</span><span style="color: #494949;">"output"</span><span style="color: #bbb;">]</span>;
conn<span style="color: #bbb;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">point</span>, <span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #000000;">#000000</span><span style="color: #494949;">"</span> <span style="font-style: italic;">penwidth=</span>3<span style="color: #bbb;">]</span>;
comp<span style="color: #bbb;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">circle</span>,<span style="font-style: italic;">label=</span><span style="color: #494949;">"Σ"</span><span style="color: #bbb;">]</span>;
actuator<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span>, <span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">white</span><span style="color: #bbb;">]</span>;
<span style="color: #bbb;">{</span> <span style="font-style: italic;">rank=</span><span style="color: #E53935;">min</span>; disturbances<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span>
<span style="color: #E53935; font-style: italic;">edge</span><span style="color: #494949;">[</span><span style="font-style: italic;">minlen=</span>2<span style="color: #494949;">]</span>
<span style="font-style: italic;">rank=</span><span style="color: #E53935;">same</span>;
sp->comp<span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #E53935;">#E53935</span><span style="color: #494949;">"</span>,xlabel=<span style="color: #494949;">"+"</span>,<span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>
comp->controller
controller->actuator
actuator->process<span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>
process -> conn <span style="color: #494949;">[</span><span style="font-style: italic;">arrowhead=</span><span style="color: #E53935;">none</span><span style="color: #494949;">]</span>
conn -> out
<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span> <span style="font-style: italic;">rank=</span><span style="color: #E53935;">max</span>; sensor; <span style="color: #bbb;">}</span>
forcelabels=<span style="color: #E53935;">true</span>;
disturbances-> process<span style="color: #bbb;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #bbb;">]</span>
conn->sensor
sensor->comp<span style="color: #bbb;">[</span>xlabel=<span style="color: #494949;">"-"</span>,<span style="font-style: italic;">fontsize=</span><span style="color: #494949;">"20pt"</span><span style="color: #bbb;">]</span>
<span style="color: #494949;">}</span>
</pre>
</div>
<p>
Which outputs this:
</p>
<div id="org2068af8" class="figure">
<p><img src="images/feedback-diagram_b0c03ade-86fa-4c4f-999e-de13476ee1db.png" alt="feedback-diagram_b0c03ade-86fa-4c4f-999e-de13476ee1db.png" />
</p>
</div>
<p>
Here some further tricks are used. FIrst we specify the top and bottom of the diagram using anonymous sub-graphs, which are ranked <code>min</code> and <code>max</code>. Sections in-between those are ranked the same, and added in the order of their appearance. This ensures that the graph is, in the 3 layer case, will align properly and produce the right output.
</p>
<p>
Subgraphs can also be used to restrict the scope of style choices, allowing you to reduce the amount of code you have to write for specific style choices.
</p>
<p>
We can also draw a simple multi-loop control model as follows:
</p>
<div class="org-src-container">
<pre class="src src-dot" id="orgd8febde"><span style="color: #E53935; font-style: italic;">digraph</span> <span style="font-weight: bold; font-style: italic;">multi_loop</span> <span style="color: #494949;">{</span>
<span style="font-style: italic;">splines=</span>ortho;
<span style="font-style: italic;">fontpath=</span><span style="color: #494949;">"~/.local/share/fonts"</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #bbb;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">record</span>,
<span style="font-style: italic;">fontname=</span><span style="color: #494949;">"Jura Bold"</span>
<span style="font-style: italic;">penwidth=</span>0,
<span style="font-style: italic;">style=</span><span style="color: #E53935;">filled</span>,
<span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #000000; background-color: #f5f5f5;">#f5f5f5</span><span style="color: #494949;">"</span><span style="color: #bbb;">]</span>
<span style="color: #E53935; font-style: italic;">edge</span><span style="color: #bbb;">[</span><span style="font-style: italic;">penwidth=</span>3<span style="color: #bbb;">]</span>
out<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">white</span>, <span style="font-style: italic;">label=</span><span style="color: #494949;">"output"</span><span style="color: #bbb;">]</span>
actuator<span style="color: #bbb;">[</span><span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span>,<span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">white</span><span style="color: #bbb;">]</span>
<span style="color: #bbb;">{</span><span style="color: #a4a4a4; font-style: italic;">// </span><span style="color: #a4a4a4; font-style: italic;">style for connectors in diagram</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #494949;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">point</span>,
<span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #000000;">#000000</span><span style="color: #494949;">"</span>,
<span style="font-style: italic;">penwidth=</span>3<span style="color: #494949;">]</span>;
conn; conn2;
<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span> <span style="color: #a4a4a4; font-style: italic;">// </span><span style="color: #a4a4a4; font-style: italic;">style for comparators</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #494949;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">circle</span>,
<span style="font-style: italic;">label=</span><span style="color: #494949;">"Σ"</span><span style="color: #494949;">]</span>
comp; comp2;
<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span> <span style="color: #a4a4a4; font-style: italic;">// </span><span style="color: #a4a4a4; font-style: italic;">style for set points</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #494949;">[</span><span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span>,
<span style="font-style: italic;">fillcolor=</span><span style="color: #494949;">white</span><span style="color: #494949;">]</span>;
sp<span style="color: #494949;">[</span><span style="font-style: italic;">label=</span><span style="color: #494949;">"set point"</span><span style="color: #494949;">]</span>; disturbances
<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span><span style="color: #a4a4a4; font-style: italic;">// </span><span style="color: #a4a4a4; font-style: italic;">style and layout of layer labels</span>
<span style="color: #E53935; font-style: italic;">node</span><span style="color: #494949;">[</span><span style="font-style: italic;">shape=</span><span style="color: #E53935;">point</span>, <span style="font-style: italic;">penwidth=</span>0<span style="color: #494949;">]</span>;
<span style="color: #E53935; font-style: italic;">edge</span><span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">white</span><span style="color: #494949;">]</span>
a->b->c->d
<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span><span style="font-style: italic;">rank=</span><span style="color: #E53935;">min</span>; a; disturbances<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span>
<span style="color: #E53935; font-style: italic;">edge</span><span style="color: #494949;">[</span><span style="font-style: italic;">minlen=</span>2<span style="color: #494949;">]</span>
<span style="font-style: italic;">rank=</span><span style="color: #E53935;">same</span>;
b;
sp->comp<span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #E53935;">#E53935</span><span style="color: #494949;">"</span>,xlabel=<span style="color: #494949;">"+"</span>,<span style="font-style: italic;">fontcolor=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #E53935;">#E53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>
comp->controller
controller -> comp2<span style="color: #494949;">[</span>xlabel=<span style="color: #494949;">"+"</span><span style="color: #494949;">]</span>
comp2->controller2
controller2->actuator
actuator->process<span style="color: #494949;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #494949;">]</span>
process -> conn <span style="color: #494949;">[</span><span style="font-style: italic;">arrowhead=</span><span style="color: #E53935;">none</span><span style="color: #494949;">]</span>
conn->conn2 <span style="color: #494949;">[</span><span style="font-style: italic;">arrowhead=</span><span style="color: #E53935;">none</span><span style="color: #494949;">]</span>
conn2 -> out
<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span><span style="font-style: italic;">rank =</span> <span style="color: #E53935;">same</span>; c; sensor2;<span style="color: #bbb;">}</span>
<span style="color: #bbb;">{</span><span style="font-style: italic;">rank=</span><span style="color: #E53935;">max</span>; d; sensor;<span style="color: #bbb;">}</span>
conn->sensor2
sensor2->comp2<span style="color: #bbb;">[</span>xlabel=<span style="color: #494949;">"-"</span>,<span style="font-style: italic;">fontsize=</span><span style="color: #494949;">"20pt"</span><span style="color: #bbb;">]</span>
disturbances-> process<span style="color: #bbb;">[</span><span style="font-style: italic;">color=</span><span style="color: #494949;">"</span><span style="color: #ffffff; background-color: #e53935;">#e53935</span><span style="color: #494949;">"</span><span style="color: #bbb;">]</span>
conn2->sensor<span style="color: #bbb;">[]</span>
sensor->comp<span style="color: #bbb;">[</span>xlabel=<span style="color: #494949;">"-"</span>,<span style="font-style: italic;">fontsize=</span><span style="color: #494949;">"20pt"</span><span style="color: #bbb;">]</span>
<span style="color: #494949;">}</span>
</pre>
</div>
<div id="org2d92591" class="figure">
<p><img src="images/multiloop-diagram_b0c03ade-86fa-4c4f-999e-de13476ee1db.png" alt="multiloop-diagram_b0c03ade-86fa-4c4f-999e-de13476ee1db.png" />
</p>
</div>
<p>
Here we use a bit of a trick to actually make it work, defining a series of "layer labels", which we then include in the groups to get them to align properly.
</p>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="date">Last Modified: 2021-W49-4 01:03</p><p class="creator">Generated Using: <a href="https://www.gnu.org/software/emacs/">Emacs</a> 27.2 (<a href="https://orgmode.org">Org</a> mode 9.4.6)</p><p class="license">Except where otherwise noted content on <a href="https://cons.dev">cons.dev</a> is licensed under a <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>
</div>
</body>
</html>