diff --git a/CNNModelTraining/.gitignore b/CNNModelTraining/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..93bdd06a87f88fe6ff8ff3b14d0b7dc686911a80
--- /dev/null
+++ b/CNNModelTraining/.gitignore
@@ -0,0 +1,5 @@
+target/
+output/
+.idea/
+.git
+*.iml
\ No newline at end of file
diff --git a/CNNModelTraining/pom.xml b/CNNModelTraining/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d0196e1109c9c050831d45c469fd81930e8b736d
--- /dev/null
+++ b/CNNModelTraining/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+ de.monticore.lang.monticar
+ cnn-model-training
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ de.monticore.lang.monticar
+ embedded-montiarc
+ 0.0.11c-SNAPSHOT
+
+
+ de.monticore.lang.monticar
+ embedded-montiarc-deeplearning
+ 0.2.0-SNAPSHOT
+
+
+
+
diff --git a/CNNModelTraining/src/main/java/de/monticore/lang/monticar/torcs_dl/CNNCodeGenerator.java b/CNNModelTraining/src/main/java/de/monticore/lang/monticar/torcs_dl/CNNCodeGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..68dbafb24ef2b154f48796449af5040b03614bac
--- /dev/null
+++ b/CNNModelTraining/src/main/java/de/monticore/lang/monticar/torcs_dl/CNNCodeGenerator.java
@@ -0,0 +1,29 @@
+package de.monticore.lang.monticar.torcs_dl;
+
+import de.monticore.lang.monticar.emadl.generator.Generator;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+
+public class CNNCodeGenerator {
+
+ public static final String TARGET_PATH_GENERATED = "./target/generated-sources-cnn-model-training/";
+ public static final String MODELS_PATH = "src/main/models/";
+
+
+ public static void main(String[] args) {
+ System.out.println("Starting code generation...");
+
+ Generator gen = new Generator();
+ gen.setGenerationTargetPath(TARGET_PATH_GENERATED);
+ try {
+ gen.generate(MODELS_PATH, "Alexnet");
+ } catch (IOException | TemplateException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/CNNModelTraining/src/main/models/Alexnet.emadl b/CNNModelTraining/src/main/models/Alexnet.emadl
new file mode 100644
index 0000000000000000000000000000000000000000..e3b1ee3452534221e66e47d33d4d8cfef5ec35ad
--- /dev/null
+++ b/CNNModelTraining/src/main/models/Alexnet.emadl
@@ -0,0 +1,47 @@
+component Alexnet{
+ ports in Z(0:255)^{3, 224, 224} image,
+ out Q(0:1)^{10,1,1} predictions;
+
+ implementation CNN {
+
+ def split1(i){
+ [i] ->
+ Convolution(kernel=(5,5), channels=128) ->
+ Lrn(nsize=5, alpha=0.0001, beta=0.75) ->
+ Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
+ Relu()
+ }
+ def split2(i){
+ [i] ->
+ Convolution(kernel=(3,3), channels=192) ->
+ Relu() ->
+ Convolution(kernel=(3,3), channels=128) ->
+ Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
+ Relu()
+ }
+ def fc(){
+ FullyConnected(units=4096) ->
+ Relu() ->
+ Dropout()
+ }
+
+ image ->
+ Convolution(kernel=(11,11), channels=96, stride=(4,4), padding="no_loss") ->
+ Lrn(nsize=5, alpha=0.0001, beta=0.75) ->
+ Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
+ Relu() ->
+ Split(n=2) ->
+ split1(i=[0|1]) ->
+ Concatenate() ->
+ Convolution(kernel=(3,3), channels=384) ->
+ Relu() ->
+ Split(n=2) ->
+ split2(i=[0|1]) ->
+ Concatenate() ->
+ fc(->=2) ->
+ FullyConnected(units=10) ->
+ Softmax() ->
+ predictions
+
+ }
+}
\ No newline at end of file
diff --git a/CNNModelTraining/src/main/models/AlexnetConfig.cnnt b/CNNModelTraining/src/main/models/AlexnetConfig.cnnt
new file mode 100644
index 0000000000000000000000000000000000000000..eb0f732d20d3dcbf018d6456db98a301c1771129
--- /dev/null
+++ b/CNNModelTraining/src/main/models/AlexnetConfig.cnnt
@@ -0,0 +1,7 @@
+configuration AlexnetConfig{
+ num_epoch : 100
+ batch_size : 500
+ optimizer : adam{
+ learning_rate : 0.001
+ }
+}
diff --git a/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/IAdapterTemplate.ftl b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/IAdapterTemplate.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..249275bbd1bec15c4cf4280b1298efa0e900966f
--- /dev/null
+++ b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/IAdapterTemplate.ftl
@@ -0,0 +1,9 @@
+#pragma once
+#include "${compName}.h"
+
+class IAdapter_${compName}{
+ public:
+ virtual ~IAdapter_${compName}(){}
+ virtual void init(${compName}* comp) = 0;
+ virtual void tick() = 0;
+};
diff --git a/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/cmakeCppTemplate.ftl b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/cmakeCppTemplate.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..a602a4e1aa7feeaa9e91f7fdd6cd8a49d5b04116
--- /dev/null
+++ b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/cmakeCppTemplate.ftl
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.5)
+project(${compName} LANGUAGES CXX)
+add_library(${compName} ${compName}.h)
+target_include_directories(${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+set_target_properties(${compName} PROPERTIES LINKER_LANGUAGE CXX)
+export(TARGETS ${compName} FILE ${compName}.cmake)
diff --git a/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/coordinatorCmakeListsTemplate.ftl b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/coordinatorCmakeListsTemplate.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..b54f386045454c5fc142eaa774e7ae22fde76806
--- /dev/null
+++ b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/coordinatorCmakeListsTemplate.ftl
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.5)
+project (Coordinator_${compName} CXX)
+
+set (CMAKE_CXX_STANDARD 11)
+set (THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+
+add_executable(Coordinator_${compName} Coordinator_${compName}.cpp)
+set_target_properties(Coordinator_${compName} PROPERTIES LINKER_LANGUAGE CXX)
+target_link_libraries(Coordinator_${compName} ${targets} Threads::Threads)
+target_include_directories(Coordinator_${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+
+export(TARGETS Coordinator_${compName} FILE Coordinator_${compName}.cmake)
\ No newline at end of file
diff --git a/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/coordinatorTemplate.ftl b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/coordinatorTemplate.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..e76d9f9b4aafc21e58a339a088caae4b548464e3
--- /dev/null
+++ b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/coordinatorTemplate.ftl
@@ -0,0 +1,81 @@
+#include
+#include
+#include
+#include
+#include
+#include "IAdapter_${compName}.h"
+
+${includes}
+
+using namespace std;
+using namespace chrono;
+
+static int exeMs = 100;
+
+bool parseCommandLineParameters(int argc, char* argv[]){
+ if(argc == 1){
+ return true;
+ }
+ if(argc == 3 && string(argv[1]) == "-t"){
+ try{
+ int tmp = stoi(argv[2]);
+ if(tmp >= 0){
+ exeMs = tmp;
+ return true;
+ }
+ }catch(...){
+ //Ignore
+ }
+ }
+ cout << "Usage: " << argv[0] << " [-h | -t sleepTimeMs]\n";
+ return false;
+}
+
+void startMiddleware(IAdapter_${compName}& adapter,${compName}& comp,atomic& done){
+ adapter.init(&comp);
+ done = true;
+}
+
+int main(int argc, char* argv[])
+{
+ if(!parseCommandLineParameters(argc,argv)){
+ return 1;
+ }
+
+ atomic done(false);
+ ${compName} comp;
+ comp.init();
+
+ list adapters;
+ ${addAdapters}
+
+ list threads;
+ for(auto a : adapters){
+ threads.push_back(new thread(startMiddleware,ref(*a),ref(comp),ref(done)));
+ }
+
+ cout << "waiting for all middleware to start\n";
+ this_thread::sleep_for(seconds(3));
+ cout << "started! Executing every " << exeMs << "ms\n";
+
+ time_point start, end;
+ while(!done){
+ start = system_clock::now();
+
+ comp.execute();
+ for(auto a : adapters){
+ (*a).tick();
+ }
+
+ end = system_clock::now();
+ int elapsedMs = duration_cast(end-start).count();
+ int newSleep = exeMs - elapsedMs;
+ if(newSleep <= 0){
+ cout << "Cant keep up! "<< (-newSleep) <<"ms late!\n";
+ }else{
+ this_thread::sleep_for(milliseconds(newSleep));
+ }
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/struct_msgsCmakeTemplate.ftl b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/struct_msgsCmakeTemplate.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..ab0cc09a2674cac800331f5dc7d781c24134a4b5
--- /dev/null
+++ b/CNNModelTraining/src/main/resources/de/monticore/lang/monticar/generator/middleware/struct_msgsCmakeTemplate.ftl
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.5)
+project (struct_msgs)
+
+find_package(genmsg REQUIRED)
+
+FILE(GLOB MSG_FILES_RAW RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../*/roscpp/struct_msgs/*.msg)
+
+#generate struct_msgs iff .msg files where found
+if(MSG_FILES_RAW)
+#filter: add each struct msg only once (distinct by filename without path)
+foreach(CUR_MSG_FILE ${MSG_FILES_RAW})
+get_filename_component(TMP_MSG_NAME ${CUR_MSG_FILE} NAME)
+IF(NOT MSG_DEFINED_${TMP_MSG})
+LIST(APPEND MSG_FILES ${CUR_MSG_FILE})
+SET(MSG_DEFINED_${TMP_MSG} TRUE)
+ENDIF()
+endforeach(CUR_MSG_FILE)
+
+#generate messages
+add_message_files(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} FILES ${MSG_FILES})
+generate_messages()
+
+#export the include_dirs, so that other subprojects can use it
+set(struct_msgs_INCLUDE_DIRS ${struct_msgs_INCLUDE_DIRS} PARENT_SCOPE)
+endif()
diff --git a/TorcsEMAMGenerator/src/main/resources/de/monticore/lang/monticar/generator/middleware/dummyAdapterTemplate.ftl b/TorcsEMAMGenerator/src/main/resources/de/monticore/lang/monticar/generator/middleware/dummyAdapterTemplate.ftl
deleted file mode 100644
index 0c13f49b13632762bf82a9afcf0029850dd5f9b0..0000000000000000000000000000000000000000
--- a/TorcsEMAMGenerator/src/main/resources/de/monticore/lang/monticar/generator/middleware/dummyAdapterTemplate.ftl
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-#include "${compName}.h"
-#include
-#include
-#include "IAdapter_${compName}.h"
-
-class DummyAdapter_${compName}: public IAdapter_${compName}{
- ${compName}* component;
-
-public:
- DummyAdapter_${compName}(){
-
- }
-
- void tick(){
- cout << "Dummy publish data: component.out1 = "<< component->out1 << endl;
- }
-
- void init(${compName}* comp){
- this->component = comp;
- while(1){
- std::this_thread::sleep_for(std::chrono::seconds(1));
- component->in2 += 1000;
- }
- }
-
-
-};
diff --git a/TorcsEMAMGenerator/src/main/resources/de/monticore/lang/monticar/generator/middleware/dummyCmakeTemplate.ftl b/TorcsEMAMGenerator/src/main/resources/de/monticore/lang/monticar/generator/middleware/dummyCmakeTemplate.ftl
deleted file mode 100644
index 59e6bb0c0a8ca7c2f31c4e4ac2fe44dea74d0c1a..0000000000000000000000000000000000000000
--- a/TorcsEMAMGenerator/src/main/resources/de/monticore/lang/monticar/generator/middleware/dummyCmakeTemplate.ftl
+++ /dev/null
@@ -1,8 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-project (DummyAdapter_${compName})
-
-add_library(DummyAdapter_${compName} DummyAdapter_${compName}.h)
-set_target_properties(DummyAdapter_${compName} PROPERTIES LINKER_LANGUAGE CXX)
-target_link_libraries(DummyAdapter_${compName} ${compName})
-target_include_directories(DummyAdapter_${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-export(TARGETS DummyAdapter_${compName} FILE DummyAdapter_${compName}.cmake)