Skip to content

Commit

Permalink
Clean up and examples (#10)
Browse files Browse the repository at this point in the history
* Some early cleanup

* license blurbs

* Some more fixes

* Makefile, nixfile

* Add example video

* Update README.md

* remove video because eww

* smaller gif

* Update readme

* Format readme differently

* More readme

* params

* Build for all pythons?

* Installation instructions

* build or older versions as well

* bump
  • Loading branch information
safijari authored Jun 2, 2024
1 parent 60f0fa6 commit 2af9989
Show file tree
Hide file tree
Showing 17 changed files with 262 additions and 637 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ jobs:
- name: Initialize submodule
run: git submodule update --init --recursive
- name: Build in manylinux container
run: docker run --rm -v `pwd`:/repo --rm safijari/manylinux_2_28-x64 /repo/build.sh
run: docker run --rm -v `pwd`:/repo --rm safijari/manylinux_2_28-x64 /repo/build.sh manylinux_2_28-x64
- name: Build in manylinux container legacy
run: docker run --rm -v `pwd`:/repo --rm safijari/manylinux2014 /repo/build.sh manylinux_2_28-x64
- name: Tar up artifacts
run: tar -czf dist.tar.gz dist/
- uses: actions/upload-artifact@main
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
setup:
git submodule update --init
pip install pybind11_cmake
56 changes: 46 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,52 @@
# YAG SLAM (Yet Another Graph SLAM)

Quick blurb on project goals: YAG SLAM is meant to be a complete graph SLAM system for life long mapping for robots using either 2D or 3D sensors. In its current form it is basically the same as Open Karto, even keeping the scan matcher from Karto mostly as is. The graph bits (including serialization/deserialization) however are implemented in Python and SBA is being used to do the graph optimization.
<table>
<tr>
<td><img src="https://github.com/safijari/yag-slam/assets/5191844/bf384bba-073f-450d-9490-63a302fa11e9" width="300" height="300"/> </td>
<td><img src="https://user-images.githubusercontent.com/5191844/64484217-e443fe80-d1c3-11e9-8f27-9fa95e7b845b.png" width="300" height="300"/></td>
</tr>
</table>

Here are the rough goals of this project:
This project is meant to be both an occupancy grid mapping package to be used in ROS as well as a library which can be used to build mapping related tools and algorithms. The core of the library is the scan matcher lifted straight from Karto and exposed to Python through the use of Pybind11 (see `src/PythonInterface.cpp`)

- Code should be easy to understand, maintain, and add to (hence the focus on Python as an interface).
- Support ROS without needing ROS as I intend to use the API exposed by this codebase in a variety of situations/cloud services that are related to robotics but aren't "on a robot".
- Do map saving, loading, and modification using portable formats (currently `Graph state -> dict -> msgpack`) to allow for tool development in a variety of ways.
- Support any sensor so long as a scan matcher and a loop closure system are supplied.
The goals of the project are:
- Code should be easy to understand, maintain, and add to. The main interface for this library is Python with the computationally intensive parts relegated to either jit compiled Python (using numba) or C++ (scan matching, sparse bundle adjustment)
- Be usable in ROS but don't require it. This package is released on PyPI and should work in any modern python version. I use the API exposed by this codebase in a variety of situations/cloud services that are related to robotics but aren't "on a robot". A recent example of this is a lifelong mapping system.
- Do map saving, loading, and modification using portable formats (currently `Graph state -> dict -> compressed msgpack`) to allow for tool development outside of ROS. I shouldn't need to provide specialized code to my web developer colleagues for them to just render the state of the underlying graph (see above for an example).
- Support any sensor type so long as a scan matcher and a loop closure checker are supplied.

Underlying Graph
![graph slam](https://user-images.githubusercontent.com/5191844/64484217-e443fe80-d1c3-11e9-8f27-9fa95e7b845b.png)
## Installation
There isn't yet a ROS package (and there may never be). YAG SLAM can be installed via pip. For ROS Noetic you might need to install the packages using the commands below due to the pip version on Ubuntu 20.04

Occupancy Grid Map
![occupancy grid map](https://user-images.githubusercontent.com/5191844/64672265-cffc3d80-d41f-11e9-915b-f984df9bb1d9.png)
```pip3 install https://files.pythonhosted.org/packages/4f/39/bda0165a68b59ca277625791b788510a6d93b160476fec4e2f0585f9b581/sparse_bundle_adjustment-0.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl```

Alternatively you can build the Dockerfile.

## How to use this package
For mapping in ROS 1 simply running the `slam_node_ros1` script is sufficient. Parameters can be set through ROS and are the same as the ones used in Karto and you can get more details on this from the Karto readme. Instead of describing them I'll give comments on how to tune them.

| Parameter | Default | Comment |
|:---------------------------------|:--------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `angle_variance_penalty` | 0.3 | Increase if your odom is good |
| `distance_variance_penalty` | 0.5 | Increase if your odom is good |
| `coarse_search_angle_offset` | 0.349 | Can decrease if odom is good, impacts compute time |
| `coarse_angle_resolution` | 0.0349 | Probably don't need to change this |
| `fine_search_angle_resolution` | 0.00349 | Probably don't need to change this |
| `use_response_expansion` | True | Can probably disable is odom is good, can increase compute time |
| `range_threshold` | 30 | Set based on reliable range for your sensor |
| `search_size` | 0.5 | dx and dy for scan matcher, can decrease if odom is good, impacts compute time |
| `resolution` | 0.01 | Steps in x and y direction for scan matcher, search_size must be an integer multiple, impacts compute time |
| `smear_deviation` | 0.05 | Must be between `0.5 * resolution` and `10 * resolution`, determines size of gaussian described in the (SRI paper)[https://april.eecs.umich.edu/pdfs/olson2009icra.pdf], larger values can help when odom is bad |
| `loop_matching_search_size` | 4 | Same as search size but for finding loops, larger values would be needed if odom and sensor quality are bad but that can also lead to more incorrect loop closures, impacts compute time |
| `loop_matching_resolution` | 0.05 | Same as resolution but for loop search |
| `loop_meatching_smear_deviation` | 0.05 | Same ... you know |
| `odom_frame` | `odom` | |
| `map_frame` | `map` | |
| `min_distance` | 0.5 | Linear distance (m) that the robot must travel to trigger integrating a scan, smaller values could lead to error accumulation but might be needed if odom is bad |
| `min_rotation` | 0.5 | Rotation (rad) ... |
| `loop_search_min_chain_size` | 10 | Number of connected together scans from a previous traversal in one area to consider for loop closure, depends a bit on `min_distance` and `min_rotation`, higher values lead to less likely loop closures |
| `min_response_coarse` | 0.35 | Minimum confidence of loop closure scan matcher for considering a loop closure, larger values lead to higher quality but less likely loop closures |
| `min_response_fine` | 0.45 | Same as previous but for the second stage of accepting a loop closure candidate |
| `range_threshold_for_map` | 12 | Effective range of sensor for creating the map. Larger values could lead to a less clean map, smaller values require more data near all obstacles |
| `scan_buffer_len` | 10 | How many running scans to keep to correct odom errors against, maybe don't decrease this, larger values can lead to higher compute time and possibly worse performance as well |
| `map_resolution` | 0.05 | How many meters to a pixel in the final map |
13 changes: 3 additions & 10 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,9 @@ set -e

yum install boost-thread boost-chrono boost-devel -y

/opt/python/cp311-cp311/bin/pip install -U auditwheel
/opt/python/cp38-cp38/bin/pip install -U auditwheel

for folder in /opt/python/cp311*
do
echo $folder
$folder/bin/pip install pybind11 pybind11-cmake
$folder/bin/python setup.py bdist_wheel
done

for folder in /opt/python/cp37*
for folder in /opt/python/cp3*
do
echo $folder
$folder/bin/pip install pybind11 pybind11-cmake
Expand All @@ -31,5 +24,5 @@ cd dist

for file in ./*
do
/opt/python/cp311-cp311/bin/auditwheel -v repair --plat manylinux_2_28_x86_64 $file
/opt/python/cp38-cp38/bin/auditwheel -v repair --plat $1 $file
done
48 changes: 48 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{ pkgs ? import <nixpkgs> {} }:
let
pypkgs = import (fetchTarball "https://github.com/cachix/nixpkgs-python/archive/refs/heads/main.zip");
in
pkgs.mkShell {

buildInputs = with pkgs; [
(python311.withPackages(ps: with ps;
[virtualenvwrapper pip requests pyperclip]))
stdenv.cc.cc

# For Numpy
zlib

# For rendering gym environments
libGL
libGLU
xorg.libX11

xorg.libX11.dev
xorg.libxcb.dev
glib.dev
glib.out
gobject-introspection
gtk3
gtk3-x11
gtk3.dev
libffi.dev
gcc
pkg-config
cairo
cairo.dev
mesa.osmesa
cmake
boost
];

shellHook = ''
# for Numpy
export LD_LIBRARY_PATH=${pkgs.zlib}/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=${pkgs.mesa.osmesa}/lib:$LD_LIBRARY_PATH
# GL libraries (for gym environment rendering)
export LD_LIBRARY_PATH=${pkgs.libGL}/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=${pkgs.libGLU}/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=${pkgs.glib.out}/lib:$LD_LIBRARY_PATH
'';
}
Loading

0 comments on commit 2af9989

Please sign in to comment.