| /******************************************************************************* |
| * 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 - initial API and implementation |
| * Regent L'Archeveque |
| * |
| * SPDX-License-Identifier: EPL-1.0 |
| *******************************************************************************/ |
| package org.eclipse.apogy.addons.vehicle.ui.composites; |
| |
| import java.text.DecimalFormat; |
| |
| import javax.vecmath.Vector3d; |
| |
| import org.eclipse.apogy.addons.vehicle.ApogyAddonsVehiclePackage; |
| import org.eclipse.apogy.addons.vehicle.OrientationCorrectionMode; |
| import org.eclipse.apogy.addons.vehicle.VehiclePoseCorrector; |
| import org.eclipse.apogy.addons.vehicle.ZCorrectionMode; |
| import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade; |
| import org.eclipse.apogy.common.math.ApogyCommonMathFacade; |
| import org.eclipse.apogy.common.math.GeometricUtils; |
| import org.eclipse.apogy.common.math.Matrix3x3; |
| import org.eclipse.apogy.common.math.Tuple3d; |
| import org.eclipse.apogy.common.math.ui.composites.Tuple3dComposite; |
| import org.eclipse.apogy.core.ApogyCorePackage; |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.conversion.Converter; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.databinding.FeaturePath; |
| import org.eclipse.emf.databinding.edit.EMFEditProperties; |
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; |
| import org.eclipse.jface.databinding.swt.WidgetProperties; |
| import org.eclipse.jface.databinding.viewers.ViewerProperties; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.ComboViewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| |
| public class VehiclePoseCorrectorComposite extends Composite { |
| public static final String DEGREE_STRING = "\u00b0"; |
| |
| private final AdapterFactory adapterFactory = new ComposedAdapterFactory( |
| ComposedAdapterFactory.Descriptor.Registry.INSTANCE); |
| |
| private VehiclePoseCorrector vehiclePoseCorrector; |
| |
| private Adapter orientationCorrectionAdapter; |
| |
| private Button btnEnable; |
| private Button btnReinitialize; |
| private ComboViewer comboZCorrectionMode; |
| private ComboViewer comboOrientationCorrectionMode; |
| private Text txtZCorrection; |
| private Tuple3dComposite orientationCorrectionComposite; |
| private final Tuple3d orientationCorrection = ApogyCommonMathFacade.INSTANCE.createTuple3d(0, 0, 0); |
| |
| private final DecimalFormat zCorrectionFormat = new DecimalFormat("0.000"); |
| private DataBindingContext m_bindingContext; |
| |
| public VehiclePoseCorrectorComposite(Composite parent, int style) { |
| super(parent, style); |
| setLayout(new GridLayout(3, false)); |
| |
| Label lblEnable = new Label(this, SWT.NONE); |
| lblEnable.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| lblEnable.setText("Enabled :"); |
| |
| this.btnEnable = new Button(this, SWT.CHECK); |
| |
| this.btnReinitialize = new Button(this, SWT.NONE); |
| this.btnReinitialize |
| .setToolTipText("Forces re-initialization of the pose corrector meshes contact geometries."); |
| this.btnReinitialize.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1)); |
| this.btnReinitialize.setText("Re-Initialize"); |
| this.btnReinitialize.addSelectionListener(new SelectionListener() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| if (getVehiclePoseCorrector() != null) { |
| // Run this in a job. |
| Job job = new Job("") { |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| getVehiclePoseCorrector().reInitialize(); |
| return Status.OK_STATUS; |
| } |
| }; |
| job.schedule(); |
| } |
| } |
| |
| @Override |
| public void widgetDefaultSelected(SelectionEvent e) { |
| } |
| }); |
| |
| Label lblZCorrectionMode = new Label(this, SWT.NONE); |
| lblZCorrectionMode.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| lblZCorrectionMode.setText("Z Correction Mode:"); |
| |
| this.comboZCorrectionMode = new ComboViewer(this, SWT.NONE); |
| this.comboZCorrectionMode.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| this.comboZCorrectionMode.setContentProvider(new ArrayContentProvider()); |
| this.comboZCorrectionMode.setLabelProvider(new AdapterFactoryLabelProvider(this.adapterFactory)); |
| this.comboZCorrectionMode.setInput(ZCorrectionMode.values()); |
| |
| Label lblOrientationCorrectionMode = new Label(this, SWT.NONE); |
| lblOrientationCorrectionMode.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| lblOrientationCorrectionMode.setText("Orientation Correction Mode:"); |
| |
| this.comboOrientationCorrectionMode = new ComboViewer(this, SWT.NONE); |
| this.comboOrientationCorrectionMode.getCombo() |
| .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| this.comboOrientationCorrectionMode.setContentProvider(new ArrayContentProvider()); |
| this.comboOrientationCorrectionMode.setLabelProvider(new AdapterFactoryLabelProvider(this.adapterFactory)); |
| this.comboOrientationCorrectionMode.setInput(OrientationCorrectionMode.values()); |
| |
| Label lblCurrentZCorrectionm = new Label(this, SWT.NONE); |
| lblCurrentZCorrectionm.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| lblCurrentZCorrectionm.setText("Z Correction (m):"); |
| |
| this.txtZCorrection = new Text(this, SWT.BORDER); |
| this.txtZCorrection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| this.txtZCorrection.setEditable(false); |
| |
| Label lblCurrentOrientationCorrection = new Label(this, SWT.NONE); |
| lblCurrentOrientationCorrection.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| lblCurrentOrientationCorrection.setText("Orientation Correction (" + DEGREE_STRING + "):"); |
| |
| this.orientationCorrectionComposite = new Tuple3dComposite(this, SWT.NONE, "0.00"); |
| GridData gd_orientation = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); |
| gd_orientation.widthHint = 300; |
| gd_orientation.minimumWidth = 300; |
| this.orientationCorrectionComposite.setLayoutData(gd_orientation); |
| this.orientationCorrectionComposite.setEnableEditing(false); |
| this.orientationCorrectionComposite.setTuple3d(this.orientationCorrection); |
| |
| enableControls(false); |
| |
| // Dispose |
| addDisposeListener(new DisposeListener() { |
| @Override |
| public void widgetDisposed(DisposeEvent e) { |
| if (VehiclePoseCorrectorComposite.this.m_bindingContext != null) |
| VehiclePoseCorrectorComposite.this.m_bindingContext.dispose(); |
| if (VehiclePoseCorrectorComposite.this.vehiclePoseCorrector != null) |
| VehiclePoseCorrectorComposite.this.vehiclePoseCorrector.eAdapters() |
| .remove(getOrientationCorrectionAdapter()); |
| } |
| }); |
| } |
| |
| public VehiclePoseCorrector getVehiclePoseCorrector() { |
| return this.vehiclePoseCorrector; |
| } |
| |
| public void setVehiclePoseCorrector(VehiclePoseCorrector vehiclePoseCorrector) { |
| if (vehiclePoseCorrector != null) |
| vehiclePoseCorrector.eAdapters().remove(getOrientationCorrectionAdapter()); |
| if (this.m_bindingContext != null) |
| this.m_bindingContext.dispose(); |
| |
| this.vehiclePoseCorrector = vehiclePoseCorrector; |
| |
| // Enables / disabled the controls. |
| enableControls(vehiclePoseCorrector != null); |
| |
| if (vehiclePoseCorrector != null) { |
| this.m_bindingContext = customInitDataBindings(); |
| vehiclePoseCorrector.eAdapters().add(getOrientationCorrectionAdapter()); |
| } |
| } |
| |
| public void enableControls(boolean enabled) { |
| if (this.btnEnable != null && !this.btnEnable.isDisposed()) |
| this.btnEnable.setEnabled(enabled); |
| if (this.btnReinitialize != null && !this.btnReinitialize.isDisposed()) |
| this.btnReinitialize.setEnabled(enabled); |
| if (this.txtZCorrection != null && !this.txtZCorrection.isDisposed()) |
| this.txtZCorrection.setEnabled(enabled); |
| if (this.orientationCorrectionComposite != null && !this.orientationCorrectionComposite.isDisposed()) |
| this.orientationCorrectionComposite.setEnabled(enabled); |
| |
| if (this.comboZCorrectionMode != null && this.comboZCorrectionMode.getCombo() != null |
| && !this.comboZCorrectionMode.getCombo().isDisposed()) { |
| this.comboZCorrectionMode.getControl().setEnabled(enabled); |
| this.comboZCorrectionMode.getCombo().setEnabled(enabled); |
| } |
| |
| if (this.comboOrientationCorrectionMode != null && this.comboOrientationCorrectionMode.getCombo() != null |
| && !this.comboOrientationCorrectionMode.getCombo().isDisposed()) { |
| this.comboOrientationCorrectionMode.getControl().setEnabled(enabled); |
| this.comboOrientationCorrectionMode.getCombo().setEnabled(enabled); |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| protected DataBindingContext customInitDataBindings() { |
| DataBindingContext bindingContext = new DataBindingContext(); |
| |
| /* Enabled. */ |
| IObservableValue<Double> observeEnabled = EMFEditProperties |
| .value(ApogyCommonTransactionFacade.INSTANCE.getDefaultEditingDomain(), |
| FeaturePath.fromList(ApogyCorePackage.Literals.ABSTRACT_APOGY_SYSTEM_POSE_CORRECTOR__ENABLED)) |
| .observe(this.vehiclePoseCorrector); |
| IObservableValue<String> observeEnabledButtton = WidgetProperties.selection().observe(this.btnEnable); |
| |
| bindingContext.bindValue(observeEnabledButtton, observeEnabled, new UpdateValueStrategy(), |
| new UpdateValueStrategy()); |
| |
| /* Z Correction Value. */ |
| IObservableValue<Double> observeZCorrection = EMFEditProperties |
| .value(ApogyCommonTransactionFacade.INSTANCE.getDefaultEditingDomain(), |
| FeaturePath.fromList(ApogyAddonsVehiclePackage.Literals.VEHICLE_POSE_CORRECTOR__ZCORRECTION)) |
| .observe(this.vehiclePoseCorrector); |
| IObservableValue<String> observeZCorrectionTxt = WidgetProperties.text(SWT.Modify).observe(this.txtZCorrection); |
| |
| bindingContext.bindValue(observeZCorrectionTxt, observeZCorrection, |
| new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), |
| new UpdateValueStrategy().setConverter(new Converter(Double.class, String.class) { |
| @Override |
| public Object convert(Object fromObject) { |
| return VehiclePoseCorrectorComposite.this.zCorrectionFormat.format(fromObject); |
| } |
| |
| })); |
| |
| /* Z Correction enablement. */ |
| IObservableValue<String> observeZCorrectionEnable = WidgetProperties.enabled().observe(this.txtZCorrection); |
| bindingContext.bindValue(observeZCorrectionEnable, observeEnabled, new UpdateValueStrategy(), |
| new UpdateValueStrategy()); |
| |
| /* Orientation correction enablement */ |
| IObservableValue<String> observeOrientationCorrectionEnable = WidgetProperties.enabled() |
| .observe(this.orientationCorrectionComposite); |
| bindingContext.bindValue(observeOrientationCorrectionEnable, observeEnabled, new UpdateValueStrategy(), |
| new UpdateValueStrategy()); |
| |
| /* Z Correction Mode. */ |
| IObservableValue<Double> observeZCorrectionMode = EMFEditProperties |
| .value(ApogyCommonTransactionFacade.INSTANCE.getDefaultEditingDomain(), |
| FeaturePath |
| .fromList(ApogyAddonsVehiclePackage.Literals.VEHICLE_POSE_CORRECTOR__ZCORRECTION_MODE)) |
| .observe(this.vehiclePoseCorrector); |
| |
| IObservableValue<?> observeZCorrectionModeCombViewer = ViewerProperties.singleSelection() |
| .observe(this.comboZCorrectionMode); |
| bindingContext.bindValue(observeZCorrectionModeCombViewer, observeZCorrectionMode, new UpdateValueStrategy(), |
| new UpdateValueStrategy()); |
| |
| /* Orientation Correction Mode. */ |
| IObservableValue<Double> observeOrientationCorrectionMode = EMFEditProperties |
| .value(ApogyCommonTransactionFacade.INSTANCE.getDefaultEditingDomain(), |
| FeaturePath.fromList( |
| ApogyAddonsVehiclePackage.Literals.VEHICLE_POSE_CORRECTOR__ORIENTATION_CORRECTION_MODE)) |
| .observe(this.vehiclePoseCorrector); |
| |
| IObservableValue<?> observeOrientationCorrectionModeComboViewer = ViewerProperties.singleSelection() |
| .observe(this.comboOrientationCorrectionMode); |
| bindingContext.bindValue(observeOrientationCorrectionModeComboViewer, observeOrientationCorrectionMode, |
| new UpdateValueStrategy(), new UpdateValueStrategy()); |
| |
| return bindingContext; |
| } |
| |
| protected Adapter getOrientationCorrectionAdapter() { |
| if (this.orientationCorrectionAdapter == null) { |
| this.orientationCorrectionAdapter = new AdapterImpl() { |
| @Override |
| public void notifyChanged(Notification msg) { |
| if (msg.getNotifier() instanceof VehiclePoseCorrector) { |
| int featureID = msg.getFeatureID(VehiclePoseCorrector.class); |
| if (featureID == ApogyAddonsVehiclePackage.VEHICLE_POSE_CORRECTOR__ORIENTATION_CORRECTION) { |
| if (msg.getNewValue() instanceof Matrix3x3) { |
| Matrix3x3 rot = (Matrix3x3) msg.getNewValue(); |
| Vector3d r = GeometricUtils.extractRotationFromXYZRotMatrix(rot.asMatrix3d()); |
| VehiclePoseCorrectorComposite.this.orientationCorrection.setX(Math.toDegrees(r.x)); |
| VehiclePoseCorrectorComposite.this.orientationCorrection.setY(Math.toDegrees(r.y)); |
| VehiclePoseCorrectorComposite.this.orientationCorrection.setZ(Math.toDegrees(r.z)); |
| } |
| } |
| } |
| } |
| }; |
| } |
| return this.orientationCorrectionAdapter; |
| } |
| |
| } |