# SynChrono

## Table of Contents

* [Project Overview](#Project-Overview)
* [General SynChrono Process](#General-SynChrono-Process)
* [Building and Running](#Building-and-Running)
* [Implementation Specific Details](#Implementation-Specific-Details)
* [Other](#Other)

## Project Overview

SynChrono is an autonomous vehicle simulation project developed by the Simulation Based Engineering Lab ([SBEL](https://sbel.wisc.edu/)) at the University of Wisconsin-Madison. This simulation framework is based around the ability to simulation one or multiple robots, autonomous vehicles, or other autonomous agents together in a unified framework. Our current motivation comes from autonomous vehicle testing, so many of our demos and examples will draw on autonomous vehicles, but since the simulation is backed by Chrono, we can support any virtual environment.

Our goal is to extend Project Chrono's physics simulation into the multi-agent realm, specifically the multi-agent realm where the dynamics of the agents are not strongly coupled. For a simulation of say two robots underwater, where the currents created by one robot will impact the dynamics of the other robot, you are better off in Chrono, where the robots and the fluid will be contained together in a single Chrono model and where the dynamics will be jointly simulated. SynChrono is suited for scenarios where the dynamics of each agent are important individually, but not in the way that they interact with each other. This is the case for autonomous vehicles where, barring a collision, the dynamics of one vehicle will not impact any other. SynChrono synchronizes the motion of all agents, but allows their dynamics to be distributed across computing nodes rather than including all dynamics in one monolithic simulation.

## General SynChrono Process

1. Environment setup
   * Find an environment mesh: e.g. surface data for the specific roads or terrain your agent will move on)
   * Obtain agents: Chrono::Vehicle provides many vehicle models but you can of course create your own in Chrono
   * Define environment parameters: How many agents? What types are they? Where will they be? How long will the simulation run for? Will they have sensors? etc...
2. Consult the agent's controller
   * Each agent has a controller that tells it what to do, provided some inputs from the world around it.
     * For a vehicle the outputs will be the thrust, braking and steering driving parameters, and the input can be anything accessible to simulation.
     * There may be messages received from e.g. a stoplight.
     * There may be data received from sensors e.g. GPS coordinates, lidar point clouds
   * Controllers can be whatever the user would like and the goal of the SynChrono project is not to develop any particular controller, but rather to develop an environment where others can test their algorithms.
   * SynChrono does currently provide some simple controllers such as a controller that will follow a path defined by GPS coordinates and maintain an appropriate following distance to any vehicles ahead of it based on lidar data.
3. Run Chrono simulation
   * Each computing node starts up starts running a Chrono simulation for the agent(s) it is responsible for.
     * It will run this simulation until it gets to the next "heartbeat" or synchronization timestep.
     * This step 1 is the same as a normal Chrono simulation, iterating a particular system's dynamics for a particular number of timesteps
   * For a vehicle this would be taking the thrust, braking, steering and computing how much the wheels will turn, how far the center of mass will travel, etc...
   * Further Chrono specific details can be found on the Project Chrono [website](http://www.projectchrono.org/).
4. Send state data to controller
   * Having computed its state at the particular heartbeat, each agent now communicates its state to the central controller so that the control can synchronize all agents
   * For a vehicle the state is just the locations and rotation angle of each of the wheels, for a stoplight it may just be the current color of the light, for a complex robot the state may be a large collection of the positions and rotations of each component of the robot.
5. Synchronize all agents
   * The central controller collects state data from every agent and sends it to every other agent in the simulation
   * Each agent will create a "zombie" version of all other agents.
     * The dynamics for this zombie agent will not be simulated, it will just be placed in the world as a visual mesh so that the real agent can compute accurate sensor data.
6. Rinse, wash, repeat
   * Each Chrono simulation has a timestep and each heartbeat has a timestep, so repeatedly doing steps 1-4 advances the simulation through time

## Implementation Specific Details

### Multi-Agent

SynChrono's main aim is to provide robust scalability for large numbers of vehicles. SynChrono has been benchmarked at faster than realtime performance for over 100 vehicles on rigid terrain. Currently, SynChrono supports multiple agents per Chrono system, with each Chrono system tied to a specific node. Multiple agents aids in resource-sharing for scenarios with large memory requirements.

### Physics

The physics for SynChrono is based on the physics of Chrono; for vehicles, this means Chrono::Vehicle's physics.

### Sensing

Sensing support in SynChrono comes through the [Chrono::Sensor module](https://project-chrono-concrete-modeling.gitbook.io/project-chrono-concrete-modeling/src/chrono_sensor). Chrono::Sensor is based around OptiX ray-tracing and currently includes support for camera, lidar, GPS and IMU.

### V2X Communication

SynChrono includes support for arbitrary communication between agents in the system, by using the same flatbuffer message mechanism that is used for synchronizing state data. Currently the main example of this communication is V2V communication of sensor data, and Traffic Light to Vehicle communication of SPAT and MAP messages.

## Build Instructions

Follow the standard [Chrono build process](http://api.projectchrono.org/tutorial_install_chrono.html) to build SynChrono. The Chrono::Vehicle module is required, and one of Chrono::Irrlicht or Chrono::Sensor is recommended for visualization. The only additional dependencies that SynChrono requires are Flatbuffers and MPI. FastDDS is an optional dependency.

#### Flatbuffers

Flatbuffers is included in chrono\_thirdparty as a submodule but you can also use a local copy if it is already installed on your system. Follow the [build instructions](https://google.github.io/flatbuffers/flatbuffers_guide_building.html). The flatbuffer include directory within CMake is pointed directly to the submodule in chrono\_thirdparty, so ensure the submodule is used and built.

#### MPI

For most systems (Linux, MacOS), you can use [OpenMPI](https://www.open-mpi.org/) or [MPICH](https://www.mpich.org/). For Windows there are two main options:

* Intel MPI: [Intel MPI](https://software.intel.com/en-us/mpi-library/choose-download/windows)
* MS-MPI: [MS-MPI](https://docs.microsoft.com/en-us/message-passing-interface/microsoft-mpi)

One consideration is the version of MPI that is supported. Intel MPI is MPI 3.1 compliant whereas MS-MPI is only MPI 2.2 compliant. SynChrono is typically developed and tested with MPI 3.x, but there is no reason that older versions will not work.

#### Windows

On Windows specifically, you'll need some CMake variables to be set correctly. For all of these variables, set both the CXX and C variation of them (e.g. both MPI\_CXX\_LIB\_NAMES and MPI\_C\_LIB\_NAMES). Example values are included for each variable, but they may vary depending on your specific system setup

* MPI\_CXX\_ADDITIONAL\_INCLUDE\_DIRS - `C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2019.5.281/windows/mpi/intel64/include`
* MPI\_CXX\_COMPILER - `C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2019.5.281/windows/mpi/intel64/bin/mpicl.bat`
* MPI\_CXX\_HEADER\_DIR - `C:/Program Files (x86)/IntelSWTools/mpi/2019.5.281/intel64/include/`
* MPI\_CXX\_LIB\_NAMES - set to `impi` if using Intel MPI or `msmpi` if using MS-MPI

Intel MPI specific:

* MPI\_impi\_LIBRARY - `C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2019.5.281/windows/mpi/intel64/lib/release/impi.lib`
* MPI\_impicxx\_LIBRARY - `C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2019.5.281/windows/mpi/intel64/lib/impicxx.lib`

MS-MPI specific, most of these can be set automatically by running `set MSMPI` in `cmd`.

* MPI\_msmpi\_LIBRARY - `C:/Program Files (x86)/Microsoft SDKs/MPI/Lib/x64/msmpi.lib`
* MSMPI\_BIN
* MSMPI\_INC
* MSMPI\_LIB32
* MSMPI\_LIB64

#### FastDDS

FastDDS is supported on most modern systems (Linux, MacOS, Windows). To install, please visit the [FastDDS website](https://fast-dds.docs.eprosima.com/en/latest/). To link to Chrono, either install globally or install in a single directory and point `FAST_DDS_INSTALL_DIR` to that location.
