blob: 8d75ca7c3c7390c3bb8bc109d3c53bd5bb5a4cbf [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.core.impl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.vecmath.Matrix4d;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.common.math.ApogyCommonMathFacade;
import org.eclipse.apogy.common.math.Matrix4x4;
import org.eclipse.apogy.common.math.Tuple3d;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFacade;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.ReferencedContentNode;
import org.eclipse.apogy.common.topology.TransformNode;
import org.eclipse.apogy.core.ApogyCoreFactory;
import org.eclipse.apogy.core.ApogySystem;
import org.eclipse.apogy.core.ApogySystemApiAdapter;
import org.eclipse.apogy.core.FeatureOfInterest;
import org.eclipse.apogy.core.PositionedResult;
import org.eclipse.apogy.core.ResultNode;
import org.eclipse.apogy.core.invocator.AbstractTypeImplementation;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFacade;
import org.eclipse.apogy.core.invocator.AttributeResultValue;
import org.eclipse.apogy.core.invocator.Environment;
import org.eclipse.apogy.core.invocator.ReferenceResultValue;
import org.eclipse.apogy.core.invocator.TypeApiAdapter;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
public class ApogyCoreFacadeCustomImpl extends ApogyCoreFacadeImpl {
@Override
public Matrix4x4 computeAbsolutePoseMatrix(ApogySystem apogySystem, Matrix4x4 relativePose) {
// Gets system pose.
Node root = ApogyCommonTopologyFacade.INSTANCE.findRoot(apogySystem.getTopologyRoot().getOriginNode());
Matrix4d systemPose = ApogyCommonTopologyFacade.INSTANCE
.expressInFrame(apogySystem.getTopologyRoot().getOriginNode(), root);
// Gets the system centric result.
Matrix4x4 pose = relativePose;
Matrix4d matrix = new Matrix4d();
matrix.setIdentity();
if (pose != null)
matrix = pose.asMatrix4d();
// Create the absolute position result.
Matrix4d m = new Matrix4d();
m.setIdentity();
m.mul(systemPose, matrix);
return ApogyCommonMathFacade.INSTANCE.createMatrix4x4(m);
}
public ResultNode createResultNode(PositionedResult result) {
// Creates the ResultNode.
ResultNode resultNode = ApogyCoreFactory.eINSTANCE.createResultNode();
resultNode.setResult(result);
// Sets the time as the ID
Date time = result.getTime();
if (time == null)
time = new Date();
resultNode.setNodeId(createNodeID(result));
resultNode.setDescription(result.getDescription());
// Attaches the result itself to the ResultNode.
if (result.getResultValue() instanceof AttributeResultValue) {
AttributeResultValue attributeResultValue = (AttributeResultValue) result.getResultValue();
if (attributeResultValue.getValue() != null) {
// TODO : Adds a marker in the topology ?
}
} else if (result.getResultValue() instanceof ReferenceResultValue) {
ReferenceResultValue referenceResultValue = (ReferenceResultValue) result.getResultValue();
if (referenceResultValue.getValue() != null) {
if (referenceResultValue.getValue() instanceof Node) {
// TODO : Do not copy the Node when bug#1429 in Link and
// ReferenceGroupNode is fixed.
Node node = EcoreUtil.copy((Node) referenceResultValue.getValue());
resultNode.getChildren().add(node);
} else {
// Creates and adds a ReferencedContentNode with the result
// as its content.
EObject content = referenceResultValue.getValue();
ReferencedContentNode<EObject> contentNode = ApogyCommonTopologyFacade.INSTANCE
.createReferencedContentNode(content);
// Adds a the node via a ReferenceNode under the
// DataProductNode.
resultNode.getChildren().add(contentNode);
}
}
}
return resultNode;
}
@Override
public ApogySystem getApogySystem(Environment environment, String fullyQualifiedName) {
ApogySystem result = null;
AbstractTypeImplementation typeImplementation = ApogyCoreInvocatorFacade.INSTANCE
.getTypeImplementation(environment, fullyQualifiedName);
if (typeImplementation != null) {
TypeApiAdapter typeApiAdapter = typeImplementation.getAdapterInstance();
if (typeApiAdapter instanceof ApogySystemApiAdapter) {
ApogySystemApiAdapter apogySystemApiAdapter = (ApogySystemApiAdapter) typeApiAdapter;
result = apogySystemApiAdapter.getApogySystem();
}
}
return result;
}
public ApogySystem getApogySystem(Environment environment, EObject instance) {
ApogySystem result = null;
AbstractTypeImplementation abstractTypeImplementation = ApogyCoreInvocatorFacade.INSTANCE
.findAbstractTypeImplementation(instance);
if (abstractTypeImplementation != null
&& abstractTypeImplementation.getAdapterInstance() instanceof ApogySystemApiAdapter) {
ApogySystemApiAdapter apogySystemApiAdapter = (ApogySystemApiAdapter) abstractTypeImplementation
.getAdapterInstance();
result = apogySystemApiAdapter.getApogySystem();
}
return result;
}
public ApogySystem loadApogySystemFromFile(String apogySystemFileAbsolutePath) throws Exception {
Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
Map<String, Object> m = reg.getExtensionToFactoryMap();
m.put("key", new XMIResourceFactoryImpl());
// Create a resource set to hold the resources.
TransactionalEditingDomain domain = ApogyCommonTransactionFacade.INSTANCE.getDefaultEditingDomain();
ResourceSet resSet = domain.getResourceSet();
Resource resource = resSet.createResource(URI.createFileURI(apogySystemFileAbsolutePath));
resource.load(m);
ApogySystem apogySystem = (ApogySystem) resource.getContents().get(0);
return apogySystem;
}
public void saveApogySystemToFile(ApogySystem apogySystem, String apogySystemFileAbsolutePath) throws Exception {
// Create a resource set to hold the resources.
TransactionalEditingDomain domain = ApogyCommonTransactionFacade.INSTANCE
.getTransactionalEditingDomain(apogySystem);
if (domain == null) {
domain = ApogyCommonTransactionFacade.INSTANCE.getDefaultEditingDomain();
}
ResourceSet resourceSet = domain.getResourceSet();
Resource resource = resourceSet.createResource(URI.createFileURI(apogySystemFileAbsolutePath));
domain.getCommandStack().execute(new AddCommand(domain, resource.getContents(), apogySystem));
resource.save(Collections.EMPTY_MAP);
}
@Override
public List<FeatureOfInterest> loadFeatureOfInterestFromFile(String urlString) throws Exception {
List<FeatureOfInterest> foiList = new ArrayList<FeatureOfInterest>();
URL url = new URL(urlString);
File tempFile = copyURLContent(url);
BufferedReader reader = new BufferedReader(new FileReader(tempFile));
String line = null;
while ((line = reader.readLine()) != null) {
line = line.trim();
FeatureOfInterest foi = parserCSVLine(line);
if (foi != null) {
foiList.add(foi);
}
}
reader.close();
return foiList;
}
private FeatureOfInterest parserCSVLine(String line) throws Exception {
FeatureOfInterest foi = null;
String[] entries = line.split(",");
if (entries.length < 8) {
throw new Exception("Line <" + line + "> contains too few entries !");
}
String name = entries[0];
String description = entries[1];
double x = Double.parseDouble(entries[2]);
double y = Double.parseDouble(entries[3]);
double z = Double.parseDouble(entries[4]);
double rx = Double.parseDouble(entries[5]);
double ry = Double.parseDouble(entries[6]);
double rz = Double.parseDouble(entries[7]);
foi = ApogyCoreFactory.eINSTANCE.createFeatureOfInterest();
foi.setName(name);
foi.setDescription(description);
// Sets pose.
TransformNode tmp = ApogyCommonTopologyFacade.INSTANCE.createTransformNodeXYZ(x, y, z, rx, ry, rz);
Matrix4d m = tmp.asMatrix4d();
foi.setPose(ApogyCommonMathFacade.INSTANCE.createMatrix4x4(m));
return foi;
}
@Override
public void saveFeatureOfInterestToFile(String path, List<FeatureOfInterest> foiList) throws Exception {
// Converts the FOI to CSV format
String cvsData = convertToCSV(foiList);
// Write data to the file.
BufferedWriter writer = new BufferedWriter(new FileWriter(path));
writer.write(cvsData);
writer.close();
}
private String convertToCSV(List<FeatureOfInterest> foiList) {
String csvString = new String();
for (FeatureOfInterest foi : foiList) {
if (foi.getName() != null) {
// Replace comma by space
csvString += foi.getName().replaceAll(",", ";") + ",";
} else {
csvString += ",";
}
if (foi.getDescription() != null) {
// Replace comma by space
csvString += foi.getDescription().replaceAll(",", ";") + ",";
} else {
csvString += ",";
}
Tuple3d position = ApogyCommonMathFacade.INSTANCE.extractPosition(foi.getPose());
csvString += position.getX() + ",";
csvString += position.getY() + ",";
csvString += position.getZ() + ",";
Tuple3d orientation = ApogyCommonMathFacade.INSTANCE.extractOrientation(foi.getPose());
csvString += orientation.getX() + ",";
csvString += orientation.getY() + ",";
csvString += orientation.getZ() + "\n";
}
return csvString;
}
// FIXME Not used.
// private List<TimeSource> getAllAvaibleTimeSource() {
// List<TimeSource> timeSources = new ArrayList<TimeSource>();
//
// List<EClass> timeSourceEClass = ApogyCommonEMFFacade.INSTANCE
// .getAllSubEClasses(ApogyCommonEMFPackage.Literals.TIME_SOURCE);
//
// for (EClass eClass : timeSourceEClass) {
// try {
// EObject eObject = EcoreUtil.create(eClass);
// if (eObject instanceof TimeSource) {
// timeSources.add((TimeSource) eObject);
// }
// } catch (Throwable t) {
// Logger.error(t.getMessage(), t);
// }
// }
//
// return timeSources;
// }
// FIXME Not used.
// private CurrentTimeSource getCurrentTimeSource(Collection<TimeSource> timeSources) {
// CurrentTimeSource currentTimeSource = null;
//
// Iterator<TimeSource> it = timeSources.iterator();
// while (it.hasNext() && currentTimeSource == null) {
// TimeSource timeSource = it.next();
// if (timeSource instanceof CurrentTimeSource) {
// currentTimeSource = (CurrentTimeSource) timeSource;
// }
// }
//
// return currentTimeSource;
// }
// FIXME Move under Common Facade.
private File copyURLContent(URL url) throws Exception {
File tempFile = null;
String fileName = getFileName(url);
String fileExtension = getFileExtension(url);
tempFile = File.createTempFile(fileName, fileExtension);
url.openConnection();
InputStream reader = url.openStream();
FileOutputStream writer = new FileOutputStream(tempFile);
byte[] buffer = new byte[153600];
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) > 0) {
writer.write(buffer, 0, bytesRead);
buffer = new byte[153600];
}
writer.close();
reader.close();
if (tempFile != null) {
tempFile.deleteOnExit();
}
return tempFile;
}
// FIXME Move under Common Facade.
private String getFileName(URL url) {
String fileName = url.getFile();
int startIndex = fileName.lastIndexOf(File.separator);
int endIndex = fileName.lastIndexOf(".");
if (startIndex > 0 && endIndex > 0) {
fileName = fileName.substring(startIndex + 1, endIndex);
}
return fileName;
}
private String getFileExtension(URL url) {
String fileExtension = url.getFile();
int index = fileExtension.lastIndexOf(".");
if (index > 0) {
fileExtension = fileExtension.substring(index);
}
return fileExtension;
}
private String createNodeID(PositionedResult positionedResult) {
String nodeId = positionedResult.eClass().getName();
Date date = positionedResult.getTime();
if (date != null) {
nodeId += " - " + date.toString();
}
return nodeId;
}
} // ApogyCoreFacadeImpl