basic outline for scan matching has been added.
This commit is contained in:
@@ -3,9 +3,10 @@ package ScanGraph;
|
|||||||
import Graph.Graph;
|
import Graph.Graph;
|
||||||
import Graph.Vertex;
|
import Graph.Vertex;
|
||||||
import Vector.Vector;
|
import Vector.Vector;
|
||||||
|
import org.ejml.simple.SimpleMatrix;
|
||||||
|
import org.ejml.simple.SimpleSVD;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class ScanGraph extends Graph{
|
public class ScanGraph extends Graph{
|
||||||
|
|
||||||
ScanPoint lastPoint;
|
ScanPoint lastPoint;
|
||||||
@@ -46,7 +47,7 @@ public class ScanGraph extends Graph{
|
|||||||
invalidPoints++;
|
invalidPoints++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
averagePosition = averagePosition.div(newScan.getScan().size() - invalidPoints);
|
SimpleMatrix averagePositionVector = new SimpleMatrix(averagePosition.div(newScan.getScan().size() - invalidPoints).toArray());
|
||||||
|
|
||||||
// compute the average position of the reference scan
|
// compute the average position of the reference scan
|
||||||
Vector averageReferencePosition = new Vector(0, 0);
|
Vector averageReferencePosition = new Vector(0, 0);
|
||||||
@@ -59,7 +60,7 @@ public class ScanGraph extends Graph{
|
|||||||
invalidPoints++;
|
invalidPoints++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
averageReferencePosition = averageReferencePosition.div(referenceScan.getScan().size() - invalidPoints);
|
SimpleMatrix averageReferencePositionVector = new SimpleMatrix(averageReferencePosition.div(referenceScan.getScan().size() - invalidPoints).toArray());
|
||||||
|
|
||||||
// compute the cross covariance matrix which is given by the formula:
|
// compute the cross covariance matrix which is given by the formula:
|
||||||
// covariance = the sum from 1 to N of (p_i) * (q_i)^T
|
// covariance = the sum from 1 to N of (p_i) * (q_i)^T
|
||||||
@@ -81,7 +82,45 @@ public class ScanGraph extends Graph{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the single value decomposition of the cross covariance matrix
|
// convert the cross covariance matrix to a simple matrix from ejml
|
||||||
|
SimpleMatrix crossCovarianceMatrixSimple = new SimpleMatrix(crossCovarianceMatrix);
|
||||||
|
// perform the single value decomposition on the cross covariance matrix
|
||||||
|
SimpleSVD svd = crossCovarianceMatrixSimple.svd();
|
||||||
|
// get the rotation matrix from the svd
|
||||||
|
SimpleMatrix rotationMatrix = (SimpleMatrix) svd.getU().mult(svd.getV().transpose());
|
||||||
|
// get the translation vector from the svd
|
||||||
|
SimpleMatrix translationVector = averageReferencePositionVector.minus(rotationMatrix.mult(averagePositionVector));
|
||||||
|
|
||||||
|
// update the new scan with the rotation matrix and translation vector
|
||||||
|
for (int i = 0; i < newScan.getScan().size(); i++) {
|
||||||
|
Vector point = newScan.getScan().get(i);
|
||||||
|
if (point != null) {
|
||||||
|
SimpleMatrix pointMatrix = new SimpleMatrix(point.toArray());
|
||||||
|
SimpleMatrix newPointMatrix = rotationMatrix.mult(pointMatrix).plus(translationVector);
|
||||||
|
newScan.getScan().set(i, new Vector((float) newPointMatrix.get(0), (float) newPointMatrix.get(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the error between the new scan and the reference scan
|
||||||
|
float error = 0;
|
||||||
|
for (int i = 0; i < correspondenceMatrix.getOldPointIndices().size(); i++) {
|
||||||
|
int oldIndex = correspondenceMatrix.getOldPointIndices().get(i);
|
||||||
|
int newIndex = correspondenceMatrix.getNewPointIndices().get(i);
|
||||||
|
Vector oldPoint = referenceScan.getScan().get(oldIndex);
|
||||||
|
Vector newPoint = newScan.getScan().get(newIndex);
|
||||||
|
if (oldPoint != null && newPoint != null) {
|
||||||
|
error += correspondenceMatrix.getDistances().get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error /= correspondenceMatrix.getOldPointIndices().size();
|
||||||
|
|
||||||
|
// if the error is less than some threshold, then we have found a match
|
||||||
|
if (error < 0.1) {
|
||||||
|
return referenceScan;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: iteratively update the scan up to 5 times before determining that there is no match.
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,4 +96,8 @@ public class Vector {
|
|||||||
public void draw(PApplet proc){
|
public void draw(PApplet proc){
|
||||||
proc.circle(this.x, this.y, 8);
|
proc.circle(this.x, this.y, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float[] toArray() {
|
||||||
|
return new float[]{x, y};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user