| /** |
| * 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.math.BigInteger; |
| import java.util.ArrayList; |
| import java.util.LinkedHashSet; |
| import java.util.LinkedList; |
| import java.util.function.BiConsumer; |
| import java.util.function.Consumer; |
| |
| import org.eclipse.app4mc.amalthea.model.ActivityGraph; |
| import org.eclipse.app4mc.amalthea.model.ActivityGraphItem; |
| import org.eclipse.app4mc.amalthea.model.Component; |
| import org.eclipse.app4mc.amalthea.model.EventStimulus; |
| import org.eclipse.app4mc.amalthea.model.Group; |
| import org.eclipse.app4mc.amalthea.model.InterProcessStimulus; |
| import org.eclipse.app4mc.amalthea.model.PeriodicStimulus; |
| import org.eclipse.app4mc.amalthea.model.RunnableCall; |
| import org.eclipse.app4mc.amalthea.model.Stimulus; |
| import org.eclipse.app4mc.amalthea.model.Tag; |
| import org.eclipse.app4mc.amalthea.model.Task; |
| import org.eclipse.app4mc.amalthea.model.TimeUnit; |
| import org.eclipse.app4mc.slg.commons.m2t.generators.LabelTranslationUnit; |
| import org.eclipse.app4mc.slg.commons.m2t.generators.RunnableTranslationUnit; |
| import org.eclipse.app4mc.slg.commons.m2t.generators.TaskTranslationUnit; |
| import org.eclipse.app4mc.slg.ros2.transformers.RosInterProcessStimulusTransformer; |
| import org.eclipse.app4mc.slg.ros2.transformers.RosLabelTransformer; |
| import org.eclipse.app4mc.slg.ros2.transformers.RosRunnableTransformer; |
| import org.eclipse.app4mc.slg.ros2.transformers.utils.Utils; |
| import org.eclipse.app4mc.transformation.util.OutputBuffer; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.xtend2.lib.StringConcatenation; |
| import org.eclipse.xtext.xbase.lib.Functions.Function1; |
| import org.eclipse.xtext.xbase.lib.IterableExtensions; |
| |
| public class RosTaskTranslationUnit extends TaskTranslationUnit { |
| private RosInterProcessStimulusTransformer ipStimulusTransformer; |
| |
| private Task task; |
| |
| private final LinkedHashSet<String> includes = new LinkedHashSet<>(); |
| |
| private final LinkedList<String> initCalls = new LinkedList<>(); |
| |
| private final LinkedList<String> stepCalls = new LinkedList<>(); |
| |
| private final ArrayList<Stimulus> stimuli = new ArrayList<>(); |
| |
| private ArrayList<String> publishers = new ArrayList<>(); |
| |
| private ArrayList<String> clientDeclarations = new ArrayList<>(); |
| |
| private ArrayList<String> clientInits = new ArrayList<>(); |
| |
| public RosTaskTranslationUnit(final OutputBuffer outputBuffer, final RosRunnableTransformer transformerRunnable, final RosLabelTransformer transformerLabel, final RosInterProcessStimulusTransformer ipStimulusTransformer, final Task task, final Component c) { |
| super(outputBuffer, transformerRunnable, transformerLabel, task); |
| this.ipStimulusTransformer = ipStimulusTransformer; |
| this.task = task; |
| this.genFiles(); |
| } |
| |
| @Override |
| public String getBasePath() { |
| return ""; |
| } |
| |
| @Override |
| public String getModuleName() { |
| return this.task.getName(); |
| } |
| |
| @Override |
| public boolean genFiles() { |
| boolean _xblockexpression = false; |
| { |
| ActivityGraph _activityGraph = null; |
| if (this.task!=null) { |
| _activityGraph=this.task.getActivityGraph(); |
| } |
| EList<ActivityGraphItem> _items = null; |
| if (_activityGraph!=null) { |
| _items=_activityGraph.getItems(); |
| } |
| if (_items!=null) { |
| final Consumer<ActivityGraphItem> _function = (ActivityGraphItem item) -> { |
| if ((item instanceof RunnableCall)) { |
| final org.eclipse.app4mc.amalthea.model.Runnable runnable = ((RunnableCall) item).getRunnable(); |
| RunnableTranslationUnit _transform = this.runnableTransformer.transform(runnable); |
| final RosRunnableTranslationUnit tu = ((RosRunnableTranslationUnit) _transform); |
| this.includes.add(tu.getIncFile()); |
| final Function1<Tag, Boolean> _function_1 = (Tag tag) -> { |
| return Boolean.valueOf("initialize".equals(tag.getName())); |
| }; |
| boolean _isEmpty = IterableExtensions.isEmpty(IterableExtensions.<Tag>filter(((RunnableCall)item).getTags(), _function_1)); |
| boolean _not = (!_isEmpty); |
| if (_not) { |
| this.initCalls.add(tu.getNodeCall()); |
| } else { |
| this.stepCalls.add(tu.getNodeCall()); |
| } |
| this.publishers.addAll(tu.getPublishers()); |
| this.clientDeclarations.addAll(tu.getClientDeclarations()); |
| this.clientInits.addAll(tu.getClientInits()); |
| } else { |
| if ((item instanceof Group)) { |
| final Group group = ((Group) item); |
| final Consumer<ActivityGraphItem> _function_2 = (ActivityGraphItem groupitem) -> { |
| if ((groupitem instanceof RunnableCall)) { |
| final org.eclipse.app4mc.amalthea.model.Runnable runnable_1 = ((RunnableCall) groupitem).getRunnable(); |
| RunnableTranslationUnit _transform_1 = this.runnableTransformer.transform(((org.eclipse.app4mc.amalthea.model.Runnable) runnable_1)); |
| final RosRunnableTranslationUnit tu_1 = ((RosRunnableTranslationUnit) _transform_1); |
| this.includes.add(tu_1.getIncFile()); |
| final Function1<Tag, Boolean> _function_3 = (Tag tag) -> { |
| return Boolean.valueOf("initialize".equals(tag.getName())); |
| }; |
| boolean _isEmpty_1 = IterableExtensions.isEmpty(IterableExtensions.<Tag>filter(((RunnableCall)groupitem).getTags(), _function_3)); |
| boolean _not_1 = (!_isEmpty_1); |
| if (_not_1) { |
| this.initCalls.add(tu_1.getNodeCall()); |
| } else { |
| this.stepCalls.add(tu_1.getNodeCall()); |
| } |
| } |
| }; |
| group.getItems().forEach(_function_2); |
| } |
| } |
| }; |
| _items.forEach(_function); |
| } |
| final BiConsumer<ArrayList<?>, LabelTranslationUnit> _function_1 = (ArrayList<?> label, LabelTranslationUnit tu) -> { |
| this.includes.add(tu.getIncFile()); |
| this.initCalls.add(tu.getInitCall()); |
| }; |
| this.labelTransformer.getCache().forEach(_function_1); |
| final Function1<Stimulus, Boolean> _function_2 = (Stimulus stimulus) -> { |
| return Boolean.valueOf((stimulus instanceof InterProcessStimulus)); |
| }; |
| final Consumer<Stimulus> _function_3 = (Stimulus stimulus) -> { |
| StringConcatenation _builder = new StringConcatenation(); |
| String _name = stimulus.getName(); |
| _builder.append(_name); |
| _builder.append("_service/srv/"); |
| String _name_1 = stimulus.getName(); |
| _builder.append(_name_1); |
| _builder.append("_service.hpp"); |
| this.includes.add(_builder.toString()); |
| this.ipStimulusTransformer.transform(((InterProcessStimulus) stimulus)); |
| }; |
| IterableExtensions.<Stimulus>filter(IterableExtensions.<Stimulus>toList(this.task.getStimuli()), _function_2).forEach(_function_3); |
| _xblockexpression = this.stimuli.addAll(IterableExtensions.<Stimulus>toList(this.task.getStimuli())); |
| } |
| return _xblockexpression; |
| } |
| |
| public CharSequence getDeclaration() { |
| StringConcatenation _builder = new StringConcatenation(); |
| { |
| for(final Stimulus stimulus : this.stimuli) { |
| { |
| if ((stimulus instanceof PeriodicStimulus)) { |
| _builder.append("rclcpp::TimerBase::SharedPtr "); |
| String _name = ((PeriodicStimulus) stimulus).getName(); |
| _builder.append(_name); |
| _builder.append("_timer_;"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| { |
| if ((stimulus instanceof EventStimulus)) { |
| _builder.append("rclcpp::Subscription<std_msgs::msg::String>::SharedPtr "); |
| String _name_1 = ((EventStimulus) stimulus).getName(); |
| _builder.append(_name_1); |
| _builder.append("_subscription_;"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| { |
| if ((stimulus instanceof InterProcessStimulus)) { |
| _builder.append("rclcpp::Service<"); |
| String _name_2 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_2); |
| _builder.append("_service::srv::"); |
| String _name_3 = ((InterProcessStimulus) stimulus).getName(); |
| String _plus = (_name_3 + "_service"); |
| String _idlCompliantName = Utils.toIdlCompliantName(_plus); |
| _builder.append(_idlCompliantName); |
| _builder.append(">::SharedPtr "); |
| String _name_4 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_4); |
| _builder.append("_service;"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| } |
| } |
| { |
| for(final String publisher : this.publishers) { |
| _builder.append("rclcpp::Publisher<std_msgs::msg::String>::SharedPtr "); |
| _builder.append(publisher); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| { |
| for(final String decl : this.clientDeclarations) { |
| _builder.append(decl); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| return _builder; |
| } |
| |
| public CharSequence getInitialisation(final String nodeName) { |
| StringConcatenation _builder = new StringConcatenation(); |
| { |
| for(final Stimulus stimulus : this.stimuli) { |
| { |
| if ((stimulus instanceof PeriodicStimulus)) { |
| String _name = ((PeriodicStimulus) stimulus).getName(); |
| _builder.append(_name); |
| _builder.append("_timer_ = this->create_wall_timer("); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t\t"); |
| BigInteger _value = ((PeriodicStimulus) stimulus).getRecurrence().getValue(); |
| _builder.append(_value, "\t\t"); |
| TimeUnit _unit = ((PeriodicStimulus) stimulus).getRecurrence().getUnit(); |
| _builder.append(_unit, "\t\t"); |
| _builder.append(", std::bind(&"); |
| _builder.append(nodeName, "\t\t"); |
| _builder.append("::"); |
| String _name_1 = ((PeriodicStimulus) stimulus).getName(); |
| _builder.append(_name_1, "\t\t"); |
| _builder.append("_timer_callback, this));"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| { |
| if ((stimulus instanceof EventStimulus)) { |
| String _name_2 = ((EventStimulus) stimulus).getName(); |
| _builder.append(_name_2); |
| _builder.append("_subscription_ = this->create_subscription<std_msgs::msg::String>("); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t"); |
| _builder.append("\""); |
| String _name_3 = ((EventStimulus) stimulus).getName(); |
| _builder.append(_name_3, "\t"); |
| _builder.append("\", 10, std::bind(&"); |
| _builder.append(nodeName, "\t"); |
| _builder.append("::"); |
| String _name_4 = ((EventStimulus) stimulus).getName(); |
| _builder.append(_name_4, "\t"); |
| _builder.append("_subscription_callback, this, _1));"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| { |
| if ((stimulus instanceof InterProcessStimulus)) { |
| String _name_5 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_5); |
| _builder.append("_service = this->create_service<"); |
| String _name_6 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_6); |
| _builder.append("_service::srv::"); |
| String _name_7 = ((InterProcessStimulus) stimulus).getName(); |
| String _plus = (_name_7 + "_service"); |
| String _idlCompliantName = Utils.toIdlCompliantName(_plus); |
| _builder.append(_idlCompliantName); |
| _builder.append(">(\""); |
| String _name_8 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_8); |
| _builder.append("_service\", &"); |
| String _name_9 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_9); |
| _builder.append("_service_callback);"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| } |
| } |
| { |
| for(final String publisher : this.publishers) { |
| _builder.append(publisher); |
| _builder.append(" = this->create_publisher<std_msgs::msg::String>(\""); |
| String _replace = publisher.replace("_publisher", ""); |
| _builder.append(_replace); |
| _builder.append("\", 10);"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| { |
| for(final String init : this.clientInits) { |
| _builder.append(init); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| return _builder; |
| } |
| |
| public CharSequence getServiceCallback() { |
| StringConcatenation _builder = new StringConcatenation(); |
| { |
| for(final Stimulus stimulus : this.stimuli) { |
| { |
| if ((stimulus instanceof InterProcessStimulus)) { |
| _builder.append("void "); |
| String _name = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name); |
| _builder.append("_service_callback(const std::shared_ptr<"); |
| String _name_1 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_1); |
| _builder.append("_service::srv::"); |
| String _name_2 = ((InterProcessStimulus) stimulus).getName(); |
| String _plus = (_name_2 + "_service"); |
| String _idlCompliantName = Utils.toIdlCompliantName(_plus); |
| _builder.append(_idlCompliantName); |
| _builder.append("::Request> request,"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t"); |
| _builder.append("std::shared_ptr<"); |
| String _name_3 = ((InterProcessStimulus) stimulus).getName(); |
| _builder.append(_name_3, "\t"); |
| _builder.append("_service::srv::"); |
| String _name_4 = ((InterProcessStimulus) stimulus).getName(); |
| String _plus_1 = (_name_4 + "_service"); |
| String _idlCompliantName_1 = Utils.toIdlCompliantName(_plus_1); |
| _builder.append(_idlCompliantName_1, "\t"); |
| _builder.append("::Response> response) {"); |
| _builder.newLineIfNotEmpty(); |
| { |
| for(final String call : this.stepCalls) { |
| _builder.append("\t\t"); |
| _builder.append(call); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| } |
| } |
| _builder.newLine(); |
| _builder.newLine(); |
| } |
| } |
| return _builder; |
| } |
| |
| public CharSequence getCallback() { |
| StringConcatenation _builder = new StringConcatenation(); |
| { |
| for(final Stimulus stimulus : this.stimuli) { |
| { |
| if ((stimulus instanceof PeriodicStimulus)) { |
| _builder.append("void "); |
| String _name = ((PeriodicStimulus) stimulus).getName(); |
| _builder.append(_name); |
| _builder.append("_timer_callback() {"); |
| _builder.newLineIfNotEmpty(); |
| { |
| for(final String call : this.stepCalls) { |
| _builder.append("\t"); |
| _builder.append(call); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.append("}"); |
| _builder.newLine(); |
| } |
| } |
| { |
| if ((stimulus instanceof EventStimulus)) { |
| _builder.append("void "); |
| String _name_1 = ((EventStimulus) stimulus).getName(); |
| _builder.append(_name_1); |
| _builder.append("_subscription_callback(const std_msgs::msg::String::SharedPtr msg) {"); |
| _builder.newLineIfNotEmpty(); |
| { |
| for(final String call_1 : this.stepCalls) { |
| _builder.append("\t"); |
| _builder.append(call_1); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| _builder.append("}"); |
| _builder.newLine(); |
| } |
| } |
| } |
| } |
| return _builder; |
| } |
| |
| public CharSequence getHeaders() { |
| StringConcatenation _builder = new StringConcatenation(); |
| { |
| for(final String include : this.includes) { |
| _builder.append("#include \""); |
| _builder.append(include); |
| _builder.append("\""); |
| _builder.newLineIfNotEmpty(); |
| } |
| } |
| return _builder; |
| } |
| } |