Simcon version 4.4 release announcement

[From Bill Powers (930322.1600)]

Here is the documentation that goes with Wolfgang Zocher's
beautiful analog-computer-on-a-PC program. I've uploaded some
ascii-converted versions of the program to Bill Silvert's file
server at biome.bio.ns.ca; Bill will no doubt check them and put
them in the pubs/csg/simcon directory. Better wait for Bill's
notification that the files have been put in the correct
directory. I've also asked Gary Cziko to download them and put a
binary version in the same directory (I still can't upload binary
files). I would like a very brief note from everyone who
downloads this program and is prepared to use it. Anyone who
can't download it can send me a self-addressed STAMPED disk
mailer with a formatted disc in it (360K or more, 5-1/4 or 3-1/2
inch), and I will send all the stuff by return mail.

If you get a copy of this program, you will be able to receive
simulations over CSGnet and run them on your computer. This is
going to make communicating principles and ideas concerning PCT
very much easier. We all owe Wolfgang a lot of thanks for the
long hours he has spent in creating this very functional and
apparently bug-free program and allowing us all to use it.

Best,

Bill P.

                This is SIMCON Version 4.4

SIMCON is a simulator of control loops.
It helps to do experiments in Perceptual Control Theory by
William T. Powers.

    Copyright (C) 1992,1993 Wolfgang Zocher

    email: zocher@rrzn.uni-hannover.dbp.de
    snail: Wolfgang Zocher
           Hauptstrasse 15
           3225 Capellenhagen
           Germany

    This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 1, or (at
your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

···

---------------------------------------------------------

                             Overview

SIMCON is an analogue computer implemented on a digital computer. It
enables the user to connect functional blocks to each other and assign
parameters to the inputs and internal operations of the blocks, then
run the simulation and plot the results. The output of each block is
designated by a user-assignable name, and plots can be made of any
named variable. Plots are globally scaled to fit the largest
excursions of variables into the plotting area; in addition, relative
scales can be assigned to each variable individually.

The program setup is contained in a user-written text file with the
extension ".inp". This text file can be sent over network
communications so that users can pass setups to each other and run
them.

A small user-written text file named simcon.rc enables the user to
integrate a text editor into the program so that the program file can
be edited without leaving Simcon. The same file can specify that the
plots be done using gnuplot3.exe (which the user must have); if the
line specifying gnuplot is left out, a built-in plotting routine is
used. If there is no file simcon.rc, the program will simply exit
after doing a plot, and the user can use any convenient means of
editing the program listing, then restart Simcon.

The C source code of SIMCON is ANSI compatible with the exception of
the built-in plotting routines. By using the provision for linking to
Gnuplot, it should be possible to port the program to Unix and other
machines without great difficulty. Contact Wolfgang Zocher for
details.

              Hardware requirements for PC environments

SIMCON should be run on AT-compatible machines: 286, 386, or 486. The
faster, the better. A math coprocesser is highly recommended.

The basic program occupies about 88K bytes; it is recommended that at
least 256K of free memory be available, and as much more as needed to
run the editor and gnuplot if they are integrated into the program.
Simcon runs under DOS only, version 3.x and up.

The built-in plotting routine can use ATT, Hercules, CGA, EGA, and VGA
graphics boards, auto-detected. Borland ".BGI" graphics interface
files must be present in the same directory as Simcon43. In addition,
if the user has a superVGA facility capable of 1024 x 768 resolution,
and the interface file "svga16.bgi" is present, the program will use
it. Gnuplot may offer more combinations.

In version 4.4 the plotted traces are color-coded, and there is no
provision for identifying traces when the number of variables plotted
exceeds the number of colors available. The program can be used with
only two-color graphics, but the user will have to identify the traces
by ingenuity. A later version will provide for putting labels on the
traces when insufficient colors are available. A workaround is to
delete plotting of specific traces and see which ones disappear.

                   The basic computing blocks

The basic blocks available are

CONST, SUMMATOR, AMPLIFIER, INTEGRATOR, MULT, COMPARATOR, GENERATOR,
DELAY, and LIMIT. Under GENERATOR there are two subtypes: PULS and
RAMP. All blocks but generators receive inputs from other blocks, and
produce just one output which can be named with a character string up
to 20 characters long.

Note that in a given program, there may be many instances of each type
of block. They are distinguished by the symbolic names given to their
outputs, and each is specified in a separate program line.

In the following, keywords that must be typed in exactly as shown are
capitalized; they must be entered, however, in lower case. Upper-case
characters are not recognized by SIMCON.

CONST:

Syntax: output_name CONST value

The value is a decimal number.

SUMMATOR:

Syntax: output_name SUMMATOR in1 weight1 in2 weight2 ... weight99

The inputs (in1 etc) are symbolic names of block outputs; the weights
are decimal numbers. The output is the sum of all the weighted
inputs. Up to 99 inputs can be specified.

COMPARATOR:

Syntax: output_name COMPARATOR input1 input2

The output is input1 minus input2. The input variables are the
symbolic names of the outputs of other blocks.

AMPLIFIER:

Syntax: output_name AMPLIFIER input initial_value gain_value
         time_constant

The amplifier is a leaky integrator; hence its output must be
initialized to a specific value (usually 0.0). The gain is a decimal
parameter (with sign). The time constant is a decimal number, in
seconds. The time constant should not be set to a value less than the
basic time-interval for computations (see "TIME" below).

INTEGRATOR:
Syntax: output_name INTEGRATOR init_value in1 wt1 ... in99 wt99

The integrator requires an initial decimal value for its output. It
takes up to 99 inputs, each with an assigned weight. The "in1" etc.
entry is the symbolic name of the output from another block; the
weight "wt1" etc. is a decimal number. The sum of inputs is
multiplied by "dt", the basic computing interval, before being summed
into the output.

The integration method used in Simcon is simple summation. This is
sufficient for use in closed-loop systems, but not for long strings
of integrations outside of negative feedback loops.

MULT:

Syntax: output_name MULT input1 input2

The multiplier outputs a value that is in1 times in2, where in1 and
in2 are symbolic names of outputs from other blocks.

GENERATOR: PULS type
There are no inputs to a generator.

  Syntax: output_name GENERATOR PULS start_time end_time amplitude

  The start time is the decimal time at which the output goes from
  zero to "amplitude" in size. The end time is the decimal time at
  which the output returns to zero. The amplitude is the decimal value
  of the output between the start and end times.

GENERATOR: RAMP type

  Syntax: output_name GENERATOR RAMP start_time end_time amplitude

  The start and end times have the same meaning as for the PULS
  generator. The output rises uniformly from zero, starting at the
  start time, to "amplitude" units at the end time, then returns to
  zero.

DELAY:

Syntax: output_name DELAY input delay_time

The delay block outputs the input variable delayed by "delay_time"
seconds, in decimal. Initially, zeros are output until the first
nonzero value of the input reaches the output. The delay time is
converted to integer units of the basic computing time "dt", so
should be as long or longer than this basic unit.

LIMIT:

Syntax: output_name LIMIT input lower_limit upper_limit

This block simply prevents the output from going below the lower
limit or above the upper limit. The (symbolic) input variable is not
affected. The limits are decimal numbers.

                          Program directives

In addition to the lines of the program specifying blocks and their
interconnections, there are program lines that specify overall
constants and tell the program how to run and plot the results.

TITLE:

Syntax: TITLE <ASCII title to be printed at top of plots>

TIME:

Syntax: TIME duration dt

"Duration" is a decimal number giving the length of a simulation run
  in seconds. "dt" is the basic computing interval in seconds. The
  length of one program iteration is "dt" seconds, usually 0.1 or
  less.

The total number of output data lines written by the program (each
containing the values of all plotted variables) is "duration" divided
by "dt." Output data lines are stored in an ASCII file with the name
filename.dat, where "filename" is the same as the name of the program
file, minus extension. In addition, there is generated an output file
called filename.plt, which contains data in the form that gnuplot and
the built-in plotter use. Old ".dat" and ".plt" files can be deleted
to conserve disk space, as they are rewritten on every run.

Long durations and short values of dt lead to generating a great
number of output data points, and to long computing times. Only as
many data points as actually needed should be generated, especially
on slower computers.

PRINT:

Syntax: PRINT < variable names separated by spaces>

This directive lists the block outputs that are to be plotted or
printed out. More than four or five variables makes a messy plot.

PLOT:

Syntax: PLOT scale1 scale2 .... scalen

For each variable listed in the PRINT directive, a scaling factor is
given in decimal. Because plots are globally scaled to fit the
plotting area, these scaling factors are relative. If one variable is
to be plotted at 10 times the scale of all others, set that
variable's scale factor to 10.0 and the rest to 1.0. If any scaling
factor is given, all must be given.

If PLOT is followed by no scaling factors at all, all scaling factors
are set to 1.0.

If the PLOT directive is omitted entirely, the output will be printed
as columns of decimal numbers to the printer. Beware -- if the run
duration is long and "dt" is small, you can use a lot of paper.

# -- comments

In any line of the program listing , all characters following a "#"
symbol are taken as comments, and are ignored. A "#" in the first
position of a line makes the whole line a comment.

                            Grouping

There is one last directive, but to understand it you must understand
a subtle feature of Simcon.

Simcon is actually a parallel computing device. All block computations
are done, in effect, at the same time -- not in sequence. For each
block having an input and an output, the inputs are used to calculate
a new output; this is done for all blocks on any one iteration of the
program. Each block, however, is taking as inputs the OLD outputs from
the other blocks to which it is connected. So in effect, all the
computations occur simultaneously. Then, when all computations are
finished for one iteration, all the "new" outputs are copied into the
"old" outputs in preparation for the next iteration.

As a result, a change at the input to a block takes one iteration to
show up as an effect on the output of that block. However, if there
are several blocks connected in sequence, as there usually are, a
change at the input to the first block doesn't reach the output of the
nth block until n iterations later. Although all blocks are acting
simultaneously, there are transport lags (like neural conduction times
or synaptic delays) in every element. This allows the simulation to
deal realistically with lags in the system, without forcing the
computing functions to "take turns acting" (a common mistake in
analyzing systems with delays).

Note that the MINIMUM lag possible is the time "dt" that specifies the
duration of one iteration of the program. Longer lags can be inserted
anywhere by using a DELAY block.

Now to the GROUP directive.

Sometimes the user will wish to create a complex block by combining
several blocks. Also, there are cases (as in modeling the acceleration
and velocity of masses in the environment) where transport lags should
be as small as possible (they can't be smaller than one iteration, of
course). In either case, the user does NOT want to have as many
transport lags as there are elements being combined, but wants the
group of elements to pass its inputs to its outputs as fast as
possible.

This is what the GROUP directive is for.

GROUP:

Syntax: GROUP < list of names of block outputs>

The group directive causes the NEW outputs of each block in the group
to be used as input to the next block instead of the OLD outputs. As
a result, an input to the first block in a group has an effect on the
output of the last block in a single iteration of the program.

Simcon automatically computes the dependencies within a group so that
the computations are done in the correct order for minimum lag.

There can be up to 10 GROUP directives, each on a separate line of
the program listing. The groupings are independent of each other.

                         LEARNING TO USE SIMCON

SIMCON does not yet allow drawing block diagrams of computing setups,
so it is a good idea to draw your own diagram on paper first. Label
the block outputs with short symbols that will remind you of their
meaning, and label any weighted inputs with the weighting factors that
go with them.

Because SIMCON emulates an analogue computer, you must get used to the
idea that all parts of a diagrammed setup are active at the same time.
Each block is continuously converting its inputs to an output
regardless of what other blocks are doing. A computing setup behaves
as a whole; it can sometimes be hard to grasp what is going on because
ordinary sequential cause and effect do not apply in the way to which
you may be accustomed.

In choosing a basic computing interval, remember that this sets the
basic delay of a signal going through a block. If you have five blocks
connected in sequence, a perturbation at the input of the first block
will take 5 iterations of the program, five times the interval dt
specified in the TIME directive, to reach the output of the last block
in sequence. If you mean for this amount of delay to exist, all is
well. Otherwise you may want to use the GROUP directive to make the
delay equal to one iteration, the shortest possible. In general you
will want to make dt short enough so that grouping will make the delay
negligible on the time scale of the modeled system's behavior.

Finally, as mentioned, the blocks in SIMCON act at the same time, so
you can write the program lines defining the blocks and their
connections in any order. This means you can collect sets of blocks
together for ease of understanding instead of having to list the
blocks in the order of connection. Comment lines (any part of a line
following a "#" symbol) can be used to make the program more self-
explanatory, so you can remember what a setup was supposed to do six
months after you wrote it. Copious comments are especially useful to
anyone else who wants to try your computing setup. The setup programs
are pure ASCII files, so you can send them over a network like
Compuserve or the internet.

                    Writing a SIMCON program

SIMCON programs can be written using any text editor. However, if you
use a word processor be sure that you save the files in DOS (pure
ASCII) format, and do not insert any typesetting or control characters
into the text. Any characters other than "#", the alphabetic
characters "a" through "z", the numbers, and the decimal point "."
will be tagged as errors by SIMCON and the program will not run. Note
that SIMCON does not recognize characters in upper case. The only
exception to these rules is the part of a line that follows a comment
symbol "#" (which can be the whole line). Any characters can be used
in comments -- except the carriage return, which ends the line.

You can integrate some text editors with SIMCON so you don't have to
leave SIMCON to modify a program. To do this, create a text file,
using your editor, with the name "simcon.rc" in the same directory
with SIMCON. The contents of the file is a line beginning with the
word "editor", a space, and the full path needed to call the editor
program into use. If you are using the DOS 5.0 editing program called
EDIT.EXE, kept in the directory \dos, you would write

editor \dos\edit

End the line with a return before storing the file.

A second line can be added to simcon.rc to use gnuplot3.exe for
plotting results; it is similar in form:

gnuplot \gnu\gnuplot

for example.

In the following it will be assumed that you have integrated an editor
into SIMCON. If you haven't, SIMCON will simply exit when it is time
to revise the program, and you can call up the program for editing in
the usual way.

One caution. SIMCON expects program files to have a normal DOS name
followed by the extension ".inp" (for "input file"). If you use a word
processor like Word Perfect, which does not use standard ASCII
formats, you must NOT give the word processor's file the extension
".inp" for the simple reason that when you store the file, you will
have to give it a different name to use for the ASCII (DOS text)
version of the program. However you do the editing, it is the ASCII
file, not the word processor file, that must have the correct name and
the ".inp" extension. You may find it impossible to use complex word
processors integrated with SIMCON.

The convention for calling a program to run and edit is

SIMCON name

Where "name" is the text file containing the program setup. Note that
in calling the named program, you do NOT add the extension ".inp",
even though the file must be named (for example) "name.inp". SIMCON
adds that extension itself before trying to open the file. If you add
it yourself, SIMCON will think you are trying to run a program called
"name.inp.inp" and will complain, and quit.

If this program file does not already exist, SIMCON will open the text
editor immediately if it can (if not, it will just exit). When it
opens the file for the first time, it will add the ".inp" extension,
so the file will be properly named. You can then write the program.

                      An introductory program

Let us write a program called "waves.inp". Switching to the directory
in which SIMCON resides, we give the command

simcon waves

If you don't have the editor integrated, call your word processor to
edit a file called "waves.inp" before giving the above command.

Enter the following program:

title Produce sine and cosine waves
time 15.0 0.03
vel integrator 0.0 force 2.0
pos integrator 100.0 vel 1.0
force summator pos -5.0
group vel pos force
print vel pos
plot

Note that each element of a line is separated by one or more spaces.

When you have typed in the program, exit the editor and you will see a
plot of sine and cosine waves. The space bar will bring up a message
asking if you want to quit (the Esc key) or return to the editor
(another space or any other key).

The first line just creates a title at the top left of the screen.

The second line specifies that the plot is to span 15.0 seconds of
time, and that one iteration is to represent an interval of 0.03
seconds. This implies that 500 iterations will occur (15.0/0.03).

The next three lines define the computation.

The first "integrator" line receives as input a variable called
"force" and it produces an output called "vel" for "velocity." This
expresses a physical law, velocity = integral (force/mass). The
integrator's input receives the "force" variable and multiplies it by
2.0, so evidently the mass is 1/2.0 or 0.5 units (in whatever units
are used consistently in all program steps). The output of the
integrator is initialized to the value 0.0.

Notice that we are using an input that hasn't been defined yet,
"force."

The second integrator line receives "vel" as an input and creates an
output "pos" for "position." This corresponds to the physical fact
that position is the integral of velocity. The input variable "vel" is
multiplied by 1.0, so that if the velocity is given in centimeters per
second, the position will be given in centimeters. If the input
velocity in centimeters per second were multiplied by 0.01, the
position would be in units of meters. It is important to keep track of
units in these analogue computations if you want to match the behavior
of the computer with that of a real system. For simple demonstrations
of relationships, units can be ignored.

The output variable is initialized to 100.0, meaning that the position
begins at 100.0 units positive.

The "summator" line models a spring that is attached between an object
and the zero-point of the position scale. It says that force = -1.0
times the position measured relative to the zero-point. The negative
sign indicates that the force acts toward the zero position. The 5.0
says that for each unit of displacement of the object, there will be
five units of restoring force generated. So this line converts the
deflection of the object from its zero position into a force tending
to restore it to the zero position, as a spring would do.

We have now created a value for the variable "force" that was used in
the first integrator line. This value is a function of itself (at a
slightly earlier time). You will often find this situation in analogue
computing: you assume a value for a variable as an input to one block
of the computation, and then through successive computations you
create that value! A sort of bootstrap effect results, in which an
unknown variable serves as the basis for computing its own value. We
have clearly left the world of linear reasoning.

The next line is a "group" directive. It is used to avoid introducing
unwanted delays into this loop of computations, by grouping the three
computing blocks together. All three blocks, once they are grouped,
compute their outputs within a single iteration of the program.

Now we want to display the results. We will look at just the position
and velocity variables, so the "print" statement mentions just those
two variables.

The next statement says to plot those variables with scaling factors
of 1.0. We could have said "plot 1.0 5.0" in which case the position
variable would appear with 5.0 times its actual amplitude, relative to
the plot of the velocity variable. Leaving out explicit scaling
factors sets all factors equal to 1.0. If you enter one scaling
factor, you must enter a scaling factor for all variables in the print
list.

When you run the program, you will see two sine waves in a box with
the coordinates scaled. Notice that the position variable begins with
a value of 100.0, the value to which we initialized the output of the
second integrator. On the y-scale you see the number 1.00, but at the
top you see "x 10E2" which means "x 100". The notation 10E2 means "10
to the second power." So the initial amplitude of the position is
100.0 units.

The initial velocity is zero, the value to which the first integrator
output was initialized. We can see that just as the position variable
crosses zero, the velocity variable is maximum: the object is moving
the fastest. Where the position variable reaches its maximum or
minimum, the velocity variable is zero; the object has just stopped.

We have now modeled a mass on a spring, released from a deflected
position. We are seeing the motions of an object following a cosine-
wave oscillation, with its velocity showing a sine-wave oscillation.
This system is evidently frictionless, because the maximum and minimum
positions repeat on each cycle.

In fact, we have set up this system to display the solution of a
second-order differential equation,

m*d2x/dt^2 - kx = 0.

                       Modifying the program

Let's modify this mass-on-a-spring simulation to introduce some
viscous friction. Viscous friction, for our purposes here, generates a
force opposed to the direction of motion and proportional to the
momentary velocity. So in our simulation, we should cause the velocity
to produce a force that subtracts from the input of the integrator
where the "force" variable appears.

This is very easy to do, using the program line

vel integrator 0.0 force 2.0

The output of this block is the velocity variable; the input is the
force variable. Integrators can receive multiple input variables, each
arbitrarily weighted. We want to add an input force that is
proportional to the negative of the velocity, or to put that
differently, add the velocity to the existing force with a negative
weight. Let's choose a weight of -0.5, which says that for a velocity
of one unit per second, a negative force of 0.5 units will act on the
object. We simply change the above line to

vel integrator 0.0 force 2.0 vel -0.5

This may answer one question: yes, an input to a block can come
directly from its own output.

Running the program again, you see that the sine and cosine waves now
decrease rapidly to zero. By altering the duration in the "time" line
from 15.0 to 30.0, you can extend the time of the run and see that the
decrease simply continues. Our mass on a spring now oscillates back
and forth by smaller and smaller amounts until -- eventually -- it
comes to rest.

You might want to try this program using "negative friction," which
creates positive feedback. Change the -0.5 to 0.5. You will notice
that the plot automatically changes scale so it includes the largest
positive and negative values of the variables.

The above programs show that SIMCON can be used for most ordinary
applications of analogue computers having nothing to do with control
systems. The primary purpose of SIMCON, however, is to allow
simulating control systems in order to teach how they work. Sometimes
the environment will need to be simulated, too, using techniques like
those we have just seen. But let us look now into how a simpler
environment can be used with a control system that controls one
environmental variable.

                     A simple control system

A control system reduced to its most basic form senses an
environmental variable, compares the signal from the sensor against an
adjustable reference signal, amplifies the resulting error signal, and
applies the output to affect the external controlled variable. The
basic control system building blocks are an input function (the
sensor), a comparison function (which subtracts the sensor's output
from a reference signal), and an output function (which converts the
error signal into a physical effect on the environment). The
environment contains a variable (the controlled quantity) affected by
the control system's output, and to make the model general, also by an
independent disturbing variable that adds its effects directly to the
controlled quantity along with the effects of the control system's
output. By an informal convention, we refer to variables inside the
control system as "signals," and to variables in its environment as
"quantities."

We can translate these statements directly into a SIMCON program.

First, the input function. We need an input "perceptual" signal sp
which depends on the controlled quantity qc:

sp summator qc 1.0 # input function

We use a summator when we just want a simple multiplication factor
without a time constant. In this case the summator has only one input,
although in general it can have many weighted inputs.

The signal sp, in a model of a living control system, is a nervous
system signal measured in impulses per second. The corresponding
controlled quantity, qc, is a physical variable measured in
appropriate physical units. By using a scaling factor of 1.0 in the
input function, we define a certain number of impulses per second,
corresponding to one unit of the physical variable qc, as "one nervous
system unit." However many impulses per second that amounts to in a
given case, the same unit is then used to measure all the other
signals inside the control system. So we start by normalizing so that
one signal unit equals one physical unit at the input. The input
function can thus always have a proportionality factor of unity,

The next function is the comparison function. Conventionally we say
that it subtracts the perceptual signal sp from a reference signal sr.
SIMCON has a specific comparison function build in which is a little
simpler than a summator (which could also be used). The output of the
comparison function or comparator is called the error signal, se.

se comparator sr sp #comparator

In a comparator block, the second input variable is subtracted from
the first. We will leave the undefined reference signal sr dangling
for now.

The last function in the control system is the output function, which
is a transducer that converts the error signal into a physical effect
on the environment. Because of the way we normalized the input
function, all of the amplification that occurs inside the control
system is taken care of in the output function. The output variable of
the output function is an environmental output quantity, qo. The
function itself is an amplifier, which in SIMCON has a limited dynamic
response to sudden changes in the error signal.

If the error signal changed instantly from zero to an nonzero value,
the output of the amplifier would rise to a value "gain" times the
value of the error signal. It would do so with a time constant that is
set by the last parameter of the amplifier statement. Varying the time
constant changes the speed with which the output comes to a new value,
but does not alter the final value. Because of the time constant, the
amplifier must be initialized to a specific starting output value,
which is normally zero. The gain factor is set to 50.0.

qo amplifier qe 0.0 50.0 0.51 # output function, t.c. = 0.51 sec.

The reason for choosing exactly that time constant will be explained
later.

The environment connects the output quantity to the controlled
quantity through a link that we will represent as a simple linear
multiplier. The input quantity is also affected by a disturbing
quantity qd through another linear multiplier. Let's assume that both
of these multipliers are set to 1.0. This establishes the controlled
quantity that we assumed back at the beginning:

qc summator qo 1.0 qd 1.0 # input quantity = output + disturbance

We have completed the closed loop, but there are two variables left
unaccounted for: the reference signal sr and the disturbing quantity
qd. To supply these, we need two "generators."

First, the reference signal. Let's say that it is provided by a ramp
generator that creates a uniformly rising reference signal starting at
time zero and going to 100.0 after 10.0 seconds, then returning to
zero for the rest of the run.

sr generator ramp 0.0 10.0 100.0 # ramp generator for ref signal

Let's put a disturbance right in the middle of this run. The
disturbing quantity qd will start at zero, then rise to 25.0 units at
3.0 seconds of elapsed time. It will remain at 25.0 until 6.0 seconds
of elapsed time, then return to zero again.

qd generator puls 3.0 6.0 25.0 # pulse generator for disturbance

To see what happens after the ramp returns to zero, let's set the run
length to 12.0 seconds. To get 1200 data points for each variable, we
set dt to 0.01 sec.

time 12.0 0.01

Finally, what do we want to plot?

One basic phenomenon of control is that a control system keeps its
perceptual signal (sp) nearly equal to its reference signal (sr), so
we want to plot both of these variables. Another principle is that the
output of the control system changes equally and oppositely to the
disturbance, plus enough more to maintain the perception near the
reference signal. So we want to plot qd and qo. The error signal se is
also a direct indication of the difference between perception and
reference. That is probably enough for one plot.

print se sp sr qo qd
plot

Those two statements designate the variables to be output, and sets
the scaling factors for all of them to 1.0.

We can now put all these statements together, provide a title for the
plot, and group the variables to minimize time delays:

title Simple control system
time 12.0 0.01 # duration 12 sec; dt 0.01 sec
sp summator qc 1.0 # input function
se comparator sr sp # comparator
qo amplifier se 0.0 50.0 0.51 # output t.c.= 0.51 sec.
qc summator qo 1.0 qd 1.0 # qc = output + dist
sr generator ramp 0.0 10.0 100.0 # ref signal is a ramp
qd generator puls 3.0 6.0 25.0 # disturbance is a pulse
group sp sr se qo qc
print se sp sr qo qd
plot

The amplifier time constant of 0.51 sec was set for the optimum value
for this control system. To find the optimum time constant, calculate
G as the product of all multiplying factors found in one trip around
the loop from perceptual signal back to perceptual signal (sp). In
this setup the product G = 1.0 * gain * 1.0 * 1.0 (the comparator
counts as a gain of 1.0). The optimum time constant is (G + 1) * dt,
or 51 * 0.01, or 0.51 sec. This is the optimum value only if there is
exactly one time constant in the loop, and if all the variables in the
loop are grouped. If the group statement is omitted, there will be a
0.04 second delay around the loop, and you will find that the
amplifier time constant must be increased to get performance without
overshoots. With the optimum time constant and all variables grouped,
the error caused by the disturbance is cancelled in one iteration.

Things to notice:

As the reference signal rises along its ramp, the perceptual signal
follows it, lagging behind by about 2% of the reference signal. The
perceptual trace can be seen only during the disturbance because it is
overlaid by the output quantity trace, qo. You can see the error
signal, near the x-axis, slowly rising as the reference signal grows.
It is this rise in the error signal, multiplied by 50, that is causing
the output to rise and the perceptual signal to rise. And it is the
rise of the perceptual signal that is keeping the error signal from
being any larger than it is!

When the disturbance suddenly appears, it tends to raise the
perceptual signal by the amount of the disturbance. At the first
instant, it does so (to see this better you can slow the reponse of
the system by increasing the amplifier time constant to, say, 10). The
perceptual signal trace rises above the reference signal, and you can
see a sudden negative-going error signal. But the control system
immediately reduces its own output, and restores the perceptual signal
to very nearly the former amount. The output quantity drops, then
proceeds in an upgoing ramp parallel to the reference signal and below
it by just the amount of the disturbance. When the disturbance ends,
all the changes occur in reverse. The perceptual signal drops below
the reference signal, a sharp positive error signal appears, and the
output quantity rises again to continue in a ramp near to the
reference signal ramp.

If you do try raising the amplifier time constant to 10 seconds, you
will see that this does NOT create a 10-second time constant in the
action of the system. The feedback effects greatly shorten the time
constant for the closed-loop system; it becomes only about 0.3
seconds. As you vary the multiplying factors in the control loop, you
will find over and over that the expected effect of the change is not
the effect that occurs.

By studying the behavior of a control system in this kind of detail,
you can become familiar with the way all the variables change in
relation to each other. This will help to train your intuition away
from the old linear cause-effect ways of understanding behavior. Your
experimentation will be made easier if you stick to a long time
constant like 10 seconds for the amplifier; this will enable you to
make changes in parameters without having to recompute the optimum
time constant for each trial.

A warning: if you use time constants less than the optimum, a computer
artifact will begin to show up. Very high-frequency oscillations will
occur, and runaway oscillations will occur if the time constant drops
to half or less of the optimum. These oscillations result from the
fact that we are emulating a continuous analogue system using a
digital computer in which values can change only in steps. They are
not part of the true behavior of the control system being modeled.

If you want to explore the effects of very short time constants, but
run into these very high frequency oscillations before you get to the
time constant you want, just reduce the value of dt (second argument
in the "time" statement). You may still run into oscillation problems,
but if they are of a lower frequency than one complete oscillation for
every two data points, they are real.

The point of SIMCON is to let you experiment with control systems.
Don't be afraid to try crazy things.

Representing Wolfgang Zocher,

William T. Powers

[From Bill Powers (930322.1600)]

Here is the documentation that goes with Wolfgang Zocher's
beautiful analog-computer-on-a-PC program. I've uploaded some
ascii-converted versions of the program to Bill Silvert's file
server at biome.bio.ns.ca; Bill will no doubt check them and put
them in the pubs/csg/simcon directory. Better wait for Bill's
notification that the files have been put in the correct
directory. I've also asked Gary Cziko to download them and put a
binary version in the same directory (I still can't upload binary
files). I would like a very brief note from everyone who
downloads this program and is prepared to use it. Anyone who
can't download it can send me a self-addressed STAMPED disk
mailer with a formatted disc in it (360K or more, 5-1/4 or 3-1/2
inch), and I will send all the stuff by return mail.

If you get a copy of this program, you will be able to receive
simulations over CSGnet and run them on your computer. This is
going to make communicating principles and ideas concerning PCT
very much easier. We all owe Wolfgang a lot of thanks for the
long hours he has spent in creating this very functional and
apparently bug-free program and allowing us all to use it.

Best,

Bill P.

                This is SIMCON Version 4.4

SIMCON is a simulator of control loops.
It helps to do experiments in Perceptual Control Theory by
William T. Powers.

    Copyright (C) 1992,1993 Wolfgang Zocher

    email: zocher@rrzn.uni-hannover.dbp.de
    snail: Wolfgang Zocher
           Hauptstrasse 15
           3225 Capellenhagen
           Germany

    This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 1, or (at
your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

···

---------------------------------------------------------

                             Overview

SIMCON is an analogue computer implemented on a digital computer. It
enables the user to connect functional blocks to each other and assign
parameters to the inputs and internal operations of the blocks, then
run the simulation and plot the results. The output of each block is
designated by a user-assignable name, and plots can be made of any
named variable. Plots are globally scaled to fit the largest
excursions of variables into the plotting area; in addition, relative
scales can be assigned to each variable individually.

The program setup is contained in a user-written text file with the
extension ".inp". This text file can be sent over network
communications so that users can pass setups to each other and run
them.

A small user-written text file named simcon.rc enables the user to
integrate a text editor into the program so that the program file can
be edited without leaving Simcon. The same file can specify that the
plots be done using gnuplot3.exe (which the user must have); if the
line specifying gnuplot is left out, a built-in plotting routine is
used. If there is no file simcon.rc, the program will simply exit
after doing a plot, and the user can use any convenient means of
editing the program listing, then restart Simcon.

The C source code of SIMCON is ANSI compatible with the exception of
the built-in plotting routines. By using the provision for linking to
Gnuplot, it should be possible to port the program to Unix and other
machines without great difficulty. Contact Wolfgang Zocher for
details.

              Hardware requirements for PC environments

SIMCON should be run on AT-compatible machines: 286, 386, or 486. The
faster, the better. A math coprocesser is highly recommended.

The basic program occupies about 88K bytes; it is recommended that at
least 256K of free memory be available, and as much more as needed to
run the editor and gnuplot if they are integrated into the program.
Simcon runs under DOS only, version 3.x and up.

The built-in plotting routine can use ATT, Hercules, CGA, EGA, and VGA
graphics boards, auto-detected. Borland ".BGI" graphics interface
files must be present in the same directory as Simcon43. In addition,
if the user has a superVGA facility capable of 1024 x 768 resolution,
and the interface file "svga16.bgi" is present, the program will use
it. Gnuplot may offer more combinations.

In version 4.4 the plotted traces are color-coded, and there is no
provision for identifying traces when the number of variables plotted
exceeds the number of colors available. The program can be used with
only two-color graphics, but the user will have to identify the traces
by ingenuity. A later version will provide for putting labels on the
traces when insufficient colors are available. A workaround is to
delete plotting of specific traces and see which ones disappear.

                   The basic computing blocks

The basic blocks available are

CONST, SUMMATOR, AMPLIFIER, INTEGRATOR, MULT, COMPARATOR, GENERATOR,
DELAY, and LIMIT. Under GENERATOR there are two subtypes: PULS and
RAMP. All blocks but generators receive inputs from other blocks, and
produce just one output which can be named with a character string up
to 20 characters long.

Note that in a given program, there may be many instances of each type
of block. They are distinguished by the symbolic names given to their
outputs, and each is specified in a separate program line.

In the following, keywords that must be typed in exactly as shown are
capitalized; they must be entered, however, in lower case. Upper-case
characters are not recognized by SIMCON.

CONST:

Syntax: output_name CONST value

The value is a decimal number.

SUMMATOR:

Syntax: output_name SUMMATOR in1 weight1 in2 weight2 ... weight99

The inputs (in1 etc) are symbolic names of block outputs; the weights
are decimal numbers. The output is the sum of all the weighted
inputs. Up to 99 inputs can be specified.

COMPARATOR:

Syntax: output_name COMPARATOR input1 input2

The output is input1 minus input2. The input variables are the
symbolic names of the outputs of other blocks.

AMPLIFIER:

Syntax: output_name AMPLIFIER input initial_value gain_value
         time_constant

The amplifier is a leaky integrator; hence its output must be
initialized to a specific value (usually 0.0). The gain is a decimal
parameter (with sign). The time constant is a decimal number, in
seconds. The time constant should not be set to a value less than the
basic time-interval for computations (see "TIME" below).

INTEGRATOR:
Syntax: output_name INTEGRATOR init_value in1 wt1 ... in99 wt99

The integrator requires an initial decimal value for its output. It
takes up to 99 inputs, each with an assigned weight. The "in1" etc.
entry is the symbolic name of the output from another block; the
weight "wt1" etc. is a decimal number. The sum of inputs is
multiplied by "dt", the basic computing interval, before being summed
into the output.

The integration method used in Simcon is simple summation. This is
sufficient for use in closed-loop systems, but not for long strings
of integrations outside of negative feedback loops.

MULT:

Syntax: output_name MULT input1 input2

The multiplier outputs a value that is in1 times in2, where in1 and
in2 are symbolic names of outputs from other blocks.

GENERATOR: PULS type
There are no inputs to a generator.

  Syntax: output_name GENERATOR PULS start_time end_time amplitude

  The start time is the decimal time at which the output goes from
  zero to "amplitude" in size. The end time is the decimal time at
  which the output returns to zero. The amplitude is the decimal value
  of the output between the start and end times.

GENERATOR: RAMP type

  Syntax: output_name GENERATOR RAMP start_time end_time amplitude

  The start and end times have the same meaning as for the PULS
  generator. The output rises uniformly from zero, starting at the
  start time, to "amplitude" units at the end time, then returns to
  zero.

DELAY:

Syntax: output_name DELAY input delay_time

The delay block outputs the input variable delayed by "delay_time"
seconds, in decimal. Initially, zeros are output until the first
nonzero value of the input reaches the output. The delay time is
converted to integer units of the basic computing time "dt", so
should be as long or longer than this basic unit.

LIMIT:

Syntax: output_name LIMIT input lower_limit upper_limit

This block simply prevents the output from going below the lower
limit or above the upper limit. The (symbolic) input variable is not
affected. The limits are decimal numbers.

                          Program directives

In addition to the lines of the program specifying blocks and their
interconnections, there are program lines that specify overall
constants and tell the program how to run and plot the results.

TITLE:

Syntax: TITLE <ASCII title to be printed at top of plots>

TIME:

Syntax: TIME duration dt

"Duration" is a decimal number giving the length of a simulation run
  in seconds. "dt" is the basic computing interval in seconds. The
  length of one program iteration is "dt" seconds, usually 0.1 or
  less.

The total number of output data lines written by the program (each
containing the values of all plotted variables) is "duration" divided
by "dt." Output data lines are stored in an ASCII file with the name
filename.dat, where "filename" is the same as the name of the program
file, minus extension. In addition, there is generated an output file
called filename.plt, which contains data in the form that gnuplot and
the built-in plotter use. Old ".dat" and ".plt" files can be deleted
to conserve disk space, as they are rewritten on every run.

Long durations and short values of dt lead to generating a great
number of output data points, and to long computing times. Only as
many data points as actually needed should be generated, especially
on slower computers.

PRINT:

Syntax: PRINT < variable names separated by spaces>

This directive lists the block outputs that are to be plotted or
printed out. More than four or five variables makes a messy plot.

PLOT:

Syntax: PLOT scale1 scale2 .... scalen

For each variable listed in the PRINT directive, a scaling factor is
given in decimal. Because plots are globally scaled to fit the
plotting area, these scaling factors are relative. If one variable is
to be plotted at 10 times the scale of all others, set that
variable's scale factor to 10.0 and the rest to 1.0. If any scaling
factor is given, all must be given.

If PLOT is followed by no scaling factors at all, all scaling factors
are set to 1.0.

If the PLOT directive is omitted entirely, the output will be printed
as columns of decimal numbers to the printer. Beware -- if the run
duration is long and "dt" is small, you can use a lot of paper.

# -- comments

In any line of the program listing , all characters following a "#"
symbol are taken as comments, and are ignored. A "#" in the first
position of a line makes the whole line a comment.

                            Grouping

There is one last directive, but to understand it you must understand
a subtle feature of Simcon.

Simcon is actually a parallel computing device. All block computations
are done, in effect, at the same time -- not in sequence. For each
block having an input and an output, the inputs are used to calculate
a new output; this is done for all blocks on any one iteration of the
program. Each block, however, is taking as inputs the OLD outputs from
the other blocks to which it is connected. So in effect, all the
computations occur simultaneously. Then, when all computations are
finished for one iteration, all the "new" outputs are copied into the
"old" outputs in preparation for the next iteration.

As a result, a change at the input to a block takes one iteration to
show up as an effect on the output of that block. However, if there
are several blocks connected in sequence, as there usually are, a
change at the input to the first block doesn't reach the output of the
nth block until n iterations later. Although all blocks are acting
simultaneously, there are transport lags (like neural conduction times
or synaptic delays) in every element. This allows the simulation to
deal realistically with lags in the system, without forcing the
computing functions to "take turns acting" (a common mistake in
analyzing systems with delays).

Note that the MINIMUM lag possible is the time "dt" that specifies the
duration of one iteration of the program. Longer lags can be inserted
anywhere by using a DELAY block.

Now to the GROUP directive.

Sometimes the user will wish to create a complex block by combining
several blocks. Also, there are cases (as in modeling the acceleration
and velocity of masses in the environment) where transport lags should
be as small as possible (they can't be smaller than one iteration, of
course). In either case, the user does NOT want to have as many
transport lags as there are elements being combined, but wants the
group of elements to pass its inputs to its outputs as fast as
possible.

This is what the GROUP directive is for.

GROUP:

Syntax: GROUP < list of names of block outputs>

The group directive causes the NEW outputs of each block in the group
to be used as input to the next block instead of the OLD outputs. As
a result, an input to the first block in a group has an effect on the
output of the last block in a single iteration of the program.

Simcon automatically computes the dependencies within a group so that
the computations are done in the correct order for minimum lag.

There can be up to 10 GROUP directives, each on a separate line of
the program listing. The groupings are independent of each other.

                         LEARNING TO USE SIMCON

SIMCON does not yet allow drawing block diagrams of computing setups,
so it is a good idea to draw your own diagram on paper first. Label
the block outputs with short symbols that will remind you of their
meaning, and label any weighted inputs with the weighting factors that
go with them.

Because SIMCON emulates an analogue computer, you must get used to the
idea that all parts of a diagrammed setup are active at the same time.
Each block is continuously converting its inputs to an output
regardless of what other blocks are doing. A computing setup behaves
as a whole; it can sometimes be hard to grasp what is going on because
ordinary sequential cause and effect do not apply in the way to which
you may be accustomed.

In choosing a basic computing interval, remember that this sets the
basic delay of a signal going through a block. If you have five blocks
connected in sequence, a perturbation at the input of the first block
will take 5 iterations of the program, five times the interval dt
specified in the TIME directive, to reach the output of the last block
in sequence. If you mean for this amount of delay to exist, all is
well. Otherwise you may want to use the GROUP directive to make the
delay equal to one iteration, the shortest possible. In general you
will want to make dt short enough so that grouping will make the delay
negligible on the time scale of the modeled system's behavior.

Finally, as mentioned, the blocks in SIMCON act at the same time, so
you can write the program lines defining the blocks and their
connections in any order. This means you can collect sets of blocks
together for ease of understanding instead of having to list the
blocks in the order of connection. Comment lines (any part of a line
following a "#" symbol) can be used to make the program more self-
explanatory, so you can remember what a setup was supposed to do six
months after you wrote it. Copious comments are especially useful to
anyone else who wants to try your computing setup. The setup programs
are pure ASCII files, so you can send them over a network like
Compuserve or the internet.

                    Writing a SIMCON program

SIMCON programs can be written using any text editor. However, if you
use a word processor be sure that you save the files in DOS (pure
ASCII) format, and do not insert any typesetting or control characters
into the text. Any characters other than "#", the alphabetic
characters "a" through "z", the numbers, and the decimal point "."
will be tagged as errors by SIMCON and the program will not run. Note
that SIMCON does not recognize characters in upper case. The only
exception to these rules is the part of a line that follows a comment
symbol "#" (which can be the whole line). Any characters can be used
in comments -- except the carriage return, which ends the line.

You can integrate some text editors with SIMCON so you don't have to
leave SIMCON to modify a program. To do this, create a text file,
using your editor, with the name "simcon.rc" in the same directory
with SIMCON. The contents of the file is a line beginning with the
word "editor", a space, and the full path needed to call the editor
program into use. If you are using the DOS 5.0 editing program called
EDIT.EXE, kept in the directory \dos, you would write

editor \dos\edit

End the line with a return before storing the file.

A second line can be added to simcon.rc to use gnuplot3.exe for
plotting results; it is similar in form:

gnuplot \gnu\gnuplot

for example.

In the following it will be assumed that you have integrated an editor
into SIMCON. If you haven't, SIMCON will simply exit when it is time
to revise the program, and you can call up the program for editing in
the usual way.

One caution. SIMCON expects program files to have a normal DOS name
followed by the extension ".inp" (for "input file"). If you use a word
processor like Word Perfect, which does not use standard ASCII
formats, you must NOT give the word processor's file the extension
".inp" for the simple reason that when you store the file, you will
have to give it a different name to use for the ASCII (DOS text)
version of the program. However you do the editing, it is the ASCII
file, not the word processor file, that must have the correct name and
the ".inp" extension. You may find it impossible to use complex word
processors integrated with SIMCON.

The convention for calling a program to run and edit is

SIMCON name

Where "name" is the text file containing the program setup. Note that
in calling the named program, you do NOT add the extension ".inp",
even though the file must be named (for example) "name.inp". SIMCON
adds that extension itself before trying to open the file. If you add
it yourself, SIMCON will think you are trying to run a program called
"name.inp.inp" and will complain, and quit.

If this program file does not already exist, SIMCON will open the text
editor immediately if it can (if not, it will just exit). When it
opens the file for the first time, it will add the ".inp" extension,
so the file will be properly named. You can then write the program.

                      An introductory program

Let us write a program called "waves.inp". Switching to the directory
in which SIMCON resides, we give the command

simcon waves

If you don't have the editor integrated, call your word processor to
edit a file called "waves.inp" before giving the above command.

Enter the following program:

title Produce sine and cosine waves
time 15.0 0.03
vel integrator 0.0 force 2.0
pos integrator 100.0 vel 1.0
force summator pos -5.0
group vel pos force
print vel pos
plot

Note that each element of a line is separated by one or more spaces.

When you have typed in the program, exit the editor and you will see a
plot of sine and cosine waves. The space bar will bring up a message
asking if you want to quit (the Esc key) or return to the editor
(another space or any other key).

The first line just creates a title at the top left of the screen.

The second line specifies that the plot is to span 15.0 seconds of
time, and that one iteration is to represent an interval of 0.03
seconds. This implies that 500 iterations will occur (15.0/0.03).

The next three lines define the computation.

The first "integrator" line receives as input a variable called
"force" and it produces an output called "vel" for "velocity." This
expresses a physical law, velocity = integral (force/mass). The
integrator's input receives the "force" variable and multiplies it by
2.0, so evidently the mass is 1/2.0 or 0.5 units (in whatever units
are used consistently in all program steps). The output of the
integrator is initialized to the value 0.0.

Notice that we are using an input that hasn't been defined yet,
"force."

The second integrator line receives "vel" as an input and creates an
output "pos" for "position." This corresponds to the physical fact
that position is the integral of velocity. The input variable "vel" is
multiplied by 1.0, so that if the velocity is given in centimeters per
second, the position will be given in centimeters. If the input
velocity in centimeters per second were multiplied by 0.01, the
position would be in units of meters. It is important to keep track of
units in these analogue computations if you want to match the behavior
of the computer with that of a real system. For simple demonstrations
of relationships, units can be ignored.

The output variable is initialized to 100.0, meaning that the position
begins at 100.0 units positive.

The "summator" line models a spring that is attached between an object
and the zero-point of the position scale. It says that force = -1.0
times the position measured relative to the zero-point. The negative
sign indicates that the force acts toward the zero position. The 5.0
says that for each unit of displacement of the object, there will be
five units of restoring force generated. So this line converts the
deflection of the object from its zero position into a force tending
to restore it to the zero position, as a spring would do.

We have now created a value for the variable "force" that was used in
the first integrator line. This value is a function of itself (at a
slightly earlier time). You will often find this situation in analogue
computing: you assume a value for a variable as an input to one block
of the computation, and then through successive computations you
create that value! A sort of bootstrap effect results, in which an
unknown variable serves as the basis for computing its own value. We
have clearly left the world of linear reasoning.

The next line is a "group" directive. It is used to avoid introducing
unwanted delays into this loop of computations, by grouping the three
computing blocks together. All three blocks, once they are grouped,
compute their outputs within a single iteration of the program.

Now we want to display the results. We will look at just the position
and velocity variables, so the "print" statement mentions just those
two variables.

The next statement says to plot those variables with scaling factors
of 1.0. We could have said "plot 1.0 5.0" in which case the position
variable would appear with 5.0 times its actual amplitude, relative to
the plot of the velocity variable. Leaving out explicit scaling
factors sets all factors equal to 1.0. If you enter one scaling
factor, you must enter a scaling factor for all variables in the print
list.

When you run the program, you will see two sine waves in a box with
the coordinates scaled. Notice that the position variable begins with
a value of 100.0, the value to which we initialized the output of the
second integrator. On the y-scale you see the number 1.00, but at the
top you see "x 10E2" which means "x 100". The notation 10E2 means "10
to the second power." So the initial amplitude of the position is
100.0 units.

The initial velocity is zero, the value to which the first integrator
output was initialized. We can see that just as the position variable
crosses zero, the velocity variable is maximum: the object is moving
the fastest. Where the position variable reaches its maximum or
minimum, the velocity variable is zero; the object has just stopped.

We have now modeled a mass on a spring, released from a deflected
position. We are seeing the motions of an object following a cosine-
wave oscillation, with its velocity showing a sine-wave oscillation.
This system is evidently frictionless, because the maximum and minimum
positions repeat on each cycle.

In fact, we have set up this system to display the solution of a
second-order differential equation,

m*d2x/dt^2 - kx = 0.

                       Modifying the program

Let's modify this mass-on-a-spring simulation to introduce some
viscous friction. Viscous friction, for our purposes here, generates a
force opposed to the direction of motion and proportional to the
momentary velocity. So in our simulation, we should cause the velocity
to produce a force that subtracts from the input of the integrator
where the "force" variable appears.

This is very easy to do, using the program line

vel integrator 0.0 force 2.0

The output of this block is the velocity variable; the input is the
force variable. Integrators can receive multiple input variables, each
arbitrarily weighted. We want to add an input force that is
proportional to the negative of the velocity, or to put that
differently, add the velocity to the existing force with a negative
weight. Let's choose a weight of -0.5, which says that for a velocity
of one unit per second, a negative force of 0.5 units will act on the
object. We simply change the above line to

vel integrator 0.0 force 2.0 vel -0.5

This may answer one question: yes, an input to a block can come
directly from its own output.

Running the program again, you see that the sine and cosine waves now
decrease rapidly to zero. By altering the duration in the "time" line
from 15.0 to 30.0, you can extend the time of the run and see that the
decrease simply continues. Our mass on a spring now oscillates back
and forth by smaller and smaller amounts until -- eventually -- it
comes to rest.

You might want to try this program using "negative friction," which
creates positive feedback. Change the -0.5 to 0.5. You will notice
that the plot automatically changes scale so it includes the largest
positive and negative values of the variables.

The above programs show that SIMCON can be used for most ordinary
applications of analogue computers having nothing to do with control
systems. The primary purpose of SIMCON, however, is to allow
simulating control systems in order to teach how they work. Sometimes
the environment will need to be simulated, too, using techniques like
those we have just seen. But let us look now into how a simpler
environment can be used with a control system that controls one
environmental variable.

                     A simple control system

A control system reduced to its most basic form senses an
environmental variable, compares the signal from the sensor against an
adjustable reference signal, amplifies the resulting error signal, and
applies the output to affect the external controlled variable. The
basic control system building blocks are an input function (the
sensor), a comparison function (which subtracts the sensor's output
from a reference signal), and an output function (which converts the
error signal into a physical effect on the environment). The
environment contains a variable (the controlled quantity) affected by
the control system's output, and to make the model general, also by an
independent disturbing variable that adds its effects directly to the
controlled quantity along with the effects of the control system's
output. By an informal convention, we refer to variables inside the
control system as "signals," and to variables in its environment as
"quantities."

We can translate these statements directly into a SIMCON program.

First, the input function. We need an input "perceptual" signal sp
which depends on the controlled quantity qc:

sp summator qc 1.0 # input function

We use a summator when we just want a simple multiplication factor
without a time constant. In this case the summator has only one input,
although in general it can have many weighted inputs.

The signal sp, in a model of a living control system, is a nervous
system signal measured in impulses per second. The corresponding
controlled quantity, qc, is a physical variable measured in
appropriate physical units. By using a scaling factor of 1.0 in the
input function, we define a certain number of impulses per second,
corresponding to one unit of the physical variable qc, as "one nervous
system unit." However many impulses per second that amounts to in a
given case, the same unit is then used to measure all the other
signals inside the control system. So we start by normalizing so that
one signal unit equals one physical unit at the input. The input
function can thus always have a proportionality factor of unity,

The next function is the comparison function. Conventionally we say
that it subtracts the perceptual signal sp from a reference signal sr.
SIMCON has a specific comparison function build in which is a little
simpler than a summator (which could also be used). The output of the
comparison function or comparator is called the error signal, se.

se comparator sr sp #comparator

In a comparator block, the second input variable is subtracted from
the first. We will leave the undefined reference signal sr dangling
for now.

The last function in the control system is the output function, which
is a transducer that converts the error signal into a physical effect
on the environment. Because of the way we normalized the input
function, all of the amplification that occurs inside the control
system is taken care of in the output function. The output variable of
the output function is an environmental output quantity, qo. The
function itself is an amplifier, which in SIMCON has a limited dynamic
response to sudden changes in the error signal.

If the error signal changed instantly from zero to an nonzero value,
the output of the amplifier would rise to a value "gain" times the
value of the error signal. It would do so with a time constant that is
set by the last parameter of the amplifier statement. Varying the time
constant changes the speed with which the output comes to a new value,
but does not alter the final value. Because of the time constant, the
amplifier must be initialized to a specific starting output value,
which is normally zero. The gain factor is set to 50.0.

qo amplifier qe 0.0 50.0 0.51 # output function, t.c. = 0.51 sec.

The reason for choosing exactly that time constant will be explained
later.

The environment connects the output quantity to the controlled
quantity through a link that we will represent as a simple linear
multiplier. The input quantity is also affected by a disturbing
quantity qd through another linear multiplier. Let's assume that both
of these multipliers are set to 1.0. This establishes the controlled
quantity that we assumed back at the beginning:

qc summator qo 1.0 qd 1.0 # input quantity = output + disturbance

We have completed the closed loop, but there are two variables left
unaccounted for: the reference signal sr and the disturbing quantity
qd. To supply these, we need two "generators."

First, the reference signal. Let's say that it is provided by a ramp
generator that creates a uniformly rising reference signal starting at
time zero and going to 100.0 after 10.0 seconds, then returning to
zero for the rest of the run.

sr generator ramp 0.0 10.0 100.0 # ramp generator for ref signal

Let's put a disturbance right in the middle of this run. The
disturbing quantity qd will start at zero, then rise to 25.0 units at
3.0 seconds of elapsed time. It will remain at 25.0 until 6.0 seconds
of elapsed time, then return to zero again.

qd generator puls 3.0 6.0 25.0 # pulse generator for disturbance

To see what happens after the ramp returns to zero, let's set the run
length to 12.0 seconds. To get 1200 data points for each variable, we
set dt to 0.01 sec.

time 12.0 0.01

Finally, what do we want to plot?

One basic phenomenon of control is that a control system keeps its
perceptual signal (sp) nearly equal to its reference signal (sr), so
we want to plot both of these variables. Another principle is that the
output of the control system changes equally and oppositely to the
disturbance, plus enough more to maintain the perception near the
reference signal. So we want to plot qd and qo. The error signal se is
also a direct indication of the difference between perception and
reference. That is probably enough for one plot.

print se sp sr qo qd
plot

Those two statements designate the variables to be output, and sets
the scaling factors for all of them to 1.0.

We can now put all these statements together, provide a title for the
plot, and group the variables to minimize time delays:

title Simple control system
time 12.0 0.01 # duration 12 sec; dt 0.01 sec
sp summator qc 1.0 # input function
se comparator sr sp # comparator
qo amplifier se 0.0 50.0 0.51 # output t.c.= 0.51 sec.
qc summator qo 1.0 qd 1.0 # qc = output + dist
sr generator ramp 0.0 10.0 100.0 # ref signal is a ramp
qd generator puls 3.0 6.0 25.0 # disturbance is a pulse
group sp sr se qo qc
print se sp sr qo qd
plot

The amplifier time constant of 0.51 sec was set for the optimum value
for this control system. To find the optimum time constant, calculate
G as the product of all multiplying factors found in one trip around
the loop from perceptual signal back to perceptual signal (sp). In
this setup the product G = 1.0 * gain * 1.0 * 1.0 (the comparator
counts as a gain of 1.0). The optimum time constant is (G + 1) * dt,
or 51 * 0.01, or 0.51 sec. This is the optimum value only if there is
exactly one time constant in the loop, and if all the variables in the
loop are grouped. If the group statement is omitted, there will be a
0.04 second delay around the loop, and you will find that the
amplifier time constant must be increased to get performance without
overshoots. With the optimum time constant and all variables grouped,
the error caused by the disturbance is cancelled in one iteration.

Things to notice:

As the reference signal rises along its ramp, the perceptual signal
follows it, lagging behind by about 2% of the reference signal. The
perceptual trace can be seen only during the disturbance because it is
overlaid by the output quantity trace, qo. You can see the error
signal, near the x-axis, slowly rising as the reference signal grows.
It is this rise in the error signal, multiplied by 50, that is causing
the output to rise and the perceptual signal to rise. And it is the
rise of the perceptual signal that is keeping the error signal from
being any larger than it is!

When the disturbance suddenly appears, it tends to raise the
perceptual signal by the amount of the disturbance. At the first
instant, it does so (to see this better you can slow the reponse of
the system by increasing the amplifier time constant to, say, 10). The
perceptual signal trace rises above the reference signal, and you can
see a sudden negative-going error signal. But the control system
immediately reduces its own output, and restores the perceptual signal
to very nearly the former amount. The output quantity drops, then
proceeds in an upgoing ramp parallel to the reference signal and below
it by just the amount of the disturbance. When the disturbance ends,
all the changes occur in reverse. The perceptual signal drops below
the reference signal, a sharp positive error signal appears, and the
output quantity rises again to continue in a ramp near to the
reference signal ramp.

If you do try raising the amplifier time constant to 10 seconds, you
will see that this does NOT create a 10-second time constant in the
action of the system. The feedback effects greatly shorten the time
constant for the closed-loop system; it becomes only about 0.3
seconds. As you vary the multiplying factors in the control loop, you
will find over and over that the expected effect of the change is not
the effect that occurs.

By studying the behavior of a control system in this kind of detail,
you can become familiar with the way all the variables change in
relation to each other. This will help to train your intuition away
from the old linear cause-effect ways of understanding behavior. Your
experimentation will be made easier if you stick to a long time
constant like 10 seconds for the amplifier; this will enable you to
make changes in parameters without having to recompute the optimum
time constant for each trial.

A warning: if you use time constants less than the optimum, a computer
artifact will begin to show up. Very high-frequency oscillations will
occur, and runaway oscillations will occur if the time constant drops
to half or less of the optimum. These oscillations result from the
fact that we are emulating a continuous analogue system using a
digital computer in which values can change only in steps. They are
not part of the true behavior of the control system being modeled.

If you want to explore the effects of very short time constants, but
run into these very high frequency oscillations before you get to the
time constant you want, just reduce the value of dt (second argument
in the "time" statement). You may still run into oscillation problems,
but if they are of a lower frequency than one complete oscillation for
every two data points, they are real.

The point of SIMCON is to let you experiment with control systems.
Don't be afraid to try crazy things.

Representing Wolfgang Zocher,

William T. Powers