evox-b: the processing pipeline
Weeks of freestyle coding and lots of experimentation led to the formation of a body-bot processing pipeline that is complete enough to be used as a basis for evolution-driven exploration. The artificial evolution system to be implemented is a very simple one. A major constraint is that all the genetic material that is being processed must have the same number of genes. With this in mind, it was decided that the body-bot ‘control programs’ should all follow a generic layout: a pipeline of code assembled out of the same number of simple low-level building blocks. Each stage of this pipeline can then be described by a virtual gene that encodes the specific building block used. Thus, the sequence of genes stored in a body-bot, its genotype, contains all the information needed to create or recreate the bot’s behavioral machinery, or phenotype.
genotype 00-01-01-00-06-00-07-02-02-03-00-04-00-10-06-01-21-52
Each gene has a value that indicates the allele in use. An allele is a variant of the gene, and in the phenotype it corresponds to a specific building block for the associated stage in the pipeline.
(this article builds on the foundations of the previous one: https://notnot.medium.com/evox-b-a-next-iteration-9d86c0b635d)
The processing pipeline specifies what exactly a body-bot will do in a single step of its lifetime, given the internal state and the external inputs from the environment. In pseudocode it looks like this:
where to go?
gather all possible next candidate positions
apply field-of-view filter
apply on-surface filter
if no valid candidate position was found
run 'is stuck' function to find a new candidate position
select next position from available candidate positions
what to do?
select the current cell type
if the desired environmental conditions are met
depending on the current cell position
set the cell at the current position to the current cell type
For each step in this pipeline one can imagine a variety of algorithms to execute it. evox-b does not have a preference for one over the other. If an algorithm is applicable and ‘seems to make sense’, it is added as an available building block (piece of code). Note that the ‘seems to make sense’ criterion is vague. Since we cannot really predict what a specific piece of code is going to do in the (unknown) context of other code, it comes down to a mix of gut feeling and broad enumeration of options?
evox-b will document and is able to describe all the settings that matter to the growth of a body. To get a feeling for possible processing pipelines, let us have a look at the description of the community of 8 body-bots that jointly produced the following body:
Concise description (genotypes)
'blobschil' seed 0 score 0.222 bots/genotype 1 :
genotype[00] genes 00-01-01-00-06-00-07-02-02-03-00-04-00-10-06-01-21-52
genotype[01] genes 01-01-01-00-05-00-09-02-00-03-00-01-00-13-12-06-25-24
genotype[02] genes 00-01-01-00-06-00-07-02-03-03-00-04-00-10-06-01-21-52
genotype[03] genes 03-01-02-03-07-02-09-02-03-03-00-01-00-13-12-06-25-24
genotype[04] genes 03-01-02-01-07-02-09-02-00-03-00-01-00-13-12-06-25-24
genotype[05] genes 02-02-01-00-05-01-05-01-01-02-00-02-01-11-06-04-47-12
genotype[06] genes 00-03-01-00-05-00-08-01-02-00-00-00-00-04-08-09-55-50
genotype[07] genes 01-02-04-00-02-00-03-01-03-03-00-00-00-04-03-03-61-47
This compact description includes the name of a community of body-bots, the seed value that was used to initialize the environment, the fitness score achieved, and the number of bots per genotype. Then follows the list of all genotypes that were active in the community.
Note that from this description alone, the object rendered above can be recreated perfectly. Variants of this object can trivially be generated by using another seed value.
Verbose description (phenotypes: pipeline building blocks)
bot[00] genes 00-01-01-00-06-00-07-02-02-03-00-04-00-10-06-01-21-52
gene[ 0] 'get' cell type: type 1
gene[ 1] 'set' cell type: type 2
gene[ 2] field of view: 120°
gene[ 3] stuck response: don't move
gene[ 4] move to: max diversity
gene[ 5] select type: setT
gene[ 6] set if: max bot distance > eMin
gene[ 7] set limit: cylinder
gene[ 8] force threshold: 0.125
gene[ 9] energy threshold: 0.750
gene[10] force mode: surf
gene[11] force mix: 1:16
gene[12] distance normalization: by grid
gene[13] trait bits: 1010
gene[14] affinity mask: 0110
gene[15] polarity mask: 0001
gene[16] response curve (internal): 21
gene[17] response curve (external): 52
bot[01] genes 01-01-01-00-05-00-09-02-00-03-00-01-00-13-12-06-25-24
gene[ 0] 'get' cell type: type 2
gene[ 1] 'set' cell type: type 2
gene[ 2] field of view: 120°
gene[ 3] stuck response: don't move
gene[ 4] move to: least common type
gene[ 5] select type: setT
gene[ 6] set if: area > eMin
gene[ 7] set limit: cylinder
gene[ 8] force threshold: 0.0
gene[ 9] energy threshold: 0.750
gene[10] force mode: surf
gene[11] force mix: 1:2
gene[12] distance normalization: by grid
gene[13] trait bits: 1101
gene[14] affinity mask: 1100
gene[15] polarity mask: 0110
gene[16] response curve (internal): 25
gene[17] response curve (external): 24
bot[02] genes 00-01-01-00-06-00-07-02-03-03-00-04-00-10-06-01-21-52
gene[ 0] 'get' cell type: type 1
gene[ 1] 'set' cell type: type 2
gene[ 2] field of view: 120°
gene[ 3] stuck response: don't move
gene[ 4] move to: max diversity
gene[ 5] select type: setT
gene[ 6] set if: max bot distance > eMin
gene[ 7] set limit: cylinder
gene[ 8] force threshold: 0.25
gene[ 9] energy threshold: 0.750
gene[10] force mode: surf
gene[11] force mix: 1:16
gene[12] distance normalization: by grid
gene[13] trait bits: 1010
gene[14] affinity mask: 0110
gene[15] polarity mask: 0001
gene[16] response curve (internal): 21
gene[17] response curve (external): 52
bot[03] genes 03-01-02-03-07-02-09-02-03-03-00-01-00-13-12-06-25-24
gene[ 0] 'get' cell type: type 4
gene[ 1] 'set' cell type: type 2
gene[ 2] field of view: 180°
gene[ 3] stuck response: search downwards
gene[ 4] move to: min diversity
gene[ 5] select type: least common
gene[ 6] set if: area > eMin
gene[ 7] set limit: cylinder
gene[ 8] force threshold: 0.25
gene[ 9] energy threshold: 0.750
gene[10] force mode: surf
gene[11] force mix: 1:2
gene[12] distance normalization: by grid
gene[13] trait bits: 1101
gene[14] affinity mask: 1100
gene[15] polarity mask: 0110
gene[16] response curve (internal): 25
gene[17] response curve (external): 24
bot[04] genes 03-01-02-01-07-02-09-02-00-03-00-01-00-13-12-06-25-24
gene[ 0] 'get' cell type: type 4
gene[ 1] 'set' cell type: type 2
gene[ 2] field of view: 180°
gene[ 3] stuck response: search any
gene[ 4] move to: min diversity
gene[ 5] select type: least common
gene[ 6] set if: area > eMin
gene[ 7] set limit: cylinder
gene[ 8] force threshold: 0.0
gene[ 9] energy threshold: 0.750
gene[10] force mode: surf
gene[11] force mix: 1:2
gene[12] distance normalization: by grid
gene[13] trait bits: 1101
gene[14] affinity mask: 1100
gene[15] polarity mask: 0110
gene[16] response curve (internal): 25
gene[17] response curve (external): 24
bot[05] genes 02-02-01-00-05-01-05-01-01-02-00-02-01-11-06-04-47-12
gene[ 0] 'get' cell type: type 3
gene[ 1] 'set' cell type: type 3
gene[ 2] field of view: 120°
gene[ 3] stuck response: don't move
gene[ 4] move to: least common type
gene[ 5] select type: most common
gene[ 6] set if: average bot distance > eMin
gene[ 7] set limit: fence
gene[ 8] force threshold: 0.0625
gene[ 9] energy threshold: 0.500
gene[10] force mode: surf
gene[11] force mix: 1:4
gene[12] distance normalization: by body
gene[13] trait bits: 1011
gene[14] affinity mask: 0110
gene[15] polarity mask: 0100
gene[16] response curve (internal): 47
gene[17] response curve (external): 12
bot[06] genes 00-03-01-00-05-00-08-01-02-00-00-00-00-04-08-09-55-50
gene[ 0] 'get' cell type: type 1
gene[ 1] 'set' cell type: type 4
gene[ 2] field of view: 120°
gene[ 3] stuck response: don't move
gene[ 4] move to: least common type
gene[ 5] select type: setT
gene[ 6] set if: density > eMin
gene[ 7] set limit: fence
gene[ 8] force threshold: 0.125
gene[ 9] energy threshold: 0.125
gene[10] force mode: surf
gene[11] force mix: never
gene[12] distance normalization: by grid
gene[13] trait bits: 0100
gene[14] affinity mask: 1000
gene[15] polarity mask: 1001
gene[16] response curve (internal): 55
gene[17] response curve (external): 50
bot[07] genes 01-02-04-00-02-00-03-01-03-03-00-00-00-04-03-03-61-47
gene[ 0] 'get' cell type: type 2
gene[ 1] 'set' cell type: type 3
gene[ 2] field of view: 360°
gene[ 3] stuck response: don't move
gene[ 4] move to: nearest type
gene[ 5] select type: setT
gene[ 6] set if: setT is most common
gene[ 7] set limit: fence
gene[ 8] force threshold: 0.25
gene[ 9] energy threshold: 0.750
gene[10] force mode: surf
gene[11] force mix: never
gene[12] distance normalization: by grid
gene[13] trait bits: 0100
gene[14] affinity mask: 0011
gene[15] polarity mask: 0011
gene[16] response curve (internal): 61
gene[17] response curve (external): 47
This elaborate description lists all the genes in each body-bot in a community, and prints the building blocks that are used in a human readable form. Once we are fairly familiar with the pipeline architecture, this textual information gives us a clear idea what is going on, much more than a series of numbers will ever do.
Note that even if all the pipeline configurations of all the body-bots in a community are known, it is still virtually impossible to predict the outcome by envisioning it. There are simply far too many interactions for our human brain to deal with! However, a very patient person with enough pencils and paper can in principle work it out. There is no magic involved.
Gene details
The exact details about the role of the genes are perhaps better understood when studying the source code. A daunting task for someone not familiar with the intricacies of the system and/or a lack of experience with programming languages. Therefore, a short description that clarifies their differences is given here. I might add pseudocode for all the allele variants, if there turns out to be an interest in that.
gene 0, ‘get cell type’ (4 alleles)
This gene encodes the cell type that can play a role in the ‘where to go’ stages of the pipeline.
gene 1 ‘set cell type’ (4 alleles)
This gene encodes the cell type that can play a role in the ‘what to do’ stages of the pipeline.
gene 2 ‘field of view’ (5 alleles)
This gene encodes the field of view of a bot. A bot has a heading, i.e. the direction it points to, and it can only see the environment that is within its field of view, measured relative to its heading. The field of view can range from a narrow 60 degrees to a full 360 degrees.
gene 3 ‘stuck response’ (4 alleles)
This gene encodes the algorithm to use whenever a bot it stuck, i.e. when there are no valid positions to move to in the local environment.
gene 4 ‘move to’ (8 alleles)
This gene encodes the algorithm that is used to select the cell position to move to, from the available candidate positions. The local environment and global bot-bot forces can play a role here.
gene 5 ‘select set type’ (4 alleles)
This gene encodes the algorithm used to select the current cell type that the body-bot will set, if the conditions are suitable. The local environment and global bot-bot forces can play a role here.
gene 6 ‘set if’ (11 alleles)
This gene encodes the conditional test used to determine if a cell can be added by the body-bot, in its current state. The local environment, global bot-bot forces, ‘set cell type’ and energy level can play a role here.
gene 7 ‘set limiter’ (3 alleles)
This gene encodes the limiter function that is being used to deal with the finite grid. A limiter function is important, because without it, body-bots will often collide with the boundaries of the grid and produce unnatural artifacts.
gene 8 ‘force threshold’ (4 alleles)
This gene encodes the threshold value that is required to let the body-bot be affected by an external force. It acts like friction: if the force acting on the bot is too small, it will not move. Forces are exerted by a mix of local environment forces, and global bot-bot forces.
gene 9 ‘energy threshold’ (4 alleles)
This gene encodes the energy threshold that is required for some things to happen. Closely affiliated with gene 6. A body-bot has an energy level that can be influenced by external and internal factors. Very sketchy at the moment!
gene 10 ‘force mode’ (4 alleles)
This gene encodes the way that global bot-bot forces are affecting the body-bot.
gene 11 ‘force mix’ (5 alleles)
This gene encodes the ratio of influence of the local environment forces and the global bot-bot forces for this body-bot. This varies from no bot-bot force influence at all, to exclusively using bot-bot forces.
gene 12 ‘distance normalization’ (2 alleles)
This gene encodes the algorithm used to normalize bot-bot distance measurements. It is either relative to the available grid size, or to the current body size.
The next three genes, 13, 14 and 15, are used in combination. Together they determine how, and how much, a bot is attracted/neutral/repelled by another bot. See the earlier article https://notnot.medium.com/evox-a-types-of-interaction-b61dade96b01 for an explanation of the combination algorithm.
gene 13 ‘trait bits’ (16 alleles)
This gene encodes the trait bits. The trait bits of a bot can be observed by other bots.
gene 14 ‘affinity mask’ (16 alleles)
This gene encodes the affinity mask. The affinity mask of a bot is used in combination with the trait bits of another bot to determine which traits are cared about, and which are not.
gene 15 ‘polarity mask’ (16 alleles)
This gene encodes the polarity mask. The polarity mask specifies to which traits there is a positive or a negative response. A trait can be either attractive or repulsive, or (in combination with the affinity mask) neutral.
The next two genes, 16 and 17, are usually combined with an XOR operation to produce a unique response curve that depends on the pair of body-bots under consideration. The purpose of this response curve is to allow all kinds of non-linearities. See the earlier article https://notnot.medium.com/evox-a-types-of-interaction-b61dade96b01 for more information about the response curves.
gene 16 ‘response curve (internal)’ (64 alleles)
This gene encodes the internal part of the response curve that is applied to the raw linear distance to another bot.
gene 17 ‘response curve (external)’ (64 alleles)
This gene encodes the external part of the response curve that is applied to the raw linear distance to another bot.
The current evox-b system, with its 18 genes and their alleles can assemble 4*4*5*4*8*4*11*3*4*4*4*5*2*16*16*16*64*64 = 3,628,388,371,660,800 different kinds of body-bots. This is a lot. A community of n bots will have 3,628,388,371,660,800^n possible configurations, which is a lot of lots…
The problem of searching this huge space of possibilities will be tackled with artificial evolution, the topic of the next article.
(next: https://notnot.medium.com/evox-b-evolution)
This is a work in progress… to be continued…