Aufgrund einer Störung des s3 Storage, könnten in nächster Zeit folgende GitLab Funktionen nicht zur Verfügung stehen: LFS, Container Registry, Job Artifacs, Uploads (Wiki, Bilder, Projekt-Exporte). Wir bitten um Verständnis. Es wird mit Hochdruck an der Behebung des Problems gearbeitet. Weitere Informationen zur Störung des Object Storage finden Sie hier: https://maintenance.itc.rwth-aachen.de/ticket/status/messages/59-object-storage-pilot

Commit 2c24c072 authored by Georg Vinogradov's avatar Georg Vinogradov
Browse files

Add static adapter generation

parent 8de94e49
Pipeline #158244 passed with stages
in 1 minute and 3 seconds
......@@ -18,6 +18,8 @@ public class GeneratorMqtt
List<File> generateMqttAdapter(EMAComponentInstanceSymbol component)
{
List<File> files = new ArrayList<>();
List<String> contents = new ArrayList<String>();
List<FileWriter> frs = new ArrayList<FileWriter>();
// Get info about the ports from the component
Collection<EMAPortInstanceSymbol> ports = component.getPortInstanceList();
......@@ -28,46 +30,50 @@ public class GeneratorMqtt
model.addPorts(ports);
//Generate files and write to project
String content = MqttTemplates.generateMqttAdapter(model);
contents.add(MqttTemplates.generateMqttAdapterH(model));
files.add(new File("./target/generated-sources/MqttAdapter_"+model.getEscapedCompName()+".h"));
contents.add(MqttTemplates.generateMqttAdapterCPP(model));
files.add(new File("./target/generated-sources/MqttAdapter_"+model.getEscapedCompName()+".cpp"));
contents.add(MqttTemplates.generateMqttCallbackH(model));
files.add(new File("./target/generated-sources/Callback.hpp"));
contents.add(MqttTemplates.generateMqttCallbackCPP(model));
files.add(new File("./target/generated-sources/Callback.cpp"));
File file = new File("./target/generated-sources/ports.txt");
files.add(file);
FileWriter fr = null;
try {
fr = new FileWriter(file);
fr.write(content);
int counter = 0;
for (File file : files)
{
frs.add(new FileWriter(file));
frs.get(counter).write(contents.get(counter));
counter++;
}
} catch (IOException e) {
e.printStackTrace();
}finally{
//Close resources
try {
fr.close();
for (FileWriter fr : frs)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
files.add(generateCMake(component));
return files;
}
List<File> generatePrettyPrint(EMAComponentInstanceSymbol component)
{
List<File> files = new ArrayList<>();
// Get info about the ports from the component
Collection<EMAPortInstanceSymbol> ports = component.getPortInstanceList();
File generateCMake(EMAComponentInstanceSymbol component)
{
// Create and fill model
MqttAdapterModel model = new MqttAdapterModel(component.getFullName());
model.addPorts(ports);
//Generate files and write to project
String content = MqttTemplates.generateMqttAdapter(model);
String content = MqttTemplates.generateMqttCMakeLists(model);
File file = new File("./target/generated-sources/ports.txt");
files.add(file);
File file = new File("./target/generated-sources/CMakeLists.txt");
FileWriter fr = null;
try {
......@@ -84,20 +90,26 @@ public class GeneratorMqtt
}
}
return files;
}
return file;
}
File generateCMake(EMAComponentInstanceSymbol component)
{
List<File> generatePrettyPrint(EMAComponentInstanceSymbol component)
{
List<File> files = new ArrayList<>();
// Get info about the ports from the component
Collection<EMAPortInstanceSymbol> ports = component.getPortInstanceList();
// Create and fill model
MqttAdapterModel model = new MqttAdapterModel(component.getFullName());
model.addPorts(ports);
//Generate files and write to project
String content = MqttTemplates.generateMqttCMakeLists(model);
String content = MqttTemplates.generatePrettyPrint(model);
File file = new File("./target/generated-sources/CMakeLists.txt");
File file = new File("./target/generated-sources/ports.txt");
files.add(file);
FileWriter fr = null;
try {
......@@ -114,7 +126,8 @@ public class GeneratorMqtt
}
}
return file;
}
return files;
}
}
......@@ -16,6 +16,10 @@ public class MqttTemplates {
private static final Template PrettyPrint;
private static final Template MQTT_CMAKELISTS;
private static final Template MQTT_ADAPTER_H;
private static final Template MQTT_ADAPTER_CPP;
private static final Template MQTT_CALLBACK_H;
private static final Template MQTT_CALLBACK_CPP;
// Loading .ftl files
static {
......@@ -27,6 +31,10 @@ public class MqttTemplates {
try {
PrettyPrint = conf.getTemplate("PrettyPrint.ftl");
MQTT_CMAKELISTS = conf.getTemplate("CMakeLists.ftl");
MQTT_ADAPTER_H = conf.getTemplate("Adapter.h.ftl");
MQTT_ADAPTER_CPP = conf.getTemplate("Adapter.cpp.ftl");
MQTT_CALLBACK_H = conf.getTemplate("Callback.hpp.ftl");
MQTT_CALLBACK_CPP = conf.getTemplate("Callback.cpp.ftl");
} catch (IOException e) {
String msg = "could not load template";
Log.error(msg, e);
......@@ -34,17 +42,41 @@ public class MqttTemplates {
}
}
public static String generateMqttAdapter(MqttAdapterModel model) {
public static String generateMqttAdapterH(MqttAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(PrettyPrint, data);
return generate(MQTT_ADAPTER_H, data);
}
public static String generateMqttCMakeLists(MqttAdapterModel model) {
public static String generateMqttAdapterCPP(MqttAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(MQTT_ADAPTER_CPP, data);
}
public static String generateMqttCallbackH(MqttAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(MQTT_CALLBACK_H, data);
}
public static String generateMqttCallbackCPP(MqttAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(MQTT_CALLBACK_CPP, data);
}
public static String generateMqttCMakeLists(MqttAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(MQTT_CMAKELISTS, data);
}
public static String generatePrettyPrint(MqttAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(PrettyPrint, data);
}
@SuppressWarnings("rawtypes")
private static String generate(Template template, Map dataForTemplate) {
......
#include "<@m.mwIdent/>Adapter_${model.getEscapedCompName()}.h"
<#import "MqttMacros.ftl" as m>
using namespace std;
#include "<@m.mwIdent/>Adapter_${model.getEscapedCompName()}.h"
<@m.mwIdent/>Adapter_${model.getEscapedCompName()}::<@m.mwIdent/>Adapter_${model.getEscapedCompName()}()
{
......@@ -13,14 +13,14 @@ void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::init(${model.getEscaped
this->component = comp;
// Initialize connect options
<@m.smallIdent/>::connect_options connOpts;
connect_options connOpts;
connOpts.set_keep_alive_interval(20);
connOpts.set_clean_session(true);
// Intitialize callback, subscriber and publisher
_clockSubscriber = new mqtt::client(SERVER_ADDRESS, SUB_ID);
_clockSubscriber = new client(SERVER_ADDRESS, SUB_ID);
_callback = new Callback(*_clockSubscriber, comp);
_echoPublisher = new mqtt::client(SERVER_ADDRESS, PUB_ID);
_echoPublisher = new client(SERVER_ADDRESS, PUB_ID);
// Connect subscriber, publisher and subscribe to the topic
try {
......@@ -35,21 +35,21 @@ void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::init(${model.getEscaped
}
void MqttAdapter_tests_a_compA::publish_echoPublisher()
void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::publish_echoPublisher()
{
string value = to_string(component->rosOut);
auto pubmsg = mqtt::make_message(TOPIC, value);
auto pubmsg = make_message(TOPIC, value);
try {
_echoPublisher->publish(pubmsg);
} catch (const mqtt::exception& exc) {
} catch (const exception& exc) {
cerr << exc.to_string() << endl;
}
}
void MqttAdapter_tests_a_compA::tick()
void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::tick()
{
publish_echoPublisher();
}
<#import "MqttMacros.ftl" as m>
#pragma once
#include "${model.getEscapedCompName()}.h"
<@m.mwDefaultIncludes/>
<#list model.getIncludes() as incl>
<@m.mwMsgInclude incl=incl/>
</#list>
using namespace std;
using namespace <@m.smallIdent/>;
class <@m.mwIdent/>Adapter_${model.getEscapedCompName()} {
......@@ -21,13 +21,15 @@ public:
void tick();
private:
const string SERVER_ADDRESS = "${model.getServerAddress()}";
const string SERVER_ADDRESS = "tcp://localhost:1883";
const string PUB_ID = "publisher_cpp";
const string SUB_ID = "subscriber_cpp";
const string TOPIC = "/clock";
${model.getEscapedCompName()}* component = nullptr;
// Callbacks, Subscribers/Publishers
Callback* _callback = nullptr;
<@m.fieldSubscriber name="${model.getSubscriberName()}"/> = nullptr;
<@m.fieldSubscriber name="${model.getPublisherName()}"/> = nullptr;
client* _clockSubscriber = nullptr;
client* _echoPublisher = nullptr;
};
<#import "MqttMacros.ftl" as m>
#include "Callback.hpp"
Callback::Callback(client& cli, ${model.getEscapedCompName()}* comp) : callback(), cli_(cli)
{
comp_ = comp;
}
// Callback for when connected to broker
void Callback::connected(const string& cause)
{
cout << "Connected" <<endl;
}
// Callback for when the connection is lost.
void Callback::connection_lost(const string& cause)
{
cout << "\nConnection lost";
if (!cause.empty())
cout << ": " << cause << endl;
}
// Callback for when message is received
void Callback::message_arrived(const_message_ptr msg)
{
cout << "Message received "<< msg->get_topic() << ": " << msg->get_payload_str() << endl;
string::size_type sz;
double value = std::stod (msg->get_payload_str(),&sz);
comp_->rosIn = value;
}
<#import "MqttMacros.ftl" as m>
#ifndef Callback_hpp
#define Callback_hpp
#include "${model.getEscapedCompName()}"
<@m.mwDefaultInclude/>
using namespace std;
using namespace <@m.smallIdent/>;
class Callback : public virtual callback
{
client& cli_;
public:
Callback(client& cli, ${model.getEscapedCompName()}* comp);
void connected(const string& cause);
void connection_lost(const string& cause);
void message_arrived(const_message_ptr msg);
private:
${model.getEscapedCompName()}* comp_;
};
#endif /* Callback_hpp */
\ No newline at end of file
......@@ -2,63 +2,11 @@
<#macro smallIdent>mqtt</#macro>
<#macro mwDefaultIncludes>
<#macro mwDefaultInclude>
#include "mqtt/client.h"
</#macro>
<#macro mwMsgInclude incl>
#include <${incl}>
</#macro>
<#macro fieldSubscriber name>
mqtt::client* ${name};
</#macro>
<#macro fieldPublisher name>
mqtt::client* ${name};
</#macro>
<#macro mwinit compname>
char* tmp = strdup("");
int i = 0;
ros::init(i, &tmp, "RosAdapter_${compname}_node");
ros::NodeHandle node_handle = ros::NodeHandle();
</#macro>
<#macro mwstart>
ros::spin();
</#macro>
<#macro initSubscriber sub compName>
${sub.getNameInTargetLanguage()} = node_handle.subscribe("${sub.getTopicName()}", 5, &RosAdapter_${compName}::${sub.getMethodName()}, this, ros::TransportHints().tcpNoDelay());
</#macro>
<#macro initPublisher pub>
${pub.getNameInTargetLanguage()} = node_handle.advertise<${pub.getTypeNameInTargetLanguage()}>("${pub.getTopicName()}",5);
</#macro>
<#macro callback sub>
void ${sub.getMethodName()}(const ${sub.getTypeNameInTargetLanguage()}::ConstPtr& msg){
<#if !sub.isStructInterface() && sub.getRosConnectionSymbol().getMsgField().isPresent()>
component->${sub.getPortNameInTargetLanguage()} = msg->${sub.getRosConnectionSymbol().getMsgField().get()};
<#else>
${sub.getRosSetStructInstruction()}
</#if>
}
</#macro>
<#macro publish pub>
void publish${pub.getNameInTargetLanguage()}(){
${pub.getTypeNameInTargetLanguage()} tmpMsg;
<#if !pub.isStructInterface() && pub.getRosConnectionSymbol().getMsgField().isPresent()>
tmpMsg.${pub.getRosConnectionSymbol().getMsgField().get()} = component->${pub.getPortNameInTargetLanguage()};
<#else>
${pub.getRosSetStructInstruction()}
</#if>
${pub.getNameInTargetLanguage()}.publish(tmpMsg);
}
<#macro mwDefaultIncludes>
#include "mqtt/client.h"
#include "Callback.hpp"
</#macro>
......@@ -4,7 +4,6 @@ import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
......@@ -33,5 +32,9 @@ public class AdapterGenerationTest extends AbstractSymtabTest {
// Connect component's ports to topics
componentInstanceSymbol.getPortInstance("portA").orElse(null).setMiddlewareSymbol(new MqttConnectionSymbol("/clock"));
List<File> files = generatorMqtt.generateMqttAdapter(componentInstanceSymbol);
testFilesAreEqual(files, "echoAdapter/");
}
}
# Setting cmake version
cmake_minimum_required(VERSION 3.1...3.14)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
# Using C++ version 11 with threads for compiling
set (CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
# Setting project name and description
project(tests.a.compA)
set(SEARCH_MQTT FALSE)
# Check is environment variable was set
IF(DEFINED ENV{MQTT_INCLUDE_DIR} AND DEFINED ENV{MQTT_LIBS})
message("...MQTT environment variables are set" )
ELSE()
message("MQTT environment variables are not defined.")
# Find mqtt packages using modules
find_package(MQTT REQUIRED)
SET(SEARCH_MQTT TRUE)
ENDIF()
# Adding library as a target
add_library(MqttAdapter_tests_a_compA
Callback.cpp
MqttAdapter_tests_a_compA.cpp
tests_a_compA.cpp
Callback.hpp
MqttAdapter_tests_a_compA.h
tests_a_compA.h
)
# Checking if everything was found
if(SEARCH_MQTT)
if (NOT MQTT_C_LIB OR NOT MQTT_A_LIB OR NOT MQTT_PP_LIB)
message(FATAL_ERROR "MQTT libraries not found!")
elseif (NOT MQTT_INCLUDE_DIR)
message(FATAL_ERROR "MQTT includes not found!")
else()
message("MQTT includes found in " ${MQTT_INCLUDE_DIR})
message("MQTT libraries found in " ${MQTT_LIBS})
endif()
endif()
# Adding include directory to a target
target_include_directories(MqttAdapter_tests_a_compA PUBLIC ${MQTT_INCLUDE_DIR})
# Linking libraries to target
target_link_libraries(MqttAdapter_tests_a_compA PUBLIC ${MQTT_LIBS})
# Export target to a cmake module file for outside usage
export(TARGETS MqttAdapter_tests_a_compA FILE MQTTAdapter_tests_a_compA.cmake)
#include "Callback.hpp"
Callback::Callback(client& cli, tests_a_compA* comp) : callback(), cli_(cli)
{
comp_ = comp;
}
// Callback for when connected to broker
void Callback::connected(const string& cause)
{
cout << "Connected" <<endl;
}
// Callback for when the connection is lost.
void Callback::connection_lost(const string& cause)
{
cout << "\nConnection lost";
if (!cause.empty())
cout << ": " << cause << endl;
}
// Callback for when message is received
void Callback::message_arrived(const_message_ptr msg)
{
cout << "Message received "<< msg->get_topic() << ": " << msg->get_payload_str() << endl;
string::size_type sz;
double value = std::stod (msg->get_payload_str(),&sz);
comp_->rosIn = value;
}
#ifndef Callback_hpp
#define Callback_hpp
#include "tests_a_compA"
#include "mqtt/client.h"
using namespace std;
using namespace mqtt;
class Callback : public virtual callback
{
client& cli_;
public:
Callback(client& cli, tests_a_compA* comp);
void connected(const string& cause);
void connection_lost(const string& cause);
void message_arrived(const_message_ptr msg);
private:
tests_a_compA* comp_;
};
#endif /* Callback_hpp */
\ No newline at end of file
#include "MqttAdapter_tests_a_compA.h"
MqttAdapter_tests_a_compA::MqttAdapter_tests_a_compA()
{
}
void MqttAdapter_tests_a_compA::init(tests_a_compA *comp)
{
// Initialize component
this->component = comp;
// Initialize connect options
connect_options connOpts;
connOpts.set_keep_alive_interval(20);
connOpts.set_clean_session(true);
// Intitialize callback, subscriber and publisher
_clockSubscriber = new client(SERVER_ADDRESS, SUB_ID);
_callback = new Callback(*_clockSubscriber, comp);
_echoPublisher = new client(SERVER_ADDRESS, PUB_ID);
// Connect subscriber, publisher and subscribe to the topic
try {
_clockSubscriber->set_callback(*_callback);
_clockSubscriber->connect(connOpts);
_echoPublisher->connect(connOpts);
_clockSubscriber->subscribe(TOPIC, 1);
} catch (const mqtt::exception& exc) {
cerr << exc.what() << endl;
}