Skip to content

Commit

Permalink
ros2: add causal message links analysis
Browse files Browse the repository at this point in the history
This collects user-level annotation data for causal links between
publishers and subscriptions. This can then later be used by other
analyses to find causal links between specific messages.

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Change-Id: I8e91bf7640b5e59e99b94448fe2b8c5d6debc446
Reviewed-on: https://git.eclipse.org/r/c/tracecompass.incubator/org.eclipse.tracecompass.incubator/+/192550
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
  • Loading branch information
christophebedard committed May 25, 2023
1 parent a57a4aa commit 5745f16
Show file tree
Hide file tree
Showing 10 changed files with 443 additions and 1 deletion.
Expand Up @@ -26,6 +26,7 @@ Export-Package: org.eclipse.tracecompass.incubator.internal.ros2.core;x-friends:
org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.objects,
org.eclipse.tracecompass.incubator.internal.ros2.core.model,
org.eclipse.tracecompass.incubator.internal.ros2.core.model.executor,
org.eclipse.tracecompass.incubator.internal.ros2.core.model.messagelinks,
org.eclipse.tracecompass.incubator.internal.ros2.core.model.messages,
org.eclipse.tracecompass.incubator.internal.ros2.core.model.objects,
org.eclipse.tracecompass.incubator.internal.ros2.core.trace;x-friends:="org.eclipse.tracecompass.incubator.ros2.core.tests,org.eclipse.tracecompass.incubator.ros2.ui",
Expand Down
Expand Up @@ -18,4 +18,5 @@ tracetype.experiment.ros2 = ROS 2 Experiment (incubator)
analysis.ros2 = ROS 2 (Incubator)
analysis.ros2.objects = ROS 2 Objects
analysis.ros2.messages = ROS 2 Messages
analysis.ros2.executor = ROS 2 Executor
analysis.ros2.executor = ROS 2 Executor
analysis.ros2.messagelinks = ROS 2 Message Links
16 changes: 16 additions & 0 deletions tracetypes/org.eclipse.tracecompass.incubator.ros2.core/plugin.xml
Expand Up @@ -67,6 +67,22 @@
class="org.eclipse.tracecompass.incubator.internal.ros2.core.trace.Ros2Experiment">
</tracetype>
</module>
<module
analysis_module="org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.messagelinks.Ros2MessageCausalLinksAnalysis"
applies_experiment="true"
automatic="false"
icon="icons/ros2.png"
id="org.eclipse.tracecompass.incubator.ros2.core.analysis.messagelinks"
name="%analysis.ros2.messagelinks">
<tracetype
applies="true"
class="org.eclipse.tracecompass.incubator.internal.ros2.core.trace.Ros2Trace">
</tracetype>
<tracetype
applies="true"
class="org.eclipse.tracecompass.incubator.internal.ros2.core.trace.Ros2Experiment">
</tracetype>
</module>
</extension>
<extension
point="org.eclipse.tracecompass.tmf.core.dataprovider">
Expand Down
@@ -0,0 +1,83 @@
/**********************************************************************
* Copyright (c) 2022 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.messagelinks;

import java.util.Collections;
import java.util.Objects;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.AbstractRos2StateSystemAnalysis;
import org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.IRos2ModelProvider;
import org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.objects.Ros2ObjectsAnalysis;
import org.eclipse.tracecompass.incubator.internal.ros2.core.model.messagelinks.Ros2MessageCausalLinksModel;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;

/**
* ROS 2 message causal links analysis. Collects causal links information from
* annotations.
*
* @author Christophe Bedard
*/
public class Ros2MessageCausalLinksAnalysis extends AbstractRos2StateSystemAnalysis implements IRos2ModelProvider<Ros2MessageCausalLinksModel> {

private static final @NonNull String ID_SUFFIX = ".messagelinks"; //$NON-NLS-1$

private Ros2MessageCausalLinksModel fModel;

/**
* Constructor
*/
public Ros2MessageCausalLinksAnalysis() {
super(getFullAnalysisId());
fModel = new Ros2MessageCausalLinksModel();
}

/**
* @return the full ID of this analysis module
*/
public static @NonNull String getFullAnalysisId() {
return AbstractRos2StateSystemAnalysis.getAnalysisIdFromSuffix(ID_SUFFIX);
}

@Override
public @Nullable Ros2MessageCausalLinksModel getModel() {
return fModel;
}

@Override
protected @NonNull ITmfStateProvider createStateProvider() {
@NonNull
ITmfTrace trace = Objects.requireNonNull(getTrace());
// Provide objects state system and (empty) message links model
ITmfStateSystem ss = getStateSystem(trace, Ros2ObjectsAnalysis.getFullAnalysisId());
return new Ros2MessageCausalLinksStateProvider(trace, Objects.requireNonNull(ss), fModel);
}

@Override
protected @NonNull Iterable<@NonNull IAnalysisModule> getDependentAnalyses() {
ITmfTrace trace = getTrace();
if (trace == null) {
return Collections.emptySet();
}
// Depends on the objects analysis
Ros2ObjectsAnalysis objectsAnalysis = TmfTraceUtils.getAnalysisModuleOfClass(trace, Ros2ObjectsAnalysis.class, Ros2ObjectsAnalysis.getFullAnalysisId());
if (objectsAnalysis == null) {
return Collections.emptySet();
}
return Collections.singleton(objectsAnalysis);
}
}
@@ -0,0 +1,97 @@
/**********************************************************************
* Copyright (c) 2022 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.messagelinks;

import java.util.Collection;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.incubator.internal.ros2.core.analysis.AbstractRos2StateProvider;
import org.eclipse.tracecompass.incubator.internal.ros2.core.model.messagelinks.Ros2MessageCausalLinkType;
import org.eclipse.tracecompass.incubator.internal.ros2.core.model.messagelinks.Ros2MessageCausalLinksModel;
import org.eclipse.tracecompass.incubator.internal.ros2.core.model.objects.Ros2ObjectHandle;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;

/**
* State provider for the ROS 2 message causal links analysis.
*
* @author Christophe Bedard
*/
public class Ros2MessageCausalLinksStateProvider extends AbstractRos2StateProvider {

private static final int VERSION_NUMBER = 0;

private final ITmfStateSystem fObjectsSs;
private final Ros2MessageCausalLinksModel fModel;

/**
* Constructor
*
* @param trace
* the trace
* @param objectsSs
* the objects state system
* @param model
* the message links model
*/
public Ros2MessageCausalLinksStateProvider(ITmfTrace trace, ITmfStateSystem objectsSs, Ros2MessageCausalLinksModel model) {
super(trace, Ros2MessageCausalLinksAnalysis.getFullAnalysisId());
fObjectsSs = objectsSs;
fModel = model;
}

@Override
public int getVersion() {
return VERSION_NUMBER;
}

@Override
public @NonNull ITmfStateProvider getNewInstance() {
return new Ros2MessageCausalLinksStateProvider(getTrace(), fObjectsSs, fModel);
}

@Override
protected void eventHandle(@NonNull ITmfEvent event) {
if (!considerEvent(event)) {
return;
}

/**
* No need to actually fill in the state system or use the event
* timestamps.
*/

// Periodic async
if (isEvent(event, LAYOUT.eventMessageLinkPeriodicAsync())) {
long[] subs = (long[]) getField(event, LAYOUT.fieldSubs());
long[] pubs = (long[]) getField(event, LAYOUT.fieldPubs());

fModel.addLink(toHandles(event, subs), toHandles(event, pubs), Ros2MessageCausalLinkType.PERIODIC_ASYNC);
}
// Partial sync
else if (isEvent(event, LAYOUT.eventMessageLinkPartialSync())) {
long[] subs = (long[]) getField(event, LAYOUT.fieldSubs());
long[] pubs = (long[]) getField(event, LAYOUT.fieldPubs());

fModel.addLink(toHandles(event, subs), toHandles(event, pubs), Ros2MessageCausalLinkType.PARTIAL_SYNC);
}
}

private static Collection<@NonNull Ros2ObjectHandle> toHandles(@NonNull ITmfEvent event, long[] handles) {
return LongStream.of(handles).boxed().map(h -> handleFrom(event, Objects.requireNonNull(h))).collect(Collectors.toUnmodifiableList());
}
}
@@ -0,0 +1,95 @@
/**********************************************************************
* Copyright (c) 2022 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.tracecompass.incubator.internal.ros2.core.model.messagelinks;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.incubator.internal.ros2.core.model.objects.Ros2ObjectHandle;

import com.google.common.base.Objects;

/**
* Complex causal link between subscriptions and publishers.
*
* @author Christophe Bedard
*/
public class Ros2MessageCausalLink {

private final Set<@NonNull Ros2ObjectHandle> fSubs;
private final Set<@NonNull Ros2ObjectHandle> fPubs;
private final @NonNull Ros2MessageCausalLinkType fType;

/**
* Constructor
*
* @param subs
* the subscriptions
* @param pubs
* the publishers
* @param type
* the causal link type
*/
public Ros2MessageCausalLink(Collection<@NonNull Ros2ObjectHandle> subs, Collection<@NonNull Ros2ObjectHandle> pubs, @NonNull Ros2MessageCausalLinkType type) {
fSubs = new HashSet<>(subs);
fPubs = new HashSet<>(pubs);
fType = type;
}

/**
* @return the subscriptions
*/
public Set<@NonNull Ros2ObjectHandle> getSubs() {
return fSubs;
}

/**
* @return the publishers
*/
public Set<@NonNull Ros2ObjectHandle> getPubs() {
return fPubs;
}

/**
* @return the message link type
*/
public @NonNull Ros2MessageCausalLinkType getType() {
return fType;
}

@Override
public int hashCode() {
return Objects.hashCode(fSubs, fPubs, fType);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Ros2MessageCausalLink o = (Ros2MessageCausalLink) obj;
return fSubs.equals(o.fSubs) && fPubs.equals(o.fPubs) && fType.equals(o.fType);
}

@Override
public String toString() {
return String.format("Ros2MessageCausalLink: subs=%s, pubs=%s, type=%s", fSubs.toString(), fPubs.toString(), fType.toString()); //$NON-NLS-1$
}
}
@@ -0,0 +1,24 @@
/**********************************************************************
* Copyright (c) 2022 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.tracecompass.incubator.internal.ros2.core.model.messagelinks;

/**
* Types of message causal links.
*
* @author Christophe Bedard
*/
public enum Ros2MessageCausalLinkType {
/** Periodic asynchronous many-to-many */
PERIODIC_ASYNC,
/** Partially synchronous many-to-many */
PARTIAL_SYNC
}

0 comments on commit 5745f16

Please sign in to comment.