I have gone through The GraphSLAM Algorithm with Applications to Large-Scale Mapping of Urban Structures. I implemented the code for GraphSLAM. The fundamental formula of GraphSLAM is
$$\mu = \Omega^{-1}\xi$$
When I inverse $\Omega$ it gives me an error that Matrix is singular
.
In the above document there are some hints how to avoid this error. But I failed to understand that. On the eighth page of the above document - on page 410 - they discuss it in section 4. The GraphSLAM Algorithm portion. If anybody can understand it, please help me to understand.
From the text:
In particular, line 2 in GraphSLAM_linearize initializes the information elements. The “infinite” information entry in line 3 fixes the initial pose $x_0$ to (0 0 0)$^T$ . It is necessary, since otherwise the resulting matrix becomes singular, reflecting the fact that from relative information alone we cannot recover absolute estimates.
I added my code here for better understanding
import java.io.IOException;
import org.ujmp.core.SparseMatrix;
import org.ujmp.core.Matrix;
import java.io.File;
import java.util.Scanner;
public class Test1 {
public static void main(String args[]) throws IOException {
Matrix omega = SparseMatrix.Factory.zeros(5, 5);
Matrix Xi=SparseMatrix.Factory.zeros(5,1);
int i = 0, i1 = 0, k1 = 0, k2 = 0,l=0,l1=0;
double[] timex = new double[5];
double[] forwardx = new double[5];
double[] angularx = new double[5];
double[]x1=new double[5];
double[]y1=new double[5];
double[]theta1=new double[5];
double []landx=new double[2];
double[]landy=new double[2];
double[] timeya = new double[2];
double[] codea = new double[2];
double[] rangea = new double[2];
double[] bearinga = new double[2];
Scanner x = new Scanner(new File("/home/froboticscse/IdeaProjects/UJMPtest/src/main/java/a.txt"));
Scanner y = new Scanner(new File("/home/froboticscse/IdeaProjects/UJMPtest/src/main/java/b.txt"));
while (x.hasNext()) {
double time = x.nextDouble();
double forward = x.nextDouble();
double angular = x.nextDouble();
timex[i] = time;
forwardx[i] = forward;
angularx[i] = angular;
x1[i]=((forwardx[i]*0.006+Math.cos(0+(angularx[i]*0.006)/2)));
y1[i]=((forwardx[i]*0.006+Math.sin(0+(angularx[i]*0.006)/2)));
theta1[i]=(angularx[i]*0.006);
i++;
}
while (y.hasNext()) {
double timey = y.nextDouble();
double code = y.nextDouble();
double range = y.nextDouble();
double bearing = y.nextDouble();
timeya[i1] = timey;
codea[i1] = code;
rangea[i1] = range;
bearinga[i1] = bearing;
i1++;
}
while (k1 < timex.length && k2 < timeya.length) {
if (timex[k1] < timeya[k2]) {
omega.setAsDouble(1, k1, k1);
omega.setAsDouble(1, k1, k1 + 1);
Xi.setAsDouble(x1[l],k1,0);
k1++;
l++;
} else if (timex[k1] == timeya[k2]) {
landx[l1]=x1[k1]+rangea[k2]*(Math.cos(bearinga[k2]+theta1[k1]));
omega.setAsDouble(1, k1, k2);
omega.setAsDouble(1, k2, k1);
Xi.setAsDouble((landx[l1]+x1[l1]),k1,0);
k2++;
l1++;
} else {
System.out.println("Nothing to add");
}
// System.out.println(Xi);
}
System.out.println(omega);
/* Matrix mu=omega.inv().mtimes(Xi);
System.out.println(mu);*/
}
}