| /** |
| * 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"); |
| } |
| |
| } |