00001 /* 00002 * Copyright 2016 The Cartographer Authors 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef CARTOGRAPHER_MAPPING_INTERNAL_CONNECTED_COMPONENTS_H_ 00018 #define CARTOGRAPHER_MAPPING_INTERNAL_CONNECTED_COMPONENTS_H_ 00019 00020 #include <map> 00021 00022 #include "absl/container/flat_hash_map.h" 00023 #include "absl/synchronization/mutex.h" 00024 #include "cartographer/mapping/proto/connected_components.pb.h" 00025 #include "cartographer/mapping/submaps.h" 00026 00027 namespace cartographer { 00028 namespace mapping { 00029 00030 // A class that tracks the connectivity structure between trajectories. 00031 // 00032 // Connectivity includes both the count ("How many times have I _directly_ 00033 // connected trajectories i and j?") and the transitive connectivity. 00034 // 00035 // This class is thread-safe. 00036 class ConnectedComponents { 00037 public: 00038 ConnectedComponents(); 00039 00040 ConnectedComponents(const ConnectedComponents&) = delete; 00041 ConnectedComponents& operator=(const ConnectedComponents&) = delete; 00042 00043 // Add a trajectory which is initially connected to only itself. 00044 void Add(int trajectory_id) LOCKS_EXCLUDED(lock_); 00045 00046 // Connect two trajectories. If either trajectory is untracked, it will be 00047 // tracked. This function is invariant to the order of its arguments. Repeated 00048 // calls to Connect increment the connectivity count. 00049 void Connect(int trajectory_id_a, int trajectory_id_b) LOCKS_EXCLUDED(lock_); 00050 00051 // Determines if two trajectories have been (transitively) connected. If 00052 // either trajectory is not being tracked, returns false, except when it is 00053 // the same trajectory, where it returns true. This function is invariant to 00054 // the order of its arguments. 00055 bool TransitivelyConnected(int trajectory_id_a, int trajectory_id_b) 00056 LOCKS_EXCLUDED(lock_); 00057 00058 // Return the number of _direct_ connections between 'trajectory_id_a' and 00059 // 'trajectory_id_b'. If either trajectory is not being tracked, returns 0. 00060 // This function is invariant to the order of its arguments. 00061 int ConnectionCount(int trajectory_id_a, int trajectory_id_b) 00062 LOCKS_EXCLUDED(lock_); 00063 00064 // The trajectory IDs, grouped by connectivity. 00065 std::vector<std::vector<int>> Components() LOCKS_EXCLUDED(lock_); 00066 00067 // The list of trajectory IDs that belong to the same connected component as 00068 // 'trajectory_id'. 00069 std::vector<int> GetComponent(int trajectory_id) LOCKS_EXCLUDED(lock_); 00070 00071 private: 00072 // Find the representative and compresses the path to it. 00073 int FindSet(int trajectory_id) EXCLUSIVE_LOCKS_REQUIRED(lock_); 00074 void Union(int trajectory_id_a, int trajectory_id_b) 00075 EXCLUSIVE_LOCKS_REQUIRED(lock_); 00076 00077 absl::Mutex lock_; 00078 // Tracks transitive connectivity using a disjoint set forest, i.e. each 00079 // entry points towards the representative for the given trajectory. 00080 std::map<int, int> forest_ GUARDED_BY(lock_); 00081 // Tracks the number of direct connections between a pair of trajectories. 00082 std::map<std::pair<int, int>, int> connection_map_ GUARDED_BY(lock_); 00083 }; 00084 00085 // Returns a proto encoding connected components. 00086 proto::ConnectedComponents ToProto( 00087 std::vector<std::vector<int>> connected_components); 00088 00089 } // namespace mapping 00090 } // namespace cartographer 00091 00092 #endif // CARTOGRAPHER_MAPPING_INTERNAL_CONNECTED_COMPONENTS_H_