I understand that the factorGraph in matlab is derived from the literature "Dellaert, Frank. Factor graphs and GTSAM: A Hands-On Introduction. Georgia: Georgia Tech, September, 2012”,
The online project GTSAM is described in section 4.2 here, and is very similar to the example I gave above, where according to the description in section 4.2 "Using the MATLAB Interface", the relative angle of rotation is also pi/2, This means that my example above looks correct, but it is still unclear where the problem lies.
%% factorGraph优化
% 由于factorTwoPoseSE2暂无法指定起始点,故用se3来进行
fg = factorGraph();
% pf = factorPoseSE3Prior(0,Measurement=[0,0,0, 1,0,0,0]);
% addFactor(fg,pf);
fctr = factorTwoPoseSE3([0 1],Measurement=[0 0 0 1 0 0 0]);
addFactor(fg,fctr);
abspos = [0,0,0,eul2quat([0,0,0],"ZYX"); % rotate 0 about Z axis
1,0,0,eul2quat([pi/2,0,0],"ZYX"); % rotate 90*pi/180 about Z axis
1,1,0,eul2quat([pi,0,0],"ZYX"); % rotate 180*pi/180 about Z axis
0,1,0,eul2quat([3*pi/2,0,0],"ZYX")]; % rotate 270*pi/180 about Z axis
relZ = pi/2;
relY = 0;
relX = 0;
relPose = [1,0,0,eul2quat([relZ,relY,relX]);
0,1,0,eul2quat([relZ,relY,relX]);
-1,0,0,eul2quat([relZ,relY,relX]);
0,-.8,0,eul2quat([relZ,relY,relX])];
% relPose = diff(abspos);
% relPose = [relPose;
% abspos(1,:)-abspos(end,:)];
zeroQuat = [1 0 0 0];
nodeID = [1 2];
f = factorTwoPoseSE3(nodeID,Measurement=[relPose(1,:)]);% odometry
addFactor(fg,f);
nodeID = [2 3];
f = factorTwoPoseSE3(nodeID,Measurement=[relPose(2,:)]);% odometry
addFactor(fg,f);
nodeID = [3 4];
f = factorTwoPoseSE3(nodeID,Measurement=[relPose(3,:)]);% odometry
addFactor(fg,f);
nodeID = [4 1];
f = factorTwoPoseSE3(nodeID,Measurement=[relPose(end,:)]);% loop closure
addFactor(fg,f);
% optimize
optns = factorGraphSolverOptions();
optimize(fg,optns);
newNodes = [fg.nodeState(1);
fg.nodeState(2);
fg.nodeState(3);
fg.nodeState(4)]
newNodes = 4×7
-0.3932 -0.3266 0 0.9992 0 0 -0.0411
0.6035 -0.4100 0 1.0000 0 0 0.0076
0.5882 0.5885 0 0.9984 0 0 0.0564
-0.4054 0.4747 0 1.0000 0 0 0.0076
theta = quat2eul(newNodes(:,4:end))
theta = 4×3
-0.0822 0 0
0.0153 0 0
0.1128 0 0
0.0153 0 0
D2 = pdist(newNodes(:,1:2))
D2 = 1×6
1.0001 1.3418 0.8013 0.9987 1.3418 1.0001
figure;
plot(newNodes(:,1),newNodes(:,2),'b-',Marker='.')
hold on;grid on;
plot(newNodes([4,1],1),newNodes([4,1],2),'r-',Marker='.')
text(newNodes(:,1),newNodes(:,2),string(1:4))
title('after factorGraph(3D) optimize')
as we can see,the initial node coordinates cannot be specified by priors, and the absolute angular orientation theta of the 4 nodes is also a problem