Skip to content
Joshua Auerbach edited this page Jun 20, 2016 · 9 revisions

Welcome to the RoboGen Developer wiki

The information here is principally for those that would like to develop RoboGen

Before thinking about developing RoboGen you should be fully familiar with using the software.

Follow the instructions on http://robogen.org/docs/get-started/ to get started and come back here when you decide you want to modify RoboGen. At that point you should fork this repository and read on.

Note In order to develop RoboGen you should be experienced developing C++ including the use of smart pointers and object oriented programming (including various forms of inheritance). If you are not familiar with these concepts there are plenty of tutorials on the web.

RoboGen Architecture

The first thing to understand about RoboGen before attempting to modify any code is its general architecture.

There are two main components to RoboGen: the Evolution Engine and the Simulation Engine. These two components communicate with each other by sending messages (protocol buffers -- https://developers.google.com/protocol-buffers/)

Attention: Before describing the architecture further it is worth pointing out something that might be confusing while looking at the code. RoboGen is now both desktop software and a browser based application. Both of these share the vast majority of the RoboGen code, since the browser application is transpiled to JavaScript with emscripten (https://github.com/kripken/emscripten). However, in order not to over-complicate things at first, it is suggested that you focus on the desktop version. Where we have to do things differently between the JavaScript and C++ generally involves checking the presence of the EMSCRIPTEN prepocessor macro. So at first, you will likely want to ignore anything inside of an #ifdef EMSCRIPTEN block.

Evolution Engine

  • To familiarize yourself with the Evolution Engine you should have a look at src/Evolver.cpp, which is the main executable for robogen-evolver. Basically this takes care of setting things up and running the main evolution loop.

  • Next you should have a look under src/config to get an idea of how the configurations are handled. This code makes heavy use of ** Boost Program Options ** so before making any modifications here, you should familiarize yourself with their usage: http://www.boost.org/doc/libs/1_58_0/doc/html/program_options.html

  • After this you will want to learn about how robots are represented in RoboGen. The code for this is all under src/evolution/representation.

    • The main components here are the RobotRepresentation that is then made of PartRepresentations and a NeuralNetworkRepresentation
  • Then you will want to see how the variation operators act on the representation, which can be found in the Mutator: src/evolution/enging/Mutator

  • Finally you will want to understand how individual robots are organized into a Population (src/evolution/engine/Population), which extends IndividualContainer (src/evolution/engine/IndividualContainer)

Once you are familiar with all of these points you may wish to understand how we provide experimental support for HyperNEAT. We use a port of Peter CH's MultiNEAT library (https://github.com/peter-ch/MultiNEAT), which can be found under src/evolution/neat. All of the logic for actually using that library for RoboGen is found in the NeatContainer (src/evolution/engine/neat/NeatContainer). The way that this is implemented could certainly be improved, but has worked fairly well for our purposes so far.

Simulation Engine

The simulation engine is built on top of the Open Dynamics Engine (http://www.ode.org/). Before modifying the RoboGen simulation engine you should first be well-versed in ODE. Read through their docs, and have a look at their demos (most of the functionality of ODE is contained within the demos somewhere).

The simulation engine is typically invoked in one of two ways. Either by running robogen-server to perform fitness evaluations for the evolver or by running robogen-file-viewer to "play back" a hand-designed or previously evolved robot. The main code for these executables is found in src/RobogenServer.cpp and src/viewer/FileViewer.cpp, respectively. In either case Simulator::runSimulations will be called, so to see how the simutions are actually run you should look at src/Simulator.cpp This in turn relies on many pieces of code organized as follows

  • src/model contains all of the physical models of any object in the RoboGen universe. This includes robots, obstacles, and light sources.

    • Robots (defined in src/Robot) are composed of physical components (defined in src/model/components and the subdirectories thereof). Note: these are the actual physical models of the robot components. Things like sensors and actuators will belong to one of these physical models and the code describing them lives in src/model/sensors and src/model/motors respectively.

    • All other objects (e.g. obstacles and light sources) are defined under src/model/objects

  • It is important to realize that what you actually see when a robot is visualized is not the physical model itself (although this can be seen by running robogen-file-viewer with the --debug option). Each component is generally modelled as a collection of geometric primitives, whereas what is visualized is a mesh representing how the component will be 3D printed. That being said, every model in robogen has a corresponding render component found in src/render/components

A number of other relevant pieces of code can be found under src/utils, including src/utils/RobogenCollision, which handles all physical collisions between objects.

More advanced topics

Communication

As mentioned above, the evolver and simulator communicate by means of protocol buffers. The schema for these messages are defined in src/robogen.proto which is then converted into C++ code by the protobuf compiler. These objects are then written to / read from on different sides of the wire.

The actual communication between the programs use sockets (Except the robogen-server-sio, which uses socket.io). Most of the code for communication can be found under src/utils/network

Saving data

When we want to save an individual we typically convert it to json. The code for going from protobuf messages to/from json is found under src/utils/json2pb

Scriptable Scenarios

A recent addition to the RoboGen platform that has added a lot of flexibility is the use of Scriptable Scenarios. Scenarios can be written in JavaScript and can run on both the browser and desktop versions of RoboGen. This is well documented for users of the system here: http://robogen.org/docs/custom-scenarios/

In order to add functionality to the scenario API there are a few things that need to be understood, especially since this is one of the places of most significant divergence between the desktop and the browser version.

  • In the browser the user's javascript is parsed by the browser and gains access to the API through the use of bindings created with embind (https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html) The code for this lives in src/scenario/JSScenario as well as bindings defined in src/js/RobogenJS.cpp

  • In the C++ version, the user's javacript is parsed by the QScriptEngine, and relies on a separate set of bindings. The code for this is found in src/scenario/QScriptScenario and src/scripting/QBindings

VERY IMPORTANT Any changes to the scenario API must be made for both versions or experiments initiated with the browser version and sharing computation with the C++ version will not work correctly!

Arduino

When going to hardware it is necessary to generate a NeuralNetwork.h file for use on Arduino. All the code for doing this is found in src/arduino

One thing that may be a bit confusing here is how this works. When you first compile Robogen a file src/brain/NeuralNetwork.template is created from src/brain/NeuralNetwork.h This is then read into string variable in ArduinoNNCompiler.cpp for use when generating the arduino NeuralNetwork.h file. Previously we would just read the NeuralNetwork.h file from the source tree directly, but this will not be present in the browser version, and so doing so like this was found to be a preferred solution.

Javascript Specific

TODO

Misc: