Мое требование - предоставить в Java функцию, которая использует линейную алгебру для поиска «откалиброванного» местоположения xyz в трехмерной системе координат. Ниже приведен интерфейс, который я пытаюсь реализовать. Аргументы могут быть изменены, чтобы соответствовать конкретной библиотеке, если это необходимо.
/**
* Given a nominal target xyz point within a three dimensional robotic coordinate system, calculate the theoretical x'y'z'
* transformation using input arrays that represent the nominal coordinates and actual measured coordinates corresponding to
* each nominal point.
*
* @param nominalPoints - a sampling of nominal values (per engineering specs) for a 3-axis robotic system
* e.g. double[][] nominalPoints = new double[][]{
* new double[]{30.0d, 68.0d, 1.0d},
* new double[]{50.0d, 6.0d, 1.0d},
* new double[]{110.d, 20.0d, 1.0d},
* new double[]{35.0d, 15.0d, 1.0d},
* new double[]{45.0d, 97.0d, 1.0d}
* };
* @param actualPoints - actual/measured values corresponding to the nominal data points. These points represent the
* variance from nominal due to manufacturing tolerances.
* e.g double[][] measuredPoints = new double[][]{
* new double[]{30.5d, 68.1d, 1.01d},
* new double[]{50.4d, 6.2d, 1.02d},
* new double[]{110.3d, 20.3d, 1.03d},
* new double[]{35.2d, 15.4d, 1.04d},
* new double[]{45.1d, 97.5d, 1.05d}
* };
* @param targetPoint - an x/y/z point in system to transform into an estimated value based on a least-squared evaluation of the
* nominal and actual arrays
*
* e.g. float[] targetPoint = new float[]{75.21f, 17.56f, 2.765f};
*
* @return
*/
public float[] getCalibratedPoint(float[][] nominalPoints, float[][] actualPoints, float[] targetPoint);
Следующий код - это одно решение, которое, как мне сказали, будет работать в Python, используя numpy, но я сосу на линейную алгебру и у меня возникают проблемы с поиском реализаций в Java для этого. В частности, я не нашел эквивалента np.hstack (..), np.ones (..) и функции наименьших квадратов, которая принимает 2 аргумента массива, таких как np.linalg.lstsq (..). Я смотрел на Apache Commons и EJML до сих пор
import numpy as np
# These are the points in the Tray Coordinate System.
primary = np.array([[40., 1160., 0.],
[40., 40., 0.],
[260., 40., 0.],
[260., 1160., 0.]])
# These are points in the Stage Coordinate System.
secondary = np.array([[610., 560., 0.],
[610., -560., 0.],
[390., -560., 0.],
[390., 560., 0.]])
# Pad the data with ones, so that our transformation can do translations too
def pad(x): return np.hstack([x, np.ones((x.shape[0], 1))])
def unpad(x): return x[:, :-1]
# This is the transform function. Pass Tray Coordinates to this.
def transform(x): return unpad(np.dot(pad(x), A))
X = pad(primary)
Y = pad(secondary)
# Solve the least squares problem X * A = Y
# to find our transformation matrix A
A, res, rank, s = np.linalg.lstsq(X, Y, rcond=None) # This is where the important work is done.
# Transforming a single point.
print('Transforming point (1, 2, 3) ...')
print(transform(np.array([[1, 2, 3]])))