3 from cslam.lidar_pr.scancontext_matching
import ScanContextMatching
7 """Sparse matching for loop closure detection
8 Matches global descriptors to generate loop closure candidates
9 Then candidates are selected such that we respect the communication budget
13 """ Initialization of loop closure matching
16 params (dict): ROS 2 parameters
21 if self.
paramsparams[
"frontend.sensor_type"] ==
"lidar":
26 for i
in range(self.
paramsparams[
'max_nb_robots']):
27 if i != self.
paramsparams[
'robot_id']:
28 if self.
paramsparams[
"frontend.sensor_type"] ==
"lidar":
34 self.
paramsparams[
'robot_id'], self.
paramsparams[
'max_nb_robots'], extra_params=self.
paramsparams)
37 """ Add a local keyframe for matching
40 embedding (np.array): global descriptor
44 self.
local_nnsmlocal_nnsm.add_item(embedding, keyframe_id)
45 for i
in range(self.
paramsparams[
'max_nb_robots']):
46 if i != self.
paramsparams[
'robot_id']:
47 kf, similarity = self.
other_robots_nnsmother_robots_nnsm[i].search_best(embedding)
49 if similarity >= self.
paramsparams[
'frontend.similarity_threshold']:
57 """ Add keyframe global descriptor info from other robot
60 msg (cslam_common_interfaces.msg.GlobalDescriptor): global descriptor info
63 np.asarray(msg.descriptor), msg.keyframe_id)
66 kf, similarity = self.
local_nnsmlocal_nnsm.search_best(np.asarray(msg.descriptor))
68 if similarity >= self.
paramsparams[
'frontend.similarity_threshold']:
70 msg.keyframe_id, similarity)
75 kfs, similarities = self.
local_nnsmlocal_nnsm.search(descriptor,
76 k=self.
paramsparams[
'frontend.nb_best_matches'])
78 if len(kfs) > 0
and kfs[0] == kf_id:
79 kfs, similarities = kfs[1:], similarities[1:]
83 for kf, similarity
in zip(kfs, similarities):
85 kf_id) < self.
paramsparams[
'frontend.intra_loop_min_inbetween_keyframes']:
88 if similarity < self.
paramsparams[
'frontend.similarity_threshold']:
97 greedy_initialization=True):
98 """Select inter-robot loop closure candidates according to budget
101 number_of_candidates (int): inter-robot loop closure budget,
102 is_neighbor_in_range: dict(int, bool): indicates which other robots are in communication range
103 greedy_initialization: bool: use greedy initialization for selection
106 list(EdgeInterRobot): selected edges
109 number_of_candidates, is_neighbor_in_range,
110 greedy_initialization)
def add_other_robot_global_descriptor(self, msg)
def add_local_global_descriptor(self, embedding, keyframe_id)
def __init__(self, params)
def match_local_loop_closures(self, descriptor, kf_id)
def select_candidates(self, number_of_candidates, is_neighbor_in_range, greedy_initialization=True)