blob: 686a13b7a3a7ed0d7fc08ebeeff2074fec67e43f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque,
* Sebastien Gemme - initial API and implementation
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.addons.ros.ui.impl;
import org.eclipse.apogy.addons.ros.ApogyAddonsROSFacade;
import org.eclipse.apogy.addons.ros.ApogyAddonsROSFactory;
import org.eclipse.apogy.addons.ros.ApogyAddonsROSPackage;
import org.eclipse.apogy.addons.ros.ROSNode;
import org.eclipse.apogy.addons.ros.ui.TFDisplay3DTool;
import org.eclipse.apogy.addons.ros.utilities.GeometryUtils;
import org.eclipse.apogy.common.math.Matrix4x4;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFactory;
import org.eclipse.apogy.common.topology.GroupNode;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.TransformNode;
import org.eclipse.apogy.common.topology.ui.NodePresentation;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.ros.message.MessageListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import geometry_msgs.Transform;
public class TFDisplay3DToolCustomImpl extends TFDisplay3DToolImpl {
private static final Logger Logger = LoggerFactory.getLogger(TFDisplay3DToolImpl.class);
private TransformListener transformListener;
private TransformNode transformNode;
@Override
public void setActive(boolean newActive) {
if (!isActive() && newActive) {
start();
} else if (isActive() && !newActive) {
stop();
}
super.setActive(newActive);
}
@Override
public void setVisible(boolean newVisible) {
super.setVisible(newVisible);
NodePresentation nodePresentation = org.eclipse.apogy.common.topology.ui.Activator
.getTopologyPresentationRegistry().getPresentationNode(this.transformNode);
if (nodePresentation != null) {
// Toggle visibility flag.
nodePresentation.setVisible(isVisible() && isActive());
}
}
@Override
public void setRootNode(Node newRootNode) {
if (getRootNode() instanceof GroupNode) {
GroupNode previousGroupNode = (GroupNode) getRootNode();
previousGroupNode.getChildren().remove(getTransformNode());
}
super.setRootNode(newRootNode);
if (newRootNode instanceof GroupNode) {
GroupNode newGroupNode = (GroupNode) newRootNode;
newGroupNode.getChildren().add(getTransformNode());
}
}
@Override
public void dispose() {
// Detach the transform node from root.
if (this.transformNode != null && this.transformNode.getParent() instanceof GroupNode) {
((GroupNode) this.transformNode.getParent()).getChildren().remove(this.transformNode);
this.transformNode.setParent(null);
this.transformNode = null;
}
super.dispose();
}
@Override
public boolean start() {
// Initialize the ROS node.
ROSNode node = ApogyAddonsROSFactory.eINSTANCE.createROSNode();
node.setNodeName("/TFDisplayClient" + ApogyAddonsROSFacade.INSTANCE.getNodeNamePrefix());
node.setEnableAutoRestartOnConnectionLost(false);
Logger.info("RosNode Initializing");
try {
node.initialize();
} catch (Exception e) {
throw new RuntimeException("Unable to initialize the TFDisplay3DTool ROS Client");
}
setNode(node);
node.register(this, false);
node.eAdapters().add(new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getFeatureID(ROSNode.class) == ApogyAddonsROSPackage.ROS_NODE__CONNECTED) {
boolean connected = msg.getNewBooleanValue();
if (connected) {
Logger.info("Connected to the topic.");
// TODO : TRANSACTION
setConnected(true);
}
}
}
});
node.start();
return true;
}
@Override
public boolean stop() {
if (getNode() != null) {
try {
// Shuts down the ROS Node.
getNode().shutdown();
// Clears the ROS node.
setNode(null);
} catch (Throwable t) {
Logger.error("stop(): failed!", t);
// TODO : TRANSACTION
setConnected(false);
return false;
}
}
// TODO : TRANSACTION
setConnected(false);
return true;
}
@Override
public void rosInit() {
Logger.info("rosInit() on topic <" + getTopicName() + ">.");
// Topics Initialization.
this.topicLauncher.createListener(getTopicName(), geometry_msgs.Transform._TYPE, new TransformListener(this));
if (!this.topicLauncher.isRunning())
this.topicLauncher.launch();
}
protected TransformNode getTransformNode() {
if (this.transformNode == null) {
this.transformNode = ApogyCommonTopologyFactory.eINSTANCE.createTransformNode();
this.transformNode.setNodeId("TFDisplay3DTool");
this.transformNode.setDescription("TF : <" + getTopicName() + ">");
NodePresentation nodePresentation = org.eclipse.apogy.common.topology.ui.Activator
.getTopologyPresentationRegistry().getPresentationNode(this.transformNode);
if (nodePresentation != null) {
// Toggle visibility flag.
nodePresentation.setVisible(isVisible() && isActive());
}
}
return this.transformNode;
}
protected TransformListener getTransformListener() {
if (this.transformListener == null) {
this.transformListener = new TransformListener(this);
}
return this.transformListener;
}
private class TransformListener implements MessageListener<geometry_msgs.Transform> {
private final TFDisplay3DTool tfDisplay3DTool;
public TransformListener(TFDisplay3DTool newTFDisplay3DTool) {
this.tfDisplay3DTool = newTFDisplay3DTool;
}
@Override
public void onNewMessage(Transform msg) {
if (getTransformNode() != null && this.tfDisplay3DTool.isActive()) {
Matrix4x4 matrix = GeometryUtils.rosTransformToMatrix(msg);
getTransformNode().setTransformation(matrix.asMatrix4d());
}
}
}
} // TFDisplay3DToolImpl