FieldVMC: An Asynchronous Model and Platform for Self-organising Morphogenesis of Artificial Structures
Anonymized for double-blind review
- About
- Getting Started
In the field of evolutionary computing, the concept of Vascular Morphogenesis Controller (VMC) has been proposed in to model the growth of artificial structures over time.
A thorough analysis of the VMC model revealed some limitations:
- assumes the organization structure is a tree, here intended as a directed acyclic graph with a single root and with a single path connecting the root with each leaf;
- the model is implicitly synchronous, as it assumes that (i) the evaluation of the nodes must proceed from the leaves to the root (and back), and (ii) the update of the whole tree occurs atomically.
Although, depending on the context, these assumptions may be acceptable, in general they may induce (possibly hidden) abstraction gaps when VMC is used to model real-world systems, and, at the same time, limit the applicability of the pattern to engineered morphogenetic systems.
To address these limitations, in this work, we propose FieldVMC: a generalisation of the VMC model as a field-based computation, in the spirit of the Aggregate Programming (AP) paradigm.
This repository contains the source code for the experiments presented in the paper "FieldVMC: An Asynchronous Model and Platform for Self-organising Morphogenesis of Artificial Structures".
The experiments want to show the capabilities of the proposed model in generating self-organising spatial structures.
Some examples of the generated structures are shown below:
![]() |
![]() |
|---|---|
| Starting Structure | Self-Organised Structure |
![]() |
![]() |
| Structure after cutting a part of it | Self-Organised Structure after the cutting |
The images show the evolution of a structure from a starting configuration to a self-organized structure, see the Understanding the experiments section for a detailed explanation of the images.
The goal of this evaluation is to show that the proposed FieldVMC supports the construction of the same structures of its predecessor, and, in addition, that it can work in scenarios not previously investigated. To this end, we designed a set of five experiments:
- self-construction from a single node (growth from seed),
- self-division after disruption (network segmentation) with no regeneration (cutting),
- self-integration of multiple FieldVMC systems (grafting)
- self-segmentation of a larger structure (budding), and
- self-optimisation of multiple large structures into a more efficient one (abscission and regrowth).
In order to successfully download and execute the graphical experiments are needed:
- Internet connection;
- Git;
- Linux, macOS and Windows systems capable of running Java 17 (or higher);
- 4GB free space on disk (the system will automatically download its dependencies through Gradle) (NOTE that if you want to download or generate data, you will need an additional free space);
- GPU with minimal OpenGL capabilities (OpenGL 2.0);
- 4GB RAM (to generate the charts, we used a PC with 32GB RAM, with lower amounts the process could take a very long time or crash).
The project uses Gradle as a build tool,
and all the project dependencies are listed in the gradle\libs.versions.toml file.
- The experiments run in "batch mode" generate a lot of data, and the simulation may take a long time to finish (up to several hours) even with high-performance computers. We suggest running the experiments in "graphic mode" to have a better understanding of the simulation;
- On different monitor types with different resolutions, the graphical interface could appear a bit different;
- For GUI interpretation, please refer to the Simulation Graphical Interface section.
In all the experiments, the cyan area represents the resource and the yellow area the success, with darker shades indicating higher values.
Nodes are represented as circles.
The root is identified by a dark outer circumference.
The size of a circle depends on the amount of resource and success received
relative to all other nodes in the system: we fix the maximum possible size
Their color depends on the amount of resource nodes have and is assigned based on the hue of the HSV color space,
with the most resource associated with indigo, and the lowest with red.
Dashed lines are communication channels, solid black lines represent the tree structure, and green (resp. orange) lines depict
the resource (resp. success) distribution flows, the thicker they are, the more resource (resp. success) is being transferred.
The experiments are:
- legacySelfConstruction: self-construction from a single node (growth from seed),
- selfDivision: self-division after disruption (network segmentation) with no regeneration (cutting). The segmentation is performed by removing a part of the structure after 500 simulated seconds, and the nodes are not able to regenerate the missing part;
- selfIntegration: self-integration of multiple FieldVMC systems (grafting). Two distinct structures are created, and after 500 simulated seconds, they are merged into a single structure;
- selfSegmentation: self-segmentation of a larger structure (budding). Two distinct structures are created with possibly more than leader each; after 500 simulated seconds, they are merged into a single structure;
- selfOptimisation: self-optimisation of multiple large structures into a more efficient one (abscission and regrowth). Sparse nodes are created far from success and resource sources, with spawning and destruction of nodes enabled, the structure is allowed to grow and optimize itself.
- selfConstructionClassicVMC: implementation of the classic VMC model, starting from a single node, with spawning of new nodes but no destruction of them;
- selfHealingClassicVMC: same of the previous one, but with the cutting of a part of the structure after 500 simulated seconds;
- selfConstructionFieldVMC: implementation of our FieldVMC model, with optimized parameters to be as close as possible to the classic VMC model;
- selfHealingFieldVMC: same of the previous one, but with the cutting of a part of the structure after 500 simulated seconds;
- selfConstructionFieldVMCOptimizer: launcher of our FieldVMC model in order to evaluate the optimized parameters used in the comparison with the classic VMC model.
This section provides a brief overview of the legacySelfConstruction experiment, to give an idea of how the experiments work. The legacySelfConstruction experiment simulates the self-construction of a structure from a single node. The detailed instructions to reproduce the experiment are in the section "Reproduce the entire experiment".
The simulation can be launched with the command ./gradlew runSelfConstructionGraphic,
or the one in the section "Extremely quick-start".
Once the simulation has started, the Alchemist GUI will open.
After the time needed for Alchemist to load the simulation,
it will show the initial structure, that is a single black point representing the root node,
in between the resource (cyan gradient) and success (yellow gradient) layers.
For more details of the simulation (e.g., the appearance, the meaning of the different shapes, etc.)
see section Understanding the experiments.
Now the simulation can be started by pressing the P key on the keyboard.
By pressing the P key again, the simulation will pause (and resume).
When the simulation starts,
if you wish to execute it at "real time" speed,
press the R key (and again to return to the fast speed).
For other features of the GUI, please refer to the Simulation Graphical Interface section.
As seen in the sequence below, the structure evolves from a single node to a more complex structure. Firstly, the structure results to expand towards the center of the available resources. This happens because the spawned nodes are in a zone with higher resources, used as weight in the leader election phase, thus the newly created node gets elected as the new leader, which results in an expansion towards the center of the resource layer. While the root gains more resources, nodes will spawn children based on their local success, meaning that the nodes which sense more success from the environment have higher probability and capabilities to spawn new children, resulting in an expansion towards the center of the success layer. The structure then stabilizes in what appears to be the optimal configuration, and the structure stops evolving.
Sequence of images showing the evolution in time of the structure in the selfConstruction experiment.WARNING: re-running the whole experiment may take a very long time on a normal computer.
The simulation environment and graphical interface are provided by Alchemist Simulator. To understand how to interact with the GUI, please refer to the Alchemist documentation.
- Requires a Unix terminal (
(ba|z|fi)?sh) curlmust be installed- run:
curl https://raw.githubusercontent.com/angelacorte/fieldVMC/master/field-vmc-basic-example.sh | bash - the repository is in your
Downloadsfolder for further inspection.
-
Install a Gradle-compatible version of Java. Use the Gradle/Java compatibility matrix to learn which is the compatible version range. The Version of Gradle used in this experiment can be found in the gradle-wrapper.properties file located in the gradle/wrapper folder.
-
Open a terminal
-
Clone this repository on your pc with
git clone https://github.com/angelacorte/fieldVMC.git. -
Move into the root folder with
cd fieldVMC -
Depending on the platform, run the following command:
- Bash compatible (Linux, Mac OS X, Git Bash, Cygwin):
./gradlew run<ExperimentName>Graphic - Windows native (cmd.exe, Powershell):
gradlew.bat run<ExperimentName>Graphic
- Bash compatible (Linux, Mac OS X, Git Bash, Cygwin):
-
Substitute
<ExperimentName>with the name of the experiment (in PascalCase) specified in the YAML simulation file. Or execute./gradlew tasksto view the list of available tasks.
Note that before each experiment command, it must be set the MAX_SEED environment variable to a specific value to run the experiment,
since that parameter is relevant only for batch experiments,
it is suggested to set it to 0 for the graphical experiments.
Depending on the platform, there may be different ways to set the environment variable:
- If you're using Bash compatible (Linux, Mac OS X, Git Bash, Cygwin):
MAX_SEED=0 ./gradlew run<ExperimentName>Graphic - If you're using Command Prompt (cmd.exe):
set MAX_SEED=0 && gradlew.bat run<ExperimentName>Graphic - If you're using PowerShell:
$env:MAX_SEED = 0; .\gradlew.bat run<ExperimentName>Graphic
For the sake of simplicity, we will show Bash compatible commands below. Moreover, due to Alchemist's limitations, the graphical interface will not appear if run on a docker container.
The corresponding YAML simulation files to the experiments cited above are the following:
- legacySelfConstruction: self-construction from a single node (growth from seed)
MAX_SEED=0 ./gradlew runLegacySelfConstructionGraphic, - selfDivision: self-division after disruption (network segmentation) with no regeneration (cutting)
MAX_SEED=0 ./gradlew runselfDivisionGraphic, - selfIntegration: self-integration of multiple FieldVMC systems (grafting)
MAX_SEED=0 ./gradlew runSelfIntegrationGraphic, - selfSegmentation: self-segmentation of a larger structure (budding)
MAX_SEED=0 ./gradlew runSelfSegmentationGraphic, and - selfOptimization: self-optimization of multiple large structures into a more efficient one (abscission and regrowth)
MAX_SEED=0 ./gradlew runSelfOptimizationGraphic; - selfConstructionClassicVMC: implementation of the classic VMC model, starting from a single node, with spawning of new nodes but no destruction of them
MAX_SEED=0 ./gradlew runSelfConstructionClassicVMCGraphic; - selfHealingClassicVMC: same of the previous one, but with the cutting of a part of the structure after 500 simulated seconds
MAX_SEED=0 ./gradlew runSelfHealingClassicVMCGraphic; - selfConstructionFieldVMC: implementation of our FieldVMC model, with optimized parameters to be as close as possible to the classic VMC model
MAX_SEED=0 ./gradlew runSelfConstructionFieldVMCGraphic; - selfHealingFieldVMC: same of the previous one, but with the cutting of a part of the structure after 500 simulated seconds
MAX_SEED=0 ./gradlew runSelfHealingFieldVMCGraphic; - selfOptimizationLeaderElection: experiment used to retrieve data for the data rate analysis
MAX_SEED=0 ./gradlew runSelfOptimizationLeaderElectionGraphic.
NOTE: The tasks above in graphic mode will run the experiments with the default parameters.
To change the parameters of the experiments, you can modify the YAML files located in the src/main/yaml folder.
The parameters that can be changed are:
seed: the seed used to generate the random numbers, to have reproducible results;leaderRadius: the radius within the leader election is performed;maxResource: the maximum resource available inside the environment;maxSuccess: the maximum success available inside the environment (usually set to the same value ofmaxResource);initialNodes: the number of nodes to be created at the beginning of the simulation (except for legacySelfConstruction, selfConstructionClassicVMC, selfHeaingClassicVMC, selfConstructionFieldVMC, selfHealingFieldVMC experiments, which start with a single node);resourceLowerBound: the minimum amount of resource that a node can have in order not to die (for the oneRoot and graftWithSpawning experiments);maxChildren: the maximum number of children a node can have (for the oneRoot and graftWithSpawning experiments);minSpanWait: the minimum time a node has to wait before spawning a new node (for the oneRoot and graftWithSpawning experiments);killingRange: the range within the nodes are removed (for the healings experiment);layerX: the position of the resource and success layer on the x-axis;layerY: the position of the resource and success layer on the Y-axis (for the oneRoot experiments);maxY&minY: position of the layer on the y-axis (for every experiment except oneRoot);width&height: the width and height of the rectangle in which the nodes are placed, used to simplify the management of the nodes' translation (for every experiment except oneRoot);gaussianShape: the shape of the Gaussian distribution used for the resource and success layer.
Each change in the parameters will result in a different structure generated by the simulation. The parameters provided in the YAML files are the ones used for the evaluation and the ones evaluated as "optimal".
For further information about the YAML structure, please refer to the Alchemist documentation.
The project is structured in the following way:
fieldVMC/
├── docker/ # Dockerfiles to build containers
├── effects/ # Json specification for Alchemist's GUI visualization
├── gradle/ # Gradle wrapper files
├── images/ # Images used in the README
├── src/main
│ ├── kotlin/it.unibo/ # Kotlin source code for the experiments
│ │ ├── alchemist # Alchemist's model and global reactions
│ │ │ ├── actions # Main implementation of the classic VMC's logic
│ │ │ ├── boundary # Alchemist utilities for data extraction, simulation launcher, and graphic interface effects
│ │ │ ├── collektive.device # Collektive device integration for Alchemist
│ │ │ ├── model # Alchemist's model for the experiments such as simulation terminators and deployments
│ │ │ ├── util # implementation of the Alchemist-related utilities
│ │ ├── collektive # The main Collektive logic for the experiments
│ │ │ ├── coordination # Main aggregate functions for leader election and resource spreading
│ │ │ ├── lib # Aggregate function for success, resource, and leader management
│ │ │ ├── utils # Spawning logic
│ │ │ ├── vmc # Programs entrypoints
│ │ ├── common # Common utilities such as the logic for the spawning angle, termination metrics etc.
│ └── yaml # YAML files for the experiments specificationThe simulations in which nodes are able to spawn new nodes and destroy them are the legacySelfConstruction and selfOptimization experiments.
Their entrypoint can be found at src/main/kotlin/it/unibo/collektive/vmc/VMCSpawning.kt.
The program takes as input the aggregate function withSpawning(), which uses a function that implements the spawning (and killing) logic.
Shortly, a node can spawn if:
- it has enough resources to spawn a new node and remain alive;
- it has less than the maximum number of spawn-able children,
- it has been stable for at least the minimum time required; or it is the only node in his surroundings.
Similarly, a node can die if:
- it has less than the minimum amount of resources required to survive;
- it has no children;
- it has been stable for at least the minimum time required.
The simulations that do not involve the spawning of new nodes are the selfDivision, selfIntegration, and selfSegmentation experiments.
Their entrypoint can be found at src/main/kotlin/it/unibo/collektive/vmc/VMCWithoutSpawning.kt.
It simply uses aggregate functions to elect leaders and manage the resource and success distribution.
The simulations that involve only the spawning of new nodes are the selfConstructionClassicVMC, selfHealingClassicVMC, selfConstructionFieldVMC, and selfHealingFieldVMC experiments.
The entrypoint for the FieldVMC approach can be found at src/main/kotlin/it/unibo/collektive/vmc/FieldVMCFixedLeader.kt,
in which the leader is fixed (there is no leader election) and all nodes are able to spawn new ones.
| Experiment | YAML file | Spawning | Destruction | Forced cutting | Forced union |
|---|---|---|---|---|---|
| legacy Self-construction | legacySelfConstruction.yaml |
Yes | Yes | No | No |
| Self-division | selfDivision.yaml |
No | No | Yes | No |
| Self-integration | selfIntegration.yaml |
No | No | No | Yes |
| Self-segmentation | selfSegmentation.yaml |
No | No | No | Yes |
| Self-optimization | selfOptimization.yaml |
Yes | Yes | No | No |
| Self-construction Classic VMC | selfConstructionClassicVMC.yaml |
Yes | No | No | No |
| Self-healing Classic VMC | selfHealingClassicVMC.yaml |
Yes | No | Yes | No |
| Self-construction Field VMC | selfConstructionFieldVMC.yaml |
Yes | No | No | No |
| Self-healing Field VMC | selfHealingFieldVMC.yaml |
Yes | No | Yes | No |
| Self-construction Field VMC Optimizer | selfConstructionFieldVMCOptimizer.yaml |
Yes | No | No | No |
| Self-optimization Leader Election | selfOptimizationLeaderElection.yaml |
Yes | Yes | No | No |
WARNING: re-running the whole experiment may take a very long time on a normal computer.
To collect the data for the analysis and the charts, the experiments have been run in "batch mode," which means that the experiments are run without the graphical interface, and with different combinations of parameters.
Since to run the experiments in batch mode in a normal computer may take a very long time (e.g., days), we launched the experiments on a cluster to shorten the time needed to collect the data.
Note: This is suggested just for data analysis purposes, since the graphical interface will not appear if run on a docker container. The docker containers will run the experiments in batch mode to collect the data, thus it is co
- Install Docker and docker-compose;
- Run
docker-compose upin the root folder of the repository: this will build the Docker images and run the containers needed to run the experiments. - From the
docker-compose.ymlfile, you can see that nine separate containers will be created, one for each experiment, and the data will be collected in thedatafolder. Note that thevolumesfield has to be updated to match your local environment.
- Install a Gradle-compatible version of Java.
Use the Gradle/Java compatibility matrix
to learn which is the compatible version range.
The Version of Gradle used in this experiment can be found in the
gradle-wrapper.propertiesfile located in thegradle/wrapperfolder. - Install the version of Python indicated in
.python-version(or usepyenv). - Launch either:
./gradlew runAllBatchon Linux, MacOS, or Windows if a bash-compatible shell is available;gradlew.bat runAllBatchon Windows cmd or Powershell;
- Once the experiment is finished, the results will be available in the
datafolder.
Note that you will need to set the MAX_SEED environment variable to a specific value to run the experiment (e.g., in our experiments, we set it to 500).
- Make sure you have Python 3.10 or higher installed.
- The
datafolder structure should be the following:experiments-2025-acsos-robots/ ├── data/ │ ├── self-optimization/ │ ├── self-integration/ │ └── ...
- Install the required Python packages by running:
pip install --upgrade pip pip install -r requirements.txt
- Run the script to process the data and generate the charts (this process may take some time):
python charts-generator.py
- The charts will be generated in the
chartsfolder. - If you want to regenerate the charts, you can run the script again.




