[![Build Status](https://travis-ci.org/MontiSim/RMIModelServer.svg?branch=master)](https://travis-ci.org/MontiSim/RMIModelServer) [![Maintainability](https://api.codeclimate.com/v1/badges/55c8774bfd4d37534691/maintainability)](https://codeclimate.com/github/MontiSim/RMIModelServer/maintainability) # RMIModelServer The RMIModelServer is used to remotely allocate a series of [_HardwareEmulators_](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/hardware_emulator), which can load different autopilots generated with [_EMAM2CPP_](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAM2Cpp). ## Requirements In order the project to be built locally, the following software is required: Apache Maven Java Development Kit, Version 8+ (optional) Git To clone this github repository, one can use the following commands cd MontiSim git clone https://github.com/MontiSim/RMIModelServer.git __NOTE:__ _MontiSim_ is the directory, in which MontiSim-belonging projects should be clonned. It has to be manually created. ## Compiling To just compile the `jar`, use mvn clean install -s settings.xml To compile and copy the server to the local `install` folder, use the `scripts/compile_install` scripts. __NOTE:__ New versions of the _HardwareEmulator_ must be copied into the `install` folder. This folder is used in a maven test to verify RMIModelServer/HardwareEmulator integration. ## Running the RMI server The `install` folder contains a sample setup for running the RMIModelServer. The RMIModelServer jar must be in the same directory as the [HardwareEmulator](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/hardware_emulator) library it will use (_HardwareEmulator.lib_ or _HardwareEmulator.so_ for Windows or Linux). The `run` script starts an instance of the RMIModelServer. It uses the `config` script to provide a way of changing the port or the autopilot folder used. The port defaults to 10101, and can be changed to start multiple RMIModelServers. The autopilot folder is a folder path (absolute or relative to the RMIModelServer) in which the RMI server will look for autopilot programs. These programs are the EmbeddedMontiArc models compiled with EMAM2CPP (or a project using EMAM2CPP such as [EMAM-showcase](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/EMAM-showcase) or [EMAStudio](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/utilities/EMAStudioBuilder)). The `autopilots` folder in the `install` folder contains the sample autopilot from `EMAM-Showcase`. ## Docker Here is another possibility to run the RMI server without compiling the AutopilotAdapter.dll yourself. First we build the docker image with ``` $ ./docker/build.sh ``` This script only does 2 things: 1. Copy the latest rmi-model-server build into ./docker/ in order to prepare the build. 2. Then use ./docker/Dockerfile to build the rmi-model-server docker image. After the docker image is built. Run following command to start the RMI server with port 10101: ``` $ docker run --name=rmi-server -p 10101:10101 --rm rmi-server ``` Or, for example with port 5000: ``` $ docker run --name=rmi-server -p 5000:10101 --rm rmi-server ``` # Dev Documentation ## Emulator configuration The [emulator_configuration](docs/emulator_configuration.pdf) document shows the configuration possibilities for the autopilot emulators. ## HardwareEmulator JNI interface The interface of between the RMIModelServer and the HardwareEmulator works with _Java Native Interface (JNI)_. In case of an update of the interface (file: [src/main/java/simulator/integration/HardwareEmulatorInterface.java](src/main/java/simulator/integration/HardwareEmulatorInterface.java)), the corresponding C header has to be generated. Currently, this happens in the [hardware_emulator](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/hardware_emulator) project under the `jni` folder, where the HardwareEmulatorInterface.java has to be copied. `generate.bat` shows how to update the interface on Windows. The java file has to be adapted to compile without its dependencies, since the JNI header will only be generated from compilable java files. Since the actual header file only depends on the `native` functions from the java file, the other dependencies can be safely deleted. The resulting header file then has to be renamed `emulator_server.h` and placed in the `hardware_emulator/src/emulator` source folder. The corresponding implementations of the C interface have to be updated in `hardware_emulator/src/emulator/emulator_server.cpp`. A better approach would be a script in the RMIModelServer project generating the header and copying it to the *hardware_emulator* project. ## New autopilot EMA port types To communicate with the ports from the autopilot, an _AutopilotAdapter_ encapsulates the EMA model. For new port data types, the *EMAM2CPP* generator and the *hardware_emulator* have to be updated to handle the new data type. In the EMAM2CPP project, the `de.monticore.lang.monticar.generator.cpp.viewmodel.AutopilotAdapterDataModel` class is responsible to create the _AutopilotAdapter_. In its `addInput` and `addOutput` functions, the new function definition and declarations for the data type have to be defined. In the *hardware_emulator* projects, three places require updates for new data types. 1. The `hardware_emulator/src/emulator/function_values.h / .cpp` files need to updated with the new data type (`enum class VALUE_TYPE`), buffer entry (`struct FunctionValue`) and type name (`FunctionValue::get_type()`). 2. The `call_input()` and `call_output()` functions from the `HardwareEmulator` structure (`hardware_emulator/src/emulator/hardware_emulator.h`) must be updated. They need to know how to pass the arguments to the emulated autopilots. 3. The `Java_simulator_integration_HardwareEmulatorInterface_add_1one_1input()` and `Java_simulator_integration_HardwareEmulatorInterface_query_1outputs()` functions need to know how to pass and read port data to and from Java. (`hardware_emulator/src/emulator/emulator_server.h`) ## Unsupported autopilot functionalities. The emulator used in this RMIModelServer only implements features encountered in previous autopilots. New autopilots might trigger new unsupported features: * Unsupported system calls (enable `debug=unsupported_syscalls` flag for the autopilot emulator). These are operating system functions for which no current emulation is implemented. These have to be added and registered in the `hardware_emulator/src/os_linux/linux_calls.h / .cpp` files for Linux and in the `hardware_emulator/src/os_windows/windows_calls.h / .cpp` files for Windows. * Unsupported instruction time value. The time table (currently `hardware_emulator/src/timetable/skylake.txt`) describing the number of CPU cycles for every instruction is manually filled. It currently only contains entries (!=0) for encountered instructions. It can be filled with elements from the `hardware_emulator/docs/instruction_time.txt` file (which contains entries from the instruction_tables.pdf file). To make sure the autopilot emulation is correct, allocate an autopilot emulator with the `test_real` flag. When loading an autopilot with the same OS as the RMIModelServer, the emulator will compare the outputs of the emulated autopilot with the outputs of the actual autopilot program.