| /** |
| * 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.HashSet; |
| import java.util.LinkedList; |
| import java.util.function.Consumer; |
| |
| import org.eclipse.app4mc.amalthea.model.Amalthea; |
| import org.eclipse.app4mc.amalthea.model.SWModel; |
| import org.eclipse.app4mc.amalthea.model.StringObject; |
| import org.eclipse.app4mc.amalthea.model.Tag; |
| import org.eclipse.app4mc.amalthea.model.Task; |
| import org.eclipse.app4mc.amalthea.model.Value; |
| import org.eclipse.app4mc.slg.commons.m2t.generators.TaskTranslationUnit; |
| import org.eclipse.app4mc.slg.commons.m2t.generators.TranslationUnit; |
| import org.eclipse.app4mc.slg.ros2.transformers.RosTaskTransformer; |
| import org.eclipse.app4mc.transformation.util.OutputBuffer; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.xtend2.lib.StringConcatenation; |
| |
| public class RosTagTranslationUnit extends TranslationUnit { |
| private RosTaskTransformer rosTransformerTask; |
| |
| private Tag tag; |
| |
| private Amalthea model; |
| |
| private HashSet<String> header = new HashSet<>(); |
| |
| private LinkedList<String> declaration = new LinkedList<>(); |
| |
| private LinkedList<String> initialization = new LinkedList<>(); |
| |
| private LinkedList<String> calls = new LinkedList<>(); |
| |
| private LinkedList<String> serviceCallbacks = new LinkedList<>(); |
| |
| private OutputBuffer outputBuffer; |
| |
| public RosTagTranslationUnit(final OutputBuffer outputBuffer, final RosTaskTransformer rosTransformerTask, |
| final Tag tag, final Amalthea model) { |
| super(); |
| this.tag = tag; |
| this.model = model; |
| this.rosTransformerTask = rosTransformerTask; |
| this.outputBuffer = outputBuffer; |
| this.genFiles(); |
| } |
| |
| public boolean genFiles() { |
| boolean _xblockexpression = false; |
| { |
| SWModel _swModel = null; |
| if (this.model != null) { |
| _swModel = this.model.getSwModel(); |
| } |
| EList<Task> _tasks = null; |
| if (_swModel != null) { |
| _tasks = _swModel.getTasks(); |
| } |
| final Consumer<Task> _function = (Task task) -> { |
| boolean _contains = task.getTags().contains(this.tag); |
| if (_contains) { |
| TaskTranslationUnit _transform = this.rosTransformerTask.transform(task, null); |
| final RosTaskTranslationUnit tu = ((RosTaskTranslationUnit) _transform); |
| this.header.add(tu.getHeaders().toString()); |
| this.declaration.add(tu.getDeclaration().toString()); |
| this.initialization.add(tu.getInitialisation(this.getModuleName()).toString()); |
| this.calls.add(tu.getCallback().toString()); |
| this.serviceCallbacks.add(tu.getServiceCallback().toString()); |
| } |
| }; |
| _tasks.forEach(_function); |
| _xblockexpression = this.srcAppend( |
| this.toCpp(this.header, this.declaration, this.initialization, this.calls, this.serviceCallbacks)); |
| } |
| return _xblockexpression; |
| } |
| |
| public String getBasePath() { |
| return ""; |
| } |
| |
| public String getModuleName() { |
| return this.tag.getName(); |
| } |
| |
| private String toCpp(final HashSet<String> headers, final LinkedList<String> declarations, |
| final LinkedList<String> inits, final LinkedList<String> calls, final LinkedList<String> serviceCallbacks) { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("#include <chrono>"); |
| _builder.newLine(); |
| _builder.append("#include <memory>"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _builder.append("#include \"rclcpp/rclcpp.hpp\""); |
| _builder.newLine(); |
| _builder.append("#include \"std_msgs/msg/string.hpp\""); |
| _builder.newLine(); |
| _builder.append("\t\t\t\t\t\t\t "); |
| _builder.newLine(); |
| { |
| for (final String header : headers) { |
| _builder.append(header); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.newLine(); |
| _builder.append("using namespace std::chrono_literals;"); |
| _builder.newLine(); |
| _builder.append("using std::placeholders::_1;"); |
| _builder.newLine(); |
| _builder.newLine(); |
| { |
| for (final String serviceCallback : serviceCallbacks) { |
| _builder.append(serviceCallback); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.newLine(); |
| _builder.append("class "); |
| String _moduleName = this.getModuleName(); |
| _builder.append(_moduleName); |
| _builder.append(" : public rclcpp::Node"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("{"); |
| _builder.newLine(); |
| _builder.append("private:"); |
| _builder.newLine(); |
| { |
| for (final String declaration : declarations) { |
| _builder.append(" "); |
| _builder.append(declaration, " "); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("public:"); |
| _builder.newLine(); |
| _builder.append("\t "); |
| String _moduleName_1 = this.getModuleName(); |
| _builder.append(_moduleName_1, "\t "); |
| _builder.append("()"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t "); |
| _builder.append(": Node(\""); |
| String _lowerCase = this.getModuleName().toLowerCase(); |
| _builder.append(_lowerCase, "\t "); |
| _builder.append("\")"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t "); |
| _builder.append("{"); |
| _builder.newLine(); |
| { |
| for (final String init : inits) { |
| _builder.append("\t \t"); |
| _builder.append(init, "\t \t"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.append("\t \t"); |
| _builder.newLine(); |
| _builder.append("\t \t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| { |
| for (final String call : calls) { |
| _builder.append("\t \t"); |
| _builder.append(call, "\t \t"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.append("\t \t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("};"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("int main(int argc, char * argv[])"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("{\t\t "); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("setvbuf(stdout, NULL, _IONBF, BUFSIZ);"); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("rclcpp::init(argc, argv);"); |
| _builder.newLine(); |
| { |
| Value _get = this.tag.getCustomProperties().get("executor_type"); |
| boolean _tripleNotEquals = (_get != null); |
| if (_tripleNotEquals) { |
| { |
| Value _get_1 = this.tag.getCustomProperties().get("executor_type"); |
| boolean _equals = ((StringObject) _get_1).getValue().equals("single_thread"); |
| if (_equals) { |
| _builder.append("\t\t "); |
| _builder.append("rclcpp::executors::SingleThreadedExecutor executor;"); |
| _builder.newLine(); |
| } else { |
| _builder.append("\t\t "); |
| _builder.append("rclcpp::executors::MultiThreadedExecutor executor;"); |
| _builder.newLine(); |
| } |
| } |
| } else { |
| _builder.append("\t\t "); |
| _builder.append("rclcpp::executors::MultiThreadedExecutor executor;"); |
| _builder.newLine(); |
| } |
| } |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("auto node = std::make_shared<"); |
| String _moduleName_2 = this.getModuleName(); |
| _builder.append(_moduleName_2, "\t\t "); |
| _builder.append(">();"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("executor.add_node(node);"); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("executor.spin();"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("rclcpp::shutdown();"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.newLine(); |
| _builder.append("\t\t "); |
| _builder.append("return 0;"); |
| _builder.newLine(); |
| _builder.append("\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| return _builder.toString(); |
| } |
| |
| public String getModulePath() { |
| return getBasePath() + "/" + getModuleName(); |
| } |
| |
| @Override |
| public String getIncFile() { |
| return getModuleName() + ".hpp"; |
| } |
| |
| @Override |
| public String getSrcFile() { |
| return getModuleName() + ".cpp"; |
| } |
| |
| public String getIncPath() { |
| return getModulePath() + "/_inc/" + getIncFile(); |
| } |
| |
| public String getSrcPath() { |
| return getModulePath() + "/_src/" + getSrcFile(); |
| } |
| |
| public boolean isIncFileEmpty() { |
| return !outputBuffer.bufferExists("H", getModulePath() + "/_inc/" + getModuleName()); |
| } |
| |
| public boolean isSrcFileEmpty() { |
| return !outputBuffer.bufferExists("C", getModulePath() + "/_src/" + getModuleName()); |
| } |
| |
| public boolean incAppend(final String str) { |
| return outputBuffer.appendTo("H", getModulePath() + "/_inc/" + getModuleName(), str); |
| } |
| |
| public boolean srcAppend(final String str) { |
| return outputBuffer.appendTo("C", getModulePath() + "/_src/" + getModuleName(), str); |
| } |
| |
| } |