Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/lifelong compression #2

Open
wants to merge 83 commits into
base: foxy-devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
e1cc2ac
[DOC]: Initial commit and loop for grid calculation
kmilo7204 Oct 22, 2021
f986ba7
[WIP]: Initial test for gris position mapping
kmilo7204 Oct 25, 2021
47b6098
[WIP]: Adding new functions for ray tracing, and probability calculation
kmilo7204 Oct 26, 2021
95de0b4
[WIP]: Adding tools for measuring distances to cells
kmilo7204 Oct 28, 2021
7aa82b9
[WIP]: Updating function to calculate intersection of beams and cells
kmilo7204 Oct 29, 2021
80bc5eb
[WIP]: Cleaning comments
kmilo7204 Nov 2, 2021
d07ddeb
[FIX]: Adding last cell to the calculation so we get the whole distance
kmilo7204 Nov 2, 2021
579c562
[WIP]: Distance to each cell is being calculated. This is not working…
kmilo7204 Nov 2, 2021
2fa788a
[ADD]: Probabilities calculation
kmilo7204 Nov 3, 2021
d91e4c7
[FIX]: RBT transformation for getting the final point
kmilo7204 Nov 4, 2021
c3f4155
[FEAT]: Finally getting the cutting points to each individual cell
kmilo7204 Nov 5, 2021
33bc43c
[FIX]: Probability function update
kmilo7204 Nov 5, 2021
a012859
[WIP]: Probability calculation is reliable
kmilo7204 Nov 8, 2021
a2c83e0
[WIP]: Adding inverseModel function to detect cell occupancy, adding …
kmilo7204 Nov 10, 2021
d6f6db1
[WIP]: Logs calculation
kmilo7204 Nov 10, 2021
f294d0d
[WIP]: Getting probability from log-odds
kmilo7204 Nov 10, 2021
c08fd69
[WIP]: Adding map entropy calculation
kmilo7204 Nov 11, 2021
e66435c
[ADD]: Adding algorithm 1 base, it is in adaptation process
kmilo7204 Nov 22, 2021
eb2c754
[ADD]: Algorithm 1 MVP (Currently working), but testing is required
kmilo7204 Nov 23, 2021
6cab676
[WIP]: Algorithm 1 completed. Adding now new poses and scans
kmilo7204 Nov 29, 2021
285d07e
[WIP]: Adding conditions for some cells. New intersections are handle…
kmilo7204 Nov 29, 2021
ec51e0b
[FIX]: Handling cells seen by Bresenham but without intersections
kmilo7204 Nov 30, 2021
116abf7
[WIP]: Final adjustments
kmilo7204 Nov 30, 2021
5f88cd6
[ADD]: Adding measurement outcome entropy (3.12) calculation
kmilo7204 Dec 7, 2021
b507842
[ADD]: Map mutual information calculation and code structure, it is w…
kmilo7204 Dec 9, 2021
384a0b5
[WIP]: Adding new robot pose for mutual information verification
kmilo7204 Dec 10, 2021
c825cc6
[WIP]> Notations and calculations improvements
kmilo7204 Dec 10, 2021
ea9ef27
[ADD]: New theoretical information object
kmilo7204 Dec 14, 2021
488868b
[WIP]: Completing theoretical information object
kmilo7204 Dec 15, 2021
64b8756
[WIP]: Completing theoretical information object, removing old code a…
kmilo7204 Dec 15, 2021
86910b8
[RMV]: Removing unused dependencies
kmilo7204 Dec 15, 2021
36f2fa9
[FIX]: Floating point absolute value changed in cell limits
kmilo7204 Dec 16, 2021
7980579
[WIP]: Changes in measurement outcomes computations and code structure
kmilo7204 Dec 17, 2021
89664a2
[WIP]: Functions reordering to improve readability
kmilo7204 Dec 20, 2021
dc970e0
[WIP]: Adding new functions for readability
kmilo7204 Dec 21, 2021
e2a13ef
[WIP]: Changes in algorithm 1
kmilo7204 Dec 22, 2021
43ce3bf
[WIP]: Function return values modifications to match Karto
kmilo7204 Dec 23, 2021
71f5930
[WIP]: Integration of new elements
kmilo7204 Dec 27, 2021
ed0f586
[WIP]: Replacing data types from double to kt_double
kmilo7204 Dec 28, 2021
542b239
[WIP]: Functions modification. At this point we now have an utils fil…
kmilo7204 Dec 28, 2021
340f6d5
[ADD]: Adding utils namespace
kmilo7204 Dec 28, 2021
e5ac4e5
[INT]: Utils integration
kmilo7204 Dec 29, 2021
6869573
[WIP]: Changing main function arguments
kmilo7204 Dec 29, 2021
b2cac9f
[WIP]: More modification to make the code clear
kmilo7204 Dec 30, 2021
8ba213b
[ADD]: Eigen addition and matrix replacement
kmilo7204 Dec 31, 2021
88d3561
[DOC]: Adding code documentation
kmilo7204 Jan 4, 2022
93a1809
[ADD]: Adding basic test logic
kmilo7204 Jan 7, 2022
899607f
[ADD]: Adding tests for Information Estimates and Utils
kmilo7204 Jan 8, 2022
1b432f3
[WIP]: Adding more test cases
kmilo7204 Jan 10, 2022
b5752c7
[WIP]: Tests updating
kmilo7204 Jan 12, 2022
8148fed
[WIP]: Renaming functions, updating tests and replacing some data str…
kmilo7204 Jan 13, 2022
296d191
[WIP]: Updating mutual information calculation
kmilo7204 Jan 19, 2022
c2e7c5c
[WIP]: Removing unused code
kmilo7204 Jan 20, 2022
8752e3e
[ADD]: Function for mutual information calculation
kmilo7204 Jan 23, 2022
969a3a7
[WIP]: Dynamic grid resizing
kmilo7204 Feb 10, 2022
a39954d
[RMV]: Unused function and adding transformations
kmilo7204 Feb 10, 2022
b799cb8
[WIP]: Returning values modification
kmilo7204 Feb 21, 2022
2825ef9
[WIP]: Replacing vectors for karto wrappers
kmilo7204 Feb 21, 2022
83203d9
[WIP]: Comparing probabilities from the same scans
kmilo7204 Feb 21, 2022
c87c408
[WIP]: Integration to lifelong mapping loop
kmilo7204 Mar 6, 2022
b3baea5
[ADD]: New logic for Algrotihm 1 implementation
kmilo7204 Apr 2, 2022
e40b217
[RMV]: Removing basic functions
kmilo7204 Apr 2, 2022
f0654c0
[ADD]: Adding base logic for new loop calculation
kmilo7204 Jun 23, 2022
d40c125
[WIP]: First complete pass on the new function
kmilo7204 Aug 2, 2022
8c206a8
[ADD]: Adding cell angle functionality. Still under testing
kmilo7204 Sep 9, 2022
75d20f6
[WIP]: Calculations up to entropy are now correct
kmilo7204 Oct 11, 2022
e2a99fc
Fully functional loop
kmilo7204 Oct 18, 2022
91bd220
Complete main function update
kmilo7204 Oct 21, 2022
bf2ede3
Checkpoint for code refactoring
kmilo7204 Oct 24, 2022
60930e3
Add new function for separaitng the jobs
kmilo7204 Oct 26, 2022
c7d6116
Code refactoring phase 1
kmilo7204 Oct 31, 2022
156be31
Remove undesired folders
kmilo7204 Oct 31, 2022
002345b
Updating test for mutual information
kmilo7204 Nov 4, 2022
656206c
[ADD]: Test cases
kmilo7204 Nov 8, 2022
97b45af
Improving redability, addition of segment and box structures, adding …
kmilo7204 Nov 14, 2022
85674bf
[RMV]: Revert test changes in the main file
kmilo7204 Dec 10, 2022
be2197a
[UPDT]: Update C++ STD version to use optional function
kmilo7204 Dec 10, 2022
be745b7
[WIP]: Structures modification to simplify readability
kmilo7204 Dec 10, 2022
89a8a18
[RMV]: Reverting changes in main file
kmilo7204 Dec 10, 2022
5ef8011
[WIP]: Remove not necessary PI addition to cell angle
kmilo7204 Dec 10, 2022
582eda9
[ADD]: Addition of new map dimensions structures to improve readability
kmilo7204 Dec 12, 2022
54ecdc1
[WIP]: Typedef for probaility map
kmilo7204 Dec 12, 2022
82a2141
[WIP]: Updating exponential distribution rate and deleting unused at…
kmilo7204 Dec 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ set(libraries
sync_slam_toolbox
localization_slam_toolbox
lifelong_slam_toolbox
information_estimates
)

find_package(PkgConfig REQUIRED)
Expand Down Expand Up @@ -144,6 +145,10 @@ ament_target_dependencies(toolbox_common
target_link_libraries(toolbox_common kartoSlamToolbox ${Boost_LIBRARIES})
rosidl_target_interfaces(toolbox_common ${PROJECT_NAME} "rosidl_typesupport_cpp")

#### Adding information estimates library
add_library(information_estimates src/experimental/information_estimates.cpp src/experimental/utils.cpp)
target_link_libraries(information_estimates toolbox_common kartoSlamToolbox ${Boost_LIBRARIES})

#### Mapping executibles
add_library(async_slam_toolbox src/slam_toolbox_async.cpp)
target_link_libraries(async_slam_toolbox toolbox_common kartoSlamToolbox ${Boost_LIBRARIES})
Expand All @@ -163,7 +168,7 @@ target_link_libraries(localization_slam_toolbox_node localization_slam_toolbox)
add_library(lifelong_slam_toolbox src/experimental/slam_toolbox_lifelong.cpp)
target_link_libraries(lifelong_slam_toolbox toolbox_common kartoSlamToolbox ${Boost_LIBRARIES})
add_executable(lifelong_slam_toolbox_node src/experimental/slam_toolbox_lifelong_node.cpp)
target_link_libraries(lifelong_slam_toolbox_node lifelong_slam_toolbox)
target_link_libraries(lifelong_slam_toolbox_node lifelong_slam_toolbox information_estimates)

#### Merging maps tool
add_executable(merge_maps_kinematic src/merge_maps_kinematic.cpp)
Expand All @@ -179,6 +184,15 @@ target_link_libraries(merge_maps_kinematic kartoSlamToolbox toolbox_common)
# target_link_libraries(lifelong_metrics_test lifelong_slam_toolbox)
#endif()

if(BUILD_TESTING)
find_package(ament_cmake_gtest REQUIRED)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
include_directories(test)
ament_add_gtest(information_estimates_test test/information_estimates_test.cpp)
target_link_libraries(information_estimates_test information_estimates)
endif()

#### Install
install(TARGETS async_slam_toolbox_node
sync_slam_toolbox_node
Expand Down
122 changes: 122 additions & 0 deletions include/slam_toolbox/experimental/information_estimates.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#ifndef SLAM_TOOLBOX__EXPERIMENTAL__THEORETIC_INFORMATION_HPP_
#define SLAM_TOOLBOX__EXPERIMENTAL__THEORETIC_INFORMATION_HPP_

#include "utils.hpp"

class InformationEstimates
{
typedef std::tuple<int, int, int> map_tuple;

public:
InformationEstimates(kt_double sensor_range, kt_double resolution, kt_double lambda, kt_double nu);
InformationEstimates();
virtual ~InformationEstimates() {}

public:
std::vector<kt_double> findMutualInfo(std::vector<karto::LocalizedRangeScan*> const& range_scans);

private:

void calculateAndAppendCellProbabilities(
std::vector<karto::Vector2<int>> & visited_cells,
std::vector<kt_double> const & distances,
karto::Vector2<int> const & cell
);

std::vector<kt_double> calculateBeamAndCellIntersections(
kt_bool & skip_cell_eval,
karto::Vector2<kt_double> const & scan_position,
karto::Vector2<kt_double> const & beam_read_point,
karto::Vector2<int> const & cell
);

int findClosestLaserIndexToCell(
kt_bool & skip_cell_eval,
kt_double const & angle_to_cell,
kt_double const & scan_pose_heading,
karto::LaserRangeFinder *laser_range_finder
);

void adjustBeamReadingDistance(
kt_bool & skip_cell_eval,
kt_double & beam_distance,
kt_double const & distance_to_cell,
karto::LaserRangeFinder *laser_range_finder
);

karto::Vector2<int> getLaserBeamCell(
kt_double const & angle_to_cell,
kt_double const & reading_distance
);

std::vector<karto::Vector2<int>> getScanGroupVisitedCells(
std::vector<karto::LocalizedRangeScan *> const & range_scans,
karto::LaserRangeFinder *laser_range_finder,
int const & scan_to_skip
);

void calculateScanGroupMutualInformation(
std::vector<karto::Vector2<int>> const & visited_cells,
std::vector<kt_double> & scans_mutual_information
);

int findClosestLaserIndexToCell(
karto::Vector2<int> const & cell,
karto::Pose2 const & grid_scan_pose);
kmilo7204 marked this conversation as resolved.
Show resolved Hide resolved

void calculateCellProbabilities(
std::vector<karto::LocalizedRangeScan *> const & range_scans,
std::vector<karto::Vector2<int>> & visited_cells,
karto::Vector2<int> const & cell,
karto::LaserRangeFinder *laser_range_finder,
int const & scan_to_skip
);

void resizeGridFromScans(
std::vector<karto::LocalizedRangeScan *> const & range_scans
);

std::vector<kt_double> getScanGroupMutualInformation(
std::vector<karto::LocalizedRangeScan *> const & range_scans
);

// Mutual information
kt_double calculateInformationContent(kt_double prob);
kt_double measurementOutcomeEntropy(map_tuple const& meas_outcome);
kt_double calculateProbabilityFromLogOdds(kt_double log);
kmilo7204 marked this conversation as resolved.
Show resolved Hide resolved

// Measurement outcomes probabilities
void appendCellProbabilities(std::vector<kt_double>& measurements, karto::Vector2<int> const & cell);
std::unordered_map<map_tuple, kt_double, utils::tuple_hash::HashTuple> computeMeasurementOutcomesHistogram(std::vector<std::vector<kt_double>>& meas_outcm);
void insertMeasurementOutcome(map_tuple tuple, kt_double probability, std::unordered_map<map_tuple, kt_double, utils::tuple_hash::HashTuple>& map);

// Measurements calculations <P(free), P(Occ), P(Unk)>
kt_double calculateScanMassProbabilityBetween(kt_double range_1, kt_double range_2);

private:
// Data structures
std::map<karto::Vector2<int>, std::vector<std::vector<kt_double>>> m_cell_probabilities;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kmilo7204 perf: IIUC this is a stack of sparse, 3D matrices ie. probability of a measurement outcomes for M scans at each relevant cell (x, y). A binary tree of dynamic arrays of dynamic arrays may be efficient in space but I wouldn't expect good performance. Memory is all over the place, so cache locality goes out the window.


We could get away with a dynamic array of tuples if we reversed the order of iteration. It's a non-trivial change, so bear with me. For every cell in the bounded grid, find all scans within maximum range radius, then find the beams that hit the cell. That way we no longer need a matrix.

To find all beams that hit a cell in O(1), we need to know what angular range is occluded by the cell box so we can index the array of laser range readings (not point readings). To do that, we could compute the position of all four cell box vertices in the scan frame, and then find the pair of vertices that subtend the outermost lines through the origin.

Drawing sketchpad

We can do that by minimizing the dot product. Note this would no longer require ray casting.


const kt_double l_free = log(0.3 / (1.0 - 0.3));
const kt_double l_occ = log(0.7 / (1.0 - 0.7));
const kt_double l_o = log(0.5 / (1.0 - 0.5));
kmilo7204 marked this conversation as resolved.
Show resolved Hide resolved

kt_double m_max_sensor_range;
kt_double m_cell_resol;
kt_double m_obs_lambda;
kt_double m_obs_nu;
kt_double m_map_dist;

Eigen::MatrixXd m_mutual_grid;
Eigen::MatrixXi m_visited_grid;

kt_double m_upper_limit_x;
kt_double m_upper_limit_y;
kt_double m_lower_limit_x;
kt_double m_lower_limit_y;

kt_double m_map_dim_x;
kt_double m_map_dim_y;
};

#endif
5 changes: 5 additions & 0 deletions include/slam_toolbox/experimental/slam_toolbox_lifelong.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@

#include <memory>
#include "slam_toolbox/slam_toolbox_common.hpp"
#include "slam_toolbox/experimental/information_estimates.hpp"

namespace slam_toolbox
{

class LifelongSlamToolbox : public SlamToolbox
{

public:
explicit LifelongSlamToolbox(rclcpp::NodeOptions options);
~LifelongSlamToolbox() {}
Expand Down Expand Up @@ -74,6 +76,9 @@ class LifelongSlamToolbox : public SlamToolbox
double candidates_scale_;
double iou_match_;
double nearby_penalty_;

InformationEstimates inf_estimates_{10.0, 0.05, 0.35, 0.28};
kmilo7204 marked this conversation as resolved.
Show resolved Hide resolved

};

} // namespace slam_toolbox
Expand Down
79 changes: 79 additions & 0 deletions include/slam_toolbox/experimental/utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#ifndef SLAM_TOOLBOX__EXPERIMENTAL__UTILS_HPP_
#define SLAM_TOOLBOX__EXPERIMENTAL__UTILS_HPP_

#include <algorithm>
#include <memory>
#include <vector>
#include <tuple>
#include <cmath>
#include <map>
#include <unordered_map>
#include "lib/karto_sdk/include/karto_sdk/Karto.h"
#include "Eigen/Core"

namespace utils
{
namespace grid_operations
{
void updateCellLimits(std::vector<kt_double>& initial_x,
std::vector<kt_double>& initial_y,
std::vector<kt_double>& final_x,
std::vector<kt_double>& final_y,
kt_double limit_x,
kt_double limit_y,
std::vector<kt_double>& cell_limits,
karto::Vector2<int> const& robot_grid_pos,
karto::Vector2<int> const& final_grid_pos,
kt_double resolution
);

int signum(int num);

karto::Vector2<int> getGridPosition(
karto::Vector2<kt_double> const& position,
kt_double resolution
);

karto::Vector2<kt_double> calculateCellIntersectionPoints(
karto::Vector2<kt_double> const & laser_start,
karto::Vector2<kt_double> const & laser_end,
karto::Vector2<kt_double> const & cell_start,
karto::Vector2<kt_double> const & cell_end
);

std::pair<std::vector<kt_double>, std::vector<kt_double>> computeLineBoxIntersection(
karto::Vector2<kt_double> const & laser_start,
karto::Vector2<kt_double> const & laser_end,
karto::Vector2<int> const& robot_grid_pos,
karto::Vector2<int> const& final_grid_pos,
kt_double limit_x,
kt_double limit_y,
kt_double resolution
);

void clearVisitedCells(Eigen::MatrixXd & grid);

void clearVisitedCells(Eigen::MatrixXi & grid);
} // namespace grid_operations

namespace tuple_hash
{
struct HashTuple
{
std::size_t operator() (std::tuple<int, int, int> const& key) const
{
/**
* Tuple Hashing
*/
std::size_t hash = 5381u;
hash = (hash << 5) + hash + std::get<0>(key);
hash = (hash << 5) + hash + std::get<1>(key);
hash = (hash << 5) + hash + std::get<2>(key);
return hash;
}
};
} // namespace tuple_hash

} // namespace utils

#endif
Loading