2 GTSAM Copyright 2010-2018, Georgia Tech Research Corporation, 3 Atlanta, Georgia 30332-0415 5 Authors: Frank Dellaert, et al. (see THANKS for the full author list) 7 See LICENSE for the license information 9 Pose SLAM example using iSAM2 in 3D space. 12 - VisualISAM2Example by: Duy-Nguyen Ta (C++), Frank Dellaert (Python) 13 - Pose2SLAMExample by: Alex Cunningham (C++), Kevin Deng & Frank Dellaert (Python) 16 from typing
import List
18 import matplotlib.pyplot
as plt
26 """Print and plot incremental progress of the robot for 2D Pose SLAM using iSAM2.""" 29 print(
"*"*50 + f
"\nInference after State {key+1}:\n")
30 print(current_estimate)
38 axes = fig.add_subplot(projection=
'3d')
44 while current_estimate.exists(i):
45 gtsam_plot.plot_pose3(0, current_estimate.atPose3(i), 10,
46 marginals.marginalCovariance(i))
49 axes.set_xlim3d(-30, 45)
50 axes.set_ylim3d(-30, 45)
51 axes.set_zlim3d(-30, 45)
55 """Creates ground truth poses of the robot.""" 56 P0 = np.array([[1, 0, 0, 0],
60 P1 = np.array([[0, -1, 0, 15],
64 P2 = np.array([[np.cos(np.pi/4), 0, np.sin(np.pi/4), 30],
66 [-np.sin(np.pi/4), 0, np.cos(np.pi/4), 30],
68 P3 = np.array([[0, 1, 0, 30],
72 P4 = np.array([[-1, 0, 0, 0],
82 key: int, xyz_tol=0.6, rot_tol=17) -> int:
83 """Simple brute force approach which iterates through previous states 84 and checks for loop closure. 87 odom_tf: The noisy odometry transformation measurement in the body frame. 88 current_estimate: The current estimates computed by iSAM2. 89 key: Key corresponding to the current state estimate of the robot. 90 xyz_tol: Optional argument for the translational tolerance, in meters. 91 rot_tol: Optional argument for the rotational tolerance, in degrees. 93 k: The key of the state which is helping add the loop closure constraint. 94 If loop closure is not found, then None is returned. 97 prev_est = current_estimate.atPose3(key+1)
98 curr_est = prev_est.compose(odom_tf)
99 for k
in range(1, key+1):
100 pose = current_estimate.atPose3(k)
101 if (
abs(pose.matrix()[:3,:3] - curr_est.matrix()[:3,:3]) <= rot_tol*np.pi/180).
all()
and \
102 (
abs(pose.matrix()[:3,3] - curr_est.matrix()[:3,3]) <= xyz_tol).
all():
106 """Perform 3D SLAM given ground truth poses as well as simple 107 loop closure detection.""" 111 prior_xyz_sigma = 0.3
117 odometry_xyz_sigma = 0.2
120 odometry_rpy_sigma = 5
126 prior_rpy_sigma*np.pi/180,
127 prior_rpy_sigma*np.pi/180,
132 odometry_rpy_sigma*np.pi/180,
133 odometry_rpy_sigma*np.pi/180,
136 odometry_xyz_sigma]))
145 parameters.setRelinearizeThreshold(0.1)
146 parameters.relinearizeSkip = 1
155 odometry_xyz = [(odometry_tf[i].
x(), odometry_tf[i].
y(), odometry_tf[i].
z())
for i
in range(
len(odometry_tf))]
156 odometry_rpy = [odometry_tf[i].
rotation().rpy()
for i
in range(
len(odometry_tf))]
159 noisy_measurements = [np.random.multivariate_normal(np.hstack((odometry_rpy[i],odometry_xyz[i])), \
160 ODOMETRY_NOISE.covariance())
for i
in range(
len(odometry_tf))]
164 graph.push_back(gtsam.PriorFactorPose3(1, true_poses[0], PRIOR_NOISE))
169 current_estimate = initial_estimate
173 noisy_odometry = noisy_measurements[i]
184 graph.push_back(gtsam.BetweenFactorPose3(i + 1, loop, noisy_tf, ODOMETRY_NOISE))
186 graph.push_back(gtsam.BetweenFactorPose3(i + 1, i + 2, noisy_tf, ODOMETRY_NOISE))
189 noisy_estimate = current_estimate.atPose3(i + 1).
compose(noisy_tf)
190 initial_estimate.insert(i + 2, noisy_estimate)
193 isam.update(graph, initial_estimate)
194 current_estimate = isam.calculateEstimate()
198 initial_estimate.clear()
203 while current_estimate.exists(i):
204 print(f
"X{i} covariance:\n{marginals.marginalCovariance(i)}\n")
210 if __name__ ==
'__main__':
void print(const Matrix &A, const string &s, ostream &stream)
static Rot3 RzRyRx(double x, double y, double z, OptionalJacobian< 3, 1 > Hx={}, OptionalJacobian< 3, 1 > Hy={}, OptionalJacobian< 3, 1 > Hz={})
Rotations around Z, Y, then X axes as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when looking from unchanging axis.
static const Eigen::internal::all_t all
Rot3_ rotation(const Pose3_ &pose)
Reshape< OutM, OutN, OutOptions, InM, InN, InOptions >::ReshapedType reshape(const Eigen::Matrix< double, InM, InN, InOptions > &m)
Pose3_ transformPoseTo(const Pose3_ &p, const Pose3_ &q)
def determine_loop_closure
static Rot3 Rodrigues(const Vector3 &w)
def Pose3_ISAM2_example()
static shared_ptr Sigmas(const Vector &sigmas, bool smart=true)
Double_ range(const Point2_ &p, const Point2_ &q)
Expression< T > compose(const Expression< T > &t1, const Expression< T > &t2)
size_t len(handle h)
Get the length of a Python object.
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x