blob: b097fa5a13cd7851db928af5a0ed6ed2857cc921 [file] [log] [blame]
/**
* Copyright (c) 2020-2021 Robert Bosch GmbH.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
*/
package org.eclipse.app4mc.slg.ros2.generators;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.BooleanObject;
import org.eclipse.app4mc.amalthea.model.Channel;
import org.eclipse.app4mc.amalthea.model.ChannelSend;
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
import org.eclipse.app4mc.slg.commons.m2t.generators.RunnableTranslationUnit;
import org.eclipse.app4mc.slg.commons.m2t.generators.TranslationUnit;
import org.eclipse.app4mc.slg.commons.m2t.transformers.sw.ActivityGraphItemTransformer;
import org.eclipse.app4mc.slg.ros2.transformers.utils.Utils;
import org.eclipse.app4mc.transformation.util.OutputBuffer;
public class RosRunnableTranslationUnit extends RunnableTranslationUnit {
private String param;
private String nodeParam;
private boolean measurePerformance;
private List<String> publishers;
private List<String> client_declarations;
private List<String> client_inits;
public RosRunnableTranslationUnit(final OutputBuffer outputBuffer, final ActivityGraphItemTransformer transformer,
final org.eclipse.app4mc.amalthea.model.Runnable runnable) {
super(outputBuffer, transformer, runnable);
}
@Override
public String getCall() {
return "run_" + runnable.getName() + "(" + param + ")";
}
public String getNodeCall() {
return "run_" + runnable.getName() + "(" + nodeParam + ")";
}
public List<String> getPublishers() {
return this.publishers;
}
public List<String> getClientDeclarations() {
return this.client_declarations;
}
public List<String> getClientInits() {
return this.client_inits;
}
@Override
public void genFiles() {
param = "";
nodeParam = "";
publishers = new ArrayList<>();
client_declarations = new ArrayList<>();
client_inits = new ArrayList<>();
if (isSrcFileEmpty()) { // all stuff only required once regardless of runnable instance
srcAppend("#include \"" + this.getIncFile() + "\"\n");
}
final HashSet<String> includes = new LinkedHashSet<>();
final List<String> calls = new ArrayList<>();
measurePerformance = false;
if (runnable != null && runnable.getCustomProperties().get("measure_performance") instanceof BooleanObject) {
measurePerformance = ((BooleanObject) runnable.getCustomProperties().get("measure_performance")).isValue();
}
if (measurePerformance) {
includes.add("aml.h");
}
if (runnable != null && runnable.getActivityGraph() != null) {
for (ActivityGraphItem item : runnable.getActivityGraph().getItems()) {
final TranslationUnit tmp = callGraphItemTransformer.transform(item);
if (tmp.getIncFile() != null && !tmp.getIncFile().isEmpty() && !getIncFile().equals(tmp.getIncFile())) {
includes.add(tmp.getIncFile());
}
// check if item is publisher
if ((item instanceof ChannelSend)) {
ChannelSend cs = (ChannelSend) item;
Channel data = cs.getData();
publishers.add(data.getName() + "_publisher");
nodeParam = nodeParam + ((nodeParam.equals("")) ? "" : ";") + data.getName() + "_publisher";
param = ((param.equals("")) ? "" : ";") + "rclcpp::Publisher<std_msgs::msg::String>::SharedPtr& "
+ data.getName() + "_publisher";
}
if ((item instanceof InterProcessTrigger)) {
InterProcessTrigger trigger = (InterProcessTrigger) item;
InterProcessStimulus stimulus = trigger.getStimulus();
includes.add(stimulus.getName() + "_service/srv/" + stimulus.getName() + "_service" + ".hpp");
client_declarations.add(
"rclcpp::Client<" + stimulus.getName() + "_service::srv::"
+ Utils.toIdlCompliantName(stimulus.getName() + "_service")
+ ">::SharedPtr " + stimulus.getName() + "_client");
client_inits.add(
stimulus.getName() + "_client = this->create_client<" + stimulus.getName() + "_service::srv::"
+ Utils.toIdlCompliantName(stimulus.getName() + "_service") + ">"
+ "(\"" + stimulus.getName() + "_service\")");
nodeParam = nodeParam + (nodeParam.equals("") ? "" : ";") + stimulus.getName() + "_client";
param = (param.equals("") ? "" : ";") + "rclcpp::Client<"
+ stimulus.getName() + "_service::srv::" + Utils.toIdlCompliantName(stimulus.getName() + "_service")
+ ">::SharedPtr& " + stimulus.getName() + "_client";
}
final String call = tmp.getCall();
if (call != null && !call.isEmpty()) {
calls.add(call);
}
}
}
// write header
incAppend("\n//Runnable " + runnable.getName() + "----\n");
toH(includes);
// write body
srcAppend("\n//Runnable " + runnable.getName() + "----\n");
toCpp(includes, calls);
}
@Override
public void toH(final HashSet<String> includes) {
for (String include : includes) {
incAppend("#include \"" + include + "\"\n");
}
incAppend("void " + getCall() + ";\n");
}
@Override
public void toCpp(final HashSet<String> includes, final List<String> calls) {
this.srcAppend("void " + this.getCall() + "{\n");
if (measurePerformance) {
srcAppend(
"uint64_t event_list[] = {0x11, 0x13, 0x17}; //CPU CYCLES, MEM ACCESS, L2 Cache Refill\n"
+ "int total_events = sizeof(event_list)/sizeof(event_list[0]);\n"
+ "int fd = instrument_start(0,event_list, total_events);\n");
}
for (String call : calls) {
srcAppend("\t" + call + ";\n");
}
if (this.measurePerformance) {
this.srcAppend("instrument_stop(fd, \"" + runnable.getName() + ".log\");\n");
}
this.srcAppend("}\n\n");
}
}